Skip to content

Commit 99a0bdc

Browse files
committed
docs: standardize release runbook and installable artifact flow
1 parent fb0569e commit 99a0bdc

6 files changed

Lines changed: 350 additions & 89 deletions

File tree

.claude/commands/release.md

Lines changed: 219 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,234 @@
1-
description: Cut a release — verify, bump version, push, publish a GitHub release, and validate the install/update path
2-
argument-hint: "[patch|minor|major|X.Y.Z] [no-deploy]"
3-
allowed-tools: Bash, Read, Edit, Write
1+
description: Cut a production-ready release with a minimal cross-platform install package
2+
argument-hint: "[patch|minor|major|X.Y.Z]"
3+
allowed-tools: Bash, PowerShell, Read, Edit, Write
44
---
55

6-
You are running the **full git-auto-sync release flow**. Follow the phases in order.
7-
Treat every verification as a gate: if a step fails, **STOP and report** — do not tag, push, or publish the release.
6+
You are running the **git-auto-sync release runbook**. Execute these phases in order.
7+
Treat any failing check as a hard stop. Do not tag, push, or publish a release until every
8+
required gate passes.
89

910
Arguments: `$ARGUMENTS`
10-
- First token = the bump: `patch` (default), `minor`, `major`, or an explicit `X.Y.Z`.
11-
- If `no-deploy` appears anywhere, skip the optional deployment verification phase.
11+
- First token = `patch` (default), `minor`, `major`, or explicit `X.Y.Z`.
1212

13-
## Phase 0 — Preflight (abort on any problem)
13+
## Phase 0 — Preflight
1414

15-
1. Confirm the branch is `main` and the working tree is clean except for changes you are about to make.
16-
2. `git fetch --tags origin` to ensure release tags are present locally.
17-
3. Run the verification gate and require all green:
18-
- `uv run pytest -q`
19-
- `uv run ruff check .`
20-
- `uv run ruff format --check git_auto_sync/ tests/`
15+
1. Confirm branch state and remote:
16+
17+
```bash
18+
git remote -v
19+
git branch --show-current
20+
git status --short
21+
git fetch --all --prune
22+
git pull --ff-only origin main
23+
```
24+
25+
2. Make sure required release tooling is available:
26+
27+
```bash
28+
command -v gh >/dev/null || { echo "Install gh first"; exit 1; }
29+
command -v uv >/dev/null || { echo "Install uv first"; exit 1; }
30+
command -v tar >/dev/null || { echo "Install tar first"; exit 1; }
31+
```
32+
33+
3. Fetch tags and run verification gates:
34+
35+
```bash
36+
git fetch --tags origin
37+
uv run pytest -q
38+
uv run ruff check .
39+
uv run ruff format --check git_auto_sync/ tests/
40+
```
41+
42+
4. Verify release payload files exist:
43+
44+
```bash
45+
test -f install.sh
46+
test -f install.ps1
47+
test -f pyproject.toml
48+
test -f git_auto_sync/__init__.py
49+
test -f uv.lock
50+
```
2151

2252
## Phase 1 — Version bump
2353

24-
1. Read current `version` from `pyproject.toml`.
25-
2. Compute new version from bump argument (default `patch`).
26-
3. Update `pyproject.toml` and refresh lockfile:
27-
- `uv sync`
28-
4. Commit exactly version files:
29-
```bash
30-
git add pyproject.toml uv.lock
31-
git commit -m "chore: bump version to X.Y.Z"
32-
```
33-
34-
## Phase 2 — Push
35-
36-
`git push origin main`.
37-
38-
## Phase 3 — GitHub release
39-
40-
1. Resolve previous tag: `git describe --tags --abbrev=0 HEAD^` (after fetching tags).
41-
2. Draft release notes from `git log <prevtag>..HEAD --no-merges` in repo style:
42-
- Title: `vX.Y.Z — <short summary>`
43-
- A short lead, then `## Fixed` / `## Changed` / `## Added` sections as warranted.
44-
- Install one-liner:
45-
`curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash`
46-
- `**Full Changelog**: https://github.com/OctopusGarage/git-auto-sync/compare/<prevtag>...vX.Y.Z`
47-
3. Create release:
48-
```bash
49-
gh release create vX.Y.Z --target main --title "vX.Y.Z — ..." --notes-file - <<'EOF'
50-
...
51-
EOF
52-
```
53-
4. Verify:
54-
- `gh release list -L 3` shows `vX.Y.Z` as **Latest**
55-
- `git ls-remote --tags origin vX.Y.Z` resolves
56-
57-
## Phase 4 — Self-consistency check
58-
59-
Because install/update pull the latest release tarball, confirm the new tag's tarball includes the built code:
54+
1. Read current versions:
55+
56+
```bash
57+
grep -n '^version' pyproject.toml
58+
grep -n '^__version__' git_auto_sync/__init__.py
59+
```
60+
61+
2. Set new version (`vX.Y.Z`, patch by default):
62+
63+
```bash
64+
VERSION="vX.Y.Z"
65+
```
66+
67+
3. Bump files and refresh lockfile:
68+
69+
```bash
70+
sed -i "s/^version = \".*\"/version = \"${VERSION#v}\"/" pyproject.toml
71+
sed -i "s/^__version__ = \".*\"/__version__ = \"${VERSION#v}\"/" git_auto_sync/__init__.py
72+
uv sync
73+
```
74+
75+
4. Commit the bump:
76+
77+
```bash
78+
git add pyproject.toml git_auto_sync/__init__.py uv.lock
79+
git commit -m "chore: bump version to ${VERSION}"
80+
```
81+
82+
## Phase 2 — Build a minimal release package
83+
84+
Build a distributable that excludes repository internals not needed by users.
85+
The package must contain runtime source + launch scripts only.
86+
87+
```bash
88+
VERSION="vX.Y.Z"
89+
PACKAGE_NAME="git-auto-sync-${VERSION}-release.tar.gz"
90+
PACKAGE_DIR="dist/tmp/git-auto-sync-${VERSION}"
91+
RELEASE_FILES=(
92+
git_auto_sync
93+
README.md
94+
config.example.toml
95+
install.sh
96+
install.ps1
97+
pyproject.toml
98+
uv.lock
99+
)
100+
101+
mkdir -p "$PACKAGE_DIR"
102+
for item in "${RELEASE_FILES[@]}"; do
103+
test -e "$item" || { echo "Missing $item"; exit 1; }
104+
cp -R "$item" "$PACKAGE_DIR/"
105+
done
106+
107+
cp -f .claude/commands/release.md "$PACKAGE_DIR/"
108+
109+
mkdir -p dist
110+
tar -czf "dist/${PACKAGE_NAME}" -C dist/tmp "git-auto-sync-${VERSION}"
111+
sha256sum "dist/${PACKAGE_NAME}" | tee "dist/${PACKAGE_NAME}.sha256sum"
112+
ls -lh "dist/${PACKAGE_NAME}" "dist/${PACKAGE_NAME}.sha256sum"
113+
114+
rm -rf dist/tmp
115+
```
116+
117+
## Phase 3 — GitHub release and asset upload
118+
119+
1. Draft release notes:
120+
121+
```bash
122+
PREV_TAG="$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-list --max-parents=0 HEAD)"
123+
cat <<'EOF' > /tmp/release-notes.md
124+
## What's Changed
125+
126+
## Added
127+
- ...
128+
129+
## Changed
130+
- ...
131+
132+
## Fixed
133+
- ...
134+
135+
**Full Changelog**
136+
https://github.com/OctopusGarage/git-auto-sync/compare/${PREV_TAG}...${VERSION}
137+
138+
**Install**
139+
curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash
140+
141+
**Install (Windows)**
142+
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.ps1 | iex"
143+
EOF
144+
```
145+
146+
2. Create release and attach package:
147+
148+
```bash
149+
gh release create "${VERSION}" --target main --title "${VERSION} — release notes" --notes-file /tmp/release-notes.md
150+
gh release upload "${VERSION}" "dist/${PACKAGE_NAME}" "dist/${PACKAGE_NAME}.sha256sum" --clobber
151+
```
152+
153+
3. Verify assets and tag:
154+
155+
```bash
156+
gh release view "${VERSION}" --json name,tagName,isLatest,publishedAt,url -q '{name, tag: .tagName, latest: .isLatest, publishedAt, url}'
157+
gh release view "${VERSION}" --json assets --jq ".assets[].name" | sort
158+
git ls-remote --tags origin "${VERSION}"
159+
```
160+
161+
## Phase 3.1 — Monitor CI for this tag
162+
163+
```bash
164+
RUN_ID="$(gh run list --workflow ci.yml --limit 1 --json databaseId --jq '.[0].databaseId')"
165+
gh run view "$RUN_ID" --json status,conclusion,workflowName,name,url -q '{workflow: .workflowName, name: .name, status: .status, conclusion: .conclusion, url: .url}'
166+
gh run watch "$RUN_ID"
167+
```
168+
169+
```powershell
170+
$runId = (gh run list --workflow ci.yml --limit 1 --json databaseId --jq "[0].databaseId")
171+
gh run view $runId --json status,conclusion,workflowName,name,url -q '{workflow: .workflowName, name: .name, status: .status, conclusion: .conclusion, url: .url}'
172+
gh run watch $runId
173+
```
174+
175+
If a failure is found, fix locally and rerun from the current failed phase only after pushing follow-up commits.
176+
177+
## Phase 4 — Validate installer and updater (all platforms)
178+
179+
### macOS / Linux
180+
60181
```bash
61-
TAG=$(git describe --tags --abbrev=0)
62-
url=$(curl -fsSLI -o /dev/null -w '%{url_effective}' "https://github.com/OctopusGarage/git-auto-sync/releases/latest")
63-
TAG="${url##*/}"
64-
curl -fsSL "https://github.com/OctopusGarage/git-auto-sync/archive/refs/tags/${TAG}.tar.gz" -o /tmp/git-auto-sync.tar.gz
65-
tar -tzf /tmp/git-auto-sync.tar.gz | rg "setup\.(sh|ps1)|pyproject.toml|git_auto_sync/cli.py"
182+
curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash
183+
git-auto-sync --help
184+
git-auto-sync --version
185+
git-auto-sync update --check
66186
```
67187

68-
## Phase 5 — Optional local validation (if not skipped)
188+
### Windows
189+
190+
```powershell
191+
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.ps1 | iex"
192+
git-auto-sync --help
193+
git-auto-sync --version
194+
git-auto-sync update --check
195+
```
196+
197+
## AI Release Operator Prompt (copy/paste)
198+
199+
```text
200+
You are a strict release operator for the git-auto-sync repository.
201+
Run this command sequence exactly:
202+
1) preflight checks on main
203+
2) version bump (`patch|minor|major|X.Y.Z`)
204+
3) minimal package build
205+
4) GitHub release creation and asset upload
206+
5) CI monitor
207+
6) macOS/Linux/Windows install+update verification
208+
Stop at the first failed command and report the command, output, and required fix.
209+
All outputs must be in English.
210+
Release argument is: `$ARGUMENTS`.
211+
```
69212

70-
Run installation/update smoke checks:
71-
1. `curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash`
72-
2. `git-auto-sync --help`
73-
3. `uv run git-auto-sync config check`
74-
4. `git-auto-sync update --check` expects to report up-to-date at new version.
213+
## AI Install Prompt (copy/paste)
214+
215+
```text
216+
I need a clean install on current machine.
217+
Use the latest release package and do not clone the full source.
218+
Run one of these:
219+
220+
macOS/Linux:
221+
curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash
222+
223+
Windows:
224+
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.ps1 | iex"
225+
```
75226

76-
## Report
227+
## Completion report
77228

78-
Summarize: new version, commit SHA, release URL, and verification results. If stopped early, identify the failing gate and required fix.
229+
Record:
230+
- New version and tag
231+
- Release URL
232+
- Asset names and checksums
233+
- Verification outputs
234+
- Blocking issues and fixes if stopped early

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,37 @@ Use the assistant command:
135135
- version bump (`pyproject.toml` + `uv.lock`)
136136
- release publish on GitHub
137137
- install/update validation
138+
- CI monitoring
139+
- dedicated release package format: `git-auto-sync-vX.Y.Z-release.tar.gz`
140+
141+
```bash
142+
# macOS / Linux
143+
cat .claude/commands/release.md
144+
145+
# Windows
146+
Get-Content .claude/commands/release.md
147+
```
148+
149+
Use this copy-paste prompt for AI-assisted release operations:
150+
151+
```text
152+
Run the full release flow in .claude/commands/release.md:
153+
preflight, version bump, minimal package build, publish + asset upload,
154+
and cross-platform validation.
155+
Stop immediately on first failure and report the blocked step plus fix.
156+
```
157+
158+
Copyable installation prompt for AI on any platform:
159+
160+
```text
161+
Install git-auto-sync using the latest release package and do not fetch the full source.
162+
163+
macOS / Linux:
164+
curl -fsSL https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.sh | bash
165+
166+
Windows:
167+
powershell -ExecutionPolicy ByPass -c "irm https://raw.githubusercontent.com/OctopusGarage/git-auto-sync/main/install.ps1 | iex"
168+
```
138169

139170
For manual release scripts, run the version bump and release flow in that file.
140171

0 commit comments

Comments
 (0)