Update dotnet monorepo to v10 #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR version check | |
| on: | |
| pull_request: | |
| branches: [main, 'release/*.x'] | |
| types: [opened, edited, labeled, unlabeled, synchronize, reopened] | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| jobs: | |
| check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout PR head | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| fetch-depth: 0 | |
| - name: Validate version.json against PR labels and history | |
| shell: pwsh | |
| env: | |
| BASE_REF: ${{ github.base_ref }} | |
| LABELS_JSON: ${{ toJSON(github.event.pull_request.labels.*.name) }} | |
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | |
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| # The version-bump bot PRs (opened by GITHUB_TOKEN from the automation workflows) | |
| # legitimately change version.json. Don't trip the manual-edit guard on them; | |
| # their content is reviewed in the workflow that opened them. | |
| $isBotBumpPr = ($env:PR_AUTHOR -eq 'github-actions[bot]') -and ($env:HEAD_REF -like 'bot/bump-*' -or $env:HEAD_REF -like 'bot/promote-*') | |
| $labels = $env:LABELS_JSON | ConvertFrom-Json | |
| $isBreaking = $labels -contains 'breaking-change' | |
| $isManualEdit = $labels -contains 'manual-version-edit' | |
| # Reject any human-authored PR that touches version.json unless explicitly | |
| # labeled 'manual-version-edit'. version.json is owned by the automation | |
| # workflows (cut-major, promote-minor, bump-major-preview); manual edits | |
| # bypass the regression guards and should be a deliberate, labeled exception. | |
| if (-not $isBotBumpPr) { | |
| $base = "origin/$env:BASE_REF" | |
| git fetch origin $env:BASE_REF --quiet | |
| if ($LASTEXITCODE -ne 0) { throw "git fetch origin $env:BASE_REF failed (exit $LASTEXITCODE)." } | |
| $diff = git diff --name-only "$base...HEAD" | |
| if ($LASTEXITCODE -ne 0) { throw "git diff against $base failed (exit $LASTEXITCODE)." } | |
| if (($diff -split "`r?`n") -contains 'version.json' -and -not $isManualEdit) { | |
| throw "This PR modifies version.json but is not authored by the automation bot and is not labeled 'manual-version-edit'. version.json is managed by the workflows in .github/workflows/ (cut-major, promote-minor, bump-major-preview). To override (e.g. for the one-time cutover or a recovery operation), add the 'manual-version-edit' label." | |
| } | |
| } | |
| if ($env:BASE_REF -ne 'main') { | |
| Write-Host "PR targets '$env:BASE_REF' (not main); breaking-change check only applies to PRs targeting main. Skipping." | |
| exit 0 | |
| } | |
| if ($isBotBumpPr) { | |
| Write-Host "PR is an automation-authored version-bump branch ('$env:HEAD_REF'); skipping breaking-change check." | |
| exit 0 | |
| } | |
| $headVersionJson = Get-Content version.json -Raw | ConvertFrom-Json | |
| $headVer = $headVersionJson.version | |
| if ($headVer -notmatch '^(0|[1-9]\d*)\.') { | |
| throw "Could not parse major version from PR head version.json: '$headVer'" | |
| } | |
| $headMajor = [int]$matches[1] | |
| git fetch origin main --quiet | |
| if ($LASTEXITCODE -ne 0) { throw "git fetch origin main failed (exit $LASTEXITCODE)." } | |
| $baseVersionJson = git show "origin/main:version.json" | ConvertFrom-Json | |
| if ($LASTEXITCODE -ne 0) { throw "Failed to read version.json from origin/main." } | |
| $baseVer = $baseVersionJson.version | |
| if ($baseVer -notmatch '^(0|[1-9]\d*)\.') { | |
| throw "Could not parse major version from main's version.json: '$baseVer'" | |
| } | |
| $baseMajor = [int]$matches[1] | |
| # Unconditional check: if this PR changes the major in version.json, it MUST be | |
| # labeled breaking-change. Catches unlabeled major-version edits. | |
| if ($headMajor -ne $baseMajor -and -not $isBreaking) { | |
| throw "This PR changes version.json's major from $baseMajor to $headMajor but is not labeled 'breaking-change'. Major-version changes must be tagged." | |
| } | |
| if (-not $isBreaking) { | |
| Write-Host "PR is not labeled 'breaking-change' and does not change the major; no further checks." | |
| exit 0 | |
| } | |
| Write-Host "PR is labeled as breaking. Verifying the PR's version.json reflects a newer major than the latest stable release." | |
| git fetch --tags --force origin | |
| if ($LASTEXITCODE -ne 0) { throw "git fetch --tags failed (exit $LASTEXITCODE); cannot safely validate breaking-change label." } | |
| $latestStable = git tag --list --sort=-v:refname | | |
| Where-Object { $_ -match '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$' } | | |
| Select-Object -First 1 | |
| if (-not $latestStable) { | |
| # No prior stable releases. Accept either the post-bump steady state | |
| # (head == base, both already at the new major) or the rare case where | |
| # the breaking PR itself does the bump (head == base + 1). | |
| if ($headMajor -eq $baseMajor -or $headMajor -eq $baseMajor + 1) { | |
| Write-Host "No stable tags found; PR head major ($headMajor) is consistent with main ($baseMajor). OK." | |
| exit 0 | |
| } | |
| throw "No stable tags found; PR head major ($headMajor) must equal or be exactly one greater than main's current major ($baseMajor) for a breaking-change PR with no prior stable history." | |
| } | |
| if ($latestStable -notmatch '^(\d+)\.') { | |
| throw "Could not parse latest stable tag: '$latestStable'" | |
| } | |
| $latestMajor = [int]$matches[1] | |
| Write-Host "Latest stable major: $latestMajor; PR head major: $headMajor" | |
| $expectedMajor = $latestMajor + 1 | |
| if ($headMajor -ne $expectedMajor) { | |
| if ($headMajor -le $latestMajor) { | |
| $msg = "PR is labeled breaking-change but its version.json major ($headMajor) is not greater than the latest stable release major ($latestMajor; tag '$latestStable'). Run the 'Bump main to next major preview' workflow with next_major=$expectedMajor first, then rebase this PR onto the updated main." | |
| } else { | |
| $msg = "PR is labeled breaking-change but its version.json major ($headMajor) skips past major $expectedMajor. Main must be at exactly latest_stable_major + 1 ($latestMajor + 1 = $expectedMajor). Reset main to $expectedMajor.0-preview.{height} before merging this PR." | |
| } | |
| throw $msg | |
| } | |
| Write-Host "OK: PR head major ($headMajor) is exactly one greater than latest stable major ($latestMajor)." |