Repository navigation
Release the app as a signed APK on GitHub - #29
Merged
Merged
Conversation
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>
This was referenced Nov 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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). Bumpingapp/version.jsononmaintriggers it. The slice leaves the roadmap with this PR.Merging releases
0.0.1immediately, since noapp-v*tag exists yet. The signing secrets and theANDROID_RELEASE_CERT_SHA256variable 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
.github/workflows/app-release.yml, thenapp/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.shruns on PRs throughapp.ymland decides in the release workflow whether to release../plugins/with-release-signing.tsbecause Expo loadsapp.config.tsas CommonJS and doesn't resolve extensionless.tsimports. It relies on Node's built-in TypeScript support, so it needsallowImportingTsExtensions.Testing
expo prebuildwrites the release signing config intobuild.gradle, with the debug fallback.actionlintis clean.🤖 Generated with Claude Code