diff --git a/.github/workflows/main-publish.yml b/.github/workflows/main-publish.yml index f667dc6..3452bc7 100644 --- a/.github/workflows/main-publish.yml +++ b/.github/workflows/main-publish.yml @@ -57,7 +57,10 @@ jobs: secrets: inherit release-Complete: - if: ${{ always() }} + # Only succeed if no upstream release job actually failed. Skipped siblings + # (the build-types that didn't match the PR title) are tolerated; a real + # failure makes this job skip so it can no longer report a false "success". + if: ${{ !failure() && !cancelled() }} needs: [upversion-major-Package, upversion-minor-Package, upversion-patch-Package, release-Package-only] name: Release complete runs-on: ubuntu-latest @@ -67,19 +70,24 @@ jobs: # Refresh the development branch with the main publish refresh-development: - if: ${{ always() }} + # Skip if the release didn't actually complete, so we never refresh + # development from a half-finished or failed release. + if: ${{ needs.release-Complete.result == 'success' }} needs: [release-Complete] name: Refresh development branch uses: ./.github/workflows/refreshbranch.yml with: build-host: ubuntu-latest target-branch: development - source-branch: main + # The branch this release PR merged into (the trigger pins this to the + # release branch). Avoids hardcoding a branch name that doesn't exist. + source-branch: ${{ github.event.pull_request.base.ref }} secrets: inherit # Up version the development branch ready for future development upversion-development: - if: ${{ always() }} + # Only re-version development once it has been refreshed successfully. + if: ${{ needs.refresh-development.result == 'success' }} needs: [refresh-development] name: UpVersion the development branch for the next release uses: ./.github/workflows/upversionandtagrelease.yml diff --git a/.github/workflows/refreshbranch.yml b/.github/workflows/refreshbranch.yml index 129d610..4ed0862 100644 --- a/.github/workflows/refreshbranch.yml +++ b/.github/workflows/refreshbranch.yml @@ -29,6 +29,33 @@ jobs: echo "Build Script Version: $scriptVersion" echo "::endgroup::" shell: pwsh + - name: Validate GIT_PAT + env: + GIT_PAT: ${{ secrets.GIT_PAT }} + shell: pwsh + run: | + if ([string]::IsNullOrWhiteSpace($env:GIT_PAT)) { + Write-Error "GIT_PAT secret is empty or not set. Add a valid Personal Access Token to the repository/org secrets and re-run." + exit 1 + } + $headers = @{ + Authorization = "Bearer $env:GIT_PAT" + "User-Agent" = "uiextensions-release-preflight" + Accept = "application/vnd.github+json" + } + try { + $repo = Invoke-RestMethod -Uri "https://api.github.com/repos/$env:GITHUB_REPOSITORY" -Headers $headers -ErrorAction Stop + } + catch { + $code = if ($_.Exception.Response) { [int]$_.Exception.Response.StatusCode } else { "unknown" } + Write-Error "GIT_PAT was rejected by GitHub (HTTP $code). It is likely expired, revoked, or lacks access to $env:GITHUB_REPOSITORY. Regenerate the token and update the GIT_PAT secret. Details: $($_.Exception.Message)" + exit 1 + } + if ($null -ne $repo.permissions -and -not $repo.permissions.push) { + Write-Error "GIT_PAT authenticated but does not have push access to $env:GITHUB_REPOSITORY. Grant 'repo' (classic PAT) or Contents: read & write (fine-grained PAT)." + exit 1 + } + Write-Host "GIT_PAT validated: authenticated with push access to $env:GITHUB_REPOSITORY." - uses: actions/checkout@v7 with: ref: ${{ inputs.target-branch }} diff --git a/.github/workflows/tagrelease.yml b/.github/workflows/tagrelease.yml index 7a8d682..38d10e0 100644 --- a/.github/workflows/tagrelease.yml +++ b/.github/workflows/tagrelease.yml @@ -29,6 +29,33 @@ jobs: echo "Build Script Version: $scriptVersion" echo "::endgroup::" shell: pwsh + - name: Validate GIT_PAT + env: + GIT_PAT: ${{ secrets.GIT_PAT }} + shell: pwsh + run: | + if ([string]::IsNullOrWhiteSpace($env:GIT_PAT)) { + Write-Error "GIT_PAT secret is empty or not set. Add a valid Personal Access Token to the repository/org secrets and re-run." + exit 1 + } + $headers = @{ + Authorization = "Bearer $env:GIT_PAT" + "User-Agent" = "uiextensions-release-preflight" + Accept = "application/vnd.github+json" + } + try { + $repo = Invoke-RestMethod -Uri "https://api.github.com/repos/$env:GITHUB_REPOSITORY" -Headers $headers -ErrorAction Stop + } + catch { + $code = if ($_.Exception.Response) { [int]$_.Exception.Response.StatusCode } else { "unknown" } + Write-Error "GIT_PAT was rejected by GitHub (HTTP $code). It is likely expired, revoked, or lacks access to $env:GITHUB_REPOSITORY. Regenerate the token and update the GIT_PAT secret. Details: $($_.Exception.Message)" + exit 1 + } + if ($null -ne $repo.permissions -and -not $repo.permissions.push) { + Write-Error "GIT_PAT authenticated but does not have push access to $env:GITHUB_REPOSITORY. Grant 'repo' (classic PAT) or Contents: read & write (fine-grained PAT)." + exit 1 + } + Write-Host "GIT_PAT validated: authenticated with push access to $env:GITHUB_REPOSITORY." - uses: actions/checkout@v7 with: fetch-depth: 0 diff --git a/.github/workflows/upversionandtagrelease.yml b/.github/workflows/upversionandtagrelease.yml index ca7ccde..bd6732b 100644 --- a/.github/workflows/upversionandtagrelease.yml +++ b/.github/workflows/upversionandtagrelease.yml @@ -48,6 +48,33 @@ jobs: echo "Build Script Version: $scriptVersion" echo "::endgroup::" shell: pwsh + - name: Validate GIT_PAT + env: + GIT_PAT: ${{ secrets.GIT_PAT }} + shell: pwsh + run: | + if ([string]::IsNullOrWhiteSpace($env:GIT_PAT)) { + Write-Error "GIT_PAT secret is empty or not set. Add a valid Personal Access Token to the repository/org secrets and re-run." + exit 1 + } + $headers = @{ + Authorization = "Bearer $env:GIT_PAT" + "User-Agent" = "uiextensions-release-preflight" + Accept = "application/vnd.github+json" + } + try { + $repo = Invoke-RestMethod -Uri "https://api.github.com/repos/$env:GITHUB_REPOSITORY" -Headers $headers -ErrorAction Stop + } + catch { + $code = if ($_.Exception.Response) { [int]$_.Exception.Response.StatusCode } else { "unknown" } + Write-Error "GIT_PAT was rejected by GitHub (HTTP $code). It is likely expired, revoked, or lacks access to $env:GITHUB_REPOSITORY. Regenerate the token and update the GIT_PAT secret. Details: $($_.Exception.Message)" + exit 1 + } + if ($null -ne $repo.permissions -and -not $repo.permissions.push) { + Write-Error "GIT_PAT authenticated but does not have push access to $env:GITHUB_REPOSITORY. Grant 'repo' (classic PAT) or Contents: read & write (fine-grained PAT)." + exit 1 + } + Write-Host "GIT_PAT validated: authenticated with push access to $env:GITHUB_REPOSITORY." - uses: actions/checkout@v7 with: ref: ${{ inputs.target-branch }}