diff --git a/.github/workflows/play-listings.yml b/.github/workflows/play-listings.yml index 1c1e9d147..63cc97624 100644 --- a/.github/workflows/play-listings.yml +++ b/.github/workflows/play-listings.yml @@ -5,10 +5,16 @@ name: Play store listings # and is published from there by .github/scripts/publish_listings.py. # # pull request touching the metadata -> validate only (no secrets, works from forks) -# push to main touching the metadata -> publish the changed locales to Play # workflow_dispatch -> pick a mode: dry-run (default), # check-permissions, or publish # +# Publishing is DELIBERATE, never automatic: no branch push runs it. Listing +# text lands in the repo on the normal feature -> dev -> staging -> main flow +# and sits there until someone decides the store should say it, then ships by a +# manual run here (or by running .github/scripts/publish_listings.py locally -- +# see docs/store-listings.md). Merging to main touches Google Play in no way at +# all: android.yml uploads no AAB there either. +# # Graphics (icon, feature graphic, screenshots) are NOT managed here — Play falls # back to the default language's graphics for locales that have none of their # own, and screenshots are still uploaded by hand. See docs/store-listings.md. @@ -17,12 +23,6 @@ name: Play store listings # distribution/whatsnew/whatsnew-en-US and hands it to the upload action. on: - push: - branches: [main] - paths: - - 'fastlane/metadata/android/**' - - '.github/scripts/publish_listings.py' - - '.github/workflows/play-listings.yml' pull_request: paths: - 'fastlane/metadata/android/**' @@ -79,7 +79,7 @@ jobs: # must never be able to push listing text to the production app. if: >- github.repository == 'patrickrb/FT8AF' - && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + && github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest # Google Play allows only one open "edit" per app. android.yml serializes its # release publishes under this same group; sharing it keeps a listing update @@ -101,8 +101,10 @@ jobs: env: PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }} PACKAGE_NAME: radio.ks3ckc.ft8af - # A push to main always publishes; a manual run does what was picked. - MODE: ${{ github.event_name == 'workflow_dispatch' && inputs.mode || 'publish' }} + # Whatever the manual run picked. Falls back to the read-only dry + # run rather than to `publish`, so a mode that somehow arrives empty + # sends nothing to Play instead of shipping every changed locale. + MODE: ${{ inputs.mode || 'dry-run' }} run: | set -euo pipefail if [[ -z "${PLAY_SERVICE_ACCOUNT_JSON:-}" ]]; then diff --git a/docs/release-pipeline.md b/docs/release-pipeline.md index a3b365d0b..1a03ea486 100644 --- a/docs/release-pipeline.md +++ b/docs/release-pipeline.md @@ -24,11 +24,10 @@ feature/* ──PR──▶ dev ──PR──▶ staging ──PR──▶ main platform: prerelease GitHub Releases + Play **internal** track for Android. - **staging → main** — promote the validated staging build. Merging this PR (a push to `main`) cuts the **production** build: full GitHub Releases with the - auto-bumped `android-v` / `desktop-v` tags. It uploads **no app - binary to Google Play** — no AAB reaches any track. (Store *listing* text is a - separate pipeline: a `main` push touching `fastlane/metadata/android/**` still - runs `play-listings.yml`, which does publish listing changes to Play. See - [Store listings](#store-listings) below.) + auto-bumped `android-v` / `desktop-v` tags. **A merge to `main` + reaches Google Play in no way at all** — no AAB to any track, and no store + listing text either. Everything Play-side is a deliberate, separate act. See + [Store listings](#store-listings) below. - **shipping a `main`-cut release to Play production is manual.** In **Actions → Android CI & Release → Run workflow**, pick the `android-v` tag the `main` merge created as the ref and run it. That run takes the same @@ -112,12 +111,17 @@ PR titles as the notes — a release is never blocked on the AI step. Play *store listing* text (title, descriptions, per-locale metadata) lives in `fastlane/metadata/android/` and ships through its own workflow, -`play-listings.yml` — not through the Android release pipeline above. It -publishes on a push to `main` that touches that directory, and can also be run -manually (with a dry-run option). So a `main` merge that changes listing text -does reach Google Play, even though it uploads no app binary; the two are -deliberately independent, because listing copy and app builds ship on different -cadences. +`play-listings.yml` — not through the Android release pipeline above, and not +on any branch push. A PR touching the metadata is **validated** (completeness +and Play's character limits) and then the text just sits in the repo; it reaches +the store only when someone runs the publish on purpose: + +- **Actions → "Play store listings" → Run workflow**, mode `publish` (the + default mode is the read-only `dry-run`), or +- locally: `python .github/scripts/publish_listings.py`. + +Listing copy and app builds ship on different cadences, and neither is tied to a +`main` merge. ## One-time setup on GitHub (manual) diff --git a/docs/store-listings.md b/docs/store-listings.md index 4fdb818f2..f6ae3f66e 100644 --- a/docs/store-listings.md +++ b/docs/store-listings.md @@ -85,13 +85,18 @@ The workflow is `.github/workflows/play-listings.yml`: - **Pull request** touching the metadata → validation only. Runs the unit tests, which load the whole tree and check completeness and character limits. No secrets, so it works from forks. -- **Push to `main`** touching the metadata → publishes the changed locales. Since - all PRs target `dev`, listing changes reach Play on the normal - dev → staging → main promotion, alongside the release they belong to. - **Manual run** (Actions → "Play store listings" → Run workflow) → pick a mode: `dry-run` (the default; prints the diff, sends nothing), `check-permissions` - (the grant probe below), or `publish` (the real thing, without waiting for a - merge to `main`). + (the grant probe below), or `publish` (the real thing). + +**No branch push publishes.** Not `dev`, not `staging`, and deliberately not +`main` — a merge to `main` cuts the GitHub Release and sends nothing whatsoever +to Google Play, listings included. Listing text is version-controlled the same +way code is: it lands in the repo through the usual feature → dev → staging → +main flow, is validated on the way in, and then waits until someone decides the +store should say it. That decision is the manual run above, or the same script +run locally (see [Running it locally](#running-it-locally)) — the store's copy +changes when you choose, not when a promotion happens to carry it. Note that `workflow_dispatch` only appears once this workflow file exists on the repository's **default branch**, `main`. Until the first promotion carries it