Today a tag builds and signs an APK/AAB but creates no release and
attaches nothing. That is the same partial-release failure mode as
rc.2/rc.3 (Play-only, no changelog). This closes it.
release-signed.yml becomes a complete release pipeline off a v* tag:
gate -> release-notes gate (backstop; fails in seconds)
android -> signed APK + AAB, cert-verified (environment-gated)
windows -> zipped Release build
linux -> tarred bundle
release -> create GitHub release, body = release notes, attach all four
Security invariant preserved: only the android job references the
release-signing Environment, so only it receives the keystore. The
windows/linux/release jobs never see it. Still no pull_request trigger.
The release job runs ONLY after every build passes, so a signing
failure yields no release rather than an empty one. Published directly
because the notes were reviewed in the cut PR.
Four-file notes gate (.github/scripts/release-gate.sh), run on every PR
(release-gate.yml) and as job one of the tag workflow:
CHANGELOG.md section for the pubspec version
release-notes/<v>.md non-empty -> GitHub release body
play/<v>.txt non-empty, <=500 chars (Play limit)
discord/<v>.md non-empty
play and discord are human-pasted; CI validates, never sends. Any
missing/oversize file fails the build, so a noteless release (rc.2/rc.3)
is unmergeable.
Gate script lives in .github/scripts/ because /scripts is in
.git/info/exclude (would not commit). Verified locally: fail surfaces
all four problems at once, pass is clean, 500 passes, 501 fails.
Backfills the combined rc.2/rc.3 CHANGELOG entry the two versions
shipped without.
release-notes/, play/, discord/ seeded with README conventions.
No ref input needed: the rc.3 backfill branch will carry these workflow
files, so tagging that branch runs them at that commit.
Part of epic #312, plan #321. Agent: SapphireCompass (session 8d755b5e)
One file per release: release-notes/<version>.md, where <version> is the marketing
version from pubspec.yaml (the part before +), e.g. release-notes/1.1.2-rc.4.md.
CI sets the GitHub release body from this file verbatim. It is published directly —
the notes are reviewed in the release-cut PR, so there is no draft step. What is in this
file at tag time is what the world sees.
Style
Narrative prose, not a bulleted changelog. Written for someone deciding whether to install
or update: what's new, what got fixed, anything they should know. Full Markdown is fine.
This is distinct from:
CHANGELOG.md — cumulative, terse, issue-referenced, for developers.
play/<version>.txt — plain, ≤500 chars, for the store.
discord/<version>.md — casual community announcement.
Same underlying changes, four different voices. The release gate
(scripts/release-gate.sh) fails the build if this file is missing or empty for the
version being tagged.