Harden release skill guidance (#555)

This commit is contained in:
Yuge Zhang
2026-08-24 11:37:22 +08:00
committed by GitHub
parent 217d8a55a3
commit 2bd0875fd3
+56 -23
View File
@@ -14,9 +14,11 @@ public side effects, not one.
## Establish the release state
1. Confirm the repository root, clean working tree, current branch, and remotes.
2. Resolve the canonical `OWNER/REPO` and its default branch with `gh repo view`.
2. Resolve the canonical `OWNER/REPO`, its default branch, and its permitted
merge methods with
`gh repo view OWNER/REPO --json nameWithOwner,defaultBranchRef,mergeCommitAllowed,rebaseMergeAllowed,squashMergeAllowed`.
Identify the local remotes for that repository and the contributor fork by
their URLs; do not assume particular remote names.
their URLs; do not assume particular remote names or merge settings.
3. Inspect the release contract in:
- `.github/workflows/pypi-release.yml`
- `.github/workflows/docs.yml`
@@ -25,7 +27,10 @@ public side effects, not one.
- `pyproject.toml`
- `agentlightning/__init__.py`
4. Confirm the canonical default branch is already green before branching from
it. A release branch inherits every failure that main is carrying.
it. Resolve its current commit with
`gh api repos/OWNER/REPO/commits/<default-branch>` and inspect that commit's
check runs; a general recent-run listing can omit or mix commits. A release
branch inherits every failure that main is carrying.
5. Query the canonical repository's tags and compare them with the versions
published at `https://pypi.org/pypi/agentlightning/json`. Confirm the target
version exists in neither place, and stop for an explicit release decision
@@ -52,6 +57,12 @@ git switch -c chore/release-vX.Y.Z <canonical-remote>/<default-branch>
scripts/bump_version.sh patch # or minor / major
```
The script updates the project version with uv and then edits
`agentlightning/__init__.py` separately. If it fails or is interrupted between
those writes, only some of the three version files may be updated. Inspect
`git diff` after any failure and restore or reconcile all three files before
retrying; blindly rerunning a partial patch bump can advance the version twice.
The bump rewrites exactly three files. Confirm that with `git diff --stat`:
- `pyproject.toml`
@@ -63,10 +74,11 @@ Other version strings in the tree, such as the FastAPI `version` in
alone; changing them is a separate pull request, not release work.
Review the version diff, but do not run the release tests or package build
locally as a matter of course. `tests.yml` runs the same test set and package
build on the pull request that `pypi-release.yml` will run on the tag, so the
pull request's GitHub checks are the verification gate. Reproduce a single
failure locally only when the workflow logs are not enough to fix it.
locally as a matter of course. `tests.yml` runs a broader test suite and the
same package build on the pull request, covering the narrower tests and build
that `pypi-release.yml` will run on the tag. The pull request's GitHub checks
are therefore the verification gate. Reproduce a single failure locally only
when the workflow logs are not enough to fix it.
Commit the version change, push it to the fork, and open the pull request with
the GitHub CLI when those external actions are authorized:
@@ -89,10 +101,21 @@ Follow the pull request through its required checks with
`gh pr checks <pr> --repo OWNER/REPO --watch`. If a check fails, take the run id
from that output, inspect it with
`gh run view <run-id> --repo OWNER/REPO --log-failed`, correct the source on the
same branch, and resume watching. Once every required check has succeeded, merge
the pull request with `gh pr merge <pr> --repo OWNER/REPO` using a merge method
the repository permits. Committing, pushing, opening the pull request, and
merging are each distinct external actions and each requires authorization.
same branch, and resume watching. Once every required check has succeeded,
extract the reviewed head and pass both a permitted merge-method flag from step
2 and `--match-head-commit` to `gh pr merge`:
```bash
HEAD_SHA="$(gh pr view <pr> --repo OWNER/REPO --json headRefOid --jq .headRefOid)"
gh pr merge <pr> --repo OWNER/REPO <merge-method-flag> \
--match-head-commit "$HEAD_SHA"
```
Replace `<merge-method-flag>` with one permitted flag discovered in step 2:
`--merge`, `--rebase`, or `--squash`.
Committing, pushing, opening the pull request, and merging are each distinct
external actions and each requires authorization.
## Tag and publish the merged release
@@ -120,11 +143,11 @@ grep '^__version__' agentlightning/__init__.py
```
The workflow itself reads the runtime value as
`python -c 'from agentlightning import __version__; print(__version__)'`, after
`uv sync` has installed the checkout. Locally that import can resolve to some
other installed copy of the package instead of the tree being tagged, so read
the file directly here; `agentlightning/__init__.py` assigns `__version__` as a
single literal, so the two agree by construction.
`python -c 'from agentlightning import __version__; print(__version__)'` from
the repository root before its dependency-sync step, so Python resolves the
checkout through the current working directory. Read the file directly for the
local pre-tag check; `agentlightning/__init__.py` assigns `__version__` as a
single literal, making that check independent of the active Python environment.
GitHub reads workflow files as they exist **at the tagged commit**, not at the
tip of the default branch. Confirm that the commit being tagged actually
@@ -155,13 +178,23 @@ One tag push starts two workflows, and both belong to the release:
versioned documentation and repoints the public `stable` alias at this
release.
Follow both to a terminal result with `gh run list --repo OWNER/REPO` and
`gh run watch <run-id> --repo OWNER/REPO --exit-status`. After `PyPI Release`
succeeds, verify that PyPI exposes the exact version with both the expected
wheel and source distribution. After `Deploy Documentation` succeeds, verify
that the published site serves `X.Y.Z` and that `stable` resolves to it. A green
PyPI job with a failed documentation job is a half-finished release: report both
workflow URLs and both outcomes.
Look up each run by workflow and tag rather than selecting from an unfiltered
recent-run list:
```bash
gh run list --repo OWNER/REPO --workflow pypi-release.yml \
--branch vX.Y.Z --event push --limit 1
gh run list --repo OWNER/REPO --workflow docs.yml \
--branch vX.Y.Z --event push --limit 1
```
Confirm both runs have the expected tag commit, then follow them to a terminal
result with `gh run watch <run-id> --repo OWNER/REPO --exit-status`. After
`PyPI Release` succeeds, verify that PyPI exposes the exact version with both
the expected wheel and source distribution. After `Deploy Documentation`
succeeds, verify that the published site serves `X.Y.Z` and that `stable`
resolves to it. A green PyPI job with a failed documentation job is a
half-finished release: report both workflow URLs and both outcomes.
For a transient workflow failure, rerun only with authorization. For a source
or workflow defect, do not move the public tag; prepare a corrective release