Frb Publish Release
DevOps & Securityfrb-publish-releaseFrb Publish Release is an Agent Skill for devops & security published in the fzyzcjy/flutter_rust_bridge repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.
Publish a flutter_rust_bridge release end to end: preflight checks, changelog preparation, frb_internal release publishing, released-version polling, CI babysitting, and post-release CI verification.
How to use this skill
Bring this guide into your coding agent with a prompt tailored to the tool you use.
- Open your project in Codex.
- Copy and paste the prompt below.
- Review files and risks before approving any action.
Inspect the Agent Skill at https://github.com/fzyzcjy/flutter_rust_bridge/blob/HEAD/.claude/skills/frb-publish-release/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/frb-publish-release, but wait for my approval before writing files or running scripts.
Copying this prompt does not install or run the skill. Review third-party files before use.
FRB Publish Release
Use this skill when preparing, publishing, or babysitting a flutter_rust_bridge release.
Workflow
1. Preflight
-
Work from the repository root on the intended release branch, normally fresh
master. If the checkout is detached but already points at the intended release commit, switch or create a local release branch from that commit before running mutating release commands; do not treat detached HEAD itself as a release blocker. -
Check
git status --short --branchand do not start publishing from a dirty tree. -
Check submodules before publishing:
git submodule update --init --recursive git submodule status --recursiveStop if any submodule path remains uninitialized. A release built without initialized submodules can publish incomplete package contents. The release script performs the same submodule-status guard before publishing.
-
Treat
masteras a moving branch. Before each irreversible release phase, fetchorigin master, confirm the current release branch or detached checkout still points at the intended latestorigin/mastercommit, and re-rungit status --short --branchto confirm there are no unexpected local changes. -
Confirm the target version in
CHANGELOG.md, rootCargo.toml, andfrb_dart/pubspec.yaml. -
Compute the release versions the same way
./frb_internal releasedoes: the topCHANGELOG.mdversion is the new version and the next release section is the old version. -
Verify both old and new versions are legal before running any mutating release command. The only allowed shapes are stable SemVer
MAJOR.MINOR.PATCHsuch as2.0.0, or beta SemVerMAJOR.MINOR.PATCH-beta.Nsuch as2.0.0-beta.1. Use exactly^\d+\.\d+\.\d+(-beta\.\d+)?$. -
Reject versions with any other prerelease label, build metadata, missing numeric components, leading
v, or loose text. Stop if either old or new version fails this check. -
Confirm the new version is different from the old version.
-
Run the publish container credential preflight before starting irreversible publish steps:
.claude/skills/frb-dev-env/frb_dev_env.py docker-run-rm --with-publish-credentials -- trueStop if the preflight fails. It checks GitHub CLI auth, Cargo credentials, and Dart pub credentials inside the same temporary credential layout used by release publishing.
-
Confirm normal CI is green for the release commit before publishing. This is the default hard gate.
A narrow exception is allowed only when all of these are true:
- A recent earlier commit on the same release branch has fully green normal CI.
- Every commit between that green commit and the intended release commit is unrelated to the publishable packages, version sources, generated release artifacts, and
frb_internalrelease logic. - The mechanical gate script below exits successfully and its output is recorded in the release notes or journal.
- The agent explicitly states that it is using the exception before publishing.
Run the mechanical gate from the repository root:
uv run --script .claude/skills/frb-publish-release/release_ci_gate.py \ --base-green-ref <LAST_GREEN_SHA> \ --release-ref HEADStop and wait for normal CI if the script reports any
BLOCKpath. The script is intentionally conservative: release-surface paths such asCargo.toml,frb_dart/pubspec.yaml,frb_codegen/**,frb_macros/**,frb_rust/**,frb_dart/**,frb_utils/**,frb_example/**,tools/frb_internal/**,pubspec.yaml,melos.yaml, and lockfiles are not in the allowlist.CHANGELOG.mdis allowed because adding the target release section is a normal release-preparation step and is reviewed directly before publishing. This exception is for changelog-only release preparation, docs, agent tooling, devcontainer, selected CI configuration, and other explicitly non-release paths only.
2. Reconcile Contributors
- Before writing the release changelog, use
frb-add-contributorto identify contributors from the target release range who may need all-contributors credit. - Follow
frb-add-contributorexactly. In particular, after determining which contributors may need to be added, stop for human confirmation before editing contributor files, posting GitHub comments, triggering all-contributors, opening PRs, or merging contributor PRs. - Do not continue to changelog preparation until contributor reconciliation is either complete, confirmed unnecessary because all contributors are already credited, or explicitly deferred by the human release owner.
3. Write Changelog
- Use
frb-write-changelogto create or refresh the target release section inCHANGELOG.md. - When reviewing the release section, explicitly check every third-party human-authored PR in the release range, including docs, CI, chore, and tooling PRs. Each must either have
(thanks @username)in the matching changelog entry or a documented reason for omission. - Be careful with grouped entries: if a local maintainer PR and a third-party PR are summarized together, the grouped entry still needs the third-party thanks attribution.
- Review the release section manually before publishing. The top
CHANGELOG.mdversion is the source used byfrb_internal release. - If changelog or version files changed, commit that release preparation before publishing.
4. Publish
Use the repository release command through a temporary Docker container with publish credentials as the normal publishing path:
.claude/skills/frb-dev-env/frb_dev_env.py docker-run-rm --with-publish-credentials -- ./frb_internal release
Do not split the normal release into separate release-update-* or publish commands. The one-shot command is the source of truth for release sequencing: it computes old/new versions from CHANGELOG.md, updates checked-in versions and generated version text, updates Scoop metadata, commits and pushes the version bump, creates the GitHub release, then runs the registry publisher:
.claude/skills/frb-dev-env/frb_dev_env.py docker-run-rm --with-publish-credentials -- ./frb_internal release-publish-all
For beta versions such as 2.13.0-beta.1, do not require the GitHub release to be labeled as a pre-release. FRB intentionally publishes beta GitHub releases as normal GitHub releases while the package version itself remains a SemVer prerelease.
release-publish-all publishes these packages:
frb_codegen-> crates.io packageflutter_rust_bridge_codegenfrb_macros-> crates.io packageflutter_rust_bridge_macrosfrb_rust-> crates.io packageflutter_rust_bridgefrb_dart-> pub.dev packageflutter_rust_bridge
Only use a split subcommand as a recovery path after confirming which one-shot step already completed. For example, if the version bump and GitHub release already exist and only registry publication is needed, use .claude/skills/frb-dev-env/frb_dev_env.py docker-run-rm --with-publish-credentials -- ./frb_internal release-publish-all directly.
5. Check Released Versions
Poll registry state with:
./frb_internal get-released-version
To check a target version from a checkout whose manifests have not been bumped, pass it explicitly:
./frb_internal get-released-version --version <VERSION>
The command prints JSON:
{
"allReleased": true,
"packages": [
{
"registry": "crates.io",
"name": "flutter_rust_bridge_codegen",
"manifestVersion": "2.12.0",
"releasedVersion": "2.12.0",
"isReleased": true
}
]
}
Wait until every package has isReleased: true and allReleased: true. If one registry lags, keep polling with bounded waits and record the mismatched package instead of assuming the publish failed. Do not add the target version option to the mutating release-* subcommands; they derive their version from CHANGELOG.md and checked-in manifests.
For beta releases, get-released-version --version <VERSION> must verify the pub.dev versions list, not only pub.dev's latest field, because pub.dev keeps latest on the latest stable release when a prerelease is uploaded.
6. Babysit CI And Post-Release CI
- Keep watching the release commit's normal CI until it is green.
- After
./frb_internal get-released-versionreportsallReleased: true, trigger.github/workflows/post_release.yamlfor the release commit ormaster. - Babysit post-release CI until it is green. Use
gh-actions-live-logswhen reading GitHub Actions logs. - If post-release fails, classify the failure by release channel (
stableorunstable) and install mode (cargo-install,cargo-binstall,scoop, orhomebrew) before changing code or rerunning.
Related Skills
frb-write-changelogfor the release section.frb-fix-ciorfrb-fix-main-cifor CI failures.gh-actions-live-logsfor GitHub Actions logs.