Skip to content

Commit 0cebd4f

Browse files
committed
Add release process
1 parent a9de77d commit 0cebd4f

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,128 @@ uv run python -m unittest discover -s tests
4848
- Keep module-level constants near the top of each module, after imports
4949
- Prefer specific package/module names over broad `helpers` or `utils` modules
5050

51+
## Release process
52+
53+
- The tagged source commit must already contain the package version it
54+
releases. Do not make the release workflow edit `pyproject.toml`.
55+
- The tag must be `vMAJOR.MINOR.PATCH`, and `.github/workflows/release.yml`
56+
verifies that it matches `project.version` before building GitHub release
57+
assets and publishing to PyPI.
58+
- Prepare releases on a branch from current `main`. Set `VERSION`, then run:
59+
60+
```sh
61+
set -euo pipefail
62+
63+
VERSION=0.1.1
64+
BRANCH="release-v${VERSION}"
65+
66+
git fetch origin --tags --prune
67+
git switch main
68+
git pull --ff-only
69+
git switch -c "${BRANCH}"
70+
71+
uv run python - "${VERSION}" <<'PY'
72+
from pathlib import Path
73+
import re
74+
import sys
75+
76+
version = sys.argv[1]
77+
path = Path("pyproject.toml")
78+
text = path.read_text()
79+
new_text = re.sub(
80+
r'(?m)^version = "[^"]+"$',
81+
f'version = "{version}"',
82+
text,
83+
count=1,
84+
)
85+
if new_text == text:
86+
raise SystemExit("pyproject.toml version was not updated")
87+
path.write_text(new_text)
88+
PY
89+
90+
uv lock
91+
```
92+
93+
- Validate before opening the PR:
94+
95+
```sh
96+
set -euo pipefail
97+
98+
uv lock --check
99+
npx --yes markdownlint-cli2
100+
uv run ruff check .
101+
uv run ruff format --check .
102+
uv run pyright
103+
uv run python -m unittest discover -s tests
104+
uv build --wheel --sdist --out-dir /tmp/src-py-lib-release-check --no-create-gitignore
105+
rm -rf /tmp/src-py-lib-release-check
106+
```
107+
108+
- Commit, push, open the PR, wait for checks, then merge it. If review is
109+
required, stop after `gh pr checks` and ask for review before merging.
110+
111+
```sh
112+
set -euo pipefail
113+
114+
VERSION=0.1.1
115+
BRANCH="release-v${VERSION}"
116+
GH_REPO="sourcegraph/src-py-lib"
117+
118+
git add pyproject.toml uv.lock
119+
git commit -m "Release v${VERSION}"
120+
git push -u origin "${BRANCH}"
121+
122+
gh pr create \
123+
--repo "${GH_REPO}" \
124+
--base main \
125+
--head "${BRANCH}" \
126+
--title "Release v${VERSION}" \
127+
--body "Bump src-py-lib package metadata to ${VERSION}."
128+
129+
gh pr checks "${BRANCH}" --repo "${GH_REPO}" --watch --fail-fast
130+
gh pr merge "${BRANCH}" --repo "${GH_REPO}" --squash --delete-branch
131+
```
132+
133+
- Tag the merged `main` commit. Do not tag a branch commit.
134+
135+
```sh
136+
set -euo pipefail
137+
138+
VERSION=0.1.1
139+
140+
git fetch origin --tags --prune
141+
git switch main
142+
git pull --ff-only
143+
git tag "v${VERSION}"
144+
git push origin "v${VERSION}"
145+
```
146+
147+
- Watch the release workflow and confirm the GitHub release and PyPI project.
148+
149+
```sh
150+
set -euo pipefail
151+
152+
VERSION=0.1.1
153+
GH_REPO="sourcegraph/src-py-lib"
154+
155+
RUN_ID="$(
156+
gh run list \
157+
--repo "${GH_REPO}" \
158+
--workflow release.yml \
159+
--branch "v${VERSION}" \
160+
--limit 1 \
161+
--json databaseId \
162+
--jq '.[0].databaseId // empty'
163+
)"
164+
test -n "${RUN_ID}"
165+
gh run watch "${RUN_ID}" --repo "${GH_REPO}" --exit-status
166+
gh release view "v${VERSION}" --repo "${GH_REPO}"
167+
uvx --from pip pip index versions src-py-lib
168+
```
169+
170+
- If a pushed tag points at the wrong commit, move it only after explicit
171+
human approval.
172+
51173
## Before finishing changes
52174

53175
- Re-read edited files for organization and stale comments

0 commit comments

Comments
 (0)