diff --git a/.github/workflows/dual-approval-check.yaml b/.github/workflows/dual-approval-check.yaml index 39453c8..5127c64 100644 --- a/.github/workflows/dual-approval-check.yaml +++ b/.github/workflows/dual-approval-check.yaml @@ -51,8 +51,8 @@ jobs: REPO: ${{ github.repository }} run: | if [ -z "${PR_NUMBER}" ]; then - echo "::error::No pull request number found in event context. This workflow must be called from a pull_request or pull_request_review trigger." - exit 1 + echo "::notice::No PR number in context (dismissed review?). Skipping dual approval check — no action needed." + exit 0 fi echo "Checking approvals on PR #${PR_NUMBER} in ${REPO}" diff --git a/.github/workflows/plugin-release.yaml b/.github/workflows/plugin-release.yaml index 480a70a..785d02f 100644 --- a/.github/workflows/plugin-release.yaml +++ b/.github/workflows/plugin-release.yaml @@ -58,6 +58,46 @@ jobs: with: node-version: ${{ inputs.node-version }} + check-token-permissions: + needs: check-secrets + if: needs.check-secrets.outputs.ready == 'true' + runs-on: runners-privilegedescalation + outputs: + has_write: ${{ steps.check.outputs.has_write }} + steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.RELEASE_APP_ID }} + private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }} + + - name: Check write permissions via API + id: check + run: | + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ + -X POST \ + -H "Authorization: Bearer ${{ steps.app-token.outputs.token }}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${{ github.repository }}/git/refs" \ + -d '{"ref":"refs/heads/_release_check","sha":"${{ github.sha }}"}') + if [ "$HTTP_CODE" = "201" ]; then + echo "::notice::Token has write permission — cleaning up test ref." + curl -s -o /dev/null -w "%{http_code}" \ + -X DELETE \ + -H "Authorization: Bearer ${{ steps.app-token.outputs.token }}" \ + "https://api.github.com/repos/${{ github.repository }}/git/refs/heads/_release_check" + echo "has_write=true" >> $GITHUB_OUTPUT + elif [ "$HTTP_CODE" = "403" ]; then + echo "::error::Token lacks write permission. Release cannot push tags or branches." + echo "has_write=false" >> $GITHUB_OUTPUT + exit 1 + else + echo "::warning::Unexpected response ($HTTP_CODE) when checking write permission." + echo "has_write=false" >> $GITHUB_OUTPUT + exit 1 + fi + check-tag: needs: check-secrets if: needs.check-secrets.outputs.ready == 'true' @@ -79,8 +119,8 @@ jobs: fi release: - needs: [ci, check-tag, check-secrets] - if: needs.check-secrets.outputs.ready == 'true' && needs.check-tag.outputs.skip != 'true' + needs: [ci, check-tag, check-secrets, check-token-permissions] + if: needs.check-secrets.outputs.ready == 'true' && needs.check-tag.outputs.skip != 'true' && needs.check-token-permissions.outputs.has_write == 'true' runs-on: runners-privilegedescalation timeout-minutes: 10