From b259470343e30bafec905a9fbbe938a0a2937df4 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Jul 2026 18:02:42 +0000 Subject: [PATCH 1/2] Fix GitHub release creation failing with bad credentials The first automated release run (2.7.23) published and tagged fine, but release creation failed with 401 Bad credentials because MAIN_REPO_PAT is invalid/expired. - Create the release with GITHUB_TOKEN, which the workflow already has contents:write for, instead of the PAT. - Since GITHUB_TOKEN-created releases don't trigger on-release.yml, dispatch the android-release event to paywall-next directly from this workflow (still via MAIN_REPO_PAT, matching on-release.yml). - Gate release creation on whether the release exists rather than the tag, so a run that tagged but failed to create the release (like 2.7.23) self-heals on the next push to main. - Replace deprecated ::set-output usage with GITHUB_OUTPUT in the steps this change touches. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01MHtJcvAKTQPjshrN6pMidJ --- .github/workflows/build+test+deploy.yml | 45 +++++++++++++++++++------ 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build+test+deploy.yml b/.github/workflows/build+test+deploy.yml index 4829b929..38926c5f 100644 --- a/.github/workflows/build+test+deploy.yml +++ b/.github/workflows/build+test+deploy.yml @@ -63,7 +63,23 @@ jobs: id: check-tag run: | EXISTS=$(git tag -l | grep -Fxq "${{steps.version.outputs.prop}}" && echo 'true' || echo 'false') - echo "::set-output name=tag-exists::$EXISTS" + echo "tag-exists=$EXISTS" >> "$GITHUB_OUTPUT" + + # Checked separately from the tag so a partially failed run self-heals: + # if the tag was pushed but the release creation failed, the next push + # to main still creates the missing release. + - name: Check if release exists + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + id: check-release + run: | + STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${{ github.repository }}/releases/tags/${{ steps.version.outputs.prop }}") + if [ "$STATUS" = "200" ]; then + echo "release-exists=true" >> "$GITHUB_OUTPUT" + else + echo "release-exists=false" >> "$GITHUB_OUTPUT" + fi - name: Import GPG key if: steps.check-tag.outputs.tag-exists == 'false' @@ -93,9 +109,9 @@ jobs: run: | VERSION=${{steps.version.outputs.prop}} if [[ "$VERSION" == *"-alpha"* || "$VERSION" == *"-beta"* || "$VERSION" == *"-rc"* ]]; then - echo "::set-output name=status::true" + echo "status=true" >> "$GITHUB_OUTPUT" else - echo "::set-output name=status::false" + echo "status=false" >> "$GITHUB_OUTPUT" fi - name: Tag @@ -118,7 +134,7 @@ jobs: # release description. Version headings look like "## 2.7.22"; the # section ends at the next version heading (or "## Unreleased"). - name: Extract release notes from changelog - if: steps.check-tag.outputs.tag-exists == 'false' + if: steps.check-release.outputs.release-exists == 'false' run: | VERSION="${{ steps.version.outputs.prop }}" awk -v ver="$VERSION" ' @@ -136,7 +152,7 @@ jobs: cat release-notes.md - name: Create GitHub release - if: steps.check-tag.outputs.tag-exists == 'false' + if: steps.check-release.outputs.release-exists == 'false' id: release uses: softprops/action-gh-release@v2 with: @@ -144,13 +160,11 @@ jobs: name: ${{ steps.version.outputs.prop }} body_path: release-notes.md prerelease: ${{ steps.prerelease.outputs.status }} - # Releases created with GITHUB_TOKEN don't trigger other workflows, - # so use a PAT to keep on-release.yml (paywall-next dispatch) working. - token: ${{ secrets.MAIN_REPO_PAT || secrets.GITHUB_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} - name: slack-send - # Only notify on a new tag - if: steps.check-tag.outputs.tag-exists == 'false' + # Only notify on a new release + if: steps.check-release.outputs.release-exists == 'false' uses: slackapi/slack-github-action@v1.24.0 with: payload: | @@ -160,3 +174,14 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK + + # Releases created with GITHUB_TOKEN don't trigger other workflows, so + # on-release.yml won't fire for automated releases. Dispatch to + # paywall-next directly instead (same event on-release.yml sends). + - name: Notify paywall-next + if: steps.check-release.outputs.release-exists == 'false' + uses: peter-evans/repository-dispatch@98b1133981c5060126325c279a8840c1711a9fe0 + with: + token: ${{ secrets.MAIN_REPO_PAT }} + repository: superwall/paywall-next + event-type: android-release From bc1b09994643baee6646cabf4cfd62a4a5e00b86 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Jul 2026 18:23:29 +0000 Subject: [PATCH 2/2] Drop PAT-based paywall-next dispatch, keep GITHUB_TOKEN release Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01MHtJcvAKTQPjshrN6pMidJ --- .github/workflows/build+test+deploy.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/build+test+deploy.yml b/.github/workflows/build+test+deploy.yml index 38926c5f..d36c6532 100644 --- a/.github/workflows/build+test+deploy.yml +++ b/.github/workflows/build+test+deploy.yml @@ -174,14 +174,3 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - - # Releases created with GITHUB_TOKEN don't trigger other workflows, so - # on-release.yml won't fire for automated releases. Dispatch to - # paywall-next directly instead (same event on-release.yml sends). - - name: Notify paywall-next - if: steps.check-release.outputs.release-exists == 'false' - uses: peter-evans/repository-dispatch@98b1133981c5060126325c279a8840c1711a9fe0 - with: - token: ${{ secrets.MAIN_REPO_PAT }} - repository: superwall/paywall-next - event-type: android-release