One linear checklist covering the whole lifecycle: setting up your machine, running the app, and publishing it to Google Play. Each phase links to a deeper doc for detail — but you can follow just this page top to bottom and not get lost. Do the phases in order; later ones depend on earlier ones.
A Flutter app (itmc_estimator) for quoting/invoicing a service business:
clients, a service-price catalog, cost estimates, invoices, PDF export. It
runs entirely on-device (no login, no server) and is set up to publish to
Google Play with almost everything automated — building, signing,
uploading, store listing text, and even screenshots.
Branching: main is the production branch — only merges and release
tags land here. dev is where ongoing work happens. Push to dev, open a
PR into main when a change is ready to ship, then tag a release from
main (Phase 8). .github/workflows/ci.yml runs lint/test/build checks on
every push to dev and every PR into main, separate from
release.yml (which only runs on version tags, regardless of branch).
You need three things: the Flutter SDK, the Android SDK, and one Android emulator (or a physical phone). If you’re on the same machine this was set up on, skip to Phase 2 — it’s already done here.
On a fresh machine:
git clone -b stable https://github.com/flutter/flutter.git
into some folder (e.g. C:\src\flutter), then add its bin folder to
your PATH.flutter doctor -v and follow whatever it flags — usually just
accepting Android licenses (flutter doctor --android-licenses).flutter emulators --create.flutter doctor should say
“No issues found!”.flutter pub get
flutter emulators --launch <your-emulator-id> # or plug in a phone via USB
flutter run
Full detail, golden-path manual test script, and why this app specifically needs an Android target (not Windows/web) → docs/RUNNING.md.
flutter build appbundle --release
This is the .aab file Google Play actually wants (not an .apk). It’ll
work with debug signing until Phase 4 is done — fine for a first test
upload, not for anything you intend to keep live.
keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
Keep this file outside the repo, somewhere safe — losing it means you
can never update the app again under the same listing. Copy
android/key.properties.example → android/key.properties and fill in the
real values for local release builds.
This is the credential the automation uses to upload on your behalf. Four parts: create a Cloud project → enable the Play Developer API → create a service account + JSON key → link it in Play Console.
Full click-by-click walkthrough → docs/PUBLISHING.md, step 4.
This is the one part Google requires a human to do — no API can create a brand-new app listing. Everything you need is already written for you:
fastlane/metadata/android/en-US/
(title, short/full description already written for this app).fastlane/metadata/android/en-US/images/ (placeholders — swap for real
branding whenever you have it, same filenames).scripts/capture_screenshots.sh first (see
docs/RUNNING.md)
and use the images it produces.main /docs) and use the resulting URL to
docs/privacy-policy.md..aab from Phase 3.Full detail → docs/PUBLISHING.md.
Repo → Settings → Secrets and variables → Actions, add 5 secrets (keystore, its passwords/alias, and the service account JSON from Phase 5). Exact list → docs/PUBLISHING.md, step 5.
Once Phases 1–7 are done once, every release is just:
scripts/capture_screenshots.sh # optional: refresh screenshots if UI changed
git add fastlane/metadata && git commit -m "Update screenshots"
git tag v1.0.1
git push origin v1.0.1 --tags
The tag push triggers CI (.github/workflows/release.yml), which builds
the signed .aab and uploads it — plus the current listing text, images,
and screenshots — to the internal testing track automatically. From
there:
production directly.Bump the version in pubspec.yaml (version: 1.0.1+2 — the number after
+ is the build number, must increase every release), add a changelog file
at fastlane/metadata/android/en-US/changelogs/<build-number>.txt, then
repeat Phase 8’s tag-and-push. That’s the entire release process, forever.