From ec2b96d0ba6ea7777259a971b319cebc7b6dcb67 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 07:46:23 +0000 Subject: [PATCH] Harmonize signing workflows with the repo's actual secret names The four Android signing secrets already exist in this repo under the ANDROID_ prefix (ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD), but build-apk.yml and release.yml still referenced them as secrets.RELEASE_*, a mismatch that would make both workflows read empty secrets and fail signing at build time. Updated only the secrets.RELEASE_* -> secrets.ANDROID_* references (plus one stale comment naming the old secret in prose) in both workflow files. Left the RELEASE_KEYSTORE_PATH/RELEASE_KEYSTORE_PASSWORD/ RELEASE_KEY_ALIAS/RELEASE_KEY_PASSWORD environment variable names untouched: app/build.gradle.kts's signingConfigs block reads those exact names via System.getenv(), an internal contract between the workflows and Gradle that has nothing to do with the GitHub secret name and would gain nothing from renaming. Updated docs/release-signing.md's secret-name table to match and added a note explaining the ANDROID_*/RELEASE_* naming split, so the next person following that doc doesn't recreate the same mismatch. RELEASE_PUSH_TOKEN is untouched (name already matched). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_018zXVpxEbSWadqKyntXTXD6 --- .github/workflows/build-apk.yml | 16 ++++++++-------- .github/workflows/release.yml | 8 ++++---- docs/release-signing.md | 33 +++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build-apk.yml b/.github/workflows/build-apk.yml index 193c613..53fc2ae 100644 --- a/.github/workflows/build-apk.yml +++ b/.github/workflows/build-apk.yml @@ -29,11 +29,11 @@ jobs: - name: Decode release keystore run: echo "$RELEASE_KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/release.keystore" env: - RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }} + RELEASE_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} # Not sensitive (size/hash only, never the secret values themselves) — printed so a signing # failure ("Given final block not properly padded", "Invalid keystore format", etc.) can be - # told apart from a corrupted/truncated RELEASE_KEYSTORE_BASE64 secret without guessing. + # told apart from a corrupted/truncated ANDROID_KEYSTORE_BASE64 secret without guessing. - name: Verify decoded keystore integrity run: | echo "Decoded keystore size (bytes):" @@ -45,18 +45,18 @@ jobs: run: ./gradlew assembleRelease --no-daemon --stacktrace env: RELEASE_KEYSTORE_PATH: ${{ runner.temp }}/release.keystore - RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }} - RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }} - RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }} + RELEASE_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + RELEASE_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + RELEASE_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} # Useful even without any Google API integration in v1 — see docs/release-signing.md. - name: Print release keystore SHA-1 run: ./gradlew signingReport --no-daemon env: RELEASE_KEYSTORE_PATH: ${{ runner.temp }}/release.keystore - RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }} - RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }} - RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }} + RELEASE_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + RELEASE_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + RELEASE_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} - name: Upload APK uses: actions/upload-artifact@v7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1a96dbd..6432a81 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -131,7 +131,7 @@ jobs: - name: Decode release keystore run: echo "$RELEASE_KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/release.keystore" env: - RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }} + RELEASE_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} - name: Verify decoded keystore integrity run: | @@ -144,9 +144,9 @@ jobs: run: ./gradlew assembleRelease --no-daemon --stacktrace env: RELEASE_KEYSTORE_PATH: ${{ runner.temp }}/release.keystore - RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }} - RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }} - RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }} + RELEASE_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + RELEASE_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} + RELEASE_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} # gh release create attaches whatever file path it's given as-is, so the APK is # uploaded as a plain .apk release asset — never zipped. diff --git a/docs/release-signing.md b/docs/release-signing.md index 5e3bbf6..de3f1e5 100644 --- a/docs/release-signing.md +++ b/docs/release-signing.md @@ -55,29 +55,34 @@ credentials from repository secrets, never from a file in the repo: base64 -w0 coverdex-release.keystore ``` -Copy that output into a repository secret named `RELEASE_KEYSTORE_BASE64`. +Copy that output into a repository secret named `ANDROID_KEYSTORE_BASE64`. Add these secrets under the repo's **Settings → Secrets and variables → Actions**: | Secret | Value | |---|---| -| `RELEASE_KEYSTORE_BASE64` | the base64 output above | -| `RELEASE_KEYSTORE_PASSWORD` | the store password from step 1 | -| `RELEASE_KEY_ALIAS` | `coverdex` (or whatever alias was used) | -| `RELEASE_KEY_PASSWORD` | the key password from step 1 | +| `ANDROID_KEYSTORE_BASE64` | the base64 output above | +| `ANDROID_KEYSTORE_PASSWORD` | the store password from step 1 | +| `ANDROID_KEY_ALIAS` | `coverdex` (or whatever alias was used) | +| `ANDROID_KEY_PASSWORD` | the key password from step 1 | | `RELEASE_PUSH_TOKEN` | a fine-grained PAT scoped to this repo, Contents: Read and write — used only by `release.yml`'s final version-bump commit | -`app/build.gradle.kts`'s `signingConfigs { create("release") { ... } }` -block (written in Phase 0) reads `RELEASE_KEYSTORE_PATH`/ -`RELEASE_KEYSTORE_PASSWORD`/`RELEASE_KEY_ALIAS`/`RELEASE_KEY_PASSWORD` as -environment variables — the workflows decode the base64 secret into a -temporary file at `$RUNNER_TEMP/release.keystore` and pass its path as -`RELEASE_KEYSTORE_PATH`. A local `./gradlew assembleRelease` with none of -these set still succeeds — the release build type is simply left unsigned -in that case, Android's own default. +Note the naming split: the four signing secrets above are prefixed +`ANDROID_` (matching how they were actually created in this repo's +settings), while `app/build.gradle.kts`'s `signingConfigs { create("release") +{ ... } }` block (written in Phase 0) still reads plain `RELEASE_KEYSTORE_PATH`/ +`RELEASE_KEYSTORE_PASSWORD`/`RELEASE_KEY_ALIAS`/`RELEASE_KEY_PASSWORD` +environment variables — an internal contract between the workflows and +Gradle, unrelated to the secret names and left as-is. The workflows are what +bridge the two: they read the `ANDROID_*` secrets and re-expose them to +Gradle as those `RELEASE_*` environment variables, decoding the base64 +secret into a temporary file at `$RUNNER_TEMP/release.keystore` and passing +its path as `RELEASE_KEYSTORE_PATH`. A local `./gradlew assembleRelease` +with none of these set still succeeds — the release build type is simply +left unsigned in that case, Android's own default. > The sibling project's (Hall of Memories) first three release attempts all -> failed on `RELEASE_KEYSTORE_BASE64` not being valid base64. Both +> failed on `ANDROID_KEYSTORE_BASE64` not being valid base64. Both > `build-apk.yml` and `release.yml` print the decoded keystore's byte size > and SHA-256 right after decoding it, precisely so a signing failure later > in the same run ("Given final block not properly padded", "Invalid