Skip to content

Commit 3ce4329

Browse files
add release skill
1 parent 4a9516a commit 3ce4329

1 file changed

Lines changed: 251 additions & 0 deletions

File tree

.claude/skills/release/SKILL.md

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
---
2+
name: release
3+
description: Prepare and execute a release to pub.dev. Bumps versions, validates changelogs, checks pub.dev status, and guides through the tiered publishing process.
4+
argument-hint: "<version>"
5+
disable-model-invocation: true
6+
allowed-tools: Bash, Read, Grep, Glob, WebFetch
7+
---
8+
9+
# Release to pub.dev
10+
11+
Prepare and execute a dart_node release. This is a multi-step process that publishes packages in tiers due to interdependencies.
12+
13+
## Arguments
14+
15+
`$ARGUMENTS` = version to release (e.g., `0.12.0-beta`, `1.0.0`)
16+
17+
If no version provided, show current versions and prompt for the target version.
18+
19+
## Step 1: Pre-flight checks
20+
21+
### 1.1 Verify clean state
22+
23+
```bash
24+
git status
25+
git branch --show-current
26+
```
27+
28+
- Must be on `main` branch (or create a release branch)
29+
- Working directory should be clean
30+
31+
### 1.2 Check current versions
32+
33+
```bash
34+
grep -h "^version:" packages/*/pubspec.yaml | head -20
35+
```
36+
37+
### 1.3 Validate all packages have configs
38+
39+
```bash
40+
dart run tools/prepare_publish.dart 2>&1 || true
41+
```
42+
43+
This shows any packages missing from `tools/lib/packages.dart`.
44+
45+
## Step 2: Switch dependencies to pub.dev versions
46+
47+
**CRITICAL**: Before publishing, all internal dependencies must point to pub.dev versions, NOT local paths!
48+
49+
Use `tools/switch_deps.dart` to switch:
50+
51+
```bash
52+
# Switch from local paths to pub.dev versioned dependencies
53+
dart run tools/switch_deps.dart release
54+
```
55+
56+
This converts:
57+
```yaml
58+
# FROM (local development):
59+
dart_node_core:
60+
path: ../dart_node_core
61+
62+
# TO (release):
63+
dart_node_core: ^0.11.0-beta
64+
```
65+
66+
To switch back to local for development:
67+
68+
```bash
69+
dart run tools/switch_deps.dart local
70+
```
71+
72+
**Note**: The CI workflow handles this automatically on the release branch.
73+
74+
## Step 3: Validate changelogs
75+
76+
Every publishable package must have a `## $ARGUMENTS` entry in its CHANGELOG.md.
77+
78+
**Publishable packages** (must have changelog entries):
79+
80+
| Tier | Package |
81+
|------|---------|
82+
| 1 | dart_logging |
83+
| 1 | dart_node_core |
84+
| 2 | reflux |
85+
| 2 | dart_node_express |
86+
| 2 | dart_node_ws |
87+
| 2 | dart_node_better_sqlite3 |
88+
| 2 | dart_node_mcp |
89+
| 3 | dart_node_react |
90+
| 3 | dart_node_react_native |
91+
92+
Check each changelog:
93+
94+
```bash
95+
VERSION="$ARGUMENTS"
96+
for pkg in dart_logging dart_node_core reflux dart_node_express dart_node_ws dart_node_better_sqlite3 dart_node_mcp dart_node_react dart_node_react_native; do
97+
if grep -q "^## $VERSION" "packages/$pkg/CHANGELOG.md" 2>/dev/null; then
98+
echo "$pkg"
99+
else
100+
echo "$pkg - missing ## $VERSION entry"
101+
fi
102+
done
103+
```
104+
105+
If any are missing, **stop and update the changelogs** before proceeding.
106+
107+
## Step 4: Validate READMEs
108+
109+
Each package should have a README.md. Quick sanity check:
110+
111+
```bash
112+
for pkg in dart_logging dart_node_core reflux dart_node_express dart_node_ws dart_node_better_sqlite3 dart_node_mcp dart_node_react dart_node_react_native; do
113+
if [[ -f "packages/$pkg/README.md" ]]; then
114+
LINES=$(wc -l < "packages/$pkg/README.md")
115+
echo "$pkg - $LINES lines"
116+
else
117+
echo "$pkg - missing README.md"
118+
fi
119+
done
120+
```
121+
122+
## Step 5: Check pub.dev status
123+
124+
Verify which versions are currently published:
125+
126+
```bash
127+
for pkg in dart_logging dart_node_core reflux dart_node_express dart_node_ws dart_node_better_sqlite3 dart_node_mcp dart_node_react dart_node_react_native; do
128+
LATEST=$(curl -s "https://pub.dev/api/packages/$pkg" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4)
129+
echo "$pkg: $LATEST"
130+
done
131+
```
132+
133+
## Step 6: Run tests
134+
135+
Before releasing, ensure all tests pass:
136+
137+
```bash
138+
./tools/test.sh
139+
```
140+
141+
Or run specific tiers:
142+
143+
```bash
144+
./tools/test.sh --tier 1
145+
./tools/test.sh --tier 2
146+
./tools/test.sh --tier 3
147+
```
148+
149+
## Step 7: Bump versions (dry run)
150+
151+
Preview what changes the prepare script will make:
152+
153+
```bash
154+
dart run tools/prepare_publish.dart $ARGUMENTS
155+
```
156+
157+
This updates:
158+
- `version:` in all pubspec.yaml files
159+
- Interdependencies to use `^$ARGUMENTS` (pub.dev versions)
160+
- Removes `publish_to: none`
161+
162+
**Do NOT commit these changes yet** - they are made on a release branch by CI.
163+
164+
## Step 8: Create release tag
165+
166+
The release is triggered by pushing a tag:
167+
168+
```bash
169+
git tag "Release/$ARGUMENTS"
170+
git push origin "Release/$ARGUMENTS"
171+
```
172+
173+
This triggers the **publish-tier1** workflow which:
174+
1. Creates a `release/$ARGUMENTS` branch
175+
2. Runs `prepare_publish.dart`
176+
3. Creates a PR to main
177+
4. Publishes dart_logging and dart_node_core
178+
179+
## Step 9: Tier 2 publishing
180+
181+
After tier 1 succeeds and packages are live on pub.dev (wait ~5 minutes for indexing):
182+
183+
```bash
184+
git tag "Release-Tier2/$ARGUMENTS"
185+
git push origin "Release-Tier2/$ARGUMENTS"
186+
```
187+
188+
Publishes: reflux, dart_node_express, dart_node_ws, dart_node_better_sqlite3, dart_node_mcp
189+
190+
## Step 10: Tier 3 publishing
191+
192+
After tier 2 succeeds:
193+
194+
```bash
195+
git tag "Release-Tier3/$ARGUMENTS"
196+
git push origin "Release-Tier3/$ARGUMENTS"
197+
```
198+
199+
Publishes: dart_node_react, dart_node_react_native
200+
201+
After tier 3 completes, it switches dependencies back to local and pushes to the release branch.
202+
203+
## Step 11: Merge the release PR
204+
205+
After all tiers complete successfully:
206+
207+
1. Go to the PR created by tier 1
208+
2. Verify all packages are published on pub.dev
209+
3. Merge the PR to main
210+
211+
## Verification
212+
213+
After release, verify all packages are available:
214+
215+
```bash
216+
VERSION="$ARGUMENTS"
217+
for pkg in dart_logging dart_node_core reflux dart_node_express dart_node_ws dart_node_better_sqlite3 dart_node_mcp dart_node_react dart_node_react_native; do
218+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "https://pub.dev/api/packages/$pkg/versions/$VERSION")
219+
if [[ "$HTTP_CODE" == "200" ]]; then
220+
echo "$pkg@$VERSION published"
221+
else
222+
echo "$pkg@$VERSION not found (HTTP $HTTP_CODE)"
223+
fi
224+
done
225+
```
226+
227+
## Troubleshooting
228+
229+
### Package already published
230+
If a package version already exists, the publish script skips it. This is safe.
231+
232+
### Dependency resolution fails
233+
Tier 2/3 packages depend on tier 1. Wait for tier 1 to be fully indexed on pub.dev before starting tier 2.
234+
235+
### Changelog validation fails
236+
Add the missing `## X.Y.Z` header to the package's CHANGELOG.md with release notes.
237+
238+
## Checklist summary
239+
240+
- [ ] On main branch, clean working directory
241+
- [ ] **No local path dependencies** (all point to pub.dev versions)
242+
- [ ] All changelogs have `## $ARGUMENTS` entries
243+
- [ ] All READMEs are present and up-to-date
244+
- [ ] All tests pass
245+
- [ ] `Release/$ARGUMENTS` tag pushed (triggers tier 1)
246+
- [ ] Tier 1 complete, packages live on pub.dev
247+
- [ ] `Release-Tier2/$ARGUMENTS` tag pushed
248+
- [ ] Tier 2 complete, packages live on pub.dev
249+
- [ ] `Release-Tier3/$ARGUMENTS` tag pushed
250+
- [ ] Tier 3 complete, packages live on pub.dev
251+
- [ ] Release PR merged to main

0 commit comments

Comments
 (0)