Skip to content

ci: release only pull-request-green commits, changelog section required, publish draft-first - #309

Merged
nofuturekid merged 1 commit into
mainfrom
ci/release-path-guard-and-draft-first
Nov 13, 2026
Merged

nofuturekid merged 1 commit into
mainfrom
ci/release-path-guard-and-draft-first

Conversation

@nofuturekid

@nofuturekid nofuturekid commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #295 (WP2).

What changed

  • release.yml is split into two jobs. guard (contents: read, actions: read) does the CI-run lookup (both paths kept, so existing tags stay re-runnable) and runs release-guard.sh. publish (contents: write, plus actions: read to download the CI artifacts) runs only when the guard succeeded and the event is a tag push. Top-level permissions are contents: read.
  • publish downloads the APK and mapping.txt (the mapping is mandatory now, no continue-on-error), runs release-verify-apk.sh unchanged, slices the changelog (an empty section is fatal), and publishes with one gh release create --verify-tag --title <tag> --notes-file ... --generate-notes [--prerelease] <apk> mapping.txt instead of softprops/action-gh-release. gh creates a draft, uploads both files, then publishes, so the assets exist before the release is public (needed for immutable releases). Asset names, title, pre-release detection and the latest behaviour are as before.
  • A workflow_dispatch trigger with inputs sha and version runs only the guard (tag v<version>, commit sha, no tag needed). Nothing is published.
  • Every job has timeout-minutes (addresses the open point of ci.yml hardening: --no-renames in docs-only diff, job timeouts, stale cache comment #256). The remaining actions were already pinned by full SHA.
  • release-guard.sh: requires a successful pull_request run of this repository on exactly the tagged commit (lookup path 1; the artifact may still come from a recovery dispatch run). Squash-era tags (path 2) keep the check that the PR was merged as this commit; a recovery dispatch on a squash-era tag falls back to that same check via the (#NN) subject. It calls release-preflight.sh (version shape, versionCode increase, tag name, non-empty changelog section) before anything is downloaded, and the duplicate versionCode check is removed. Stale squash wording is updated.
  • Docs: CONTRIBUTING, HANDOFF ("Release dry run" now describes the dispatch dry run; the shell variant stays as a fallback), ADR-0014 and ADR-0010 amendments, R-RELEASE, release-engineer role file.

Deliberately left out

  • The immutable-releases repository setting and all rulesets (switched by the maintainer after this lands).
  • ci.yml (its mapping upload already uses if-no-files-found: error), signing (WP3), app code.

Not proven before landing

The publish job needs a real tag, so it has no platform acceptance yet; the next beta tag is the acceptance. After landing, run the dispatch dry run on main. The guard logic was run locally against real history (v0.1.45 path 1, v0.1.44 and v0.1.45-beta1 path 2, a commit without a pull request run, a missing changelog section).

🤖 Generated with Claude Code

…ed, publish draft-first

Work package WP2 of #295.

release.yml is split into a read-only guard job and a publish job.
Top-level permissions are contents: read; only publish has contents:
write and it runs only after the guard succeeded on a tag push. Every
job has timeout-minutes (the open point of #256). A workflow_dispatch
with inputs sha and version runs only the guard as a dry run: nothing
is published and no tag is needed.

The release is published with one gh release create (--verify-tag,
draft, upload both files, then public) instead of
softprops/action-gh-release, so the assets exist before the release is
public, as immutable releases require. mapping.txt is mandatory now.
A missing CHANGELOG section is fatal instead of a warning.

release-guard.sh requires a successful pull_request run of this
repository on the tagged commit itself (lookup path 1; a recovery
dispatch run still supplies the artifact), calls release-preflight.sh
for version shape, versionCode, tag name and changelog, and drops the
versionCode check that the preflight covers identically. Squash-era
tags keep their check that the PR was merged as this commit. Stale
squash wording in the comments and messages is updated.

Docs: CONTRIBUTING, HANDOFF (dispatch dry run), ADR-0014 and ADR-0010
amendments, R-RELEASE and the release-engineer role file.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@nofuturekid
nofuturekid force-pushed the ci/release-path-guard-and-draft-first branch from 6009222 to 38bc3e1 Compare November 13, 2026 12:16
@nofuturekid
nofuturekid merged commit 38bc3e1 into main Nov 13, 2026
12 checks passed
@nofuturekid
nofuturekid deleted the ci/release-path-guard-and-draft-first branch November 13, 2026 12:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant