From ec423ead84d615b561de3ca1875e9f5f25f663a5 Mon Sep 17 00:00:00 2001 From: Steven Gates Date: Mon, 7 Sep 2026 15:57:29 -0500 Subject: [PATCH 1/2] fix(release): set the executable bit on gradlew before building MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dry run reached Gradle and died with "./gradlew: Permission denied". gradlew is mode 100644 in the index — the normal result of a Windows-only checkout, where git does not track the executable bit — so a Linux runner cannot execute it. chmod in the workflow rather than assuming the mode: this fixes CI without touching the tree, and it keeps working whether or not the index mode is corrected later. --- .github/workflows/release.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 396db4e..1f5bfdf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,7 +47,7 @@ jobs: RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} run: | if [[ -z "$RELEASE_TOKEN" ]]; then - echo "::error::RELEASE_TOKEN is not set. A real release run pushes the bump branch and merges its own PR, which needs a fine-grained PAT with contents and pull-requests write. Add it as a repository secret, or re-run with dry_run to build only." + echo "::error::RELEASE_TOKEN is not set. A real release run pushes the bump branch and merges its own PR, which needs a credential that can bypass the ruleset — a fine-grained PAT, or a GitHub App token. Add it as a repository secret, or re-run with dry_run to build only." exit 1 fi echo "RELEASE_TOKEN is present." @@ -195,7 +195,12 @@ jobs: echo "Keystore opens and contains the alias." - name: Build the release bundle - run: ./gradlew :app:bundleRelease --no-daemon --stacktrace + run: | + set -euo pipefail + # gradlew is mode 100644 in the index — git on Windows does not track the executable + # bit, so a Linux runner checks it out non-executable. Set it here rather than assuming. + chmod +x gradlew + ./gradlew :app:bundleRelease --no-daemon --stacktrace - name: Verify the signature id: sign From 6d472bcd74502968b18bb032d7cb630b93b5742c Mon Sep 17 00:00:00 2001 From: Steven Gates Date: Mon, 7 Sep 2026 15:58:01 -0500 Subject: [PATCH 2/2] fix(tag): fall back to GITHUB_TOKEN and request contents write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same empty-token bug release.yml just hit: with RELEASE_TOKEN unset, `token: ${{ secrets.RELEASE_TOKEN }}` resolves to "" and actions/checkout refuses it before anything runs. Also raises permissions to contents: write — creating a tag and a GitHub release is a write, and read-only would have failed at the last step. --- .github/workflows/tag.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml index cfe3a23..5cbce4c 100644 --- a/.github/workflows/tag.yml +++ b/.github/workflows/tag.yml @@ -34,8 +34,10 @@ on: type: boolean default: false +# Creating a tag and a GitHub release is a write. Tags are not covered by the branch ruleset, so +# the job's own GITHUB_TOKEN is enough here — no PAT or App token needed for run 2. permissions: - contents: read + contents: write concurrency: group: openloop-release @@ -46,7 +48,7 @@ jobs: name: Cut tag and GitHub release runs-on: ubuntu-latest env: - GH_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GH_TOKEN: ${{ secrets.RELEASE_TOKEN || github.token }} steps: - name: Checkout @@ -54,7 +56,7 @@ jobs: with: ref: main fetch-depth: 0 - token: ${{ secrets.RELEASE_TOKEN }} + token: ${{ secrets.RELEASE_TOKEN || github.token }} # tag-release.ps1 warns when releases/openloop--.aab is missing. In CI it # always would be, which turns a real safety check into noise — so pull the artifact the