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