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.

DimensionConfig keyASF defaultNon-ASF examples
Distribution backendrelease_dist_backendsvnpubsub (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 mechanismrelease_approval_mechanismdev-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 backendrelease_announce_backendannounce-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-allocate pattern (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:

  1. git tag -s <version>-rcN -m "..." (signed tag, RM's key).
  2. Build invocation, project-specific (<project-config>/release-build.md).
  3. gpg --detach-sign --armor <artefact> for each artefact.
  4. sha512sum <artefact> > <artefact>.sha512 for 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 + .sha512 files into https://dist.apache.org/repos/dist/dev/<project>/<version>-rcN/ (svnpubsub-backed, automatically mirrored to the public dist.apache.org host 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's KEYS file (NOT against the RM's keyring, Step 3's KEYS is the project's source of truth).
  • Checksums. sha512sum -c against the published .sha512 (and .sha256 where configured).
  • License headers on source artefacts, per Apache RAT configuration shipped with the adopter.
  • NOTICE and LICENSE presence at the artefact root, content diff against the previous release.
  • No prohibited binaries in the source artefact (per <project-config>/release-build.md binary-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 to announce@apache.org (mandatory for ASF TLP releases per release-policy.html § announcements) with dev@<project> and users@<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.org address, the announce list rejects other senders. The body links the project's Download Page, not a direct dist.apache.org URL. 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.lua mirror redirector, never a hard-coded dist.apache.org path (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

LabelApplied atRemoved atSkill that proposes
release-planningStep 1Step 2 (prep PR opens)release-prepare
prep-pr-openStep 2Step 4 (RC tag exists)release-prepare
rc-stagedStep 5Step 7 ([VOTE] posted) or Step 9-failrelease-rc-cut
vote-openStep 7Step 9release-vote-draft
vote-passedStep 9 (pass)Step 10 (promote committed)release-vote-tally
rc-rolledStep 9 (fail)Step 5 (new RC staged)release-vote-tally
promotedStep 10Step 11 ([ANNOUNCE] sent)release-promote
announcedStep 11Step 12 (archive sweep done)release-announce-draft
archivedStep 12terminalrelease-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