Mobile release

SkillDocs & knowledge

Summarize mobile changes since the previous release, bump the Beancount mobile version, prepare localized release notes and listings, and release to the Apple App Store and Google Play. Use for $mobile-release or requests to cut a mobile store release. Skip ordinary code shipping, OTA-only updates, release-status questions, and requests to create or edit this skill.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Mobile release skill

What this skill tells your AI

The instructions your AI receives, as published by bex-co/beancount-io in .agents/skills/mobile-release/SKILL.md and read by ahel’s review.

Usage: $mobile-release [optional release context] (Claude Code: /mobile-release).

Carry a release through preparation, verification, shipping, and both stores. A release request authorizes the necessary store writes, build/submission jobs, and push to main. Naming individual steps — bump the version, write the release notes, cut the build — still requests the whole release: yarn bump exists only to cut one, and the release workflow is gated on a bumped-but-untagged version, so a bump that is not shipped strands the release half-done. Narrow the scope only on an explicit stop signal such as “prepare only”, “do not publish yet”, or “just the notes”; without one, carry through to both stores rather than stopping to confirm. Creating this skill does not invoke it. Do not ask again for authorization already given. Review concrete plans before recording approvals; never bypass the repository's release gates.

Establish release state

Locate the repository with git rev-parse --show-toplevel. Read root and mobile CLAUDE.md, mobile/docs/app-store-localization.md, mobile/scripts/app-store-release.sh, mobile/scripts/play-release.sh, mobile/eas.json, and .github/workflows/deploy.yml. Run package commands inside mobile/; keep scratch artifacts in mobile/tmp/. Discover installed gh, asc, and the workflow's pinned EAS CLI capabilities with --help rather than assuming newer commands exist.

Inspect branch, staged and unstaged changes, and remote state. Fetch origin and tags. Preserve unrelated work; release only reviewed changes. Bring the release base up to date before preparing notes. Do not push a version bump until its store staging receipt is ready.

Find the previous reachable mobile tag using git describe --tags --match 'mobile-v*' --abbrev=0 HEAD. Compare that tag to the candidate release using mobile-scoped git log and git diff; inspect release workflow changes too. If no tag exists, label this a first release and inspect available mobile history. Tags from other packages are not a baseline.

Check GitHub release runs, EAS builds/submissions, App Store Connect versions, and Google Play tracks. A mobile-v<version> tag only proves build/submit kickoff: the workflow uses --no-wait. It does not prove either store is live. Report any difference between the tag baseline and the last live version; include still-unreleased changes in store notes when needed.

If the current version is untagged or has incomplete jobs, determine whether it is an existing release to resume before bumping. Do not create another version merely to retry. Do not edit an Apple version already in review; report the pending review as the blocker to a new release.

Verify credentials and access without printing secrets. Check the effective Android submission profile, Google Play application identity, service-account access, production track, release status, and review settings. submit.production.android currently targets production with completed release status; verify service-account access separately because the profile does not contain a local key path. Resolve needed non-secret configuration within release scope, or identify the precise missing access. Never substitute a testing track for the requested production release.

Summarize and bump

Write concise user-facing release notes grounded in the inspected diff: features, fixes, and material behavior changes. Omit internal churn and unsupported claims. Show the baseline tag/SHA and candidate SHA, and keep the summary for the final report and commit context.

For a new release, run yarn bump once. Use the version it emits: this repository uses 1.YYYYMMDD.build, not a conventional patch increment. Inspect all generated changes, including native versions when present. For a resumed release, retain its version and completed preparation.

Fill every metadata/version/<version>/<locale>.json whatsNew using the same factual summary, translated using shipped terminology and metadata/store-locales.json. Preserve stable listing copy unless the release warrants a change. Keep template whatsNew blank. Fill the Android changelog emitted by the bump script, if present; inspect the actual script/output rather than assuming the legacy fastlane directory exists or is uploaded by EAS. Ensure the same notes are applied to the Google Play release through available authenticated tooling.

EAS uses remote native build numbers with auto-increment. Inspect the actual resulting iOS build number and Android version code; do not assume they equal the local suffix when selecting builds or attaching Android notes.

Prepare Google Play listing copy

Set GOOGLE_PLAY_SERVICE_ACCOUNT to the local JSON key path used by EAS Submit, without printing the key or token. Run yarn play:baseline, inspect tmp/play-baseline/baseline.json, and record the actual locale coverage. Do not assume the existing listing is English-only. Baseline reads create and delete an uncommitted edit; avoid concurrent Play edits with that account.

Run yarn play:generate after the bump and baseline review. It derives metadata/play/<locale>.json from canonical app-info/version metadata, using metadata/play-source/bg.json and fa.json for the languages Apple cannot offer. The result must cover all 16 Play locales / 13 runtime languages. Regenerate after any canonical listing change. Keep the baseline and credentials ignored; commit only the generated public copy and its canonical inputs.

Stage Apple listing before pushing

Run yarn format:check, yarn test, and yarn metadata:validate. Fix release-related failures and inspect any lint autofixes. Build and validate screenshots using yarn screenshots:build and yarn screenshots:validate; use the public demo sources, never a private ledger.

Follow the current release helper and localization guide. The required order is below; replace <version> with the actual target. Repeating the version is the helper's confirmation mechanism, not a reason to solicit authorization again.

./scripts/app-store-release.sh create <version> <version>
./scripts/app-store-release.sh plan <version>
# Inspect metadata/plan.md, metadata/keywords-plan.md, and screenshots/index.html
# under mobile/.asc/releases/<version>/; visually inspect generated screenshots.
./scripts/app-store-release.sh approve <version> <version>
./scripts/app-store-release.sh apply-metadata <version> <version>
./scripts/app-store-release.sh plan-screenshots <version>
# Inspect the separate screenshot replacement/order plan before applying.
./scripts/app-store-release.sh apply-screenshots <version> <version>
./scripts/app-store-release.sh verify <version>
yarn store:staging-check

Inspect helper assumptions before using it (including its metadata-copy source and automatic release setting). The verification writes metadata/releases/<version>.json bound to the exact listing inputs. Never fabricate or hand-edit that receipt. If any bound input changes afterward, repeat the affected plan/review/apply and parity verification. Keep .asc/, generated screenshots, credentials, and raw remote responses out of Git.

If authorization is actually missing, finish all possible local preparation first, present the target version, notes, intended store actions, and available plans, then ask only for the missing scope. Cite the precise applicable instruction if it requires additional human approval. Do not claim to have obtained operator approval that was never given.

Apply and verify Google Play listing

After building and validating all screenshots, run ./scripts/play-release.sh plan-play (also the default command). It uses the recorded baseline without credentials or network access and writes tmp/play-release/plan.txt and plan.json. Review every locale's title, short/full description diff, and ordered phone screenshots/feature graphic. Visually inspect the generated Play images, including Persian text shaping.

Run ./scripts/play-release.sh apply-play <plan-sha256> with the exact SHA-256 printed by the reviewed plan, within the release authorization already given. The helper checks for changed local inputs and remote baseline drift, updates only listing text and the phone/feature images, validates, and commits. It refuses to cancel another review in progress. It then checks all 16 locales' text and image checksums; rerun ./scripts/play-release.sh verify-play to repeat that read-only parity check. After drift, pull a new baseline and review a new plan rather than bypassing the check.

API parity does not prove publication. Check the review/publishing state in Play Console and sample the public listings, including Bulgarian and Persian. If review is pending, report that state and resume verification when it completes. Do not manage tracks or release notes through the listing helper; those remain part of the platform release steps below.

Ship and follow both platforms

Review the final diff and run the required secret scan before pushing. Use the repository's ship skill for the reviewed release files, including notes and staging receipt. If rebasing changes release contents or bound inputs, update the notes, repeat affected checks and parity verification before the push.

The main push triggers Release (mobile): checks → receipt verification → production OTA → EAS builds for both platforms with auto-submit → tag/GitHub release. Use this workflow as the single build kickoff; do not also start duplicate local builds. Locate the run for the shipped SHA with gh, follow it, and capture the exact EAS build and submission IDs for both platforms. Poll long jobs in bounded waits while giving progress updates.

Complete each store's remaining steps with available authenticated tools, checking current CLI help/documentation:

  • Apple: wait for the exact iOS build to finish uploading and processing, attach it to the prepared version, check required review information, submit for App Review, and verify the version's review/release state. EAS Submit uploads to TestFlight; it does not itself submit for App Review. Do not invent compliance answers or replace existing review credentials. Honor the configured release mode and complete a manual release after approval when applicable.
  • Google Play: verify the exact Android artifact/version code reached production, apply release notes, send pending changes for review when necessary, and verify the rollout/review state. An internal-track upload, draft release, or changes waiting to be sent for review is unfinished. Preserve an explicitly requested staged rollout.

Use Expo iOS submission documentation, submission automation, and EAS configuration to verify current store semantics when needed; prefer the repository-pinned CLI's supported commands.

On failure, inspect status/logs before retrying. Resume the failed platform or step using its exact build ID; never use submit --latest, delete a release tag to retrigger everything, or rebuild the successful platform unnecessarily. Rerun the workflow only after checking for in-flight jobs and whether the tag gate will skip deployment. A tagged release with a failed submission needs targeted recovery. After a retry encounters the same unresolved failure, stop retrying and report the required fix; do not create endless paid builds.

Finish all automatable steps. If store review is pending, report it explicitly with links and the next action; do not wait indefinitely or call it live. If credentials, mandatory store answers, or an unavailable console action block completion, name the exact action and continue independent work on the other platform.

Report

Return the version and baseline, a short change summary, shipped SHA and workflow link, checks performed, and separate iOS/Android statuses with build/submission links. Distinguish build queued, uploaded, submitted for review, approved, and live. Claim both stores released only when both production states have been verified. Report an unfinished run as unfinished, leading with where it stopped and the next required step; never present preparation — a bump, localized notes, or green checks — as a release.

Signals

GitHub stars
267
Forks
30
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
mobile-release
Source
github.com/bex-co/beancount-io
Mobile release (mobile-release) by bex-co: Skill · ahel