diff --git a/src/main.py b/src/main.py index 0b59f3cf..c6c8db06 100644 --- a/src/main.py +++ b/src/main.py @@ -79,12 +79,12 @@ def _create_new_version_artifacts(args): raise Exception() base_patch_version = get_semver(args.base_patch_version) - if base_patch_version.prerelease: - # We don't support creating new patch/major/minor versions from a prerelease version - # Re-run the build command for the prerelease version again to pick the latest versions - # of the marquee packages + if base_patch_version.prerelease and args.pre_release_identifier: + # We support creating new patch/major/minor versions from a pre-release version. + # But We don't support passing the pre_release_identifier parameter while creating a new + # patch/major/minor versions from the pre-release version. raise Exception() - next_version = getattr(base_patch_version, runtime_version_upgrade_func)() + next_version = _get_next_version(base_patch_version, runtime_version_upgrade_func) if args.pre_release_identifier: next_version = next_version.replace(prerelease=args.pre_release_identifier) @@ -291,32 +291,41 @@ def _build_local_images( return generated_image_ids, generated_image_versions +def _get_next_version(current_version: Version, upgrade_func: str) -> Version: + next_version = getattr(current_version, upgrade_func)() + if current_version.prerelease: + # Semver Ignores prerelease identifier when we do bump_{patch/minor/major} + next_version = next_version.replace(prerelease=current_version.prerelease) + return next_version + + # At some point of time, let's say some patch versions exist for both 2.6 and 2.7, and we create new patch # versions for both of them. Now, for the new 2.6.x, we can tag it as '2.6.x-cpu' and '2.6-cpu' but NOT '2-cpu' because # there is a more recent version (i.e. 2.7.x) that should be considered '2-cpu'. So, given a patch version, the # following function returns a list of versions for which the current patch version is latest for. +# For versions with pre-release identifier, this method will return the appropriate tags +# Example: For an version 2.0.0-beta, this method will return [2.0.0-beta, 2.0-beta, 2-beta, +# latest-beta] def _get_version_tags(target_version: Version, env_out_file_name: str) -> list[str]: # First, add '2.6.x' as is. res = [str(target_version)] - # If this is a pre-release version, then don't add additional tags - if target_version.prerelease: - return res + prerelease_version_suffix = f"-{target_version.prerelease}" if target_version.prerelease else "" # If we were to add '2.6', check if '2.6.(x+1)' is present. - if not is_exists_dir_for_version(target_version.bump_patch(), env_out_file_name): - res.append(f"{target_version.major}.{target_version.minor}") + if not is_exists_dir_for_version(_get_next_version(target_version, "bump_patch"), env_out_file_name): + res.append(f"{target_version.major}.{target_version.minor}{prerelease_version_suffix}") else: return res # If we were to add '2', check if '2.7' is present. - if not is_exists_dir_for_version(target_version.bump_minor(), env_out_file_name): - res.append(str(target_version.major)) + if not is_exists_dir_for_version(_get_next_version(target_version, "bump_minor"), env_out_file_name): + res.append(f"{target_version.major}{prerelease_version_suffix}") else: return res # If we were to add 'latest', check if '3.0.0' is present. - if not is_exists_dir_for_version(target_version.bump_major(), env_out_file_name): - res.append("latest") + if not is_exists_dir_for_version(_get_next_version(target_version, "bump_major"), env_out_file_name): + res.append(f"latest{prerelease_version_suffix}") return res diff --git a/test/test_main.py b/test/test_main.py index e1ed2752..7fc3b372 100644 --- a/test/test_main.py +++ b/test/test_main.py @@ -169,13 +169,13 @@ def test_get_semver_version(): def test_new_version_artifacts_for_an_input_prerelease_version(): input_version = "1.23.0-beta" - args = CreateVersionArgs("patch", input_version) + args = CreateVersionArgs("patch", input_version, pre_release_identifier="new-beta") with pytest.raises(Exception): create_patch_version_artifacts(args) - args = CreateVersionArgs("minor", input_version) + args = CreateVersionArgs("minor", input_version, pre_release_identifier="new-beta") with pytest.raises(Exception): create_minor_version_artifacts(args) - args = CreateVersionArgs("major", input_version) + args = CreateVersionArgs("major", input_version, pre_release_identifier="new-beta") with pytest.raises(Exception): create_major_version_artifacts(args) @@ -528,8 +528,38 @@ def test_get_version_tags(mock_path_exists): # case 4.2 The patch version is not a prerelease version mock_path_exists.side_effect = [True, True] assert _get_version_tags(version, file_name) == ["1.124.5"] - # case 5: The given version includes a prerelease identifier - assert _get_version_tags(get_semver("1.124.5-beta"), file_name) == ["1.124.5-beta"] + + +@patch("os.path.exists") +def test_get_version_tags_with_prerelease_identifier(mock_path_exists): + version = get_semver("1.124.5-beta") + file_name = "cpu.env.out" + # case 1: The given version is the latest for patch, minor and major + mock_path_exists.side_effect = [False, False, False] + assert _get_version_tags(version, file_name) == ["1.124.5-beta", "1.124-beta", "1-beta", "latest-beta"] + # case 2: The given version is the latest for patch, minor but not major + # case 2.1 The major version is a different prerelease version + mock_path_exists.side_effect = [False, False, True, False] + assert _get_version_tags(version, file_name) == ["1.124.5-beta", "1.124-beta", "1-beta", "latest-beta"] + # case 2.2 The major version is not a prerelease version + mock_path_exists.side_effect = [False, False, True, True] + assert _get_version_tags(version, file_name) == ["1.124.5-beta", "1.124-beta", "1-beta"] + # case 3: The given version is the latest for patch and major but not for minor + # case 3.1 The minor version is a prerelease version (we need to mock path.exists for major + # version twice - one for the actual directory, one for the docker file) + mock_path_exists.side_effect = [False, True, False, True, True] + assert _get_version_tags(version, file_name) == ["1.124.5-beta", "1.124-beta", "1-beta"] + # case 3.2 The minor version is not a prerelease version + mock_path_exists.side_effect = [False, True, True] + assert _get_version_tags(version, file_name) == ["1.124.5-beta", "1.124-beta"] + # case 4: The given version is not the latest for patch, minor, major + # case 4.1 The patch version is a prerelease version (we need to mock path.exists for minor + # and major twice - one for the actual directory, one for the docker file) + mock_path_exists.side_effect = [True, False, True, True, True, True] + assert _get_version_tags(version, file_name) == ["1.124.5-beta", "1.124-beta"] + # case 4.2 The patch version is not a prerelease version + mock_path_exists.side_effect = [True, True] + assert _get_version_tags(version, file_name) == ["1.124.5-beta"] def _test_push_images_upstream(mocker, repository):