Release-management workflow: process and label lifecycle
June 2, 2026 · View on GitHub
The authoritative reference for the 14-step release lifecycle and the label-lifecycle state diagram the release-management skills execute against. The family README lists the skills; this document is the process they share. The spec defines per-skill scope, state-change boundary, and adopter knobs.
The lifecycle is described in ASF terminology by default
(svnpubsub on dist.apache.org, [VOTE] on dev@, [ANNOUNCE]
on announce@apache.org), because the framework's first pilots
include an ASF PMC release. Every step that touches an ASF-specific
surface is implemented as a backend call the adopter selects in
release-management-config.md,
not a hard-coded operation. Non-ASF adopters resolve the same
abstract step to their own backend; see the
Adopter backends section for the dimensions
and the per-step backend mapping.
Adopter backends
Three dimensions parametrise the lifecycle. Each adopter picks one
value per dimension in release-management-config.md. The 14
steps stay identical; only the backend the agent emits commands
against changes.
| Dimension | Config key | ASF default | Non-ASF examples |
|---|---|---|---|
| Distribution backend | release_dist_backend | svnpubsub (svn import to dist/dev/, svn mv to dist/release/) | github-releases (gh release upload / gh release edit --draft=false), s3 (aws s3 cp / aws s3 mv), self-hosted (project-supplied command template) |
| Approval mechanism | release_approval_mechanism | dev-list-vote ([VOTE] thread on dev@<project>.apache.org, 72h window, 3 binding +1, more +1 than -1) | github-discussion (named Discussion thread on <upstream> repo), pr-approval (a "release-NN" PR with approvals from the configured roster), maintainer-roster (signed approvals from a named roster file) |
| Announcement backend | release_announce_backend | announce-list (mail to announce@apache.org, cc dev@, users@) | github-release-notes (the release-page body is the announcement), site-post (a blog post in site_repo), discord-channel (a webhook into a named channel) |
Each release-* skill consults the relevant key and emits
backend-shaped paste-ready commands. The state-change boundaries
(spec § Cross-cutting commitments)
do not change: the agent still emits a recipe; the human still
runs it. Swapping svn for gh release upload swaps the
backend, not the boundary.
The vote-tally roster (release-vote-tally) reads from the
adopter's pmc-roster.md for ASF projects, or
<release_approver_roster_path> (typically
<project-config>/release-approvers.md) for non-ASF adopters; both
files share the same schema (handle, binding-flag, optional GPG
fingerprint).
Important
Release Management is proposed in the framework today. No
release-* skill code exists yet. This document, the family
README.md, the spec.md, and
projects/_template/release-management-config.md
land first so the lifecycle, the state-change boundaries, and the
adopter contract are reviewable independently from the runtime
behaviour. The pattern matches Mentoring.
See docs/modes.md § Drafting / Triage
for status.
Process reference: the 14 steps
This is the authoritative outline of the 14-step lifecycle. Each
step links to the skill that owns it (or marks it proposed if the
skill is not yet implemented). The brief descriptions below are an
overview, not a substitute for the linked skill's SKILL.md.
Two non-negotiable boundaries cross the lifecycle:
- The agent never holds, invokes, or proxies the Release
Manager's private signing key. Any step that needs a signature
emits a paste-ready command sequence; the RM runs it on their own
machine, as themselves. This mirrors the
security-cve-allocatepattern (Vulnogram URL + paste-ready JSON, human submits) and satisfies RFC-AI-0004 Principle 1. - The agent never publishes the release. Steps 10
(
svn mv dist/dev → dist/release) and 11 ([ANNOUNCE]send, site bump merge) are the moments of release; the agent drafts artefacts, the RM and the PMC execute and merge.
flowchart TD
S1[1. Plan + version bump]
S2[2. Changelog + NOTICE/LICENSE]
S3[3. KEYS reconciliation]
S4[4. Cut RC: tag + build + sign]
S5[5. Stage to dist/dev]
S6[6. Pre-flight verify]
S7[7. VOTE thread on dev@]
S8[8. Voting window]
S9{9. Tally: pass or fail?}
FAIL([Fail: revert RC, return to step 4])
S10[10. Promote dist/dev to dist/release]
S11[11. ANNOUNCE + site bump]
S12[12. Archive sweep]
S13[13. Audit log]
S14[14. Post-release version bump]
S1 --> S2
S2 --> S3
S3 --> S4
S4 --> S5
S5 --> S6
S6 --> S7
S7 --> S8
S8 --> S9
S9 -->|pass| S10
S9 -->|fail| FAIL
FAIL --> S4
S10 --> S11
S11 --> S12
S11 --> S13
S11 --> S14
classDef prep fill:#fff3cd,stroke:#664d03,color:#000
classDef rc fill:#cfe2ff,stroke:#055160,color:#000
classDef vote fill:#e2d9f3,stroke:#3d2a6b,color:#000
classDef publish fill:#d4edda,stroke:#0f5132,color:#000
classDef terminal fill:#f8d7da,stroke:#842029,color:#000
class S1,S2,S3 prep
class S4,S5,S6 rc
class S7,S8,S9 vote
class S10,S11,S12,S13,S14 publish
class FAIL terminal
Colour key: yellow = preparation, blue = release candidate, purple = vote, green = publication and follow-up.
Step 1: Release planning + version bump
Owner: PMC + nominated Release Manager (RM).
Skill: release-prepare
(proposed), Drafting.
The RM opens a planning issue listing the target version, the
release train it belongs to (see
<project-config>/release-trains.md),
the cut-off commit, and the issues / PRs in scope. The skill drafts
that planning issue from the configured release-train metadata, then
drafts the version-bump PR (e.g. pom.xml, pyproject.toml,
Cargo.toml, setup.py, package manifests). The PR remains in
draft until the RM marks it ready; the agent never marks ready, never
merges.
For non-ASF adopters with no release-train concept the planning step
collapses to a tag-and-PR pair; the skill detects the absence of
<project-config>/release-trains.md
and adapts.
Step 2: Changelog, NOTICE, LICENSE
Owner: RM.
Skill: release-prepare
(proposed), Drafting (same skill as Step 1, second invocation).
The skill drafts the changelog entry from the merged-PR set since
the previous release tag, the NOTICE diff (third-party
attributions added or removed), and the LICENSE diff if any
license-categorised dependency changed
(ASF Category-A/B/X policy).
The skill flags any Category-X dependency for the RM to remove before
the cut and refuses to advance the planning issue until that flag
clears.
Output: a single PR proposed against the release branch, RM merges after their own review.
Note
The Step 2 LICENSE / NOTICE draft is provisional. It is
drafted before the build, so it covers only content the skill can
see in the source tree; build-time-only or generated dependencies
are not yet visible. Step 6's
Apache RAT pass verifies
LICENSE / NOTICE against the actual built artefact, and that
verification, not the Step 2 draft, is authoritative.
Step 3: KEYS reconciliation
Owner: RM.
Skill: release-keys-sync
(proposed), Drafting.
If the RM is signing their first release for the project, their
public key must appear in the project's KEYS file under
dist/release/<project>/KEYS. The skill drafts the KEYS diff
(public-key block appended in the project's existing format),
emits the svn command sequence to commit it, and reminds the RM
that the key must also be uploaded to a public keyserver per
the ASF release-signing FAQ.
The agent never holds the private key and never runs svn commit;
the RM executes both as themselves.
If the RM's key is already present and unchanged, the skill is a no-op and reports so on the planning issue.
Step 4: Cut the release candidate
Owner: RM.
Skill: release-rc-cut
(proposed), Drafting.
The skill emits a paste-ready command sequence:
git tag -s <version>-rcN -m "..."(signed tag, RM's key).- Build invocation, project-specific
(
<project-config>/release-build.md). gpg --detach-sign --armor <artefact>for each artefact.sha512sum <artefact> > <artefact>.sha512for each artefact.
The skill writes nothing to disk and runs nothing locally. The RM runs every command on their own machine, with their own key, in their own checkout. The skill's output is the recipe; correctness of the recipe is reviewable independently from execution. After the RM reports back the artefact list + checksums + sig filenames, the skill records them in the planning issue's audit-trail comment for Step 13.
Note
Detached .asc signatures and .sha512 checksums are the ASF
baseline; some projects also publish .sha256 for older
downstream tools. MD5 and SHA-1 are prohibited for new
releases per
release-distribution § sigs-and-sums,
and signatures are published as detached .asc only, never a
binary .sig. The skill reads
<project-config>/release-build.md
to determine which digests apply.
Step 5: Stage to dist/dev/
Owner: RM.
Skill: release-rc-cut
(proposed), Drafting (same skill as Step 4).
The skill emits the svn command sequence to import the artefacts
.asc+.sha512files intohttps://dist.apache.org/repos/dist/dev/<project>/<version>-rcN/(svnpubsub-backed, automatically mirrored to the publicdist.apache.orghost per the release-distribution documentation). The RM commits with their ASF credentials; the skill never holds those credentials.
Output: the staging URL and the candidate artefact list, written back to the planning issue.
Step 6: Pre-flight RC verification
Owner: RM (self-check) + any committer who plans to vote.
Skill: release-verify-rc
(proposed), Triage / Pairing.
Read-only. The skill fetches the staged artefacts from
dist/dev/<project>/<version>-rcN/, then verifies:
- Signatures.
gpg --verify <artefact>.asc <artefact>against the project'sKEYSfile (NOT against the RM's keyring, Step 3'sKEYSis the project's source of truth). - Checksums.
sha512sum -cagainst the published.sha512(and.sha256where configured). - License headers on source artefacts, per Apache RAT configuration shipped with the adopter.
NOTICEandLICENSEpresence at the artefact root, content diff against the previous release.- No prohibited binaries in the source artefact (per
<project-config>/release-build.mdbinary-exclusion list). - Version string consistency between artefact filename, embedded manifests, and tag.
The skill emits a pass/fail report to the planning issue. A failure does not auto-flip any label; the RM decides whether to roll a new RC (back to Step 4) or fix the verification source itself (e.g. update RAT excludes).
This skill is the most valuable Pairing-mode candidate in the family:
voters run it in their own dev loop before posting a +1 so the
mechanical verification work is done before the human-to-human vote
conversation.
Step 7: [VOTE] thread on dev@
Owner: RM.
Skill: release-vote-draft
(proposed), Drafting.
The skill drafts the [VOTE] email body to dev@<project> from
the planning issue's metadata: version, RC number, staging URL,
tag URL, KEYS URL, changelog URL, voting-window deadline
(per the release-policy.html § release approval
baseline, the configured per-project window in
<project-config>/release-management-config.md
overrides). The RM sends the email; the skill never sends mail.
The skill simultaneously drafts a [VOTE] notification on the
planning issue for committer awareness; that PR / issue comment is
also proposed, not auto-posted.
Step 8: Voting window
Owner: PMC voters (binding) + committers / community (non-binding). Skill: none, passive window.
No skill runs during the window. The planning issue carries the
vote-open label so other skills (Triage on adjacent issues,
Mentoring on the [VOTE] thread) can spot the window and behave
appropriately (e.g. Mentoring stays out of the [VOTE] thread per
its hand-off rules, vote discussion is PMC business).
Step 9: Tally + [RESULT] [VOTE]
Owner: RM.
Skill: release-vote-tally
(proposed), Triage.
After the window closes, the skill fetches the thread from the
project's mail archive (PonyMail by default), parses each reply,
classifies each vote (+1 / 0 / -1), determines binding vs
non-binding by cross-referencing
<project-config>/pmc-roster.md
with the From-address, and proposes the [RESULT] [VOTE] body. The
RM reviews and sends.
The tally is conservative: when a vote is ambiguous (binding voter
posts +1 with one caveat, or +0.5), the skill marks it
AMBIGUOUS, needs RM call and refuses to count it. A vote count
the RM cannot defend on dev@ is worse than a slow tally.
Pass / fail follows the
release-policy.html § release approval
baseline (three binding +1 minimum, more binding +1 than -1);
the configured per-project rule in
<project-config>/release-management-config.md
overrides if the project demands stricter conditions.
On fail the planning issue gets the rc-rolled label, the RM
returns to Step 4 with a new RC number. The skill never closes the
planning issue on a failed vote.
Step 10: Promote dist/dev/ to dist/release/
Owner: RM.
Skill: release-promote
(proposed), Drafting.
The skill emits a paste-ready svn mv command set that moves the
voted artefacts from
https://dist.apache.org/repos/dist/dev/<project>/<version>-rcN/
to https://dist.apache.org/repos/dist/release/<project>/<version>/,
together with the commit message template (referencing the
[RESULT] [VOTE] archive URL). The RM executes the svn mv + svn commit under their own ASF credentials.
This is the moment of release. The skill writes nothing and runs nothing; the human commit is the act.
The dist/release/ tree is PMC-write-only by default
(release-policy.html).
If the RM is a committer but not a PMC member, the svn mv will
fail; the skill checks PMC membership against the roster and emits
an "ask a PMC member to publish" hand-off instead of the command
set (see release-promote § hand-off).
Note
Per release-distribution,
mirrors propagate within ~24h. ASF policy also requires waiting
at least one hour after the promote svn commit before updating
the download page or sending the [ANNOUNCE]
(release-policy.html).
The skill writes the expected mirror-availability time and the
earliest-announce time to the planning issue so Step 11 can wait.
Step 11: [ANNOUNCE] + site bump
Owner: RM ([ANNOUNCE]) + PMC committers (site PR merge).
Skill: release-announce-draft
(proposed), Drafting.
Two artefacts:
[ANNOUNCE]email body, addressed toannounce@apache.org(mandatory for ASF TLP releases per release-policy.html § announcements) withdev@<project>andusers@<project>(or equivalent) on Cc. It may go out no sooner than one hour after the Step 10 promote commit, and the RM must send it from an@apache.orgaddress, the announce list rejects other senders. The body links the project's Download Page, not a directdist.apache.orgURL. The RM sends.- Site-bump PR updating the project website's download page,
release notes, current-version banner, and any version-dependent
navigation. Download links on that page resolve through the
closer.luamirror redirector, never a hard-codeddist.apache.orgpath (release-distribution). The PR is opened against the site repo configured in<project-config>/site-repo.md; a committer merges.
The skill never sends the [ANNOUNCE] email and never merges the
site PR.
Step 12: Archive sweep
Owner: RM (or whoever holds release-archive duty per
<project-config>/release-management-config.md).
Skill: release-archive-sweep
(proposed), Triage.
Per release-distribution § archiving,
only the current release line is kept on dist/release/;
non-current releases must be moved to
archive.apache.org. The skill reads the configured retention
rule (per-project, in
<project-config>/release-management-config.md;
the ASF baseline is "only the latest version of each supported
line"), lists releases past retention, and proposes the svn mv
sequence to move them to dist/release/<project>/archive/ or the
equivalent
archive.apache.org location
the project's <project-config> declares.
The skill never runs svn mv itself. The RM executes the sequence
under their own credentials.
Step 13: Audit log
Owner: the framework (per-project audit-log store configured in
<project-config>/release-management-config.md).
Skill: release-audit-report
(proposed), Triage (read-only dashboard).
Read-only. The skill assembles a per-release record from the
planning issue, the [VOTE] and [RESULT] archive URLs, the
voter list with binding flags, the RC artefact list with sigs and
checksums, the promotion svn revision, and the [ANNOUNCE]
archive URL. The output is a structured markdown report appended
to the project's audit log (e.g.
<project-config>/audit/releases/<version>.md in the adopter
repo).
The report is the project's evidence trail for compliance, board reporting, supply-chain queries, and reproducibility. The skill does not modify the artefacts it summarises.
Step 14: Post-release version bump
Owner: RM.
Skill: release-prepare
(proposed), Drafting (same skill as Steps 1-2, third
invocation).
The skill drafts the PR that bumps the development branch to the
next -SNAPSHOT / dev / next version, depending on the
project's manifest format. Runs in parallel with Step 12, the
two steps share no state.
Label lifecycle
State diagram
The planning issue carries a single status label at any point. Skills propose label transitions; the RM applies them.
stateDiagram-v2
[*] --> planning
planning --> prep_pr_open: Step 1-2
prep_pr_open --> rc_staged: Step 4-5
rc_staged --> vote_open: Step 7
vote_open --> vote_passed: Step 9 (pass)
vote_open --> rc_rolled: Step 9 (fail)
rc_rolled --> rc_staged: Step 4 (new RC)
vote_passed --> promoted: Step 10
promoted --> announced: Step 11
announced --> archived: Step 12
announced --> audited: Step 13
announced --> bumped: Step 14
archived --> [*]
audited --> [*]
bumped --> [*]
Label reference
| Label | Applied at | Removed at | Skill that proposes |
|---|---|---|---|
release-planning | Step 1 | Step 2 (prep PR opens) | release-prepare |
prep-pr-open | Step 2 | Step 4 (RC tag exists) | release-prepare |
rc-staged | Step 5 | Step 7 ([VOTE] posted) or Step 9-fail | release-rc-cut |
vote-open | Step 7 | Step 9 | release-vote-draft |
vote-passed | Step 9 (pass) | Step 10 (promote committed) | release-vote-tally |
rc-rolled | Step 9 (fail) | Step 5 (new RC staged) | release-vote-tally |
promoted | Step 10 | Step 11 ([ANNOUNCE] sent) | release-promote |
announced | Step 11 | Step 12 (archive sweep done) | release-announce-draft |
archived | Step 12 | terminal | release-archive-sweep |
The release-audit-report skill (Step 13) reads every label
transition but proposes none of its own; it is a dashboard, not a
state machine participant.
Cross-references
README.md, family overview, skill table.spec.md, per-skill scope, state-change boundary, hand-off protocol, adopter knobs.projects/_template/release-management-config.md, adopter contract scaffold.docs/modes.md§ Drafting,§ Triage, the modes the skills inhabit.MISSION.md§ Initial Goals, theCut a first Apache release through the standard process within 3 monthscommitment this family operationalises.docs/rfcs/RFC-AI-0004.md§ Principle 1, the human-in-the-loop rule every state-change boundary in this lifecycle inherits.- ASF release policy, canonical.
- ASF release distribution,
dist/dev/+dist/release/mechanics, mirror propagation, archive policy. - ASF release signing FAQ,
KEYSfile and signing-key onboarding. - ASF licensing-howto, Category-A/B/X dependency rules referenced by Step 2.
- Apache RAT, license-header verification referenced by Step 6.