potiuk commented on code in PR #163: URL: https://github.com/apache/airflow-steward/pull/163#discussion_r3247374597
########## docs/release-management/process.md: ########## @@ -0,0 +1,521 @@ +<!-- START doctoc generated TOC please keep comment here to allow auto update --> +<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Release-management workflow: process and label lifecycle](#release-management-workflow-process-and-label-lifecycle) + - [Adopter backends](#adopter-backends) + - [Process reference: the 14 steps](#process-reference-the-14-steps) + - [Step 1: Release planning + version bump](#step-1-release-planning--version-bump) + - [Step 2: Changelog, NOTICE, LICENSE](#step-2-changelog-notice-license) + - [Step 3: `KEYS` reconciliation](#step-3-keys-reconciliation) + - [Step 4: Cut the release candidate](#step-4-cut-the-release-candidate) + - [Step 5: Stage to `dist/dev/`](#step-5-stage-to-distdev) + - [Step 6: Pre-flight RC verification](#step-6-pre-flight-rc-verification) + - [Step 7: `[VOTE]` thread on `dev@`](#step-7-vote-thread-on-dev) + - [Step 8: Voting window](#step-8-voting-window) + - [Step 9: Tally + `[RESULT] [VOTE]`](#step-9-tally--result-vote) + - [Step 10: Promote `dist/dev/` to `dist/release/`](#step-10-promote-distdev-to-distrelease) + - [Step 11: `[ANNOUNCE]` + site bump](#step-11-announce--site-bump) + - [Step 12: Archive sweep](#step-12-archive-sweep) + - [Step 13: Audit log](#step-13-audit-log) + - [Step 14: Post-release version bump](#step-14-post-release-version-bump) + - [Label lifecycle](#label-lifecycle) + - [State diagram](#state-diagram) + - [Label reference](#label-reference) + - [Cross-references](#cross-references) + +<!-- END doctoc generated TOC please keep comment here to allow auto update --> + +<!-- SPDX-License-Identifier: Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0 --> + +# Release-management workflow: process and label lifecycle + +The authoritative reference for the 14-step release lifecycle and +the label-lifecycle state diagram the [release-management +skills](../../.claude/skills/) execute against. The +[family README](README.md) lists the skills; this document is the +process they share. The [spec](spec.md) 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 `[email protected]`), 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`](../../projects/_template/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](#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 `[email protected]`, 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](spec.md#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`](README.md), the [`spec.md`](spec.md), and +> [`projects/_template/release-management-config.md`](../../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](../mentoring/spec.md). +> See [`docs/modes.md` § Drafting / Triage](../modes.md#drafting) +> 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`](../../.claude/skills/security-cve-allocate/SKILL.md) + pattern (Vulnogram URL + paste-ready JSON, human submits) and + satisfies [RFC-AI-0004 Principle 1](../rfcs/RFC-AI-0004.md#principle-1--human-in-the-loop-on-every-state-change). +- **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. + +```mermaid +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 --> S14 + S12 --> S13 + S14 --> S13 + + 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`](../../projects/_template/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 Review Comment: I would not even mention "non-ASF" - I woudl rather say that we should explicitly mention here that in various projects this step can have differnt shapes. For example some projects (like Airflow) might release from release branches and version might be already set there, or version might be dynamically generated based on tag name etc. .. So even in ASF this step might be different - I think it might be worth mentioning here that it's even likely and that it often needs an override or maybe better - it needs a pointer to existing release documentation that can be used as strong reference. Possibly we should add - in the configuration - a way for the project to tell where their "local" relase documentation is, rather than using the overrride mechanism, because this is something that we anyhow want to make "manually" followable, not only agentically. This should not be really an "override" but more clarification of particular implementation steps, and we could even add a check here to see if such existing release docuementation is complete and has all the boxes checked. I would even go as far as to say that we should "import" all the configuration from that exising release documentation at adoption time - and keep it in sync while doing the release. The release process should also have expectation that agent stores the changes / isues/ new things during the release and proposes to RM to create a PR After release is done that will fix both - release documentation and SKILL overrides / configuration in their repo. ########## docs/release-management/README.md: ########## @@ -0,0 +1,201 @@ +<!-- START doctoc generated TOC please keep comment here to allow auto update --> +<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Release-management skill family](#release-management-skill-family) + - [Status](#status) + - [Skills](#skills) + - [Deep documentation](#deep-documentation) + - [Adopter contract](#adopter-contract) + - [Mode mapping](#mode-mapping) + - [Cross-references](#cross-references) + +<!-- END doctoc generated TOC please keep comment here to allow auto update --> + +<!-- SPDX-License-Identifier: Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0 --> + +# Release-management skill family + +End-to-end automation for an ASF project's release lifecycle, +from the planning issue and version bump through to `[ANNOUNCE]` +on `[email protected]`, archive sweep, and the per-release +audit log. Ten skills that compose into the canonical 14-step +process documented in [`process.md`](process.md). + +Why a framework skill family? Every ASF project runs essentially +the same release process: version bump, `KEYS` reconciliation, RC +signed with the Release Manager's key, staged to +`dist/apache.org/repos/dist/dev/<project>/`, voted on `dev@` per +[`release-policy.html § release approval`](https://www.apache.org/legal/release-policy.html#release-approval), +promoted to `dist/release/<project>/`, announced on +`[email protected]` per +[`release-policy.html § announcements`](https://www.apache.org/legal/release-policy.html#release-announcements), +and archived past retention per +[`release-distribution`](https://infra.apache.org/release-distribution.html). +The procedural shape is foundation-wide; the project-specific +content (release-train identity, build invocation, `KEYS` file +path, vote-window length, retention rule, audit-log location) +plugs in through [`<project-config>/`](../../projects/_template/) +just like the security family. + +Non-ASF adopters are first-class adopters of this family, not a +follow-up case. The 14-step lifecycle is described in ASF +terminology because the framework's first pilot is an ASF PMC, +but every step that touches an ASF-specific surface is implemented +as a backend call the adopter selects in +[`release-management-config.md`](../../projects/_template/release-management-config.md). +Three dimensions parametrise the lifecycle, with no ASF assumption +baked into the install path: + +- **Distribution backend** (`release_dist_backend`): `svnpubsub` + (ASF), `github-releases`, `s3`, `self-hosted`. +- **Approval mechanism** (`release_approval_mechanism`): + `dev-list-vote` (ASF), `github-discussion`, `pr-approval`, + `maintainer-roster`. +- **Announcement backend** (`release_announce_backend`): + `announce-list` (ASF), `github-release-notes`, `site-post`, + `discord-channel`. + +The 14 steps stay identical across backends; only the command set +the agent emits changes. The state-change boundaries (Drafting vs +Triage; agent never holds the signing key; agent never publishes) +stay identical too. See +[`process.md` § Adopter backends](process.md#adopter-backends) +for the full backend table and per-step mapping. + +## Status + +**Proposed.** No `release-*` skill code exists in the framework +today. This family lands as docs first (this README, the 14-step +[`process.md`](process.md), the per-skill [`spec.md`](spec.md), and +the adopter scaffold +[`projects/_template/release-management-config.md`](../../projects/_template/release-management-config.md)) +so the lifecycle, the state-change boundaries, and the adopter +contract are reviewable independently from runtime behaviour. +The skills follow in subsequent PRs, each shipped flagged +`experimental` and tracked in [`docs/modes.md`](../modes.md). This +pattern matches [Mentoring](../mentoring/README.md). + +Promotion of any skill in this family from `experimental` to +default-on, or from Drafting to a state-changing lane, requires +evidence sourced from Release Managers and binding voters that +the project's release process is healthier (fewer stalled +RCs, shorter time-to-`[ANNOUNCE]`, fewer reverted promotions), +not throughput numbers alone. The evidence window is set by +adopter governance, not by this family. + +See [`MISSION.md` § Initial Goals](../../MISSION.md#initial-goals) +for the commitment to *cut a first Apache release through the +standard process within 3 months of resolution adoption*; this +family operationalises it. + +## Skills + +The skill table below names each `release-*` skill, its mode, and +the lifecycle step(s) it owns. Read [`spec.md`](spec.md) for the +per-skill state-change boundary; read [`process.md`](process.md) +for the step it executes against. + +| Skill | Mode | Steps owned | Purpose | +|---|---|---|---| +| `release-prepare` | Drafting | 1, 2, 14 | Open the planning issue, draft the version-bump + changelog + NOTICE/LICENSE PR, then draft the post-release `-SNAPSHOT` bump. | +| `release-keys-sync` | Drafting | 3 | Draft the `KEYS` diff for a Release Manager cutting their first release for the project. Agent never holds the private key. | +| `release-rc-cut` | Drafting | 4, 5 | Emit the paste-ready command sequence, signed tag, build, detached signatures, checksums, `svn` import to `dist/dev/<project>/`. Agent never signs and never imports. | +| `release-verify-rc` | Triage / Pairing | 6 | Read-only pre-flight: signatures against the project's `KEYS`, checksums, license headers (Apache RAT), NOTICE/LICENSE presence, no prohibited binaries, version-string consistency. Voters can run it in their own dev loop before posting `+1`. | +| `release-vote-draft` | Drafting | 7 | Draft the `[VOTE]` email body to `dev@<project>`. Agent never sends. | +| `release-vote-tally` | Triage | 9 | Parse the vote thread, classify each reply (+1 / 0 / -1) binding vs non-binding against the PMC roster, propose `[RESULT] [VOTE]`. Conservative on ambiguous votes, refuses to count, flags `AMBIGUOUS, needs RM call`. | +| `release-promote` | Drafting | 10 | Emit the paste-ready `svn mv dist/dev → dist/release` command set plus commit message. Agent never moves; the human commit is the act of release. | +| `release-announce-draft` | Drafting | 11 | Draft the `[ANNOUNCE]` email body to `[email protected]` and the site-bump PR (download page, release notes, version banner). Agent never sends mail and never merges the site PR. | +| `release-archive-sweep` | Triage | 12 | Scan `dist/release/<project>/`, identify releases past retention, propose the `svn mv` sequence to `archive.apache.org`. Agent never moves. | +| `release-audit-report` | Triage (dashboard) | 13 | Read-only structured report per release, RM, voters with binding flags, artefacts with sigs and checksums, promotion revision, `[ANNOUNCE]` archive URL. Output appended to the project's audit log. | + +Two non-negotiable boundaries cross every Drafting skill above: + +- **The agent never holds, invokes, or proxies the Release Review Comment: One comment here. PRACTICALLY speaking, the "isolation" framework already prevents those credentials to leak. Currently it does "svn commit" -> isolated environment does not have credentials -> it detects that it needs to get out of sandbox, proposes it to the RM -> RM allows to run **this particular command** outside of sandbox. I think we should show it as a viable alternative/ way of achieving it, because I think it maintains all the expectations of "never share your credentials with agent". -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
