Skip to content

Release the app as a signed APK on GitHub - #29

Merged
lakaniemi merged 6 commits into
mainfrom
feat/app-release-apk
Nov 10, 2026
Merged

lakaniemi merged 6 commits into
mainfrom
feat/app-release-apk

Conversation

@lakaniemi

Copy link
Copy Markdown
Owner

What and why

Last PR of the App baseline slice: a signed production APK is published as a GitHub release (life-app.apk, the name the Update required screen links to). Bumping app/version.json on main triggers it. The slice leaves the roadmap with this PR.

Merging releases 0.0.1 immediately, since no app-v* tag exists yet. The signing secrets and the ANDROID_RELEASE_CERT_SHA256 variable are already set.

Size

About 257 logic lines (workflow 104, check script 66, signing plugin 60, rest small), under the ~300 target.

How to review

  • Start with .github/workflows/app-release.yml, then app/plugins/with-release-signing.ts (the Gradle edit, which throws on an unknown template instead of silently falling back to the debug key).
  • check-app-version.sh runs on PRs through app.yml and decides in the release workflow whether to release.
  • Docs (README runbook, ARCHITECTURE §9, specs, roadmap) can be skimmed.
  • The plugin is imported as ./plugins/with-release-signing.ts because Expo loads app.config.ts as CommonJS and doesn't resolve extensionless .ts imports. It relies on Node's built-in TypeScript support, so it needs allowImportingTsExtensions.

Testing

  • Lint, typecheck and all tests pass, including 5 new tests for the plugin transform.
  • A production expo prebuild writes the release signing config into build.gradle, with the debug fallback.
  • The version check script was run against 10 cases in a scratch repo, and actionlint is clean.
  • Not run before merge: the Gradle build on the runner and the certificate check (apksigner output format). The certificate check comes before publishing, so a failure publishes nothing, and the workflow can be re-run from the Actions tab.

🤖 Generated with Claude Code

lakaniemi and others added 6 commits November 10, 2026 15:59
version.json holds the version name and the versionCode Android compares,
bumped by hand in a release PR. A local config plugin adds a release
signing config to the generated build.gradle, reading the keystore from
Gradle properties and falling back to the debug key when they are unset,
so local production builds keep working.

The plugin is imported with its .ts extension because Expo loads
app.config.ts as plain CommonJS and doesn't resolve other .ts files.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
check-app-version.sh compares app/version.json with the latest app-v* tag
and reports whether the commit is a new release. It fails on an
inconsistent bump (versionCode changed alone, a lower version, a
versionCode that didn't go up), so the mistake shows on the PR. The
release workflow will use the same script to decide whether to release.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A push to main that changes app/version.json builds the production
variant, signs it with the release keystore from the repository secrets,
and attaches it to the app-v<version> release as life-app.apk, the name
the Update required screen links to. Before publishing, the APK's
certificate must match ANDROID_RELEASE_CERT_SHA256, so the debug-key
fallback can never be released.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Adds the Releasing runbook (version bump, signing key setup, secrets) to
app/README.md, records the release decisions in ARCHITECTURE.md and the
root CLAUDE.md, and takes the App baseline off the roadmap now that its
last PR is here.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Satisfies shellcheck SC2012, reported by actionlint.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Drop a comment that restated the plugin's name, and explain why the
keystore is base64-encoded instead of just saying that it is.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@lakaniemi
lakaniemi merged commit 010c936 into main Nov 10, 2026
1 check passed
@lakaniemi
lakaniemi deleted the feat/app-release-apk branch November 10, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant