diff --git a/.github/scripts/test_update_dependency_changes.py b/.github/scripts/test_update_dependency_changes.py index fde9720590..2afaeec6a3 100644 --- a/.github/scripts/test_update_dependency_changes.py +++ b/.github/scripts/test_update_dependency_changes.py @@ -14,7 +14,7 @@ import sys import os sys.path.insert(0, os.path.dirname(__file__)) -from update_dependency_changes import merge_changes, render_section, normalize_version, extract_preamble +from update_dependency_changes import merge_changes, render_section, normalize_version, extract_preamble, bump_patch_if_released def test_update_then_revert(): @@ -438,6 +438,55 @@ def test_normalize_version_stable(): print("✓ Passed: stable versions unchanged\n") +def test_bump_patch_no_tag(): + """Test: version tag does not exist, should return as-is.""" + print("Test 23: bump_patch_if_released - no tag exists") + tag_exists = lambda t: False + assert bump_patch_if_released("10.3.0", tag_exists) == "10.3.0" + assert bump_patch_if_released("10.2.0", tag_exists) == "10.2.0" + print("✓ Passed: version unchanged when tag does not exist\n") + + +def test_bump_patch_tag_exists(): + """Test: version tag exists, should bump patch.""" + print("Test 24: bump_patch_if_released - tag exists") + existing_tags = {"10.3.0"} + tag_exists = lambda t: t in existing_tags + assert bump_patch_if_released("10.3.0", tag_exists) == "10.3.1", \ + f"Expected '10.3.1', got: {bump_patch_if_released('10.3.0', tag_exists)}" + print("✓ Passed: version bumped to 10.3.1\n") + + +def test_bump_patch_multiple_tags(): + """Test: multiple consecutive tags exist, should bump past all.""" + print("Test 25: bump_patch_if_released - multiple tags exist") + existing_tags = {"10.3.0", "10.3.1", "10.3.2"} + tag_exists = lambda t: t in existing_tags + assert bump_patch_if_released("10.3.0", tag_exists) == "10.3.3", \ + f"Expected '10.3.3', got: {bump_patch_if_released('10.3.0', tag_exists)}" + print("✓ Passed: version bumped past all existing tags\n") + + +def test_bump_patch_prerelease_skipped(): + """Test: pre-release versions should not be bumped.""" + print("Test 26: bump_patch_if_released - pre-release skipped") + tag_exists = lambda t: True # all tags "exist" + assert bump_patch_if_released("10.3.0-rc.1", tag_exists) == "10.3.0-rc.1" + assert bump_patch_if_released("10.3.0-rc.2", tag_exists) == "10.3.0-rc.2" + assert bump_patch_if_released("10.3.0-preview", tag_exists) == "10.3.0-preview" + print("✓ Passed: pre-release versions not bumped\n") + + +def test_bump_patch_non_zero_patch(): + """Test: version with non-zero patch, tag exists, should bump.""" + print("Test 27: bump_patch_if_released - non-zero patch version") + existing_tags = {"10.3.1"} + tag_exists = lambda t: t in existing_tags + assert bump_patch_if_released("10.3.1", tag_exists) == "10.3.2", \ + f"Expected '10.3.2', got: {bump_patch_if_released('10.3.1', tag_exists)}" + print("✓ Passed: non-zero patch correctly bumped\n") + + def run_all_tests(): """Run all test cases.""" print("=" * 70) @@ -466,9 +515,14 @@ def run_all_tests(): test_normalize_version_preview() test_normalize_version_rc() test_normalize_version_stable() + test_bump_patch_no_tag() + test_bump_patch_tag_exists() + test_bump_patch_multiple_tags() + test_bump_patch_prerelease_skipped() + test_bump_patch_non_zero_patch() print("=" * 70) - print("All 22 tests passed! ✓") + print("All 27 tests passed! ✓") print("=" * 70) print("\nTest coverage summary:") print(" ✓ Basic scenarios (update, add, remove)") @@ -478,6 +532,7 @@ def run_all_tests(): print(" ✓ Document format validation") print(" ✓ Preamble extraction (SEO block, no preamble, no heading)") print(" ✓ Version normalization (preview -> rc.1)") + print(" ✓ Patch version bump when tag already released") print("=" * 70) diff --git a/.github/scripts/update_dependency_changes.py b/.github/scripts/update_dependency_changes.py index f4f2c3db6c..02ab623ff8 100644 --- a/.github/scripts/update_dependency_changes.py +++ b/.github/scripts/update_dependency_changes.py @@ -25,6 +25,46 @@ def normalize_version(version): return version +def check_tag_exists(tag): + """Check if a git tag exists.""" + result = subprocess.run( + ["git", "tag", "-l", tag], + capture_output=True, + text=True, + ) + return result.returncode == 0 and tag in result.stdout.strip().split("\n") + + +def bump_patch_if_released(version, tag_exists_fn=None): + """If the version tag already exists, bump the patch version. + + Only applies to stable versions (no pre-release suffix like -rc.N). + """ + if tag_exists_fn is None: + tag_exists_fn = check_tag_exists + + # Only bump stable versions (no pre-release suffix) + if "-" in version: + return version + + parts = version.split(".") + if len(parts) != 3: + return version + + major, minor = parts[0], parts[1] + try: + patch = int(parts[2]) + except ValueError: + return version + + current = version + while tag_exists_fn(current): + patch += 1 + current = f"{major}.{minor}.{patch}" + + return current + + def get_version(): """Read the current version from common.props.""" try: @@ -296,6 +336,9 @@ def main(): print("Could not read version from common.props.") sys.exit(1) + version = bump_patch_if_released(version) + print(f"Resolved version: {version}") + diff = get_diff(base_ref) if not diff: print("No diff found for Directory.Packages.props.") diff --git a/.github/workflows/nuget-packages-version-change-detector.yml b/.github/workflows/nuget-packages-version-change-detector.yml index 45dba3332b..4ed7fad8de 100644 --- a/.github/workflows/nuget-packages-version-change-detector.yml +++ b/.github/workflows/nuget-packages-version-change-detector.yml @@ -44,8 +44,10 @@ jobs: ref: ${{ github.event.pull_request.head.ref }} fetch-depth: 1 - - name: Fetch base branch - run: git fetch origin ${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} --depth=1 + - name: Fetch base branch and tags + run: | + git fetch origin ${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} --depth=1 + git fetch --tags origin - uses: actions/setup-python@v5 with: diff --git a/Directory.Packages.props b/Directory.Packages.props index df4d704afc..4b5cfa90f1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -174,7 +174,7 @@ - + diff --git a/docs/en/package-version-changes.md b/docs/en/package-version-changes.md index 86a4a0cfc9..5b4722e976 100644 --- a/docs/en/package-version-changes.md +++ b/docs/en/package-version-changes.md @@ -7,6 +7,12 @@ # Package Version Changes +## 10.3.1 + +| Package | Old Version | New Version | PR | +|---------|-------------|-------------|-----| +| System.Security.Cryptography.Xml | 10.0.2 | 10.0.6 | #25279 | + ## 10.3.0-rc.1 | Package | Old Version | New Version | PR |