From 10a6d4402cc2f5e1303a4521efd9d8888033c158 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 21:23:12 +0800 Subject: [PATCH 01/12] ci: align release preparation with ATR composition --- .agents/skills/release/SKILL.md | 17 +++-- .../skills/release/references/candidate.md | 67 +++++++------------ .../release/references/infrastructure.md | 28 ++++++-- .../skills/release/references/publication.md | 61 ++++++++--------- .../skills/release/references/verification.md | 25 +++++-- .github/workflows/release-compose.yml | 6 +- 6 files changed, 108 insertions(+), 96 deletions(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index 1e6643a3..48f3ee52 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -28,17 +28,18 @@ Help the release manager carry out the requested release work, explain the curre ## Resume the requested work -Establish the requested scope and what has already happened from the conversation, current checkout, and relevant external records. Read the affected parts of `asyncband/Cargo.toml`, `Cargo.lock`, `CHANGELOG.md`, `.github/workflows/release.yml`, `.asf.yaml`, and `xtask/src/main.rs` when needed. Use live GitHub, ASF distribution, mailing-list archives, and registry records to resolve uncertain state. Load only the reference for the current phase; an existing candidate does not require repeating preparation or setup. +Establish the requested scope and what has already happened from the conversation, current checkout, and relevant external records. Read the affected parts of `asyncband/Cargo.toml`, `Cargo.lock`, `CHANGELOG.md`, `.github/workflows/release-compose.yml`, `.github/workflows/release.yml`, `.asf.yaml`, and `xtask/src/main.rs` when needed. Use live GitHub, Apache Trusted Releases (ATR), ASF distribution, mailing-list archives, and registry records to resolve uncertain state. Load only the reference for the current phase; an existing candidate does not require repeating preparation or setup. Carry forward the user's existing authorization. A status check, review, or plan stays read-only. For execution, complete authorized work and prepare any proposed external action before asking about authorization that is actually missing. Sending vote or announcement messages, publishing, merging, or changing tags needs authorization for that action; opening this skill does not provide it. Preserve the user's work when selecting a checkout or creating a release worktree. Keep these values and supporting links in the conversation so work can resume across turns: -- `VERSION`: the final crate version, such as `0.7.2`; RCs do not change the package version. +- `VERSION`: the final crate and ATR version, such as `0.7.3`; RCs do not change the package version. - `RC`: the positive candidate number; `RC_TAG` is `v${VERSION}-rc.${RC}`. - `RELEASE_COMMIT`: the merged release pull request commit bound to the candidate. -- `RELEASE_DIR`: an absolute working directory outside the repository for artifacts, verification, and SVN checkouts; reuse it while continuing the same candidate. -- Candidate tag and artifact location, checksum/signature results, relevant CI runs, PPMC/IPMC vote threads and results, and completed publication steps. +- `RELEASE_DIR`: an absolute working directory outside the repository for downloaded artifacts, verification, and the release checkout; reuse it while continuing the same candidate. +- The ATR candidate URL and revision, RC tag, source checksum, compose run URL and attempt, and separate tag-signer and automated source-signer fingerprints with their provenance. +- Signature, reproducibility, build, and license-review results, both release workflow results, PPMC/IPMC vote threads and results, and completed publication steps. Report completed work with evidence, the next useful step, and any input still needed. Distinguish pending, failed, and unverified steps. Keep handoff notes in the conversation unless the user requests a file. @@ -60,15 +61,17 @@ Read `cargo x --help` and the relevant subcommand help before running repository Use the `release_verifier` Codex agent for a substantial check of an existing candidate when the main agent can continue independent work, such as preparing vote materials. Other coding agents can delegate the same candidate-verification guide to a worker or follow it directly. Keep a small status query in the main conversation. -Give the verifier the repository root, candidate commit and tag, version, absolute artifact paths, expected signing fingerprint and its provenance, requested checks, and a scratch directory outside the checkout. It returns the checked revision and artifacts, observed results, and remaining gaps. Preserve the original artifacts for a separate `license-audit` review; the verifier does not duplicate that audit. Collect the results before staging or publishing the candidate. +Give the verifier the repository root, candidate commit and tag, version, ATR candidate URL and revision, absolute artifact paths, expected tag and source signing fingerprints with their provenance, requested checks, and a scratch directory outside the checkout. It returns the checked revision and artifacts, observed results, and remaining gaps. Preserve the original artifacts for a separate `license-audit` review; the verifier does not duplicate that audit. Collect the results before starting a vote or publishing the candidate. ## Candidate and publication continuity The signed source archive approved by the Apache Incubator PMC and published through ASF distribution is the official Apache release. Its name is `apache-asyncband-${VERSION}-incubating-src.tar.gz`. The crates.io package is a convenience distribution from the same approved commit; keep its Cargo-generated name and layout. -Keep the RC tag, commit, artifacts, and vote tied together. A later `main` commit does not invalidate an existing candidate. Reuse an existing signed tag and staged bytes when retrying a transient failure. If candidate content changes or the community rejects it, agree on the replacement candidate and increment `RC`; preserve existing tags rather than rewriting them. +RC tag pushes run two workflows: `release-compose.yml` builds, signs, and uploads the source candidate to ATR after `release` environment approval; `release.yml` checks the Cargo package and skips publication. PR compose runs only exercise packaging. Git tags use the release manager's key; CI source signatures use the ASF-provisioned automated project key. -After both vote results record approval, promote the exact voted source artifacts. The signed final `v${VERSION}` tag uses the approved RC commit and starts the crates.io publication workflow, subject to the configured `release` environment review. Successful CI alone does not establish vote approval. Confirm each external action's result before reporting completion or retrying it. +Keep the RC tag, commit, ATR revision, artifacts, and vote tied together. A later `main` commit does not invalidate an existing candidate. Reuse an existing signed tag and staged bytes when retrying a transient failure. Re-running signing/upload can create a new signature and ATR revision, so inspect ATR before retrying and never replace the revision under an active vote. If candidate content changes or the community rejects it, agree on the replacement candidate and increment `RC`; preserve existing tags rather than rewriting them. + +After both vote results record approval, publish the exact voted source revision through ATR's finish phase, which writes to ASF distribution. Keep automatic publication disabled during the PPMC vote because IPMC approval is still required. The signed final `v${VERSION}` tag uses the approved RC commit and starts the crates.io publication workflow, subject to a separate `release` environment review. Successful CI or ATR checks alone do not establish vote approval. Confirm each external action's result before reporting completion or retrying it. Use the shared `license-audit` skill to examine the relevant checkout or artifact contents. In Codex, the configured `license_auditor` can perform a delegated review; another agent can follow the same skill directly. Provide the candidate revision and actual artifact paths, then discuss the review's evidence and suggestions with the release manager. diff --git a/.agents/skills/release/references/candidate.md b/.agents/skills/release/references/candidate.md index 7dbd2b7a..55df6bc9 100644 --- a/.agents/skills/release/references/candidate.md +++ b/.agents/skills/release/references/candidate.md @@ -21,12 +21,12 @@ under the License. ## Prepare the release pull request -For a new release, start from current `main` and choose `VERSION` from the changes since the latest crates.io release. If the release pull request or candidate already exists, resume its recorded version and commit. +For a new release, start from current `main` and choose `VERSION` from the changes since the latest crates.io release. For example, preparing `0.7.3` uses package version `0.7.3`, RC tag `v0.7.3-rc.1`, and ATR version `0.7.3`. If the release pull request or candidate already exists, resume its recorded version and commit. 1. Change `version` in `asyncband/Cargo.toml` and refresh `Cargo.lock` with Cargo. 2. Move the entries under `Unreleased` in `CHANGELOG.md` into an undated `v${VERSION}` section immediately below it, then restore an empty `Unreleased` section. Keep user-impacting sections ordered as breaking changes, new features, bug fixes, and improvements; add the actual release date only after publication. 3. Review `LICENSE`, `NOTICE`, `DISCLAIMER`, source headers, and bundled dependencies using the `license-audit` skill. Codex can delegate that review to `license_auditor`; provide the repository root and requested revision. Use its evidence and suggestions to decide what follow-up is needed during release preparation. -4. Run the release checks: +4. Read `cargo x --help` and the relevant subcommand help, then run the release checks: ```shell cargo x lint @@ -34,20 +34,24 @@ cargo x check cargo x test --no-capture RUSTUP_TOOLCHAIN=1.86.0 cargo x test --no-capture cargo x semver --release-version "${VERSION}" -cargo publish --package asyncband --locked --dry-run +cargo publish --package asyncband --locked --dry-run --allow-dirty ``` +The preparation dry run allows the edited version files; the RC workflow and downloaded candidate checks package committed or extracted sources without `--allow-dirty`. + For a semver-major release, including a pre-1.0 minor release such as `0.7.0`, the semver command uses minor compatibility rules to report breaking API changes. When it reports expected changes, record and review them in `CHANGELOG.md`, then rerun: ```shell cargo x semver --release-version "${VERSION}" --acknowledge-breaking-changes ``` -Merge the release pull request and record its merge commit as `RELEASE_COMMIT`. Every candidate artifact, the final tag, and the crates.io package use this exact commit. +Before the first automated candidate, confirm the signing secrets, project public key, and ATR policy described in [Infrastructure](infrastructure.md). A successful PR compose check does not exercise signing or ATR authentication. + +Merge the release pull request when authorized and record its merge commit as `RELEASE_COMMIT`. Every candidate artifact, the final tag, and the crates.io package use this exact commit. -## Create and validate a release candidate +## Create the RC tag -For a new candidate, create a release directory outside the repository and a detached worktree at `RELEASE_COMMIT`. When resuming, reuse the recorded `RELEASE_DIR`, worktree, and RC tag. Run later Git and Cargo commands from that worktree root. +For a new candidate, create a release directory outside the repository and a detached worktree at `RELEASE_COMMIT`. When resuming, reuse the recorded `RELEASE_DIR`, worktree, and RC tag. Run later Git and Cargo commands from that worktree root. Set `TAG_SIGNING_FINGERPRINT` to the release manager's independently verified signing key; this is separate from the automated project key used by CI. ```shell RELEASE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/asyncband-release.XXXXXX")" @@ -58,55 +62,30 @@ cd "${RELEASE_DIR}/checkout" git grep -F "version = \"${VERSION}\"" -- asyncband/Cargo.toml Cargo.lock git grep -Fx "## v${VERSION}" -- CHANGELOG.md test -z "$(git status --porcelain)" -git tag --sign "${RC_TAG}" \ +git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "${RC_TAG}" \ --message "Apache Asyncband ${VERSION} release candidate ${RC}" \ "${RELEASE_COMMIT}" +git verify-tag "${RC_TAG}" git push https://github.com/apache/asyncband.git "${RC_TAG}" ``` -Wait for the `Release` GitHub Actions workflow to pass. The workflow validates the RC tag and runs `cargo publish --dry-run` against the unchanged `${VERSION}` package; it skips the crates.io publish job for RC tags. A candidate that needs a code change gets a new release pull request, merge commit, RC number, and signed tag. +## Follow both release workflows -## Build and verify the source archive +The RC tag starts two independent workflows: -For a new candidate, build the source archive from the verified RC tag. Reuse existing signed artifacts for a retry of the same candidate. The `incubating` marker is required in the filename, and `gzip -n` keeps the gzip header independent of the local build time. +- `Release` (`release.yml`) validates the tag and runs `cargo publish --dry-run` against the unchanged `${VERSION}` package. Its crates.io publish job is skipped for RC tags. +- `Compose source release` (`release-compose.yml`) validates the RC version and ancestry on `main`, creates `apache-asyncband-${VERSION}-incubating-src.tar.gz` and its SHA-512 checksum, then waits for `release` environment approval. After review of the tag, commit, and checksum, `sign-and-upload` signs with the automated project key and uploads the three files to ATR project `asyncband`, version `${VERSION}`. -```shell -RC_TAG="v${VERSION}-rc.${RC}" -SOURCE_DIR="apache-asyncband-${VERSION}-incubating-src" -ARTIFACT_DIR="${RELEASE_DIR}/dist" -mkdir -p "${ARTIFACT_DIR}" -git verify-tag "${RC_TAG}" -git archive --format=tar --prefix="${SOURCE_DIR}/" "${RC_TAG}" \ - | gzip -n -9 > "${ARTIFACT_DIR}/${SOURCE_DIR}.tar.gz" -( - cd "${ARTIFACT_DIR}" - shasum -a 512 "${SOURCE_DIR}.tar.gz" > "${SOURCE_DIR}.tar.gz.sha512" - gpg --armor --detach-sign --local-user "${ASF_GPG_FINGERPRINT}" \ - "${SOURCE_DIR}.tar.gz" -) -``` +Record both run URLs and the compose run attempt. Require the package check to pass and confirm upload completion in the [Asyncband ATR project](https://releases.apache.org/projects/asyncband). Normally the compose run succeeds; if it failed after sending files, use the [recovery procedure](publication.md#recover-from-failures) to establish whether the complete revision is already present. Record the actual candidate URL, ATR revision, source checksum, and commit together. The pinned upload action creates revisions but does not return a candidate URL or revision as a workflow output; obtain those from ATR. The RC number and ATR revision number are independent. -Verify the existing artifacts with the [candidate-verification guide](verification.md), directly or through `release_verifier`. Supply the candidate identity, signing-key fingerprint, repository root, and absolute artifact paths. Keep the signed archive unchanged throughout verification. +A code change requires a new release pull request, merge commit, RC number, and signed tag. For an interrupted upload, follow [recovery](publication.md#recover-from-failures) before rerunning a job. -For the separate `license-audit` review, provide the original source archive, the extracted source, and the Cargo package produced by verification, together with `RELEASE_COMMIT`. Discuss its evidence and suggestions with the release manager. Keep the verification directory available until both reviews finish; then remove that disposable directory. +## Verify the ATR candidate before voting -## Stage the candidate on ASF infrastructure +ATR is the staging location. Download the archive, `.asc`, and `.sha512` from the recorded revision into `${RELEASE_DIR}/dist`, using the candidate page's download links. Confirm the archive checksum matches the compose summary and that all three files belong to that revision. Do not substitute a locally generated signature or the unsigned GitHub Actions bundle for the files voters will download. -Check whether this candidate is already staged. For a new staging operation, check out a working copy under `RELEASE_DIR`, add the three candidate files, and commit them: +Review ATR's checks, then follow the [candidate-verification guide](verification.md), directly or through `release_verifier`. Supply the tag and source signing identities separately. Verification includes independently reproducing the compressed source archive, as well as signatures, source contents, builds, and Cargo packaging. -```shell -svn checkout --depth=empty \ - https://dist.apache.org/repos/dist/dev/incubator/asyncband "${RELEASE_DIR}/svn-dev" -mkdir "${RELEASE_DIR}/svn-dev/${VERSION}-rc.${RC}" -cp \ - "${ARTIFACT_DIR}/${SOURCE_DIR}.tar.gz" \ - "${ARTIFACT_DIR}/${SOURCE_DIR}.tar.gz.asc" \ - "${ARTIFACT_DIR}/${SOURCE_DIR}.tar.gz.sha512" \ - "${RELEASE_DIR}/svn-dev/${VERSION}-rc.${RC}/" -svn add "${RELEASE_DIR}/svn-dev/${VERSION}-rc.${RC}" -svn status "${RELEASE_DIR}/svn-dev" -svn commit "${RELEASE_DIR}/svn-dev" \ - -m "Stage Apache Asyncband ${VERSION} release candidate ${RC}" -``` +For the separate `license-audit` review, provide the original source archive, the extracted source, and the Cargo package produced by verification, together with `RELEASE_COMMIT`. Discuss its evidence and suggestions with the release manager. Retain the verification directory until both reviews finish. -Confirm the candidate at `https://dist.apache.org/repos/dist/dev/incubator/asyncband/${VERSION}-rc.${RC}/` and verify every link prepared for the vote email. +Once verification is complete, use the recorded ATR revision for [voting](publication.md). Link the ATR candidate as the artifact source in the vote; a second SVN staging copy is unnecessary. See ATR's [staging and voting guide](https://releases.apache.org/docs/staging-and-voting). diff --git a/.agents/skills/release/references/infrastructure.md b/.agents/skills/release/references/infrastructure.md index 69a078a0..80a7e4db 100644 --- a/.agents/skills/release/references/infrastructure.md +++ b/.agents/skills/release/references/infrastructure.md @@ -19,16 +19,34 @@ under the License. # Release infrastructure -This is a reference for the existing design, not a recurring release checklist. Consult it when changing configuration, troubleshooting publication, or arranging a new release manager's signing key. +Consult this reference when configuring or troubleshooting automated source composition, arranging a new signing key, or diagnosing publication. Routine releases reuse the established settings. + +## ATR source composition + +`.github/workflows/release-compose.yml` handles upstream `vX.Y.Z-rc.N` pushes. `.asf.yaml` enables `atr_sync` and registers repository `asyncband` and compose workflow `.github/workflows/release-compose.yml`. It sets email voting to `dev@asyncband.apache.org`, a 72-hour minimum, and download path suffix `{{VERSION}}`. Confirm the live ATR project has imported those settings; repository configuration alone does not establish successful synchronization. + +The `release` environment reviews the signing/upload job. ASF-provisioned secrets may be repository secrets; the workflow reads all signing settings through `secrets`, including the fingerprint: + +| Secret | Value | +| ---------------------------- | -------------------------------------------------------------------- | +| `GPG_SECRET_KEY` | ASCII-armored automated project private key provisioned by ASF Infra | +| `SOURCE_SIGNING_FINGERPRINT` | Full uppercase primary-key fingerprint (40 or 64 hexadecimal digits) | +| `GPG_PASSPHRASE` | Passphrase, only when the supplied key is protected | + +Inspect secret names with `gh secret list --repo apache/asyncband` and `gh secret list --repo apache/asyncband --env release`; these commands do not reveal values. `SOURCE_SIGNING_FINGERPRINT` is a secret, not an Actions variable. Never print or export the private key while diagnosing a failure. A missing setting or incorrect fingerprint prevents signing before any ATR upload. + +The automated key setup is tracked in [INFRA-28407](https://issues.apache.org/jira/browse/INFRA-28407). Follow the [ATR Trusted Publishing setup](https://releases.apache.org/docs/trusted-publishing) for reproducibility approval, key provisioning, and recognition of the automated project identity. Confirm the public key is present in the project's published `KEYS` file and imported into ATR through the committee's configured KEYS management. The upload job uses GitHub OIDC; it does not require a personal ATR token. A successful upload still needs ATR artifact checks and candidate verification before voting. + +The release manager signs Git tags with an individual key. The automated project key signs source archives. Record and verify the two fingerprints independently; neither is inferred from the other. ## crates.io Trusted Publishing Trusted Publishing is already configured for `asyncband`: repository `apache/asyncband`, workflow `release.yml`, and environment `release`. Routine releases reuse this configuration. -`.github/workflows/release.yml` obtains a short-lived crates.io token through GitHub OIDC. Only a final `v${VERSION}` tag can enter the publish job; RC tags run package checks. `.asf.yaml` configures version-tag deployments and required reviewers for the `release` environment. Consult those repository files and the live crate settings when diagnosing a mismatch. See the [crates.io Trusted Publishing documentation](https://crates.io/docs/trusted-publishing) for changes to this setup. +`.github/workflows/release.yml` obtains a short-lived crates.io token through GitHub OIDC. Only a final `v${VERSION}` tag can enter the publish job; RC tags run package checks. `.asf.yaml` configures version-tag deployments and required reviewers for the `release` environment. Source composition and crates.io publication are separate environment approvals. Consult those repository files and the live crate settings when diagnosing a mismatch. See the [crates.io Trusted Publishing documentation](https://crates.io/docs/trusted-publishing) for changes to this setup. -## Signing and ASF distribution +## ASF distribution and public keys -Candidates are staged under `https://dist.apache.org/repos/dist/dev/incubator/asyncband/`; approved releases are promoted to `https://dist.apache.org/repos/dist/release/incubator/asyncband/`. The public verification key list is `https://downloads.apache.org/incubator/asyncband/KEYS`. +Candidates are staged in [ATR](https://releases.apache.org/projects/asyncband). After PPMC and IPMC approval, ATR's finish phase publishes the voted revision to `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`, using the configured download suffix. Inspect the destination before publication and record the resulting SVN revision. The public download location is `https://downloads.apache.org/incubator/asyncband/${VERSION}/`; the public verification key list is `https://downloads.apache.org/incubator/asyncband/KEYS`. -The release manager uses an ASF-associated signing key published in the existing project `KEYS` file. For a new signing key, follow the [ASF release signing guide](https://infra.apache.org/release-signing.html), verify the fingerprint through an independent channel, and add the public key while preserving existing keys. Reuse established distribution areas and signing configuration; investigate a reported access or verification failure before proposing infrastructure changes. +Follow the committee's existing [KEYS management mode](https://releases.apache.org/docs/promoting-to-release#the-keys-file) rather than introducing a second source of truth. Preserve existing keys when adding one, and independently verify its fingerprint. Legacy candidates already staged under `dist/dev` retain their recorded artifacts and vote links; an infrastructure migration is not a reason to rebuild an existing candidate. diff --git a/.agents/skills/release/references/publication.md b/.agents/skills/release/references/publication.md index d850c6bb..802e3698 100644 --- a/.agents/skills/release/references/publication.md +++ b/.agents/skills/release/references/publication.md @@ -19,70 +19,67 @@ under the License. # Vote, publish, and follow up -Resume from the recorded candidate and vote results. Check which publication steps already succeeded before running commands again. +Resume from the recorded RC commit, ATR candidate revision, and vote results. Check which publication steps already succeeded before running commands again. ## Hold the two-phase vote -Incubating releases use the [Incubator two-phase vote](https://incubator.apache.org/cookbook/#two-phase-vote-on-podling-releases). Each vote remains open for at least 72 hours. +Incubating releases use the [Incubator two-phase vote](https://incubator.apache.org/cookbook/#two-phase-vote-on-podling-releases). Each vote remains open for at least 72 hours, so allow at least six days for the two sequential votes, plus preparation and publication time. -When the staged candidate and supporting links have been verified, send `[VOTE] Release Apache Asyncband (Incubating) ${VERSION} RC${RC}` to `dev@asyncband.apache.org`. Include: +Use the verified ATR revision for both votes. The project's email vote policy targets `dev@asyncband.apache.org`; it does not replace the subsequent vote on `general@incubator.apache.org`. Leave ATR's automatic SVN publication option disabled when starting the PPMC vote, and do not publish from the finish page merely because that first vote has passed. -- the staged source URL; -- the `KEYS` URL and signing-key fingerprint; -- the signed RC tag and commit hash; +When the candidate and supporting links have been verified and sending is authorized, start `[VOTE] Release Apache Asyncband (Incubating) ${VERSION} RC${RC}` on `dev@asyncband.apache.org`, using ATR's email vote flow. Review the generated message and include: + +- the ATR candidate URL and revision as the source of the voted files; +- the `KEYS` URL and automated source-signing fingerprint; +- the signed RC tag, release manager's tag-signing fingerprint, and commit hash; - the changelog or comparison with the previous release; -- verification commands or a checklist for signatures, checksums, licensing, unexpected binaries, and the build; +- the compose workflow run, archive checksum, and verification instructions for signatures, reproducibility, licensing, unexpected binaries, and the build; - a closing time at least 72 hours after the vote starts. -The PPMC vote passes with at least three PPMC `+1` votes and more PPMC `+1` votes than `-1` votes. Publish a result email that identifies the voters and links the archived vote thread. +The PPMC vote passes with at least three PPMC `+1` votes and more PPMC `+1` votes than `-1` votes. Publish a result email identifying the voters and linking the archived vote thread, and record the result with the candidate. -Then send the proposal to `general@incubator.apache.org` with the PPMC result and archive link. The IPMC vote passes with at least three binding IPMC `+1` votes and more binding `+1` votes than `-1` votes. Publish its result email and record the archive link. +Then send the same candidate proposal to `general@incubator.apache.org`, including the PPMC result and archive link. Identify any PPMC voters who are also IPMC members so their binding votes can be carried forward. The IPMC vote passes with at least three binding IPMC `+1` votes and more binding `+1` votes than `-1` votes. Publish its result email and record the archive link alongside the PPMC result and ATR revision. -Begin publication after the IPMC result records a passing vote. +## Publish the approved source revision -## Promote and publish the approved release +After both vote results record approval and publication is authorized, open the candidate's ATR finish page. Confirm the revision and source checksum match the vote, then publish it to ASF distribution. With the repository's `download_path_suffix: "{{VERSION}}"`, the destination is `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`. -Promote the exact voted artifacts from the development distribution area: +ATR commits the approved artifacts to SVN. Record the resulting SVN revision and URL, and check the archive, signature, and checksum against the voted files. Do not rebuild or re-sign the release, and do not perform a second manual `svn move`. See [ATR promotion](https://releases.apache.org/docs/promoting-to-release). -```shell -svn move \ - "https://dist.apache.org/repos/dist/dev/incubator/asyncband/${VERSION}-rc.${RC}" \ - "https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}" \ - -m "Release Apache Asyncband ${VERSION}" -``` +## Publish the crates.io convenience package -If the final tag already exists, verify that it points to the approved RC commit and continue with its workflow state. Otherwise, create the signed final tag from the verified RC tag and push it: +If the final tag already exists, verify its signature and that it points to the approved RC commit, then continue with its workflow state. Otherwise, create the signed final tag from the verified RC tag and push it: ```shell RC_TAG="v${VERSION}-rc.${RC}" git verify-tag "${RC_TAG}" -git tag --sign "v${VERSION}" \ +test "$(git rev-parse "${RC_TAG}^{commit}")" = "${RELEASE_COMMIT}" +git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "v${VERSION}" \ --message "Apache Asyncband ${VERSION}" \ - "${RC_TAG}^{commit}" + "${RELEASE_COMMIT}" git push https://github.com/apache/asyncband.git "v${VERSION}" ``` -The final tag starts the crates.io publishing job. A configured reviewer compares the final tag with the approved RC, confirms the IPMC vote result, and approves the `release` environment deployment. The workflow verifies the package version and publishes with a short-lived crates.io token. +The final tag starts `release.yml`; it does not run source composition again. A configured reviewer compares the final tag with the approved RC, confirms both vote results and source publication, and approves the `release` environment deployment. The workflow verifies the package version and publishes with a short-lived crates.io token. This approval is separate from the approval to sign and upload the RC. After publication: 1. Verify the version and metadata on crates.io and docs.rs. 2. After ASF distribution syncs, verify the source archive, checksum, and signature under `https://downloads.apache.org/incubator/asyncband/${VERSION}/` and the project `KEYS` file at `https://downloads.apache.org/incubator/asyncband/KEYS`. 3. Submit a post-release pull request that adds the actual publication date to the `v${VERSION}` changelog heading. -4. Announce the release on `dev@asyncband.apache.org` and other appropriate channels as Apache Asyncband (Incubating). -5. Remove superseded releases from `dist/release`; ASF retains them in the archive. +4. Announce the release through ATR after the source downloads and crates.io package are available. Review recipients and text before sending, use Apache Asyncband (Incubating), and avoid a duplicate manual announcement to the same list. +5. Remove superseded releases from `dist/release` after confirming the replacement is available and the old files are archived. Check the actual distribution contents; an ATR catalog archive entry alone does not establish that distribution cleanup succeeded. ## Recover from failures -A transient CI, staging, or registry error can be retried against the same candidate after checking what already succeeded. +Inspect the recorded GitHub run, ATR revision and phase, vote threads, ASF distribution, and crates.io as relevant before retrying a failed operation. -If the community rejects a candidate or its content changes, coordinate a new candidate with an incremented `RC`. Remove the rejected candidate from the development distribution area: - -```shell -svn delete \ - "https://dist.apache.org/repos/dist/dev/incubator/asyncband/${VERSION}-rc.${RC}" \ - -m "Remove rejected Apache Asyncband ${VERSION} release candidate ${RC}" -``` +- For a package-check failure, diagnose the check without changing the candidate. A source fix requires a new candidate. +- If signing failed before upload, repair the signing configuration and rerun the failed job against the same RC and stored source bundle. A workflow-code fix must be present in the tagged commit to take effect, so it requires a new merged commit and RC tag. +- If upload failed or its outcome is uncertain, first inspect ATR for the three expected files and their checksum/signature. An upload retry can create a new ATR revision and re-sign the archive; resume an existing complete revision when possible. Before voting, record and verify whichever revision will actually be voted on. Do not rerun signing/upload against an active or approved vote. +- If the source bundle has expired, do not assume rerunning only the failed signing job can recover it. Before a vote, rerun composition from the unchanged RC tag, compare the new archive with the recorded checksum, and verify the resulting ATR revision. During or after voting, use the voted files retained in ATR. +- If the community rejects a candidate or its content changes, cancel the vote or return the release to compose in ATR as appropriate, increment `RC`, and preserve the previous signed tags and vote history. ATR revisions and Git RC numbers need not match; record the replacement mapping explicitly. +- For an interrupted ATR publication, check the finish page's publication result and destination SVN files before retrying. Continue from a matching completed publication without recomposing or uploading the candidate. For a failed final crates.io job, first check whether the version exists on crates.io. If it exists and its contents and metadata match the approved release, continue post-publication verification and follow-up; the upload may have succeeded before the job lost its response. If the version is absent, rerun the same final-tag workflow for a transient or publishing-infrastructure failure. A source or package change uses a new version and the full ASF vote process. A published version is immutable; if it has a confirmed problem, discuss any yank and follow-up release on the development list. diff --git a/.agents/skills/release/references/verification.md b/.agents/skills/release/references/verification.md index e915013d..df413919 100644 --- a/.agents/skills/release/references/verification.md +++ b/.agents/skills/release/references/verification.md @@ -23,19 +23,34 @@ Perform the requested checks against the supplied candidate and return evidence ## Inputs and scope -Use the caller's repository root, `VERSION`, `RC_TAG`, `RELEASE_COMMIT`, absolute archive/signature/checksum paths, expected signing fingerprint and its provenance, and requested verification scope. The caller may supply an existing Cargo package as well. Resolve repository files from that explicit root; this guide's location does not identify the audited checkout. +Use the caller's repository root, `VERSION`, `RC_TAG`, `RELEASE_COMMIT`, ATR candidate URL and revision, compose run and attempt, absolute archive/signature/checksum paths, expected tag and source signing fingerprints with their provenance, and requested verification scope. The caller may supply an existing Cargo package as well. Resolve repository files from that explicit root; this guide's location does not identify the audited checkout. Establish which checks are requested and which inputs are available. Continue independent checks when an input is missing and report the resulting gap. A key bundled with an archive is not independent evidence of signer identity. Use a temporary GPG home when importing supplied verification keys so the user's keyring stays unchanged. ## Verify identity and source contents -1. Record the resolved commit and artifact paths. Check the supplied RC tag's commit and signature against `RELEASE_COMMIT` and the expected signing fingerprint. Keep an existing candidate tied to that commit even if `main` has advanced. -2. Verify the SHA-512 checksum and detached archive signature on the original bytes. Record signature validity separately from whether the signer matches the expected identity; a checksum or signature alone does not establish agreement with the candidate commit. +1. Record the resolved commit, ATR revision, and artifact paths. Check the supplied RC tag's commit and signature against `RELEASE_COMMIT` and the release manager's expected tag-signing fingerprint. Keep an existing candidate tied to that commit even if `main` has advanced. +2. Verify the SHA-512 checksum and detached archive signature on the original downloaded bytes against the expected source-signing fingerprint: the automated project key for CI candidates, or the recorded release manager's key for legacy candidates. For CI candidates, check the archive checksum against the compose summary as well. Record signature validity separately from signer identity, including the primary fingerprint when a signing subkey is used. The archive signer can differ from the Git tag signer; neither signature alone establishes agreement with the candidate commit. 3. Inspect the archive member list before extracting. Check the expected `apache-asyncband-${VERSION}-incubating-src/` root, reject paths that escape the extraction directory, and inspect symlinks without following them outside the extracted tree. -4. Compare the archived source inventory, file contents, executable bits, and symlink targets with `git archive` of the resolved candidate commit, using a separate temporary extraction. Compare logical entries rather than compressed bytes or timestamps. Report missing, added, or changed entries with concrete paths. Check the package version in the extracted manifest against `VERSION`. +4. Compare the archived source inventory, file contents, executable bits, and symlink targets with `git archive` of the resolved candidate commit, using a separate temporary extraction. Report missing, added, or changed entries with concrete paths. Check the package version in the extracted manifest against `VERSION`. For example, use `git -C "${REPO_ROOT}" rev-parse "${RC_TAG}^{commit}"` to resolve a candidate and `git -C "${REPO_ROOT}" verify-tag "${RC_TAG}"` to inspect its signature. Run `shasum -a 512 --check` from the artifact directory and `gpg --verify` with the explicitly supplied signature and archive. Inspect checksum filenames before using the checksum file so it checks the intended artifact. +## Independently reproduce the automated archive + +For an automated source candidate, reproduce the archive using the recipe in its tagged `.github/workflows/release-compose.yml`, writing the result separately from the downloaded archive. The current recipe runs on Ubuntu 24.04 and archives the commit, not the annotated tag object: + +```shell +set -euo pipefail +SOURCE_DIR="apache-asyncband-${VERSION}-incubating-src" +git -C "${REPO_ROOT}" -c core.attributesFile=/dev/null -c tar.umask=0022 archive \ + --format=tar --prefix="${SOURCE_DIR}/" "${RELEASE_COMMIT}" \ + | gzip -n -9 > "${VERIFY_DIR}/${SOURCE_DIR}.reproduced.tar.gz" +cmp "${ARCHIVE_PATH}" "${VERIFY_DIR}/${SOURCE_DIR}.reproduced.tar.gz" +``` + +Use a clean verification checkout and a scratch `VERIFY_DIR` outside it. Record the Git and gzip versions. If compressed bytes differ, compare logical archive entries to diagnose the difference and repeat with the workflow's Linux toolchain; logical equality alone does not establish reproducibility. Do not compare detached signature bytes from independently signed archives, since signature creation times can differ. Preserve and verify the original ATR signature. Record the independent reproduction result for the vote, following [ATR Trusted Publishing](https://releases.apache.org/docs/trusted-publishing#step-6-confirm-reproducibility-during-the-vote). + ## Verify the build and Cargo package Run these checks when the caller requests build and packaging verification. Read `cargo x --help` and the relevant subcommand help in the extracted source first. The archive test uses Cargo's `--locked` mode to check the shipped lockfile; `cargo x test` does not expose that option. @@ -52,4 +67,4 @@ Preserve the original archive inventory when builds add files to the extracted d ## Return the result -Return a concise account of the checked candidate, signature/checksum and source-comparison results, requested build/package results, concrete discrepancies, and checks not completed. Include commands and exit results when they matter. Give the caller the extracted source and package paths for `license-audit`; retain these scratch outputs until the caller has finished with them. Do not create a report file unless requested. +Return a concise account of the checked candidate and ATR revision, the two signing identities, signature/checksum, source-comparison and byte-reproduction results, requested build/package results, concrete discrepancies, and checks not completed. Include commands and exit results when they matter. Give the caller the extracted source and package paths for `license-audit`; retain these scratch outputs until the caller has finished with them. Do not create a report file unless requested. diff --git a/.github/workflows/release-compose.yml b/.github/workflows/release-compose.yml index 9c047663..63df3436 100644 --- a/.github/workflows/release-compose.yml +++ b/.github/workflows/release-compose.yml @@ -113,7 +113,7 @@ jobs: needs: compose runs-on: ubuntu-24.04 timeout-minutes: 10 - # Keep signing secrets in this environment so access requires release approval. + # Release approval gates signing with the ASF-provisioned secrets and ATR upload. environment: name: release url: https://releases.apache.org/projects/asyncband @@ -136,11 +136,11 @@ jobs: env: ARCHIVE: ${{ needs.compose.outputs.archive }} IMPORTED_FINGERPRINT: ${{ steps.gpg.outputs.fingerprint }} - SIGNING_FINGERPRINT: ${{ vars.SOURCE_SIGNING_FINGERPRINT }} + SIGNING_FINGERPRINT: ${{ secrets.SOURCE_SIGNING_FINGERPRINT }} run: | set -euo pipefail if [[ ! "${SIGNING_FINGERPRINT}" =~ ^([0-9A-F]{40}|[0-9A-F]{64})$ ]]; then - echo "::error::SOURCE_SIGNING_FINGERPRINT must be the full uppercase primary fingerprint." + echo "::error::The SOURCE_SIGNING_FINGERPRINT secret must be the full uppercase primary fingerprint." exit 1 fi if [[ "${IMPORTED_FINGERPRINT}" != "${SIGNING_FINGERPRINT}" ]]; then From 66f0bbc3b32c6614226a9c20212aaffe9f85b7f1 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 21:30:18 +0800 Subject: [PATCH 02/12] docs: verify release packages from a clean checkout --- .agents/skills/release/references/candidate.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.agents/skills/release/references/candidate.md b/.agents/skills/release/references/candidate.md index 55df6bc9..20388c58 100644 --- a/.agents/skills/release/references/candidate.md +++ b/.agents/skills/release/references/candidate.md @@ -34,17 +34,21 @@ cargo x check cargo x test --no-capture RUSTUP_TOOLCHAIN=1.86.0 cargo x test --no-capture cargo x semver --release-version "${VERSION}" -cargo publish --package asyncband --locked --dry-run --allow-dirty ``` -The preparation dry run allows the edited version files; the RC workflow and downloaded candidate checks package committed or extracted sources without `--allow-dirty`. - For a semver-major release, including a pre-1.0 minor release such as `0.7.0`, the semver command uses minor compatibility rules to report breaking API changes. When it reports expected changes, record and review them in `CHANGELOG.md`, then rerun: ```shell cargo x semver --release-version "${VERSION}" --acknowledge-breaking-changes ``` +Commit the reviewed release changes, then verify the Cargo package from a clean checkout: + +```shell +test -z "$(git status --porcelain)" +cargo publish --package asyncband --locked --dry-run +``` + Before the first automated candidate, confirm the signing secrets, project public key, and ATR policy described in [Infrastructure](infrastructure.md). A successful PR compose check does not exercise signing or ATR authentication. Merge the release pull request when authorized and record its merge commit as `RELEASE_COMMIT`. Every candidate artifact, the final tag, and the crates.io package use this exact commit. From 7eef5f6d79bd978c9e080a944fd22664b04a87df Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 22:22:17 +0800 Subject: [PATCH 03/12] docs: rebuild the release runbook around tracking issues and ATR --- .agents/skills/release/SKILL.md | 108 ++++++++++++------ .agents/skills/release/references/atr.md | 61 ++++++++++ .../skills/release/references/candidate.md | 95 --------------- .../release/references/infrastructure.md | 34 ++---- .../skills/release/references/publication.md | 86 -------------- .../release/references/tracking-issue.md | 77 +++++++++++++ 6 files changed, 224 insertions(+), 237 deletions(-) create mode 100644 .agents/skills/release/references/atr.md delete mode 100644 .agents/skills/release/references/candidate.md delete mode 100644 .agents/skills/release/references/publication.md create mode 100644 .agents/skills/release/references/tracking-issue.md diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index 48f3ee52..cb94e111 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -1,6 +1,6 @@ --- name: release -description: Prepare, resume, or verify Apache Asyncband releases when release-manager work is requested, including candidate artifacts, votes, publication, and recovery. +description: Run or resume an Apache Asyncband release, from its tracking issue and frozen source through RC composition, ATR voting, publication, and follow-up; also verify an existing candidate. --- + +# Operate the release in ATR + +Use the [Asyncband project](https://releases.apache.org/projects/asyncband) with the release manager's ASF login. The normal interface is the ATR website. The repository configures email voting; voters reply on the mailing lists and the release manager reviews the tally in ATR. Do not switch to Trusted Vote mode as an incidental release step. + +## Start the vote + +1. Open the uploaded `${VERSION}` draft in Compose. Confirm the revision and checksum recorded in the tracking issue, inspect ATR's checks, and complete the candidate verification and artifact license review. Resolve blockers and review any concerns before acknowledging them. If ATR's commit field is empty, enter the frozen `RELEASE_COMMIT` using its commit-hash form. +2. Open the voting form. Set the first-round recipient to `dev@asyncband.apache.org`, the second-round recipient to `general@incubator.apache.org`, and the minimum duration to at least 72 hours. The second round uses that duration too. +3. Review the generated subject and body. Identify Apache Asyncband (Incubating), `${VERSION}`, and the RC; include the ATR candidate/revision, RC tag and commit, source checksum, KEYS and signer information, changelog, and verification evidence. Link ATR as the location of the voted files. Submit **Send vote email** when sending the vote is authorized, then record its archive link and closing time. + +The automatic publication option is optional. Enable it only when publication after successful completion of both rounds is within the authorized scope, and confirm the download suffix is `${VERSION}`. For podlings, ATR carries this setting into round two and publishes only after that round passes; it does not publish on PPMC approval alone. Otherwise publish manually in Finish. + +## Resolve both rounds + +Each round needs at least 72 hours, at least three eligible `+1` votes, and more eligible `+1` than `-1` votes. Eligibility is PPMC membership for round one and IPMC membership for round two. Allow at least six days for the two sequential votes. See the [Incubator vote rules](https://incubator.apache.org/cookbook/#two-phase-vote-on-podling-releases). + +1. After the PPMC period, open the vote resolution page. Compare ATR's email tally with the thread, including voters' roles and any carried IPMC votes, and review the result body. Select `Passed` only if the requirements are met, then resolve the vote. +2. ATR sends the PPMC result and automatically starts the IPMC vote on the selected second-round list. Confirm delivery and record both links. Check the actual IPMC email for the PPMC result, its `lists.apache.org` tally link, and any IPMC votes carried from round one. ATR currently regenerates this email from the project template without adding that evidence; if missing, have the release manager supplement the existing IPMC thread. Do not start another vote. The files stay in the same candidate revision. +3. After the IPMC period, review its binding tally, including eligible votes carried from round one and counting only each voter's latest vote, and review the result body before resolving it as `Passed`. ATR sends the result, also reports the passing result to the first-round thread, and moves the release to Finish. Record both vote results before final publication. + +These transitions are implemented for email votes in ATR's [vote resolution](https://github.com/apache/tooling-trusted-releases/blob/0d156e9a/atr/storage/writers/vote.py#L676). A recorded state change and an email delivery can succeed or fail separately; check both before reporting completion. + +## Publish and announce + +In Finish, inspect **Publish to ASF Distribution Area**. If automatic publication already completed, record its result. Otherwise confirm the approved revision and destination `dist/release/incubator/asyncband/${VERSION}/`, then use the publish action. ATR commits the voted files to SVN; record the SVN revision and compare the published archive, signature, and checksum with the candidate. No local rebuild, re-signing, or `svn move` is needed. + +Return to the main runbook to push the final tag and verify crates.io publication. Once both the ASF downloads and the crate are available, use **Announce** in ATR, review the recipients and message, and submit it. ATR sends the announcement and updates its release catalog. Record the announcement link in the tracking issue instead of sending the same email manually. See [ATR publication](https://releases.apache.org/docs/promoting-to-release). + +Use ATR's archive action or the configured auto-archive option for superseded releases. Confirm the archive and distribution results; follow up on any cleanup warning rather than assuming a catalog entry proves completion. + +## API and CLI alternative + +ATR has a [CLI](https://github.com/apache/tooling-releases-client) and authenticated API. The CLI exposes `atr vote start`, `atr vote tabulate`, `atr vote resolve`, and `atr announce`; the server exposes `/api/vote/start`, `/api/vote/tabulate`, `/api/vote/resolve`, and `/api/release/announce`. See the [CLI command reference](https://github.com/apache/tooling-releases-client/blob/main/COMMANDS.md) and [server API](https://github.com/apache/tooling-trusted-releases/blob/0d156e9a/atr/api/__init__.py). + +Use the website for the ordinary handoff: it exposes the current tally, editable result email, and publication state together. The CLI/API are evolving, and the current API's vote resolution sends only a short generic result body. If automation is explicitly requested, check the installed client's help and current API schema and use existing authorized credentials; do not invent endpoints or introduce vote/finish workflows as part of a routine release. Our registered GitHub workflow handles composition only. + +## Recover without replacing voted files + +- Failed or uncertain upload: inspect ATR before retrying. If all three files arrived and verification succeeds, record that revision even if the GitHub run reported a late failure. Otherwise retry before voting and verify the resulting revision; signing/upload can produce a new signature and revision. If the GitHub source bundle expired, rerun composition from the same RC and compare the recorded checksum. +- Source or workflow correction: use a new reviewed commit and refresh affected checks. If an RC already exists, use a new RC number. A workflow rerun uses the old tagged workflow, so changing `main` cannot repair it. +- Rejected or cancelled vote: resolve that outcome in ATR, which returns the release to Compose. Preserve the previous tag and vote history in the issue, then prepare and verify the replacement candidate. Do not modify an active vote's files. +- Vote or publication error: inspect the current round, mail-delivery status, Finish state, and destination files before retrying. Resume a completed transition; do not resend an IPMC vote or republish matching files merely to obtain a green status. diff --git a/.agents/skills/release/references/candidate.md b/.agents/skills/release/references/candidate.md deleted file mode 100644 index 20388c58..00000000 --- a/.agents/skills/release/references/candidate.md +++ /dev/null @@ -1,95 +0,0 @@ - - -# Prepare and stage a release candidate - -## Prepare the release pull request - -For a new release, start from current `main` and choose `VERSION` from the changes since the latest crates.io release. For example, preparing `0.7.3` uses package version `0.7.3`, RC tag `v0.7.3-rc.1`, and ATR version `0.7.3`. If the release pull request or candidate already exists, resume its recorded version and commit. - -1. Change `version` in `asyncband/Cargo.toml` and refresh `Cargo.lock` with Cargo. -2. Move the entries under `Unreleased` in `CHANGELOG.md` into an undated `v${VERSION}` section immediately below it, then restore an empty `Unreleased` section. Keep user-impacting sections ordered as breaking changes, new features, bug fixes, and improvements; add the actual release date only after publication. -3. Review `LICENSE`, `NOTICE`, `DISCLAIMER`, source headers, and bundled dependencies using the `license-audit` skill. Codex can delegate that review to `license_auditor`; provide the repository root and requested revision. Use its evidence and suggestions to decide what follow-up is needed during release preparation. -4. Read `cargo x --help` and the relevant subcommand help, then run the release checks: - -```shell -cargo x lint -cargo x check -cargo x test --no-capture -RUSTUP_TOOLCHAIN=1.86.0 cargo x test --no-capture -cargo x semver --release-version "${VERSION}" -``` - -For a semver-major release, including a pre-1.0 minor release such as `0.7.0`, the semver command uses minor compatibility rules to report breaking API changes. When it reports expected changes, record and review them in `CHANGELOG.md`, then rerun: - -```shell -cargo x semver --release-version "${VERSION}" --acknowledge-breaking-changes -``` - -Commit the reviewed release changes, then verify the Cargo package from a clean checkout: - -```shell -test -z "$(git status --porcelain)" -cargo publish --package asyncband --locked --dry-run -``` - -Before the first automated candidate, confirm the signing secrets, project public key, and ATR policy described in [Infrastructure](infrastructure.md). A successful PR compose check does not exercise signing or ATR authentication. - -Merge the release pull request when authorized and record its merge commit as `RELEASE_COMMIT`. Every candidate artifact, the final tag, and the crates.io package use this exact commit. - -## Create the RC tag - -For a new candidate, create a release directory outside the repository and a detached worktree at `RELEASE_COMMIT`. When resuming, reuse the recorded `RELEASE_DIR`, worktree, and RC tag. Run later Git and Cargo commands from that worktree root. Set `TAG_SIGNING_FINGERPRINT` to the release manager's independently verified signing key; this is separate from the automated project key used by CI. - -```shell -RELEASE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/asyncband-release.XXXXXX")" -RC_TAG="v${VERSION}-rc.${RC}" -git fetch https://github.com/apache/asyncband.git main -git worktree add --detach "${RELEASE_DIR}/checkout" "${RELEASE_COMMIT}" -cd "${RELEASE_DIR}/checkout" -git grep -F "version = \"${VERSION}\"" -- asyncband/Cargo.toml Cargo.lock -git grep -Fx "## v${VERSION}" -- CHANGELOG.md -test -z "$(git status --porcelain)" -git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "${RC_TAG}" \ - --message "Apache Asyncband ${VERSION} release candidate ${RC}" \ - "${RELEASE_COMMIT}" -git verify-tag "${RC_TAG}" -git push https://github.com/apache/asyncband.git "${RC_TAG}" -``` - -## Follow both release workflows - -The RC tag starts two independent workflows: - -- `Release` (`release.yml`) validates the tag and runs `cargo publish --dry-run` against the unchanged `${VERSION}` package. Its crates.io publish job is skipped for RC tags. -- `Compose source release` (`release-compose.yml`) validates the RC version and ancestry on `main`, creates `apache-asyncband-${VERSION}-incubating-src.tar.gz` and its SHA-512 checksum, then waits for `release` environment approval. After review of the tag, commit, and checksum, `sign-and-upload` signs with the automated project key and uploads the three files to ATR project `asyncband`, version `${VERSION}`. - -Record both run URLs and the compose run attempt. Require the package check to pass and confirm upload completion in the [Asyncband ATR project](https://releases.apache.org/projects/asyncband). Normally the compose run succeeds; if it failed after sending files, use the [recovery procedure](publication.md#recover-from-failures) to establish whether the complete revision is already present. Record the actual candidate URL, ATR revision, source checksum, and commit together. The pinned upload action creates revisions but does not return a candidate URL or revision as a workflow output; obtain those from ATR. The RC number and ATR revision number are independent. - -A code change requires a new release pull request, merge commit, RC number, and signed tag. For an interrupted upload, follow [recovery](publication.md#recover-from-failures) before rerunning a job. - -## Verify the ATR candidate before voting - -ATR is the staging location. Download the archive, `.asc`, and `.sha512` from the recorded revision into `${RELEASE_DIR}/dist`, using the candidate page's download links. Confirm the archive checksum matches the compose summary and that all three files belong to that revision. Do not substitute a locally generated signature or the unsigned GitHub Actions bundle for the files voters will download. - -Review ATR's checks, then follow the [candidate-verification guide](verification.md), directly or through `release_verifier`. Supply the tag and source signing identities separately. Verification includes independently reproducing the compressed source archive, as well as signatures, source contents, builds, and Cargo packaging. - -For the separate `license-audit` review, provide the original source archive, the extracted source, and the Cargo package produced by verification, together with `RELEASE_COMMIT`. Discuss its evidence and suggestions with the release manager. Retain the verification directory until both reviews finish. - -Once verification is complete, use the recorded ATR revision for [voting](publication.md). Link the ATR candidate as the artifact source in the vote; a second SVN staging copy is unnecessary. See ATR's [staging and voting guide](https://releases.apache.org/docs/staging-and-voting). diff --git a/.agents/skills/release/references/infrastructure.md b/.agents/skills/release/references/infrastructure.md index 80a7e4db..9827fbe8 100644 --- a/.agents/skills/release/references/infrastructure.md +++ b/.agents/skills/release/references/infrastructure.md @@ -17,36 +17,22 @@ specific language governing permissions and limitations under the License. --> -# Release infrastructure +# Infrastructure reference -Consult this reference when configuring or troubleshooting automated source composition, arranging a new signing key, or diagnosing publication. Routine releases reuse the established settings. +Routine releases assume this setup is complete. Read this reference only for an observed signing, authorization, synchronization, or publication failure. -## ATR source composition +## Source composition -`.github/workflows/release-compose.yml` handles upstream `vX.Y.Z-rc.N` pushes. `.asf.yaml` enables `atr_sync` and registers repository `asyncband` and compose workflow `.github/workflows/release-compose.yml`. It sets email voting to `dev@asyncband.apache.org`, a 72-hour minimum, and download path suffix `{{VERSION}}`. Confirm the live ATR project has imported those settings; repository configuration alone does not establish successful synchronization. +`.asf.yaml` registers repository `asyncband` and `.github/workflows/release-compose.yml` with ATR through `atr_sync`. It selects email voting on `dev@asyncband.apache.org`, a 72-hour minimum, and download suffix `{{VERSION}}`. ATR must recognize Asyncband as a podling for the two-round vote. Inspect the live project policy when behavior differs from the repository settings. -The `release` environment reviews the signing/upload job. ASF-provisioned secrets may be repository secrets; the workflow reads all signing settings through `secrets`, including the fingerprint: +The `release` environment gates signing/upload. The workflow reads `GPG_SECRET_KEY`, `SOURCE_SIGNING_FINGERPRINT`, and optional `GPG_PASSPHRASE` through GitHub `secrets`; ASF-provisioned values can be repository secrets. The fingerprint is the full uppercase primary fingerprint, not an Actions variable. Inspect names with `gh secret list --repo apache/asyncband` and `gh secret list --repo apache/asyncband --env release`; do not export private-key material for diagnosis. -| Secret | Value | -| ---------------------------- | -------------------------------------------------------------------- | -| `GPG_SECRET_KEY` | ASCII-armored automated project private key provisioned by ASF Infra | -| `SOURCE_SIGNING_FINGERPRINT` | Full uppercase primary-key fingerprint (40 or 64 hexadecimal digits) | -| `GPG_PASSPHRASE` | Passphrase, only when the supplied key is protected | +The automated project key must be present in [KEYS](https://downloads.apache.org/incubator/asyncband/KEYS) and recognized by ATR under the committee's existing key-management mode. Consult [Trusted Publishing setup](https://releases.apache.org/docs/trusted-publishing) and [INFRA-28407](https://issues.apache.org/jira/browse/INFRA-28407) for provisioning issues. Check the actual primary UID and deployed ATR recognition rules if it is not identified as an automated key. Preserve old keys when adding a public key. -Inspect secret names with `gh secret list --repo apache/asyncband` and `gh secret list --repo apache/asyncband --env release`; these commands do not reveal values. `SOURCE_SIGNING_FINGERPRINT` is a secret, not an Actions variable. Never print or export the private key while diagnosing a failure. A missing setting or incorrect fingerprint prevents signing before any ATR upload. +Git tags are signed with the release manager's individual key. Source archives are signed with the automated project key. Verify each against its own recorded fingerprint. The upload action authenticates through GitHub OIDC; a personal ATR token is not required for composition. -The automated key setup is tracked in [INFRA-28407](https://issues.apache.org/jira/browse/INFRA-28407). Follow the [ATR Trusted Publishing setup](https://releases.apache.org/docs/trusted-publishing) for reproducibility approval, key provisioning, and recognition of the automated project identity. Confirm the public key is present in the project's published `KEYS` file and imported into ATR through the committee's configured KEYS management. The upload job uses GitHub OIDC; it does not require a personal ATR token. A successful upload still needs ATR artifact checks and candidate verification before voting. +## Final publication -The release manager signs Git tags with an individual key. The automated project key signs source archives. Record and verify the two fingerprints independently; neither is inferred from the other. +ATR publishes approved files to `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`; they propagate to `https://downloads.apache.org/incubator/asyncband/${VERSION}/`. Inspect Finish's actual destination and result when diagnosing publication. Legacy releases retain their recorded vote artifacts and provenance. -## crates.io Trusted Publishing - -Trusted Publishing is already configured for `asyncband`: repository `apache/asyncband`, workflow `release.yml`, and environment `release`. Routine releases reuse this configuration. - -`.github/workflows/release.yml` obtains a short-lived crates.io token through GitHub OIDC. Only a final `v${VERSION}` tag can enter the publish job; RC tags run package checks. `.asf.yaml` configures version-tag deployments and required reviewers for the `release` environment. Source composition and crates.io publication are separate environment approvals. Consult those repository files and the live crate settings when diagnosing a mismatch. See the [crates.io Trusted Publishing documentation](https://crates.io/docs/trusted-publishing) for changes to this setup. - -## ASF distribution and public keys - -Candidates are staged in [ATR](https://releases.apache.org/projects/asyncband). After PPMC and IPMC approval, ATR's finish phase publishes the voted revision to `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`, using the configured download suffix. Inspect the destination before publication and record the resulting SVN revision. The public download location is `https://downloads.apache.org/incubator/asyncband/${VERSION}/`; the public verification key list is `https://downloads.apache.org/incubator/asyncband/KEYS`. - -Follow the committee's existing [KEYS management mode](https://releases.apache.org/docs/promoting-to-release#the-keys-file) rather than introducing a second source of truth. Preserve existing keys when adding one, and independently verify its fingerprint. Legacy candidates already staged under `dist/dev` retain their recorded artifacts and vote links; an infrastructure migration is not a reason to rebuild an existing candidate. +crates.io Trusted Publishing is configured for repository `apache/asyncband`, workflow `release.yml`, and environment `release`. Only the final `v${VERSION}` tag enters the publication job, with a separate environment approval and short-lived OIDC token. Consult the workflow and [crates.io documentation](https://crates.io/docs/trusted-publishing) for an authentication failure; do not repeat initial setup for each release. diff --git a/.agents/skills/release/references/publication.md b/.agents/skills/release/references/publication.md deleted file mode 100644 index 802e3698..00000000 --- a/.agents/skills/release/references/publication.md +++ /dev/null @@ -1,86 +0,0 @@ - - -# Vote, publish, and follow up - -Resume from the recorded RC commit, ATR candidate revision, and vote results. Check which publication steps already succeeded before running commands again. - -## Hold the two-phase vote - -Incubating releases use the [Incubator two-phase vote](https://incubator.apache.org/cookbook/#two-phase-vote-on-podling-releases). Each vote remains open for at least 72 hours, so allow at least six days for the two sequential votes, plus preparation and publication time. - -Use the verified ATR revision for both votes. The project's email vote policy targets `dev@asyncband.apache.org`; it does not replace the subsequent vote on `general@incubator.apache.org`. Leave ATR's automatic SVN publication option disabled when starting the PPMC vote, and do not publish from the finish page merely because that first vote has passed. - -When the candidate and supporting links have been verified and sending is authorized, start `[VOTE] Release Apache Asyncband (Incubating) ${VERSION} RC${RC}` on `dev@asyncband.apache.org`, using ATR's email vote flow. Review the generated message and include: - -- the ATR candidate URL and revision as the source of the voted files; -- the `KEYS` URL and automated source-signing fingerprint; -- the signed RC tag, release manager's tag-signing fingerprint, and commit hash; -- the changelog or comparison with the previous release; -- the compose workflow run, archive checksum, and verification instructions for signatures, reproducibility, licensing, unexpected binaries, and the build; -- a closing time at least 72 hours after the vote starts. - -The PPMC vote passes with at least three PPMC `+1` votes and more PPMC `+1` votes than `-1` votes. Publish a result email identifying the voters and linking the archived vote thread, and record the result with the candidate. - -Then send the same candidate proposal to `general@incubator.apache.org`, including the PPMC result and archive link. Identify any PPMC voters who are also IPMC members so their binding votes can be carried forward. The IPMC vote passes with at least three binding IPMC `+1` votes and more binding `+1` votes than `-1` votes. Publish its result email and record the archive link alongside the PPMC result and ATR revision. - -## Publish the approved source revision - -After both vote results record approval and publication is authorized, open the candidate's ATR finish page. Confirm the revision and source checksum match the vote, then publish it to ASF distribution. With the repository's `download_path_suffix: "{{VERSION}}"`, the destination is `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`. - -ATR commits the approved artifacts to SVN. Record the resulting SVN revision and URL, and check the archive, signature, and checksum against the voted files. Do not rebuild or re-sign the release, and do not perform a second manual `svn move`. See [ATR promotion](https://releases.apache.org/docs/promoting-to-release). - -## Publish the crates.io convenience package - -If the final tag already exists, verify its signature and that it points to the approved RC commit, then continue with its workflow state. Otherwise, create the signed final tag from the verified RC tag and push it: - -```shell -RC_TAG="v${VERSION}-rc.${RC}" -git verify-tag "${RC_TAG}" -test "$(git rev-parse "${RC_TAG}^{commit}")" = "${RELEASE_COMMIT}" -git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "v${VERSION}" \ - --message "Apache Asyncband ${VERSION}" \ - "${RELEASE_COMMIT}" -git push https://github.com/apache/asyncband.git "v${VERSION}" -``` - -The final tag starts `release.yml`; it does not run source composition again. A configured reviewer compares the final tag with the approved RC, confirms both vote results and source publication, and approves the `release` environment deployment. The workflow verifies the package version and publishes with a short-lived crates.io token. This approval is separate from the approval to sign and upload the RC. - -After publication: - -1. Verify the version and metadata on crates.io and docs.rs. -2. After ASF distribution syncs, verify the source archive, checksum, and signature under `https://downloads.apache.org/incubator/asyncband/${VERSION}/` and the project `KEYS` file at `https://downloads.apache.org/incubator/asyncband/KEYS`. -3. Submit a post-release pull request that adds the actual publication date to the `v${VERSION}` changelog heading. -4. Announce the release through ATR after the source downloads and crates.io package are available. Review recipients and text before sending, use Apache Asyncband (Incubating), and avoid a duplicate manual announcement to the same list. -5. Remove superseded releases from `dist/release` after confirming the replacement is available and the old files are archived. Check the actual distribution contents; an ATR catalog archive entry alone does not establish that distribution cleanup succeeded. - -## Recover from failures - -Inspect the recorded GitHub run, ATR revision and phase, vote threads, ASF distribution, and crates.io as relevant before retrying a failed operation. - -- For a package-check failure, diagnose the check without changing the candidate. A source fix requires a new candidate. -- If signing failed before upload, repair the signing configuration and rerun the failed job against the same RC and stored source bundle. A workflow-code fix must be present in the tagged commit to take effect, so it requires a new merged commit and RC tag. -- If upload failed or its outcome is uncertain, first inspect ATR for the three expected files and their checksum/signature. An upload retry can create a new ATR revision and re-sign the archive; resume an existing complete revision when possible. Before voting, record and verify whichever revision will actually be voted on. Do not rerun signing/upload against an active or approved vote. -- If the source bundle has expired, do not assume rerunning only the failed signing job can recover it. Before a vote, rerun composition from the unchanged RC tag, compare the new archive with the recorded checksum, and verify the resulting ATR revision. During or after voting, use the voted files retained in ATR. -- If the community rejects a candidate or its content changes, cancel the vote or return the release to compose in ATR as appropriate, increment `RC`, and preserve the previous signed tags and vote history. ATR revisions and Git RC numbers need not match; record the replacement mapping explicitly. -- For an interrupted ATR publication, check the finish page's publication result and destination SVN files before retrying. Continue from a matching completed publication without recomposing or uploading the candidate. - -For a failed final crates.io job, first check whether the version exists on crates.io. If it exists and its contents and metadata match the approved release, continue post-publication verification and follow-up; the upload may have succeeded before the job lost its response. If the version is absent, rerun the same final-tag workflow for a transient or publishing-infrastructure failure. A source or package change uses a new version and the full ASF vote process. A published version is immutable; if it has a confirmed problem, discuss any yank and follow-up release on the development list. - -Once release follow-up is complete and the release manager no longer needs the local artifacts, remove the detached worktree with `git worktree remove "${RELEASE_DIR}/checkout"` and clean up the recorded release directory. Retain it while there are unresolved verification or recovery questions. diff --git a/.agents/skills/release/references/tracking-issue.md b/.agents/skills/release/references/tracking-issue.md new file mode 100644 index 00000000..483a5c36 --- /dev/null +++ b/.agents/skills/release/references/tracking-issue.md @@ -0,0 +1,77 @@ + + +# Release tracking issue + +Use title `Tracking Issue to Release ${VERSION}` in `apache/asyncband`. The [0.7.2 issue](https://github.com/apache/asyncband/issues/285) is historical context; its manual packaging, SVN staging, and initial setup tasks are superseded. The issue below is the handoff record, not a request to perform every external action regardless of the user's scope. + +Fill in known values and leave future evidence pending. With `gh`, send the prepared body through standard input using `--body-file -` for creation and updates. Preserve other participants' edits. Do not check an item merely because a command was suggested, a job started, or an earlier candidate passed; attach the checked revision and outcome. + +```markdown +Release manager: @ +Target version: +Previous release: +Source cutoff: +Release PR: pending +Frozen release commit: pending +Current phase / next action: initial license audit +Runbook: https://github.com/apache/asyncband/blob/main/.agents/skills/release/SKILL.md + +## Prepare and freeze + +- [ ] Audit the selected source with `license-audit`; resolve release-blocking findings. +- [ ] Merge the version, lockfile, and undated changelog PR; record the frozen release commit. +- [ ] Complete the final license review, including the actual Cargo package and any audit corrections. + +## Check the frozen release commit + +- [ ] `cargo x lint` +- [ ] `cargo x check` +- [ ] `cargo x test --no-capture` +- [ ] `RUSTUP_TOOLCHAIN=1.86.0 cargo x test --no-capture` +- [ ] `cargo x semver --release-version `; document any allowed major-release API breaks. +- [ ] `cargo publish --package asyncband --locked --dry-run` from the clean checkout. +- [ ] Required GitHub CI passes for the release commit. + +## Candidate + +RC / signed tag: pending +Compose run and attempt / package-check run: pending +ATR candidate URL / revision: pending +Source SHA-512: pending +Tag signer / source signer fingerprints and provenance: pending + +- [ ] Push the signed RC tag at the frozen commit; confirm both release workflows and ATR upload. +- [ ] Download and verify the ATR revision: signatures, checksum, source identity, reproducibility, build, and packaging. +- [ ] Complete the license review of the actual source archive and Cargo distribution; address ATR findings. + +## Vote and publish + +- [ ] Start the PPMC vote in ATR; record the vote link and closing time. +- [ ] After the required duration and votes, resolve PPMC as Passed in ATR; record its result and the automatically started IPMC vote, and ensure that thread includes the PPMC tally link and any carried IPMC votes. +- [ ] After the required duration and binding votes, resolve IPMC as Passed in ATR; record its result. +- [ ] Confirm ATR publishes the voted revision to ASF distribution; record the SVN revision and download URL. +- [ ] Push the signed final tag at the approved commit and approve/verify crates.io publication. +- [ ] Verify ASF downloads and signatures, crates.io, and docs.rs. +- [ ] Send the announcement through ATR and record its archive link. +- [ ] Merge the publication-date changelog PR and confirm superseded-release archival as applicable. +- [ ] Close this issue after the preceding required items are complete. +``` + +For a replacement candidate, retain the previous tag, commit, ATR revision, and vote outcome in the issue history. Update the active candidate fields, invalidate checks affected by changed contents, and make the next action explicit. Keep local scratch paths in the conversation; another release manager should be able to resume from the public issue and artifact links. From c1052077b7ccd2e3e754c7293546717456a2033a Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 22:29:02 +0800 Subject: [PATCH 04/12] docs: simplify release guidance and archive verification --- .agents/skills/release/SKILL.md | 6 +++--- .../release/references/infrastructure.md | 2 +- .../release/references/tracking-issue.md | 4 ++-- .../skills/release/references/verification.md | 19 ++++--------------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index cb94e111..8e6f6fef 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -32,7 +32,7 @@ For an actual release, follow the steps below. For a status check, resume from t Set `VERSION` to the target stable crate version, such as `0.7.3`, after comparing the previous published crate and changes since its release tag. Use the user's proposed version when compatible; `cargo x semver` below verifies the decision. Record a source cutoff commit and defer unrelated pending work so the release does not keep following `main`. -Find an existing `Tracking Issue to Release ${VERSION}` before creating one. Otherwise create it immediately from the [tracking issue template](references/tracking-issue.md). Use it as the release record: link the release PR, checked revisions, workflow runs, candidate, votes, and publication results; update completed items with evidence and keep the next action current. Do not copy an old release's checked boxes or one-time setup tasks. +Find an existing `Tracking Issue to Release ${VERSION}` before creating one. Otherwise create it immediately from the [tracking issue template](references/tracking-issue.md). Use it as the release record: link the release PR, checked revisions, workflow runs, candidate, votes, and publication results; update completed items with evidence and keep the next action current. ## 2. Audit first, prepare the version, and freeze the source @@ -86,9 +86,9 @@ git push https://github.com/apache/asyncband.git "${RC_TAG}" Follow both workflows for this tag: - `Release` checks the unchanged `${VERSION}` Cargo package and skips crates.io publication. -- `Compose source release` builds `apache-asyncband-${VERSION}-incubating-src.tar.gz` and its checksum. Approve its `release` environment job to sign with the automated project key and upload the archive, `.asc`, and `.sha512` to ATR project `asyncband`, version `${VERSION}`. There is no manual packaging or SVN staging step. +- `Compose source release` builds `apache-asyncband-${VERSION}-incubating-src.tar.gz` and its checksum. Approve its `release` environment job to sign with the automated project key and upload the archive, `.asc`, and `.sha512` to ATR project `asyncband`, version `${VERSION}`. -Open the uploaded candidate in [ATR](https://releases.apache.org/projects/asyncband), inspect its checks, and record its actual URL and revision with the tag, commit, workflow run, and SHA-512. The ATR revision is not the Git RC number. Download that revision and follow [verification](references/verification.md): verify the tag and archive against their separate signing identities, independently reproduce the source archive, and check its build and Cargo package. Use `release_verifier` for substantial independent verification and the `license-audit` skill (or `license_auditor` agent) for the actual distributions; collect both results before voting. +Open the uploaded candidate in [ATR](https://releases.apache.org/projects/asyncband), inspect its checks, and record its actual URL and revision with the tag, commit, workflow run, and SHA-512. The ATR revision is not the Git RC number. Download that revision and follow [verification](references/verification.md): check signatures and checksum, compare the source contents with the RC commit, and test the build and Cargo package. Use `release_verifier` for substantial independent verification, including the archive rebuild required for automated signing, and the `license-audit` skill (or `license_auditor` agent) for the actual distributions. Collect both results before voting; reuse completed checks for the same candidate. ## 5. Vote and publish through ATR diff --git a/.agents/skills/release/references/infrastructure.md b/.agents/skills/release/references/infrastructure.md index 9827fbe8..25b7ad1f 100644 --- a/.agents/skills/release/references/infrastructure.md +++ b/.agents/skills/release/references/infrastructure.md @@ -33,6 +33,6 @@ Git tags are signed with the release manager's individual key. Source archives a ## Final publication -ATR publishes approved files to `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`; they propagate to `https://downloads.apache.org/incubator/asyncband/${VERSION}/`. Inspect Finish's actual destination and result when diagnosing publication. Legacy releases retain their recorded vote artifacts and provenance. +ATR publishes approved files to `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`; they propagate to `https://downloads.apache.org/incubator/asyncband/${VERSION}/`. Inspect Finish's actual destination and result when diagnosing publication. crates.io Trusted Publishing is configured for repository `apache/asyncband`, workflow `release.yml`, and environment `release`. Only the final `v${VERSION}` tag enters the publication job, with a separate environment approval and short-lived OIDC token. Consult the workflow and [crates.io documentation](https://crates.io/docs/trusted-publishing) for an authentication failure; do not repeat initial setup for each release. diff --git a/.agents/skills/release/references/tracking-issue.md b/.agents/skills/release/references/tracking-issue.md index 483a5c36..d28fb1d5 100644 --- a/.agents/skills/release/references/tracking-issue.md +++ b/.agents/skills/release/references/tracking-issue.md @@ -19,7 +19,7 @@ under the License. # Release tracking issue -Use title `Tracking Issue to Release ${VERSION}` in `apache/asyncband`. The [0.7.2 issue](https://github.com/apache/asyncband/issues/285) is historical context; its manual packaging, SVN staging, and initial setup tasks are superseded. The issue below is the handoff record, not a request to perform every external action regardless of the user's scope. +Use title `Tracking Issue to Release ${VERSION}` in `apache/asyncband`. Keep the release's current state, check results, and next action in this issue so another release manager can take over. Fill in known values and leave future evidence pending. With `gh`, send the prepared body through standard input using `--body-file -` for creation and updates. Preserve other participants' edits. Do not check an item merely because a command was suggested, a job started, or an earlier candidate passed; attach the checked revision and outcome. @@ -58,7 +58,7 @@ Source SHA-512: pending Tag signer / source signer fingerprints and provenance: pending - [ ] Push the signed RC tag at the frozen commit; confirm both release workflows and ATR upload. -- [ ] Download and verify the ATR revision: signatures, checksum, source identity, reproducibility, build, and packaging. +- [ ] Download and verify the ATR revision: signatures, checksum, source contents against the RC commit, independent archive rebuild for automated signing, build, and packaging. - [ ] Complete the license review of the actual source archive and Cargo distribution; address ATR findings. ## Vote and publish diff --git a/.agents/skills/release/references/verification.md b/.agents/skills/release/references/verification.md index df413919..f9897b65 100644 --- a/.agents/skills/release/references/verification.md +++ b/.agents/skills/release/references/verification.md @@ -30,26 +30,15 @@ Establish which checks are requested and which inputs are available. Continue in ## Verify identity and source contents 1. Record the resolved commit, ATR revision, and artifact paths. Check the supplied RC tag's commit and signature against `RELEASE_COMMIT` and the release manager's expected tag-signing fingerprint. Keep an existing candidate tied to that commit even if `main` has advanced. -2. Verify the SHA-512 checksum and detached archive signature on the original downloaded bytes against the expected source-signing fingerprint: the automated project key for CI candidates, or the recorded release manager's key for legacy candidates. For CI candidates, check the archive checksum against the compose summary as well. Record signature validity separately from signer identity, including the primary fingerprint when a signing subkey is used. The archive signer can differ from the Git tag signer; neither signature alone establishes agreement with the candidate commit. +2. Verify the downloaded archive's SHA-512 against its checksum file and the compose summary. Verify its detached signature against the expected source-signing fingerprint, recording the primary fingerprint when a signing subkey is used. The archive signer can differ from the Git tag signer; check both identities. 3. Inspect the archive member list before extracting. Check the expected `apache-asyncband-${VERSION}-incubating-src/` root, reject paths that escape the extraction directory, and inspect symlinks without following them outside the extracted tree. 4. Compare the archived source inventory, file contents, executable bits, and symlink targets with `git archive` of the resolved candidate commit, using a separate temporary extraction. Report missing, added, or changed entries with concrete paths. Check the package version in the extracted manifest against `VERSION`. For example, use `git -C "${REPO_ROOT}" rev-parse "${RC_TAG}^{commit}"` to resolve a candidate and `git -C "${REPO_ROOT}" verify-tag "${RC_TAG}"` to inspect its signature. Run `shasum -a 512 --check` from the artifact directory and `gpg --verify` with the explicitly supplied signature and archive. Inspect checksum filenames before using the checksum file so it checks the intended artifact. -## Independently reproduce the automated archive +Compare source contents independently of archive headers and compression: different macOS and Linux packaging tools can produce different `.tar.gz` bytes for the same files. A compression difference alone is not a source mismatch. -For an automated source candidate, reproduce the archive using the recipe in its tagged `.github/workflows/release-compose.yml`, writing the result separately from the downloaded archive. The current recipe runs on Ubuntu 24.04 and archives the commit, not the annotated tag object: - -```shell -set -euo pipefail -SOURCE_DIR="apache-asyncband-${VERSION}-incubating-src" -git -C "${REPO_ROOT}" -c core.attributesFile=/dev/null -c tar.umask=0022 archive \ - --format=tar --prefix="${SOURCE_DIR}/" "${RELEASE_COMMIT}" \ - | gzip -n -9 > "${VERIFY_DIR}/${SOURCE_DIR}.reproduced.tar.gz" -cmp "${ARCHIVE_PATH}" "${VERIFY_DIR}/${SOURCE_DIR}.reproduced.tar.gz" -``` - -Use a clean verification checkout and a scratch `VERIFY_DIR` outside it. Record the Git and gzip versions. If compressed bytes differ, compare logical archive entries to diagnose the difference and repeat with the workflow's Linux toolchain; logical equality alone does not establish reproducibility. Do not compare detached signature bytes from independently signed archives, since signature creation times can differ. Preserve and verify the original ATR signature. Record the independent reproduction result for the vote, following [ATR Trusted Publishing](https://releases.apache.org/docs/trusted-publishing#step-6-confirm-reproducibility-during-the-vote). +[ASF automated signing](https://infra.apache.org/release-signing.html#automated-release-signing) additionally requires an independent rebuild on trusted hardware outside GitHub Actions. Have the verifier run the tagged compose recipe in a Linux environment on that hardware and record the matching archive SHA-512 once per candidate. Reuse that evidence; the release manager does not need to repeat it. Source comparison alone does not establish this separate result, and the downloaded archive and signature remain the release artifacts. ## Verify the build and Cargo package @@ -67,4 +56,4 @@ Preserve the original archive inventory when builds add files to the extracted d ## Return the result -Return a concise account of the checked candidate and ATR revision, the two signing identities, signature/checksum, source-comparison and byte-reproduction results, requested build/package results, concrete discrepancies, and checks not completed. Include commands and exit results when they matter. Give the caller the extracted source and package paths for `license-audit`; retain these scratch outputs until the caller has finished with them. Do not create a report file unless requested. +Return the checked candidate and ATR revision, signer fingerprints, signature/checksum results, source differences, independent rebuild checksum, requested build/package results, and any checks not completed. Give the caller the extracted source and package paths for `license-audit`; retain these scratch outputs until the caller has finished with them. Do not create a report file unless requested. From bb7929fbdfbfb343aa03055ae2a441d3647dfc10 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 22:30:19 +0800 Subject: [PATCH 05/12] docs: pin release issue runbooks to their commit --- .agents/skills/release/references/tracking-issue.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.agents/skills/release/references/tracking-issue.md b/.agents/skills/release/references/tracking-issue.md index d28fb1d5..32939e1e 100644 --- a/.agents/skills/release/references/tracking-issue.md +++ b/.agents/skills/release/references/tracking-issue.md @@ -23,6 +23,8 @@ Use title `Tracking Issue to Release ${VERSION}` in `apache/asyncband`. Keep the Fill in known values and leave future evidence pending. With `gh`, send the prepared body through standard input using `--body-file -` for creation and updates. Preserve other participants' edits. Do not check an item merely because a command was suggested, a job started, or an earlier candidate passed; attach the checked revision and outcome. +Set `RUNBOOK_COMMIT` to the full SHA of the upstream commit containing the runbook used when opening the issue. Keep this link pinned throughout the release. + ```markdown Release manager: @ Target version: @@ -31,7 +33,7 @@ Source cutoff: Release PR: pending Frozen release commit: pending Current phase / next action: initial license audit -Runbook: https://github.com/apache/asyncband/blob/main/.agents/skills/release/SKILL.md +Runbook: https://github.com/apache/asyncband/blob//.agents/skills/release/SKILL.md ## Prepare and freeze From 4c3f7501477b2e259d26f7fa07e72039df89e5bb Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 23:23:28 +0800 Subject: [PATCH 06/12] docs: focus release guidance on execution and handoff --- .agents/skills/release/SKILL.md | 20 +++++++++---------- .agents/skills/release/references/atr.md | 18 +++++++---------- .../release/references/infrastructure.md | 18 +++++++---------- .../release/references/tracking-issue.md | 4 ++-- .../skills/release/references/verification.md | 18 ++++++++--------- 5 files changed, 34 insertions(+), 44 deletions(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index 8e6f6fef..b859dc7f 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -26,21 +26,21 @@ under the License. Use the release tracking issue to coordinate the release and hand it to another PMC member. The normal path assumes signing, GitHub environments, ATR, and crates.io Trusted Publishing are already configured: GitHub builds and stages the candidate; ATR runs the votes and publishes the approved source; the final Git tag publishes the convenience crate. -For an actual release, follow the steps below. For a status check, resume from the issue and live workflow/ATR state. For an independent candidate check, use [verification](references/verification.md). A request to edit this skill does not start a release. Carry forward the user's authorization; prepare concrete tags, messages, and publication actions before asking only for authorization that is still missing. When the release manager operates ATR, provide the current page and next action, then confirm the result before proceeding. +Follow the steps below for a new release, or resume from the tracking issue and current GitHub/ATR state. For an independent candidate check, use [verification](references/verification.md). ## 1. Choose the version and open the tracking issue -Set `VERSION` to the target stable crate version, such as `0.7.3`, after comparing the previous published crate and changes since its release tag. Use the user's proposed version when compatible; `cargo x semver` below verifies the decision. Record a source cutoff commit and defer unrelated pending work so the release does not keep following `main`. +Choose the stable `VERSION` (`X.Y.Z`) from the changes since the previous published release; the semver check below validates compatibility. Record a source cutoff commit and any work deferred to a later release. Find an existing `Tracking Issue to Release ${VERSION}` before creating one. Otherwise create it immediately from the [tracking issue template](references/tracking-issue.md). Use it as the release record: link the release PR, checked revisions, workflow runs, candidate, votes, and publication results; update completed items with evidence and keep the next action current. ## 2. Audit first, prepare the version, and freeze the source -Start with the `license-audit` skill on the selected checkout. Resolve release-blocking licensing or attribution findings before packaging. The configured `license_auditor` can perform this review independently. A checkout audit does not yet verify the distributed archive or Cargo package. +Audit the selected checkout with the `license-audit` skill. Prepare a release PR from the chosen scope: update `asyncband/Cargo.toml`, refresh `Cargo.lock` with Cargo, and move the final user-visible changelog entries from `Unreleased` into an undated `v${VERSION}` section, leaving `Unreleased` empty. Include necessary audit corrections; defer unrelated source changes. Respect required CI and merge authorization. -Before freezing, check that the merged PR's tree matches the reviewed release scope. If `main` advanced during preparation and the merge includes additional changes, review them and update the scope and affected audit results first. Record the PR's merge commit, not a later `main` HEAD, as `RELEASE_COMMIT` in the issue. This freezes the entire release tree, including manifests, licensing, and documentation. `main` may then advance without changing this release. Use a detached checkout for all remaining checks and tags: +Review the merged PR's tree, including any changes added since the source cutoff, and update affected audit results. Record its merge commit as `RELEASE_COMMIT` in the issue. Use a detached checkout of this frozen snapshot for all remaining checks and tags: ```shell RELEASE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/asyncband-release.XXXXXX")" @@ -65,7 +65,7 @@ cargo x semver --release-version "${VERSION}" cargo publish --package asyncband --locked --dry-run ``` -Record results against `RELEASE_COMMIT`, including the required CI result for that commit. Do not use `--allow-dirty`. Pass the generated `target/package/asyncband-${VERSION}.crate` to the license review to check the actual Cargo distribution. If audit fixes changed the selected source, include those changes in the final review. +Record results against `RELEASE_COMMIT`, including its required CI result. Pass the generated `target/package/asyncband-${VERSION}.crate` to the license review. For a semver-major release, including a pre-1.0 minor bump, document and review expected API breaks before rerunning `cargo x semver --release-version "${VERSION}" --acknowledge-breaking-changes`. An incompatible patch release needs a corrected version or source before the snapshot can pass. @@ -85,10 +85,10 @@ git push https://github.com/apache/asyncband.git "${RC_TAG}" Follow both workflows for this tag: -- `Release` checks the unchanged `${VERSION}` Cargo package and skips crates.io publication. +- `Release` checks the `${VERSION}` Cargo package. - `Compose source release` builds `apache-asyncband-${VERSION}-incubating-src.tar.gz` and its checksum. Approve its `release` environment job to sign with the automated project key and upload the archive, `.asc`, and `.sha512` to ATR project `asyncband`, version `${VERSION}`. -Open the uploaded candidate in [ATR](https://releases.apache.org/projects/asyncband), inspect its checks, and record its actual URL and revision with the tag, commit, workflow run, and SHA-512. The ATR revision is not the Git RC number. Download that revision and follow [verification](references/verification.md): check signatures and checksum, compare the source contents with the RC commit, and test the build and Cargo package. Use `release_verifier` for substantial independent verification, including the archive rebuild required for automated signing, and the `license-audit` skill (or `license_auditor` agent) for the actual distributions. Collect both results before voting; reuse completed checks for the same candidate. +Open the candidate in [ATR](https://releases.apache.org/projects/asyncband), inspect its checks, and record its URL, ATR revision, workflow run, and SHA-512 in the issue. Download that revision and complete [verification](references/verification.md) and `license-audit` on the actual distributions before voting. The `release_verifier` and `license_auditor` agents can perform these checks independently; reuse completed checks for the same candidate. ## 5. Vote and publish through ATR @@ -99,7 +99,7 @@ Follow the [ATR operations guide](references/atr.md). In the configured email-vo 3. After at least another 72 hours and sufficient binding IPMC votes, review and resolve that vote as `Passed`. ATR sends the result and moves the release to Finish. 4. In Finish, publish the exact approved revision to ASF distribution, or verify the completed automatic publication if it was enabled. Keep the candidate bytes unchanged. -Record both rounds' vote and result links in the issue. Do not send duplicate vote/result emails yourself. GitHub checks and a passing PPMC vote alone do not authorize an ASF release. +Record both rounds' vote and result links in the issue. ## 6. Publish the crate and close the issue @@ -113,10 +113,10 @@ git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "v${VERSION}" \ git push https://github.com/apache/asyncband.git "v${VERSION}" ``` -Approve the final tag's `release` environment deployment in `release.yml`, then verify crates.io, docs.rs, and the ASF downloads. Final tags do not compose another source candidate. Use ATR's Announce action after both distributions are available; review the message and recipients and record the sent announcement. Submit the changelog publication-date PR, confirm any superseded-release archival, and close the tracking issue only after its required items are complete. Remove the detached worktree and scratch directory when no longer needed. +Approve the final tag's `release` environment deployment in `release.yml`, then verify crates.io, docs.rs, and the ASF downloads. Use ATR's Announce action after both distributions are available; review the message and recipients and record the sent announcement. Submit the changelog publication-date PR, confirm any superseded-release archival, and close the tracking issue after its required items are complete. Remove the detached worktree and scratch directory when no longer needed. ## Resume or recover Use the issue's frozen commit and candidate revision rather than the latest `main`. Reuse an existing tag after checking its signature and target. For uncertain uploads, votes, or publications, inspect ATR and the destination before repeating an action; signing/upload retries can create a new signature and revision. See [ATR recovery](references/atr.md#recover-without-replacing-voted-files). For a failed crates.io run, check whether that version already exists before retrying; a published package is immutable. -Consult [infrastructure](references/infrastructure.md) only for a concrete setup or access problem. Resolve repository paths from the caller's supplied repository root; skill reference links stay inside this directory. Discover `license-audit` by name, or use `.agents/skills/license-audit/SKILL.md` under that root. +Consult [infrastructure](references/infrastructure.md) for setup or access failures. Resolve repository paths from the caller's supplied repository root. diff --git a/.agents/skills/release/references/atr.md b/.agents/skills/release/references/atr.md index 1fd91ac9..dc2c1a91 100644 --- a/.agents/skills/release/references/atr.md +++ b/.agents/skills/release/references/atr.md @@ -19,7 +19,7 @@ under the License. # Operate the release in ATR -Use the [Asyncband project](https://releases.apache.org/projects/asyncband) with the release manager's ASF login. The normal interface is the ATR website. The repository configures email voting; voters reply on the mailing lists and the release manager reviews the tally in ATR. Do not switch to Trusted Vote mode as an incidental release step. +Open the [Asyncband project](https://releases.apache.org/projects/asyncband) with the release manager's ASF login. Use email voting: voters reply on the mailing lists and the release manager reviews the tally in ATR. ## Start the vote @@ -27,31 +27,27 @@ Use the [Asyncband project](https://releases.apache.org/projects/asyncband) with 2. Open the voting form. Set the first-round recipient to `dev@asyncband.apache.org`, the second-round recipient to `general@incubator.apache.org`, and the minimum duration to at least 72 hours. The second round uses that duration too. 3. Review the generated subject and body. Identify Apache Asyncband (Incubating), `${VERSION}`, and the RC; include the ATR candidate/revision, RC tag and commit, source checksum, KEYS and signer information, changelog, and verification evidence. Link ATR as the location of the voted files. Submit **Send vote email** when sending the vote is authorized, then record its archive link and closing time. -The automatic publication option is optional. Enable it only when publication after successful completion of both rounds is within the authorized scope, and confirm the download suffix is `${VERSION}`. For podlings, ATR carries this setting into round two and publishes only after that round passes; it does not publish on PPMC approval alone. Otherwise publish manually in Finish. +If publication is authorized, automatic publication can publish the source after IPMC approval; confirm the download suffix is `${VERSION}` when selecting it. Otherwise publish in Finish after both votes pass. ## Resolve both rounds Each round needs at least 72 hours, at least three eligible `+1` votes, and more eligible `+1` than `-1` votes. Eligibility is PPMC membership for round one and IPMC membership for round two. Allow at least six days for the two sequential votes. See the [Incubator vote rules](https://incubator.apache.org/cookbook/#two-phase-vote-on-podling-releases). 1. After the PPMC period, open the vote resolution page. Compare ATR's email tally with the thread, including voters' roles and any carried IPMC votes, and review the result body. Select `Passed` only if the requirements are met, then resolve the vote. -2. ATR sends the PPMC result and automatically starts the IPMC vote on the selected second-round list. Confirm delivery and record both links. Check the actual IPMC email for the PPMC result, its `lists.apache.org` tally link, and any IPMC votes carried from round one. ATR currently regenerates this email from the project template without adding that evidence; if missing, have the release manager supplement the existing IPMC thread. Do not start another vote. The files stay in the same candidate revision. +2. ATR sends the PPMC result and automatically starts the IPMC vote on the selected second-round list. Confirm delivery and record both links. Check that the IPMC thread includes the PPMC result, its `lists.apache.org` tally link, and any IPMC votes carried from round one; supplement that thread with any missing evidence. 3. After the IPMC period, review its binding tally, including eligible votes carried from round one and counting only each voter's latest vote, and review the result body before resolving it as `Passed`. ATR sends the result, also reports the passing result to the first-round thread, and moves the release to Finish. Record both vote results before final publication. -These transitions are implemented for email votes in ATR's [vote resolution](https://github.com/apache/tooling-trusted-releases/blob/0d156e9a/atr/storage/writers/vote.py#L676). A recorded state change and an email delivery can succeed or fail separately; check both before reporting completion. - ## Publish and announce -In Finish, inspect **Publish to ASF Distribution Area**. If automatic publication already completed, record its result. Otherwise confirm the approved revision and destination `dist/release/incubator/asyncband/${VERSION}/`, then use the publish action. ATR commits the voted files to SVN; record the SVN revision and compare the published archive, signature, and checksum with the candidate. No local rebuild, re-signing, or `svn move` is needed. +In Finish, inspect **Publish to ASF Distribution Area**. If automatic publication already completed, record its result. Otherwise confirm the approved revision and destination `dist/release/incubator/asyncband/${VERSION}/`, then use the publish action. ATR commits the voted files to SVN; record the SVN revision and compare the published archive, signature, and checksum with the candidate. -Return to the main runbook to push the final tag and verify crates.io publication. Once both the ASF downloads and the crate are available, use **Announce** in ATR, review the recipients and message, and submit it. ATR sends the announcement and updates its release catalog. Record the announcement link in the tracking issue instead of sending the same email manually. See [ATR publication](https://releases.apache.org/docs/promoting-to-release). +Return to the main runbook to push the final tag and verify crates.io publication. Once both the ASF downloads and the crate are available, use **Announce** in ATR, review the recipients and message, and submit it. ATR sends the announcement and updates its release catalog. Record the announcement link in the tracking issue. See [ATR publication](https://releases.apache.org/docs/promoting-to-release). -Use ATR's archive action or the configured auto-archive option for superseded releases. Confirm the archive and distribution results; follow up on any cleanup warning rather than assuming a catalog entry proves completion. +Use ATR's archive action or the configured auto-archive option for superseded releases. Confirm archival and removal from active downloads, and resolve any cleanup warnings. ## API and CLI alternative -ATR has a [CLI](https://github.com/apache/tooling-releases-client) and authenticated API. The CLI exposes `atr vote start`, `atr vote tabulate`, `atr vote resolve`, and `atr announce`; the server exposes `/api/vote/start`, `/api/vote/tabulate`, `/api/vote/resolve`, and `/api/release/announce`. See the [CLI command reference](https://github.com/apache/tooling-releases-client/blob/main/COMMANDS.md) and [server API](https://github.com/apache/tooling-trusted-releases/blob/0d156e9a/atr/api/__init__.py). - -Use the website for the ordinary handoff: it exposes the current tally, editable result email, and publication state together. The CLI/API are evolving, and the current API's vote resolution sends only a short generic result body. If automation is explicitly requested, check the installed client's help and current API schema and use existing authorized credentials; do not invent endpoints or introduce vote/finish workflows as part of a routine release. Our registered GitHub workflow handles composition only. +Use the website to review the tally, edit emails, and publish. For scripted operations, consult the [CLI](https://github.com/apache/tooling-releases-client) and [server API](https://github.com/apache/tooling-trusted-releases/blob/0d156e9a/atr/api/__init__.py). Check the client's help, current API schema, and generated vote/result messages against the steps above. ## Recover without replacing voted files diff --git a/.agents/skills/release/references/infrastructure.md b/.agents/skills/release/references/infrastructure.md index 25b7ad1f..554ae880 100644 --- a/.agents/skills/release/references/infrastructure.md +++ b/.agents/skills/release/references/infrastructure.md @@ -17,22 +17,18 @@ specific language governing permissions and limitations under the License. --> -# Infrastructure reference +# Troubleshoot release services -Routine releases assume this setup is complete. Read this reference only for an observed signing, authorization, synchronization, or publication failure. +Start with the failed workflow step or ATR operation, then check the corresponding configuration below. ## Source composition -`.asf.yaml` registers repository `asyncband` and `.github/workflows/release-compose.yml` with ATR through `atr_sync`. It selects email voting on `dev@asyncband.apache.org`, a 72-hour minimum, and download suffix `{{VERSION}}`. ATR must recognize Asyncband as a podling for the two-round vote. Inspect the live project policy when behavior differs from the repository settings. +For a blocked or failed compose run, check the `release` environment approval and the settings required by `.github/workflows/release-compose.yml`. For ATR authentication or key-recognition failures, compare the project's Trusted Publishing settings with `.asf.yaml` and confirm that the signing key is available in the project's [KEYS](https://downloads.apache.org/incubator/asyncband/KEYS). See [ATR Trusted Publishing](https://releases.apache.org/docs/trusted-publishing). -The `release` environment gates signing/upload. The workflow reads `GPG_SECRET_KEY`, `SOURCE_SIGNING_FINGERPRINT`, and optional `GPG_PASSPHRASE` through GitHub `secrets`; ASF-provisioned values can be repository secrets. The fingerprint is the full uppercase primary fingerprint, not an Actions variable. Inspect names with `gh secret list --repo apache/asyncband` and `gh secret list --repo apache/asyncband --env release`; do not export private-key material for diagnosis. +## ATR voting and publication -The automated project key must be present in [KEYS](https://downloads.apache.org/incubator/asyncband/KEYS) and recognized by ATR under the committee's existing key-management mode. Consult [Trusted Publishing setup](https://releases.apache.org/docs/trusted-publishing) and [INFRA-28407](https://issues.apache.org/jira/browse/INFRA-28407) for provisioning issues. Check the actual primary UID and deployed ATR recognition rules if it is not identified as an automated key. Preserve old keys when adding a public key. +Check Asyncband's podling status and voting settings in ATR, and compare its synchronized settings with `.asf.yaml`. For publication failures, inspect Finish's result and the destination `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`. Published files propagate to `https://downloads.apache.org/incubator/asyncband/${VERSION}/`. See [ATR publication](https://releases.apache.org/docs/promoting-to-release). -Git tags are signed with the release manager's individual key. Source archives are signed with the automated project key. Verify each against its own recorded fingerprint. The upload action authenticates through GitHub OIDC; a personal ATR token is not required for composition. +## crates.io publication -## Final publication - -ATR publishes approved files to `https://dist.apache.org/repos/dist/release/incubator/asyncband/${VERSION}/`; they propagate to `https://downloads.apache.org/incubator/asyncband/${VERSION}/`. Inspect Finish's actual destination and result when diagnosing publication. - -crates.io Trusted Publishing is configured for repository `apache/asyncband`, workflow `release.yml`, and environment `release`. Only the final `v${VERSION}` tag enters the publication job, with a separate environment approval and short-lived OIDC token. Consult the workflow and [crates.io documentation](https://crates.io/docs/trusted-publishing) for an authentication failure; do not repeat initial setup for each release. +Check the final tag's run of `.github/workflows/release.yml` and its `release` environment approval. For an authentication failure, confirm that the crate's Trusted Publisher matches repository `apache/asyncband`, workflow `release.yml`, and environment `release`. See [crates.io Trusted Publishing](https://crates.io/docs/trusted-publishing). diff --git a/.agents/skills/release/references/tracking-issue.md b/.agents/skills/release/references/tracking-issue.md index 32939e1e..ea831100 100644 --- a/.agents/skills/release/references/tracking-issue.md +++ b/.agents/skills/release/references/tracking-issue.md @@ -21,7 +21,7 @@ under the License. Use title `Tracking Issue to Release ${VERSION}` in `apache/asyncband`. Keep the release's current state, check results, and next action in this issue so another release manager can take over. -Fill in known values and leave future evidence pending. With `gh`, send the prepared body through standard input using `--body-file -` for creation and updates. Preserve other participants' edits. Do not check an item merely because a command was suggested, a job started, or an earlier candidate passed; attach the checked revision and outcome. +Fill in known values and leave unfinished items unchecked. Record the checked revision and result for each completed item. With `gh`, pass the body through standard input using `--body-file -` and preserve other participants' edits. Set `RUNBOOK_COMMIT` to the full SHA of the upstream commit containing the runbook used when opening the issue. Keep this link pinned throughout the release. @@ -76,4 +76,4 @@ Tag signer / source signer fingerprints and provenance: pending - [ ] Close this issue after the preceding required items are complete. ``` -For a replacement candidate, retain the previous tag, commit, ATR revision, and vote outcome in the issue history. Update the active candidate fields, invalidate checks affected by changed contents, and make the next action explicit. Keep local scratch paths in the conversation; another release manager should be able to resume from the public issue and artifact links. +For a replacement candidate, retain the previous tag, commit, ATR revision, and vote outcome in the issue history. Update the active candidate fields, invalidate checks affected by changed contents, and make the next action explicit. diff --git a/.agents/skills/release/references/verification.md b/.agents/skills/release/references/verification.md index f9897b65..3766b23c 100644 --- a/.agents/skills/release/references/verification.md +++ b/.agents/skills/release/references/verification.md @@ -19,26 +19,24 @@ under the License. # Verify an existing release candidate -Perform the requested checks against the supplied candidate and return evidence to the caller. This is a bounded technical check: preserve the supplied repository and artifacts, and create extraction or build outputs only in the caller's scratch directory or a new temporary directory outside the checkout. Do not change tags, sign replacement artifacts, stage, publish, send messages, or perform a separate license audit. +Verify the supplied candidate and return results to the release manager. Preserve the original artifacts and use a scratch directory outside the checkout for extraction and builds. ## Inputs and scope -Use the caller's repository root, `VERSION`, `RC_TAG`, `RELEASE_COMMIT`, ATR candidate URL and revision, compose run and attempt, absolute archive/signature/checksum paths, expected tag and source signing fingerprints with their provenance, and requested verification scope. The caller may supply an existing Cargo package as well. Resolve repository files from that explicit root; this guide's location does not identify the audited checkout. +Use the supplied repository root, `VERSION`, `RC_TAG`, `RELEASE_COMMIT`, ATR URL and revision, compose run and attempt, archive/signature/checksum paths, expected signing fingerprints and their provenance, and requested verification scope. -Establish which checks are requested and which inputs are available. Continue independent checks when an input is missing and report the resulting gap. A key bundled with an archive is not independent evidence of signer identity. Use a temporary GPG home when importing supplied verification keys so the user's keyring stays unchanged. +Obtain signing fingerprints from trusted project key records and import verification keys into a temporary GPG home. Report any missing inputs or incomplete checks. ## Verify identity and source contents -1. Record the resolved commit, ATR revision, and artifact paths. Check the supplied RC tag's commit and signature against `RELEASE_COMMIT` and the release manager's expected tag-signing fingerprint. Keep an existing candidate tied to that commit even if `main` has advanced. +1. Record the resolved commit, ATR revision, and artifact paths. Check the RC tag's commit and signature against `RELEASE_COMMIT` and the release manager's expected tag-signing fingerprint. 2. Verify the downloaded archive's SHA-512 against its checksum file and the compose summary. Verify its detached signature against the expected source-signing fingerprint, recording the primary fingerprint when a signing subkey is used. The archive signer can differ from the Git tag signer; check both identities. 3. Inspect the archive member list before extracting. Check the expected `apache-asyncband-${VERSION}-incubating-src/` root, reject paths that escape the extraction directory, and inspect symlinks without following them outside the extracted tree. 4. Compare the archived source inventory, file contents, executable bits, and symlink targets with `git archive` of the resolved candidate commit, using a separate temporary extraction. Report missing, added, or changed entries with concrete paths. Check the package version in the extracted manifest against `VERSION`. For example, use `git -C "${REPO_ROOT}" rev-parse "${RC_TAG}^{commit}"` to resolve a candidate and `git -C "${REPO_ROOT}" verify-tag "${RC_TAG}"` to inspect its signature. Run `shasum -a 512 --check` from the artifact directory and `gpg --verify` with the explicitly supplied signature and archive. Inspect checksum filenames before using the checksum file so it checks the intended artifact. -Compare source contents independently of archive headers and compression: different macOS and Linux packaging tools can produce different `.tar.gz` bytes for the same files. A compression difference alone is not a source mismatch. - -[ASF automated signing](https://infra.apache.org/release-signing.html#automated-release-signing) additionally requires an independent rebuild on trusted hardware outside GitHub Actions. Have the verifier run the tagged compose recipe in a Linux environment on that hardware and record the matching archive SHA-512 once per candidate. Reuse that evidence; the release manager does not need to repeat it. Source comparison alone does not establish this separate result, and the downloaded archive and signature remain the release artifacts. +On trusted hardware outside GitHub Actions, run the candidate's compose recipe in a Linux environment and compare the rebuilt archive's SHA-512 with the ATR artifact. Record this once per candidate to satisfy [ASF automated signing](https://infra.apache.org/release-signing.html#automated-release-signing). When diagnosing a mismatch, compare source contents separately from archive headers and compression. ## Verify the build and Cargo package @@ -50,10 +48,10 @@ cargo test --workspace --all-features --locked cargo publish --package asyncband --locked --dry-run ``` -Use the resulting `target/package/asyncband-${VERSION}.crate` for packaging verification and the caller's license review. If a package is supplied separately, inspect its actual contents and compare it with the package generated from the candidate when available. Check the package name, version, packaged source, and Cargo provenance metadata where present. Account for Cargo-generated manifests and repository metadata when comparing; an absent commit field in a package built outside a Git checkout is not itself a mismatch. +Use the resulting `target/package/asyncband-${VERSION}.crate` for packaging verification and license review. Check its name, version, source contents, and provenance metadata where present. When comparing a separately supplied package, account for Cargo-generated manifests and metadata that depend on whether a Git checkout is available. -Preserve the original archive inventory when builds add files to the extracted directory. Report build or dependency-fetch failures as observed failures; do not change the candidate to make verification pass. +Keep the original archive inventory for license review; build outputs belong only to the verification workspace. ## Return the result -Return the checked candidate and ATR revision, signer fingerprints, signature/checksum results, source differences, independent rebuild checksum, requested build/package results, and any checks not completed. Give the caller the extracted source and package paths for `license-audit`; retain these scratch outputs until the caller has finished with them. Do not create a report file unless requested. +Return the checked candidate and ATR revision, signer fingerprints, signature/checksum results, source differences, independent rebuild checksum, build/package results, and any incomplete checks. Provide the extracted source and package paths for `license-audit` and retain them until that review is complete. From 726b2a8bee9b054c0567c3ed9ea447669bf12f20 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 23:37:39 +0800 Subject: [PATCH 07/12] fixup Signed-off-by: tison --- .agents/skills/release/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index b859dc7f..78198ffe 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -24,7 +24,7 @@ under the License. # Release Apache Asyncband -Use the release tracking issue to coordinate the release and hand it to another PMC member. The normal path assumes signing, GitHub environments, ATR, and crates.io Trusted Publishing are already configured: GitHub builds and stages the candidate; ATR runs the votes and publishes the approved source; the final Git tag publishes the convenience crate. +Use the release tracking issue to coordinate the release. The normal path assumes that signing, GitHub environments, ATR, and crates.io Trusted Publishing are already configured: GitHub builds and stages the candidate; ATR runs the votes and publishes the approved source; the final Git tag publishes the convenience crate. Follow the steps below for a new release, or resume from the tracking issue and current GitHub/ATR state. For an independent candidate check, use [verification](references/verification.md). @@ -32,7 +32,7 @@ Follow the steps below for a new release, or resume from the tracking issue and Choose the stable `VERSION` (`X.Y.Z`) from the changes since the previous published release; the semver check below validates compatibility. Record a source cutoff commit and any work deferred to a later release. -Find an existing `Tracking Issue to Release ${VERSION}` before creating one. Otherwise create it immediately from the [tracking issue template](references/tracking-issue.md). Use it as the release record: link the release PR, checked revisions, workflow runs, candidate, votes, and publication results; update completed items with evidence and keep the next action current. +Find an existing `Tracking Issue to Release ${VERSION}` before creating one. Otherwise, create it immediately from the [tracking issue template](references/tracking-issue.md). Use it as the release record: link the release PR, checked revisions, workflow runs, candidate, votes, and publication results; update completed items with evidence and keep the next action current. ## 2. Audit first, prepare the version, and freeze the source @@ -50,7 +50,7 @@ cd "${RELEASE_DIR}/checkout" test -z "$(git status --porcelain)" ``` -Keep scratch artifacts outside the repository. If a check requires a correction, prepare a new reviewed commit and replace the recorded snapshot explicitly; recheck affected results. After an RC tag exists, changed release contents require a new RC number. Never silently move an existing tag or change the files under a vote. +Keep scratch artifacts outside the repository. If a check requires a correction, prepare a new reviewed commit and replace the recorded snapshot explicitly; recheck the affected results. After an RC tag exists, changed release contents require a new RC number. Never silently move an existing tag or change the files under a vote. ## 3. Check the frozen checkout From c103564d70dceda104957ea6b7007cb5f19abf95 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 23:41:17 +0800 Subject: [PATCH 08/12] docs: clarify the release manager signing key --- .agents/skills/release/SKILL.md | 13 ++++++++++--- .agents/skills/release/references/verification.md | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index 78198ffe..d5e8969a 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -71,13 +71,20 @@ For a semver-major release, including a pre-1.0 minor bump, document and review ## 4. Push the RC and verify the ATR candidate -Set `RC` to the next unused positive candidate number and `TAG_SIGNING_FINGERPRINT` to the release manager's verified signing-key fingerprint. The package and ATR version remain `${VERSION}`; only the Git tag carries the RC suffix: +Use the release manager's personal OpenPGP code-signing key. It must be valid for signing, have a user ID containing their `@apache.org` address, and have its public key published in Asyncband's [KEYS](https://downloads.apache.org/incubator/asyncband/KEYS). List the matching local keys and set `SIGNING_KEY_FINGERPRINT` to the selected key's primary fingerprint: + +```shell +gpg --list-secret-keys --with-fingerprint '@apache.org' +SIGNING_KEY_FINGERPRINT='' +``` + +Set `RC` to the next unused positive candidate number. The package and ATR version remain `${VERSION}`; only the Git tag carries the RC suffix: ```shell RC_TAG="v${VERSION}-rc.${RC}" test "$(git rev-parse HEAD)" = "${RELEASE_COMMIT}" test -z "$(git status --porcelain)" -git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "${RC_TAG}" \ +git tag --sign --local-user "${SIGNING_KEY_FINGERPRINT}" "${RC_TAG}" \ --message "Apache Asyncband ${VERSION} release candidate ${RC}" "${RELEASE_COMMIT}" git verify-tag "${RC_TAG}" git push https://github.com/apache/asyncband.git "${RC_TAG}" @@ -108,7 +115,7 @@ Once both votes have passed and the source publication is confirmed, create the ```shell git verify-tag "${RC_TAG}" test "$(git rev-parse "${RC_TAG}^{commit}")" = "${RELEASE_COMMIT}" -git tag --sign --local-user "${TAG_SIGNING_FINGERPRINT}" "v${VERSION}" \ +git tag --sign --local-user "${SIGNING_KEY_FINGERPRINT}" "v${VERSION}" \ --message "Apache Asyncband ${VERSION}" "${RELEASE_COMMIT}" git push https://github.com/apache/asyncband.git "v${VERSION}" ``` diff --git a/.agents/skills/release/references/verification.md b/.agents/skills/release/references/verification.md index 3766b23c..9367873c 100644 --- a/.agents/skills/release/references/verification.md +++ b/.agents/skills/release/references/verification.md @@ -29,7 +29,7 @@ Obtain signing fingerprints from trusted project key records and import verifica ## Verify identity and source contents -1. Record the resolved commit, ATR revision, and artifact paths. Check the RC tag's commit and signature against `RELEASE_COMMIT` and the release manager's expected tag-signing fingerprint. +1. Record the resolved commit, ATR revision, and artifact paths. Check the RC tag's commit and signature against `RELEASE_COMMIT` and the release manager's personal signing-key fingerprint recorded in the issue. 2. Verify the downloaded archive's SHA-512 against its checksum file and the compose summary. Verify its detached signature against the expected source-signing fingerprint, recording the primary fingerprint when a signing subkey is used. The archive signer can differ from the Git tag signer; check both identities. 3. Inspect the archive member list before extracting. Check the expected `apache-asyncband-${VERSION}-incubating-src/` root, reject paths that escape the extraction directory, and inspect symlinks without following them outside the extracted tree. 4. Compare the archived source inventory, file contents, executable bits, and symlink targets with `git archive` of the resolved candidate commit, using a separate temporary extraction. Report missing, added, or changed entries with concrete paths. Check the package version in the extracted manifest against `VERSION`. From c248bb2948c276ef31d99fcece6206cc94a09d64 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 23:47:32 +0800 Subject: [PATCH 09/12] fixup Signed-off-by: tison --- .agents/skills/release/SKILL.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index d5e8969a..8fa34a04 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -1,6 +1,6 @@ --- name: release -description: Run or resume an Apache Asyncband release, from its tracking issue and frozen source through RC composition, ATR voting, publication, and follow-up; also verify an existing candidate. +description: Run or resume an Apache Asyncband (Incubating) release, from its tracking issue and frozen source through RC composition, ATR voting, publication, and follow-up; also verify an existing candidate. --- -# Release Apache Asyncband +# Release Apache Asyncband (Incubating) Use the release tracking issue to coordinate the release. The normal path assumes that signing, GitHub environments, ATR, and crates.io Trusted Publishing are already configured: GitHub builds and stages the candidate; ATR runs the votes and publishes the approved source; the final Git tag publishes the convenience crate. @@ -71,7 +71,7 @@ For a semver-major release, including a pre-1.0 minor bump, document and review ## 4. Push the RC and verify the ATR candidate -Use the release manager's personal OpenPGP code-signing key. It must be valid for signing, have a user ID containing their `@apache.org` address, and have its public key published in Asyncband's [KEYS](https://downloads.apache.org/incubator/asyncband/KEYS). List the matching local keys and set `SIGNING_KEY_FINGERPRINT` to the selected key's primary fingerprint: +Use the release manager's personal OpenPGP code-signing key. It must be valid for signing, have a user ID containing their `@apache.org` address, and have its public key published in the [KEYS](https://downloads.apache.org/incubator/asyncband/KEYS) file. List the matching local keys and set `SIGNING_KEY_FINGERPRINT` to the selected key's primary fingerprint: ```shell gpg --list-secret-keys --with-fingerprint '@apache.org' @@ -84,8 +84,7 @@ Set `RC` to the next unused positive candidate number. The package and ATR versi RC_TAG="v${VERSION}-rc.${RC}" test "$(git rev-parse HEAD)" = "${RELEASE_COMMIT}" test -z "$(git status --porcelain)" -git tag --sign --local-user "${SIGNING_KEY_FINGERPRINT}" "${RC_TAG}" \ - --message "Apache Asyncband ${VERSION} release candidate ${RC}" "${RELEASE_COMMIT}" +git tag --sign --local-user "${SIGNING_KEY_FINGERPRINT}" "${RC_TAG}" --message "Apache Asyncband (Incubating) ${VERSION} release candidate ${RC}" "${RELEASE_COMMIT}" git verify-tag "${RC_TAG}" git push https://github.com/apache/asyncband.git "${RC_TAG}" ``` @@ -115,12 +114,11 @@ Once both votes have passed and the source publication is confirmed, create the ```shell git verify-tag "${RC_TAG}" test "$(git rev-parse "${RC_TAG}^{commit}")" = "${RELEASE_COMMIT}" -git tag --sign --local-user "${SIGNING_KEY_FINGERPRINT}" "v${VERSION}" \ - --message "Apache Asyncband ${VERSION}" "${RELEASE_COMMIT}" +git tag --sign --local-user "${SIGNING_KEY_FINGERPRINT}" "v${VERSION}" --message "Apache Asyncband (Incubating) ${VERSION}" "${RELEASE_COMMIT}" git push https://github.com/apache/asyncband.git "v${VERSION}" ``` -Approve the final tag's `release` environment deployment in `release.yml`, then verify crates.io, docs.rs, and the ASF downloads. Use ATR's Announce action after both distributions are available; review the message and recipients and record the sent announcement. Submit the changelog publication-date PR, confirm any superseded-release archival, and close the tracking issue after its required items are complete. Remove the detached worktree and scratch directory when no longer needed. +Approve the final tag's `release` environment deployment in `release.yml`, then verify crates.io, docs.rs, and the ASF downloads. Use ATR's Announce action after both distributions are available; review the message and recipients and record the announcement. Submit the changelog publication-date PR, confirm any superseded-release archival, and close the tracking issue after its required items are complete. Remove the detached worktree and scratch directory when no longer needed. ## Resume or recover From 23aeff321343bd1b3c26056c5ff485ffb44377ef Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 23:49:54 +0800 Subject: [PATCH 10/12] docs: render release issue metadata as labeled lists --- .../release/references/tracking-issue.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.agents/skills/release/references/tracking-issue.md b/.agents/skills/release/references/tracking-issue.md index ea831100..fd1e7b09 100644 --- a/.agents/skills/release/references/tracking-issue.md +++ b/.agents/skills/release/references/tracking-issue.md @@ -26,14 +26,14 @@ Fill in known values and leave unfinished items unchecked. Record the checked re Set `RUNBOOK_COMMIT` to the full SHA of the upstream commit containing the runbook used when opening the issue. Keep this link pinned throughout the release. ```markdown -Release manager: @ -Target version: -Previous release: -Source cutoff: -Release PR: pending -Frozen release commit: pending -Current phase / next action: initial license audit -Runbook: https://github.com/apache/asyncband/blob//.agents/skills/release/SKILL.md +- **Release manager:** @ +- **Target version:** +- **Previous release:** +- **Source cutoff:** +- **Release PR:** pending +- **Frozen release commit:** pending +- **Current phase / next action:** initial license audit +- **Runbook:** https://github.com/apache/asyncband/blob//.agents/skills/release/SKILL.md ## Prepare and freeze @@ -53,11 +53,11 @@ Runbook: https://github.com/apache/asyncband/blob//.agents/skill ## Candidate -RC / signed tag: pending -Compose run and attempt / package-check run: pending -ATR candidate URL / revision: pending -Source SHA-512: pending -Tag signer / source signer fingerprints and provenance: pending +- **RC / signed tag:** pending +- **Compose run and attempt / package-check run:** pending +- **ATR candidate URL / revision:** pending +- **Source SHA-512:** pending +- **Tag signer / source signer fingerprints and provenance:** pending - [ ] Push the signed RC tag at the frozen commit; confirm both release workflows and ATR upload. - [ ] Download and verify the ATR revision: signatures, checksum, source contents against the RC commit, independent archive rebuild for automated signing, build, and packaging. From 8ce30b0c6ab5ee8470276a14ba7342e5b0cd58bd Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 21 Sep 2026 23:56:17 +0800 Subject: [PATCH 11/12] fixup Signed-off-by: tison --- .agents/skills/release/references/atr.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.agents/skills/release/references/atr.md b/.agents/skills/release/references/atr.md index dc2c1a91..540686a5 100644 --- a/.agents/skills/release/references/atr.md +++ b/.agents/skills/release/references/atr.md @@ -27,7 +27,7 @@ Open the [Asyncband project](https://releases.apache.org/projects/asyncband) wit 2. Open the voting form. Set the first-round recipient to `dev@asyncband.apache.org`, the second-round recipient to `general@incubator.apache.org`, and the minimum duration to at least 72 hours. The second round uses that duration too. 3. Review the generated subject and body. Identify Apache Asyncband (Incubating), `${VERSION}`, and the RC; include the ATR candidate/revision, RC tag and commit, source checksum, KEYS and signer information, changelog, and verification evidence. Link ATR as the location of the voted files. Submit **Send vote email** when sending the vote is authorized, then record its archive link and closing time. -If publication is authorized, automatic publication can publish the source after IPMC approval; confirm the download suffix is `${VERSION}` when selecting it. Otherwise publish in Finish after both votes pass. +If publication is authorized, automatic publication can publish the source after IPMC approval; confirm the download suffix is `${VERSION}` when selecting it. Otherwise, publish in Finish after both votes pass. ## Resolve both rounds @@ -39,7 +39,7 @@ Each round needs at least 72 hours, at least three eligible `+1` votes, and more ## Publish and announce -In Finish, inspect **Publish to ASF Distribution Area**. If automatic publication already completed, record its result. Otherwise confirm the approved revision and destination `dist/release/incubator/asyncband/${VERSION}/`, then use the publish action. ATR commits the voted files to SVN; record the SVN revision and compare the published archive, signature, and checksum with the candidate. +In Finish, inspect **Publish to ASF Distribution Area**. If automatic publication already completed, record its result. Otherwise, confirm the approved revision and destination `dist/release/incubator/asyncband/${VERSION}/`, then use the Publish action. ATR commits the voted files to SVN; record the SVN revision and compare the published archive, signature, and checksum with the candidate. Return to the main runbook to push the final tag and verify crates.io publication. Once both the ASF downloads and the crate are available, use **Announce** in ATR, review the recipients and message, and submit it. ATR sends the announcement and updates its release catalog. Record the announcement link in the tracking issue. See [ATR publication](https://releases.apache.org/docs/promoting-to-release). @@ -51,7 +51,7 @@ Use the website to review the tally, edit emails, and publish. For scripted oper ## Recover without replacing voted files -- Failed or uncertain upload: inspect ATR before retrying. If all three files arrived and verification succeeds, record that revision even if the GitHub run reported a late failure. Otherwise retry before voting and verify the resulting revision; signing/upload can produce a new signature and revision. If the GitHub source bundle expired, rerun composition from the same RC and compare the recorded checksum. +- Failed or uncertain upload: inspect ATR before retrying. If all three files arrived and verification succeeds, record that revision even if the GitHub run reported a late failure. Otherwise, retry before voting and verify the resulting revision; signing/upload can produce a new signature and revision. If the GitHub source bundle expired, rerun composition from the same RC and compare the recorded checksum. - Source or workflow correction: use a new reviewed commit and refresh affected checks. If an RC already exists, use a new RC number. A workflow rerun uses the old tagged workflow, so changing `main` cannot repair it. - Rejected or cancelled vote: resolve that outcome in ATR, which returns the release to Compose. Preserve the previous tag and vote history in the issue, then prepare and verify the replacement candidate. Do not modify an active vote's files. - Vote or publication error: inspect the current round, mail-delivery status, Finish state, and destination files before retrying. Resume a completed transition; do not resend an IPMC vote or republish matching files merely to obtain a green status. From d690ae73f46acb2868e15bb9fc6d146154a04ca5 Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 22 Sep 2026 00:01:24 +0800 Subject: [PATCH 12/12] docs: record release vote and result permalinks --- .agents/skills/release/SKILL.md | 2 +- .agents/skills/release/references/atr.md | 2 ++ .agents/skills/release/references/tracking-issue.md | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.agents/skills/release/SKILL.md b/.agents/skills/release/SKILL.md index 8fa34a04..0fa9ee3f 100644 --- a/.agents/skills/release/SKILL.md +++ b/.agents/skills/release/SKILL.md @@ -105,7 +105,7 @@ Follow the [ATR operations guide](references/atr.md). In the configured email-vo 3. After at least another 72 hours and sufficient binding IPMC votes, review and resolve that vote as `Passed`. ATR sends the result and moves the release to Finish. 4. In Finish, publish the exact approved revision to ASF distribution, or verify the completed automatic publication if it was enabled. Keep the candidate bytes unchanged. -Record both rounds' vote and result links in the issue. +Record both rounds' `[VOTE]` threads and `[RESULT]` messages in the tracking issue using their `lists.apache.org` permalinks. ## 6. Publish the crate and close the issue diff --git a/.agents/skills/release/references/atr.md b/.agents/skills/release/references/atr.md index 540686a5..b980a2f1 100644 --- a/.agents/skills/release/references/atr.md +++ b/.agents/skills/release/references/atr.md @@ -21,6 +21,8 @@ under the License. Open the [Asyncband project](https://releases.apache.org/projects/asyncband) with the release manager's ASF login. Use email voting: voters reply on the mailing lists and the release manager reviews the tally in ATR. +Fill the tracking issue's ATR vote page and communication links as each step completes. Use `lists.apache.org` permalinks for the PPMC and IPMC vote threads, their result messages, and the announcement. Each result link should open the message containing the outcome and tally. + ## Start the vote 1. Open the uploaded `${VERSION}` draft in Compose. Confirm the revision and checksum recorded in the tracking issue, inspect ATR's checks, and complete the candidate verification and artifact license review. Resolve blockers and review any concerns before acknowledging them. If ATR's commit field is empty, enter the frozen `RELEASE_COMMIT` using its commit-hash form. diff --git a/.agents/skills/release/references/tracking-issue.md b/.agents/skills/release/references/tracking-issue.md index fd1e7b09..6f21e5c5 100644 --- a/.agents/skills/release/references/tracking-issue.md +++ b/.agents/skills/release/references/tracking-issue.md @@ -65,6 +65,13 @@ Set `RUNBOOK_COMMIT` to the full SHA of the upstream commit containing the runbo ## Vote and publish +- **ATR vote page:** pending +- **PPMC vote thread:** pending +- **PPMC result:** pending +- **IPMC vote thread:** pending +- **IPMC result:** pending +- **Announcement:** pending + - [ ] Start the PPMC vote in ATR; record the vote link and closing time. - [ ] After the required duration and votes, resolve PPMC as Passed in ATR; record its result and the automatically started IPMC vote, and ensure that thread includes the PPMC tally link and any carried IPMC votes. - [ ] After the required duration and binding votes, resolve IPMC as Passed in ATR; record its result.