-
Notifications
You must be signed in to change notification settings - Fork 2.2k
increase and verify version functions #6980
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 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,18 @@ | |
| # | ||
| # python utilities/set_versions.py --ut [library|external_dependency|all] --bt [client|data|management] --bq <BuildQualifierString> --ar <artifactId> | ||
| # | ||
| # Use case: increment the version of a given artifact in the approprate version_[client|data|management].txt file | ||
| # | ||
| # python eng/versioning/set_versions.py --bt [client|data|management] --increase-version --artifact-id <artifactId> | ||
| # For example: To update increase the version of azure-core | ||
| # python eng/versioning/update_versions.py --bt client --iv -ar azure-core | ||
| # | ||
| # Use case: verify the version of a given artifact in the approprate version_[client|data|management].txt file | ||
| # | ||
| # python eng/versioning/set_versions.py --bt [client|data|management] --verify-version --artifact-id <artifactId> | ||
| # For example: To update increase the version of azure-core | ||
| # python eng/versioning/update_versions.py --bt client --vv -ar azure-core | ||
| # | ||
| # The script must be run at the root of azure-sdk-for-java. | ||
|
|
||
| import argparse | ||
|
|
@@ -28,11 +40,15 @@ | |
| from utils import CodeModule | ||
| from utils import UpdateType | ||
| from utils import version_regex_str_with_anchor | ||
| from utils import version_regex_str_with_names_anchored | ||
| from utils import prerelease_version_regex_with_name | ||
|
|
||
| # The regex string we want should be the anchored one since the entire string is what's being matched | ||
| version_regex = re.compile(version_regex_str_with_anchor) | ||
| version_regex_named = re.compile(version_regex_str_with_names_anchored) | ||
| prerelease_regex_named = re.compile(prerelease_version_regex_with_name) | ||
|
|
||
| def update_versions_file(update_type, build_type, build_qualifier, artifact_id): | ||
| def update_versions_file_for_nightly_devops(update_type, build_type, build_qualifier, artifact_id): | ||
|
|
||
| version_file = os.path.normpath('eng/versioning/version_' + build_type.name + '.txt') | ||
| print('version_file=' + version_file) | ||
|
|
@@ -93,23 +109,133 @@ def prep_version_file_for_source_testing(build_type): | |
| f.write(line) | ||
|
|
||
| return file_changed | ||
|
|
||
|
|
||
| # given a build type and artifact id | ||
| def increase_version_for_artifact(build_type, artifact_id): | ||
|
|
||
| if not build_type: | ||
| raise ValueError('build_type cannot be empty.') | ||
|
|
||
| if not artifact_id: | ||
| raise ValueError('artifact_id cannot be empty.') | ||
|
|
||
| version_file = os.path.normpath('eng/versioning/version_' + build_type.name + '.txt') | ||
| print('version_file=' + version_file) | ||
|
|
||
| artifact_found = False | ||
| newlines = [] | ||
| with open(version_file, encoding='utf-8') as f: | ||
| for raw_line in f: | ||
| stripped_line = raw_line.strip() | ||
| if not stripped_line or stripped_line.startswith('#'): | ||
| newlines.append(raw_line) | ||
| else: | ||
| module = CodeModule(stripped_line) | ||
| # Tick up the version here. If the version is already a pre-release | ||
| # version then just increment the revision. Otherwise increment the | ||
| # hotfix version and add the prerelease tag "-beta.1" to the end | ||
| if module.artifact_id == artifact_id: | ||
| artifact_found = True | ||
| vmatch = version_regex_named.match(module.current) | ||
| if (vmatch.group('prerelease') is not None): | ||
| prever = prerelease_regex_named.match(vmatch.group('prerelease')) | ||
| rev = int(prever.group('revision')) | ||
| rev += 1 | ||
| new_version = '{}.{}.{}-beta.{}'.format(vmatch.group('major'), vmatch.group('minor'), vmatch.group('patch'), str(rev)) | ||
| else: | ||
| hotfix = int(vmatch.group('patch')) | ||
| hotfix += 1 | ||
| new_version = '{}.{}.{}-beta.1'.format(vmatch.group('major'), vmatch.group('minor'), hotfix) | ||
| print('artifact_id {}, previous version={}, new current version={}'.format(artifact_id, module.current, new_version)) | ||
| module.current = new_version | ||
| newlines.append(module.string_for_version_file()) | ||
|
|
||
| if not artifact_found: | ||
| raise ValueError('artifact_id ({}) was not found in version file {}'.format(artifact_id, version_file)) | ||
|
|
||
| with open(version_file, 'w', encoding='utf-8') as f: | ||
| for line in newlines: | ||
| f.write(line) | ||
|
|
||
| # Verify that the current version of an artifact matches our versioning scheme. This is meant to be called | ||
| # as part of the release pipeline for a given artifact to verify that we don't accidentally release a version | ||
| # that doesn't match our versioning scheme | ||
| def verify_current_version_of_artifact(build_type, artifact_id): | ||
| if not build_type: | ||
| raise ValueError('build_type cannot be empty.') | ||
|
|
||
| if not artifact_id: | ||
| raise ValueError('artifact_id cannot be empty.') | ||
|
|
||
| version_file = os.path.normpath('eng/versioning/version_' + build_type.name + '.txt') | ||
| print('version_file=' + version_file) | ||
|
|
||
| artifact_found = False | ||
| with open(version_file, encoding='utf-8') as f: | ||
| for raw_line in f: | ||
| stripped_line = raw_line.strip() | ||
| if not stripped_line or stripped_line.startswith('#'): | ||
| continue | ||
| else: | ||
| module = CodeModule(stripped_line) | ||
| # verify the current version of the artifact matches our version schema which is one | ||
| # of the following: | ||
| # <major>.<minor>.<patch/hotfix> | ||
| # <major>.<minor>.<patch/hotfix>-beta.<prerelease> | ||
| if module.artifact_id == artifact_id: | ||
| artifact_found = True | ||
| vmatch = version_regex_named.match(module.current) | ||
| temp_ver = '{}.{}.{}'.format(vmatch.group('major'), vmatch.group('minor'), vmatch.group('patch')) | ||
| # we should never have buildmetadata in our versioning scheme | ||
| if vmatch.group('buildmetadata') is not None: | ||
| raise ValueError('artifact ({}) version ({}) in version file ({}) is not a correct version to release. buildmetadata is set and should never be {}'.format(artifact_id, module.current, version_file, vmatch.group('buildmetadata'))) | ||
|
|
||
| # reconstruct the version from the semver pieces and it should match exactly the current | ||
| # version in the module | ||
| # If there's a pre-release version it should be beta.X | ||
| if vmatch.group('prerelease') is not None: | ||
| prerel = vmatch.group('prerelease') | ||
|
|
||
| if prerelease_regex_named.match(prerel) is None: | ||
| raise ValueError('artifact ({}) version ({}) in version file ({}) is not a correct version to release. The accepted prerelease tag is (beta.X) and the current prerelease tag is ({})'.format(artifact_id, module.current, version_file, prerel)) | ||
|
|
||
| prever = prerelease_regex_named.match(prerel) | ||
| rev = int(prever.group('revision')) | ||
| temp_ver = '{}-beta.{}'.format(temp_ver, str(rev)) | ||
|
|
||
| # last but not least, for sanity verify that the version constructed from the | ||
| # semver pieces matches module's current version | ||
| if module.current != temp_ver: | ||
| raise ValueError('artifact ({}) version ({}) in version file ({}) does not match the version constructed from the semver pieces ({})'.format(artifact_id, module.current, version_file, temp_ver)) | ||
|
|
||
| print('The version {} for artifact_id {} looks good!'.format(module.name, module.current)) | ||
|
|
||
|
|
||
| if not artifact_found: | ||
| raise ValueError('artifact_id ({}) was not found in version file {}'.format(artifact_id, version_file)) | ||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser(description='set version numbers in the appropriate version text file') | ||
| parser.add_argument('--update-type', '--ut', type=UpdateType, choices=list(UpdateType)) | ||
| parser.add_argument('--build-type', '--bt', type=BuildType, choices=list(BuildType)) | ||
| parser.add_argument('--build-qualifier', '--bq', help='build qualifier to append onto the version string.') | ||
| parser.add_argument('--artifact-id', '--ar', help='artifactId to target.') | ||
| parser.add_argument('--prep-source-testing', '--pst', action='store_true', help='prep the version file for source testing') | ||
| parser.add_argument('--increase-version', '--iv', action='store_true', help='increase the version for a given artifact') | ||
|
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. nit: minor but the other scripts call this increment-version.
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. changed to increment, will be updated with next commit |
||
| parser.add_argument('--verify-version', '--vv', action='store_true', help='verify the version for a given artifact') | ||
| args = parser.parse_args() | ||
| if (args.build_type == BuildType.management): | ||
| raise ValueError('{} is not currently supported.'.format(BuildType.management.name)) | ||
| start_time = time.time() | ||
| file_changed = False | ||
| if (args.prep_source_testing): | ||
| file_changed = prep_version_file_for_source_testing(args.build_type) | ||
| elif (args.increase_version): | ||
| increase_version_for_artifact(args.build_type, args.artifact_id) | ||
| elif (args.verify_version): | ||
| verify_current_version_of_artifact(args.build_type, args.artifact_id) | ||
| else: | ||
| update_versions_file(args.update_type, args.build_type, args.build_qualifier, args.artifact_id) | ||
| update_versions_file_for_nightly_devops(args.update_type, args.build_type, args.build_qualifier, args.artifact_id) | ||
| elapsed_time = time.time() - start_time | ||
| print('elapsed_time={}'.format(elapsed_time)) | ||
| print('Total time for replacement: {}'.format(str(timedelta(seconds=elapsed_time)))) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,10 @@ | |
| # semver format | ||
| # https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string | ||
| version_regex_str_with_anchor = r'^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' | ||
| version_regex_str_with_names_anchored = r'^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' | ||
|
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. probably worth just having the one regex with the named anchored instead of both.
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. Removed the non-named one. Will be updated with next commit. |
||
|
|
||
| # This is specific to our revision which, if there is one, needs to have the format of beta.X | ||
| prerelease_version_regex_with_name = r'^beta\.(?P<revision>0|[1-9]\d*)$' | ||
|
|
||
| class UpdateType(Enum): | ||
| external_dependency = 'external_dependency' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,8 @@ com.azure:azure-storage-file-datalake;12.0.0-beta.7;12.0.0-beta.8 | |
| com.azure:azure-storage-queue;12.1.0;12.2.0-beta.1 | ||
| com.azure:azure-e2e;1.0.0-beta.1;1.0.0-beta.1 | ||
|
|
||
| # This is a temporary fix for libaries that need the unreleased dependency version of core | ||
| # This is a temporary fix for libaries that need the unreleased dependency version of core. It's worth | ||
|
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. We should consider putting an invalid version in there something like "Unused" or "Unreleased" just so it is clear and there is no confusion later if we increment the one but not the other. |
||
| # noting that the 'current' version isn't used, these entries are for the dependency versions | ||
| unreleased_com.azure:azure-core;1.2.0-beta.1;1.2.0-beta.1 | ||
|
|
||
| # This is a temporary fix for libaries that need the unreleased dependency version of azure-core-test | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should increment the minor version by default. https://github.com/Azure/azure-sdk/blob/master/docs/policies/releases.md#java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The next commit will have this behavior as well as the link to the doc.