-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Tools: update release date checker to check for release date vs. last commit of release #16712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
a9e241f
3c5b5ea
b247687
2d772a7
a3e1f3c
56a7812
b67b7ab
3b4a698
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,21 +15,23 @@ | |
| import sys | ||
|
|
||
| import github | ||
|
|
||
| import exports | ||
| import utils | ||
|
|
||
| from colorama import Fore, Style | ||
| from packaging import version | ||
|
|
||
|
|
||
| # Thrown on errors related to release date. | ||
| class ReleaseDateError(Exception): | ||
| # Thrown on errors related to release date or version. | ||
| class ReleaseDateVersionError(Exception): | ||
| pass | ||
|
|
||
|
|
||
| # Format a datetime object as UTC YYYY-MM-DD. | ||
| def format_utc_date(date): | ||
| # We only handle naive datetime objects right now, which is what PyGithub | ||
| # appears to be handing us. | ||
| assert (date.tzinfo is None) | ||
| assert date.tzinfo is None | ||
|
moderation marked this conversation as resolved.
Outdated
|
||
| return date.date().isoformat() | ||
|
|
||
|
|
||
|
|
@@ -38,35 +40,67 @@ def format_utc_date(date): | |
| def verify_and_print_latest_release(dep, repo, metadata_version, release_date): | ||
| try: | ||
| latest_release = repo.get_latest_release() | ||
| if latest_release.created_at > release_date and latest_release.tag_name != metadata_version: | ||
| print( | ||
| f'*WARNING* {dep} has a newer release than {metadata_version}@<{release_date}>: ' | ||
| f'{latest_release.tag_name}@<{latest_release.created_at}>') | ||
| except github.UnknownObjectException: | ||
| pass | ||
| except github.GithubException as err: | ||
| # Repositories can not have releases or if they have releases may not publish a latest releases. Return | ||
| print(f'GithubException {repo.name}: {err.data} {err.status} while getting latest release.') | ||
| return | ||
| if latest_release.created_at > release_date and latest_release.tag_name != metadata_version: | ||
| print( | ||
| f'{Fore.YELLOW}*WARNING* {dep} has a newer release than {metadata_version}@<{release_date}>: ' | ||
| f'{latest_release.tag_name}@<{latest_release.created_at}>{Style.RESET_ALL}') | ||
|
|
||
|
|
||
| # Print GitHub release date, throw ReleaseDateError on mismatch with metadata release date. | ||
| # Print GitHub release date, throw ReleaseDateVersionError on mismatch with metadata release date. | ||
| def verify_and_print_release_date(dep, github_release_date, metadata_release_date): | ||
| mismatch = '' | ||
| iso_release_date = format_utc_date(github_release_date) | ||
| print(f'{dep} has a GitHub release date {iso_release_date}') | ||
| print(f'{Fore.GREEN}{dep} has a GitHub release date {iso_release_date}{Style.RESET_ALL}') | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i would move this after the condition/raise - and in the raise provide more info about the mismatch
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way this is structured today makes finding the date mismatches easy to find. The script outputs the real GH date followed by the exception that shows the erroneous date. I don't expect many people to view this but helpful for myself and the deps maintainers. But let me know if I'm missing something
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. kinda unreliable iiuc - because one is going to stdout and the other to stderr there is no guarantee that both will be shown and if they are that they will be in correct order not a blocker - but that is the reason i suggested this
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (also that it flashes green even when its about to fail) |
||
| if iso_release_date != metadata_release_date: | ||
| raise ReleaseDateError(f'Mismatch with metadata release date of {metadata_release_date}') | ||
| raise ReleaseDateVersionError( | ||
| f'Mismatch with metadata release date of {metadata_release_date}') | ||
|
|
||
|
|
||
| # Extract release date from GitHub API for tagged releases. | ||
| def get_tagged_release_date(repo, metadata_version, github_release): | ||
|
|
||
| try: | ||
| latest = repo.get_latest_release() | ||
| except github.GithubException as err: | ||
| # Repositories can not have releases or if they have releases may not publish a latest releases. If this is the case we keep going | ||
| latest = '' | ||
| print(f'GithubException {repo.name}: {err.data} {err.status} while getting latest release.') | ||
| pass | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this im wondering if it should
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've improved the error handling using the Github exception data and added comments explaining why it is OK to not find latest releases in some cases and keep processing.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok - but the |
||
|
|
||
| # Extract release date from GitHub API. | ||
| def get_release_date(repo, metadata_version, github_release): | ||
| if github_release.tagged: | ||
| if latest and github_release.version <= latest.tag_name: | ||
| release = repo.get_release(github_release.version) | ||
| return release.published_at | ||
| else: | ||
| tags = repo.get_tags() | ||
| for tag in tags: | ||
| current_metadata_tag_commit_date = '' | ||
| for tag in tags.reversed: | ||
| if tag.name == github_release.version: | ||
| return tag.commit.commit.committer.date | ||
| return None | ||
| else: | ||
| assert (metadata_version == github_release.version) | ||
| commit = repo.get_commit(github_release.version) | ||
| return commit.commit.committer.date | ||
| current_metadata_tag_commit_date = tag.commit.commit.committer.date | ||
| if not version.parse(tag.name).is_prerelease and version.parse( | ||
| tag.name) > version.parse(github_release.version): | ||
|
moderation marked this conversation as resolved.
|
||
| print( | ||
| f'{Fore.YELLOW}*WARNING* {repo.name} has a newer release than {github_release.version}@<{current_metadata_tag_commit_date}>: ' | ||
| f'{tag.name}@<{tag.commit.commit.committer.date}>{Style.RESET_ALL}') | ||
| return current_metadata_tag_commit_date | ||
|
|
||
|
|
||
| # Extract release date from GitHub API for untagged releases. | ||
| def get_untagged_release_date(repo, metadata_version, github_release): | ||
| if metadata_version != github_release.version: | ||
| raise ReleaseDateVersionError( | ||
| f'Mismatch with metadata version {metadata_version} and github release version {github_release.version}' | ||
| ) | ||
| commit = repo.get_commit(github_release.version) | ||
| commits = repo.get_commits(since=commit.commit.committer.date) | ||
| if commits.totalCount > 1: | ||
| print( | ||
| f'{Fore.YELLOW}*WARNING* {repo.name} has {str(commits.totalCount - 1)} commits since {github_release.version}@<{commit.commit.committer.date}>{Style.RESET_ALL}' | ||
| ) | ||
| return commit.commit.committer.date | ||
|
|
||
|
|
||
| # Verify release dates in metadata against GitHub API. | ||
|
|
@@ -75,19 +109,23 @@ def verify_and_print_release_dates(repository_locations, github_instance): | |
| release_date = None | ||
| # Obtain release information from GitHub API. | ||
| github_release = utils.get_github_release_from_urls(metadata['urls']) | ||
| print('github_release: ', github_release) | ||
| if not github_release: | ||
| print(f'{dep} is not a GitHub repository') | ||
| continue | ||
| repo = github_instance.get_repo(f'{github_release.organization}/{github_release.project}') | ||
| release_date = get_release_date(repo, metadata['version'], github_release) | ||
| if github_release.tagged: | ||
| release_date = get_tagged_release_date(repo, metadata['version'], github_release) | ||
| else: | ||
| release_date = get_untagged_release_date(repo, metadata['version'], github_release) | ||
| if release_date: | ||
| # Check whether there is a more recent version and warn if necessary. | ||
| verify_and_print_latest_release(dep, repo, github_release.version, release_date) | ||
| # Verify that the release date in metadata and GitHub correspond, | ||
| # otherwise throw ReleaseDateError. | ||
| # otherwise throw ReleaseDateVersionError. | ||
| verify_and_print_release_date(dep, release_date, metadata['release_date']) | ||
| else: | ||
| raise ReleaseDateError( | ||
| raise ReleaseDateVersionError( | ||
| f'{dep} is a GitHub repository with no no inferrable release date') | ||
|
|
||
|
|
||
|
|
@@ -105,8 +143,8 @@ def verify_and_print_release_dates(repository_locations, github_instance): | |
| try: | ||
| verify_and_print_release_dates( | ||
| spec_loader(path_module.REPOSITORY_LOCATIONS_SPEC), github.Github(access_token)) | ||
| except ReleaseDateError as e: | ||
| except ReleaseDateVersionError as e: | ||
| print( | ||
| f'An error occurred while processing {path}, please verify the correctness of the ' | ||
| f'metadata: {e}') | ||
| f'{Fore.RED}An error occurred while processing {path}, please verify the correctness of the ' | ||
| f'metadata: {e}{Style.RESET_ALL}') | ||
| sys.exit(1) | ||
Uh oh!
There was an error while loading. Please reload this page.