Swasti · mForm V2→V3

15 — Release runbook

This is the operational checklist for shipping a change to the staging testers. It assumes you’ve read note 14 for the repo/branch/environment map. There is no CI release pipeline — every build happens on an engineer’s laptop.

Two halves move independently:

  1. Backend (Frappe app) — push to development, staging auto-pulls and migrates.
  2. Mobile (Flutter app) — build the APK locally, upload to Firebase, notify testers.

If a release only touches one half, you only run that half.


A. Backend release (Frappe app)

Repo: frappe_mform_swasti · Staging branch: development → auto-deploys to stg.swasti.mform.in.

Branch policy: development is the only branch that accepts direct pushes and auto-deploys to staging. master → uat is PR-only. Never push straight to uat/main.

  1. Commit your changes. Doctype JSON, controllers, patches, fixtures.
  2. Push to development. Staging’s autopull picks it up and runs bench migrate automatically — no need to ping DevOps if the migration is clean.
  3. Wait ~2–5 min, then verify. Probe the API for any new doctype:
    POST /api/method/login            usr=Administrator&pwd=<staging pwd>
    GET  /api/method/frappe.client.get_count?doctype=<New Doctype>
    200 = the doctype migrated. 404 = it didn’t (see the checklist below).

Adding a NEW doctype? Three things must travel together

A new doctype is invisible to the mobile app until all three are in place. Miss any one and the form will render but its dropdowns show “No options available” (the app couldn’t fetch the doctype’s metaJson).

#WhatWhere
1The doctype JSON + controller + __init__.pymform_swasti/<module>/doctype/<name>/
2A patch granting Mobile User + Swasti Surveyor read/create permspatches/v3_0/_NNN_*.py + patches.txt
3The same patch appends the doctype to the Mobile Configuration manifest (table_lwis)same patch

The SDK only pulls metaJson for doctypes listed in the Mobile Configuration manifest. No manifest row → no meta on the device → empty dropdowns. (Perms baked into the doctype JSON are not enough on their own — the manifest entry is what triggers the metaJson sync.)

Migrate-failure checklist

If bench migrate fails on staging (or new doctypes stay 404), it’s almost always one of these — all seen on this project:

  • ModuleNotFoundError for a patch → the patch .py is listed in patches.txt but the file was never committed. Run git ls-files and confirm every patch in patches.txt is tracked.
  • A doctype’s files are untracked → the JSON returns 404 but exists locally. Same fix: commit the untracked files.
  • Unknown column / OperationalError mid-migrate → a patch reads or writes a field that isn’t in the committed doctype JSON. One crashing patch aborts the entire migration, so every patch after it silently never runs. Confirm any column a patch touches is in a committed .json.
  • Patch ran but had no effect → check Patch Log (list it filtered by your patch name). A patch only runs once; if it ran with a bug, fixing the code won’t re-run it — bump it to a new _NNN number or clear its Patch Log row.

Lesson from 27 May: a Document Master.is_applyable_document column was added locally but never pushed. Patch _013 read it, crashed on the unknown column, and aborted the migrate — so _014/_015 never ran and two whole forms had empty dropdowns. The fix was to commit the field, not to touch the app.


B. Mobile release (Flutter app)

Repo: frappe_mform_swasti_app · builds are local, distribution is Firebase (staging) / Play Store via DevOps (uat/prod).

  1. Build the staging APK (from the app root):

    flutter build apk --flavor staging -t lib/main_staging.dart

    Output: build/app/outputs/flutter-apk/app-staging-debug.apk (~200 MB).

  2. Write release notes — plain-language, surveyor-facing, “what to test.” Keep a file (e.g. /tmp/swasti-release-notes-<date>.txt).

  3. Upload to Firebase App Distribution:

    firebase appdistribution:distribute \
      build/app/outputs/flutter-apk/app-staging-release.apk \
      --app "1:79062936320:android:cf185872e152002cae61e5" \
      --groups "<group-alias[,group-alias…]>" \
      --release-notes-file /tmp/swasti-release-notes-<date>.txt

    Success prints the release version + console/tester links. Testers in the named group(s) get a notification.

    Which group(s) to distribute to

    Two groups exist on the Firebase project (swasti-mform-v3):

    Group aliasDisplay nameWhoWhen to include
    dhwaniDhwani7 internal testers (Abhijit, Ankit, Ritesh, Fahim, etc.)Every drop — internal dev/PM + Swasti PMs
    swasti-clientSwasti Client TestersCatalysts staff (shanmathi@, dharshini.m@, santosh.r@)Stable drops only — once the change has been verified on the Vivo / dhwani round and the KB tracker isn’t in the middle of a triage burst

    Default for an in-flight triage commit: --groups "dhwani". Default for a stable / weekly-summary drop: --groups "dhwani,swasti-client". Don’t fire client drops for every internal fix — they’ll get notification fatigue and the App-Tester install backlog grows.

    Adding new testers

    firebase appdistribution:testers:add <email1> [<email2>…] \
      --group-alias <dhwani|swasti-client> \
      --project swasti-mform-v3

    Adding a new group

    firebase appdistribution:group:create "<Display Name>" <alias> \
      --project swasti-mform-v3
  4. Notify the testers on Teams — post the highlights to the mForm V3 ↔ Swasti group chat (always send as HTML). Lead with what’s new and what to test, not the changelog.

Direct install for your own device (skip Firebase)

adb -s <device-id> install -r -d build/app/outputs/flutter-apk/app-staging-debug.apk

C. After the release

  • New doctypes need a sync on-device. Once the manifest is updated server-side, the tester must pull-to-refresh / tap the Home sync pill to pull the new metaJson. Dropdowns populate after that sync, not on first launch.
  • Log feedback in the tracker. Triage each batch with the PM before fixing — not every report is in scope.

Standing gaps

  • No release.sh wrapper yet — the build/upload/notify steps are run by hand.
  • No CI. Builds depend on one laptop’s Flutter + Android toolchain.
  • The mobile SDK does not yet ALTER existing docs__ tables when a synced doctype gains a column — a device that already synced an older schema may need a reinstall to pick up new columns (tracked separately).

Last updated 2026-05-04