22name : release
33description : >
44 Ships a TablePro release end to end: bumps Configs/Version.xcconfig, finalizes CHANGELOG.md,
5- commits, tags, pushes, releases plugins, and then, when the release is big enough to be worth
6- announcing, writes the blog post, the newsletter and the X posts that point at it. Use whenever the
7- user says "release", "bump version", "ship version", "tag a release", "cut a release", gives a
8- version number ("/release 0.67.0", "/release plugin-oracle 1.0.0"), or asks for the announcement
9- that goes with one: "newsletter for 0.67", "blog post for the release", "announce 0.67", "write the
10- X thread".
5+ commits, tags, pushes and releases plugins. Use whenever the user says "release", "bump version",
6+ "ship version", "tag a release", "cut a release", or gives a version number ("/release 0.67.0",
7+ "/release plugin-oracle 1.0.0"). Not for the blog post, newsletter or X posts: those are the
8+ announce skill in TableProApp/web.
119---
1210
1311# Release
@@ -21,26 +19,15 @@ description: >
2119- Once a release run is past ** Publish the release** , only ** Re-run failed jobs**
2220 (` RELEASING.md ` , When a release run fails).
2321
24- Run the stages in order, starting one only when the one before it is real: 1 decide the shape, 2
25- release (always), 3 plugins (when they changed), 4 to 6 blog post, newsletter and X posts (big
26- only). A normal release stops after stage 3; the changelog and docs changelog are its announcement.
27- A big release's newsletter and X posts come from the finished post, so the three cannot disagree.
22+ Run the stages in order, starting one only when the one before it is real: 1 release (always), 2
23+ plugins (when they changed). Announcing it is the ` announce ` skill in TableProApp/web
24+ (` ../tablepro-web ` ).
2825
2926House rules relied on, not repeated: ` .claude/rules/changelog.md ` , ` .claude/rules/plugin-system.md ` ,
3027the commit format in the top comment of ` .github/pull_request_template.md ` , and ` RELEASING.md ` for
3128the pipeline.
3229
33- ## Stage 1: Decide the shape
34-
35- The release is ** big** when ` ### Added ` has something a reader would change their behavior over (a
36- new pane or mode, a new way to connect, a new database, a rebuilt surface they will not recognize),
37- when something people rely on was removed or changed under them, or when a long-standing class of
38- bugs users have asked about is gone. Otherwise it is ** normal** : fixes, small changes, plugin work.
39- The entry count per section is a sanity check, not the rule. Say which shape you picked and why
40- before any work, and ask when it is borderline: an unwanted newsletter costs an hour, a skipped one
41- costs a launch.
42-
43- ## Stage 2: Release
30+ ## Stage 1: Release
4431
4532### Pre-flight
4633
@@ -52,7 +39,7 @@ Check each. If one fails, stop and say what is wrong.
5239 release. ` [Unreleased] ` has entries; if not, say the release has no notes.
53403 . ` swiftlint lint --strict ` is clean: the tag's checks do not cover SwiftLint. Fix findings
5441 through their own pull request.
55- 4 . If ` Plugins/TableProPluginKit/ ` changed since the last tag, do Stage 3 , PluginKit, now, before
42+ 4 . If ` Plugins/TableProPluginKit/ ` changed since the last tag, do Stage 2 , PluginKit, now, before
5643 the tag.
57445 . ` scripts/export-cloudkit-schema.sh --check ` passes; it needs the cktool management token on this
5845 Mac. A field in the snapshot but not in Production makes CloudKit reject every record carrying
@@ -233,7 +220,7 @@ Only when a build loses data, fails to launch or breaks connecting, and the fix
233220minutes away. Commands and effects: ` RELEASING.md ` , Withdrawing a release; the user runs its push.
234221Users already on the build are reached by the corrective release with ` criticalUpdate ` set.
235222
236- ## Stage 3 : Plugins
223+ ## Stage 2 : Plugins
237224
238225After the app tag is pushed, list the registry plugins with commits since their last tag:
239226
@@ -272,28 +259,3 @@ before publishing anything, and act on the diff as `.claude/rules/plugin-system.
272259` scripts/release-all-plugins.sh ` runs for a breaking bump only: each run uses a registry retention
273260slot for every plugin. One driver fix reaches users who have not updated through
274261` scripts/release-plugin-for-shipped-app.sh plugin-<slug>-v<version> v<appVersion> ` .
275-
276- ## Stages 4 to 6: Announce (big only)
277-
278- 1 . ** Blog post** , by ` references/blog-post.md ` : one file in ` resources/blog/ ` of the marketing site
279- repo (` ../tablepro-web ` by default; confirm the path). It goes live first, because the
280- newsletter and the X posts link to it. Once live, link it from the version's ` <Update> ` block in
281- the docs ` changelog.mdx ` with ` [Read the announcement](https://tablepro.app/blog/<slug>) ` on its
282- own line before the first ` ### ` , pushed as ` docs(changelog): link the <version> announcement ` .
283- 2 . ** Newsletter** , by ` references/newsletter.md ` : 150 to 250 words that name the headline items and
284- link the post.
285- 3 . ** X posts** , by ` references/newsletter.md ` : four to six posts plus one standalone, written from
286- the finished post and newsletter.
287-
288- Lint each draft, then work ` references/fact-checks.md ` top to bottom. Its closing blocker list
289- gates all three; report blockers apart from the drafts.
290-
291- ``` bash
292- python3 .claude/skills/release/scripts/lint-draft.py --blog < web repo> /resources/blog/< slug> .md
293- python3 .claude/skills/release/scripts/lint-draft.py < newsletter-or-x-draft.md>
294- ```
295-
296- Newsletter and X drafts go in the session scratchpad, named by version (` newsletter-v0.77.0.md ` ,
297- ` x-posts-v0.77.0.md ` ). Sending is out of scope. If the user asks to send the newsletter, warn them
298- first: in the license backend ` all ` means verified subscribers only, a small fraction of the list,
299- and ` everyone ` is the real list.
0 commit comments