on main help sign in
Check all signing secrets up front and document releases

The release workflow now checks the secrets in a job of its own: it also stops in seconds when MULTIGRAM_KEYSTORE_BASE64 is set without MULTIGRAM_KEYSTORE_PASSWORD or MULTIGRAM_KEY_ALIAS, instead of failing when Gradle signs the APK after the native build. Keeping secrets out of the job that writes the notes also stops the runner from dropping the notes output when a secret value (a key alias like "release") appears in them. The README gains a Releases section. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019mVy1fu8zBn38wHgJqmLNz

commit1f233339e525b06fb32f899476b1074d2715b5fa authorClaude <noreply@anthropic.com> dateTue 29 Sep 2026, 07:49 (2 weeks ago) parente4d8565
2 files changed+51−14
unifiedsplit
.github/workflows/release.yml+40−14 README.md+11
.github/workflows/release.yml+40−14
@@ -37,8 +37,44 @@ concurrency:
3737 cancel-in-progress: false
3838
3939jobs:
40+ check_secrets:
41+ # A job of its own, so that no secret value is registered in the job that writes the release
42+ # notes: the runner drops any job output that contains a secret's value (a key alias like
43+ # "release" would otherwise blank the notes).
44+ name: Check the secrets
45+ runs-on: ubuntu-latest
46+ outputs:
47+ signed: ${{ steps.s.outputs.signed }}
48+ steps:
49+ - name: Check the secrets
50+ id: s
51+ env:
52+ DRY_RUN: ${{ inputs.dry_run }}
53+ APP_ID: ${{ secrets.MULTIGRAM_APP_ID }}
54+ APP_HASH: ${{ secrets.MULTIGRAM_APP_HASH }}
55+ KEYSTORE_BASE64: ${{ secrets.MULTIGRAM_KEYSTORE_BASE64 }}
56+ KEYSTORE_PASSWORD: ${{ secrets.MULTIGRAM_KEYSTORE_PASSWORD }}
57+ KEY_ALIAS: ${{ secrets.MULTIGRAM_KEY_ALIAS }}
58+ run: |
59+ set -euo pipefail
60+ # Stop here, in seconds, rather than after the long build. A dry run only warns.
61+ problem() { if [ "$DRY_RUN" = true ]; then echo "::warning::$1"; else echo "::error::$1"; exit 1; fi; }
62+ if [ -z "$APP_ID" ] || [ -z "$APP_HASH" ]; then
63+ problem "The MULTIGRAM_APP_ID and MULTIGRAM_APP_HASH secrets are not set, so the APK could not log in. Add them (Settings > Secrets and variables > Actions) and run this again."
64+ fi
65+ if [ -n "$KEYSTORE_BASE64" ]; then
66+ if [ -z "$KEYSTORE_PASSWORD" ] || [ -z "$KEY_ALIAS" ]; then
67+ problem "MULTIGRAM_KEYSTORE_BASE64 is set, but MULTIGRAM_KEYSTORE_PASSWORD or MULTIGRAM_KEY_ALIAS is not: signing would fail at the end of the build. Add both."
68+ fi
69+ echo "signed=true" >> "$GITHUB_OUTPUT"
70+ else
71+ echo "::warning::No MULTIGRAM_KEYSTORE_BASE64 secret: the release will be signed with Forkgram's public test key and published as a pre-release."
72+ echo "signed=false" >> "$GITHUB_OUTPUT"
73+ fi
74+
4075 prepare:
4176 name: Work out the version
77+ needs: check_secrets
4278 runs-on: ubuntu-latest
4379 outputs:
4480 sha: ${{ steps.v.outputs.sha }}
@@ -58,9 +94,7 @@ jobs:
5894 NUMBER: ${{ inputs.number }}
5995 PRERELEASE: ${{ inputs.prerelease }}
6096 DRY_RUN: ${{ inputs.dry_run }}
61− APP_ID: ${{ secrets.MULTIGRAM_APP_ID }}
62− APP_HASH: ${{ secrets.MULTIGRAM_APP_HASH }}
63− KEYSTORE_BASE64: ${{ secrets.MULTIGRAM_KEYSTORE_BASE64 }}
97+ SIGNED: ${{ needs.check_secrets.outputs.signed }}
6498 run: |
6599 set -euo pipefail
66100 fail() { echo "::error::$1"; exit 1; }
@@ -97,17 +131,9 @@ jobs:
97131 fg_version=${fg_version:-unknown}; tg_version=${tg_version:-unknown}
98132 fi
99133
100− if [ -z "$APP_ID" ] || [ -z "$APP_HASH" ]; then
101− m="The MULTIGRAM_APP_ID and MULTIGRAM_APP_HASH secrets are not set, so the APK could not log in. Add them (Settings > Secrets and variables > Actions) and run this again."
102− if [ "$DRY_RUN" = true ]; then echo "::warning::$m"; else fail "$m"; fi
103− fi
104− signed=true
105− [ -n "$KEYSTORE_BASE64" ] || signed=false
134+ signed=${SIGNED:-false}
106135 prerelease=$PRERELEASE
107− if [ "$signed" = false ]; then
108− prerelease=true
109− echo "::warning::No MULTIGRAM_KEYSTORE_BASE64 secret: MultiGram $version will be signed with Forkgram's public test key and published as a pre-release."
110− fi
136+ [ "$signed" = true ] || prerelease=true
111137
112138 notes=$(mktemp)
113139 {
@@ -151,7 +177,7 @@ jobs:
151177
152178 build:
153179 name: Build
154− needs: prepare
180+ needs: [check_secrets, prepare]
155181 if: ${{ !inputs.dry_run }}
156182 uses: ./.github/workflows/build.yml
157183 with:
README.md+11
@@ -21,6 +21,17 @@ the exact code, so the stack can be re-applied by hand.
2121code (a few minutes). Tick **APK** to also build a release APK; it compiles the native code
2222too, so it takes much longer, and the APK is attached to the run as `multigram-apk`.
2323
24+## Releases
25+
26+**Actions > Release MultiGram > Run workflow** builds the release APK of `multigram` and publishes
27+it on the Releases page (about 80 minutes; tick **dry_run** to see only the version and notes).
28+Versions follow Forkgram's scheme: `12.10.6.1` is the first MultiGram release on Forkgram 12.10.6,
29+`12.10.6.2` the second, and after a Forkgram update the count starts again at 1 (at most 9 per
30+Forkgram version). The tag is the version. It needs the API id and hash secrets below. Without the
31+signing secrets the APK is signed with Forkgram's public test key and published as a pre-release
32+that says so. Details: section 10.6 of
33+[PATCH.md](https://github.com/iko-soy/Multigram/blob/docs/PATCH.md).
34+
2435## Secrets
2536
2637Set these in **Settings > Secrets and variables > Actions**: