ship-release-skill 0.0.0-stage → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "ship-release",
3
+ "owner": { "name": "joezhuo2" },
4
+ "plugins": [
5
+ {
6
+ "name": "ship-release",
7
+ "source": "./",
8
+ "description": "Ships a release end to end: bump manifests, changelog, README badges, tag, GitHub release, npm publish and check."
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "ship-release",
3
+ "version": "0.1.2",
4
+ "description": "Ships a release end to end: bump manifests, changelog, README badges, tag, GitHub release, npm publish and check.",
5
+ "author": { "name": "joezhuo2" },
6
+ "repository": "https://github.com/joezhuo2/ship-release-skill",
7
+ "license": "MIT"
8
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 joezhuo2
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,109 @@
1
- # Temporary Holding Version
1
+ <h1 align="center">ship-release</h1>
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <p align="center">
4
+ <a href="https://www.npmjs.com/package/ship-release-skill"><img src="https://img.shields.io/npm/v/ship-release-skill?logo=npm&color=orange" alt="npm version"></a>
5
+ <a href="https://www.npmjs.com/package/ship-release-skill"><img src="https://img.shields.io/npm/dt/ship-release-skill?logo=npm&color=blue" alt="npm downloads"></a>
6
+ <img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey" alt="platform: Windows | macOS | Linux">
7
+ <a href="https://code.claude.com/docs/en/plugins"><img src="https://img.shields.io/badge/Claude%20Code-plugin-D97757?logo=claude&logoColor=white" alt="Claude Code plugin"></a>
8
+ <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-18%2B-5FA04E?logo=nodedotjs&logoColor=white" alt="Node 18+"></a>
9
+ <a href="LICENSE"><img src="https://img.shields.io/github/license/joezhuo2/ship-release-skill?color=green" alt="license"></a>
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="#install">Install</a> •
14
+ <a href="#what-it-does">What it does</a> •
15
+ <a href="#usage">Usage</a> •
16
+ <a href="#files">Files</a> •
17
+ <a href="#development">Development</a> •
18
+ <a href="#license">License</a>
19
+ </p>
20
+
21
+ > ship-release is a Claude Code skill that ships a release of the project you
22
+ > are in, the same way every time: bump every version manifest, write the
23
+ > changelog, fix README badges, commit, tag, create the GitHub release, then
24
+ > publish to npm and check the registry.
25
+
26
+ ## Install
27
+
28
+ Pick one. All of them install the same plugin.
29
+
30
+ - **npx:** nothing stays installed besides the plugin.
31
+
32
+ ```bash
33
+ npx ship-release-skill
34
+ ```
35
+
36
+ - **npm, global:** installs the `ship-release-skill` command, which you then run once.
37
+
38
+ ```bash
39
+ npm i -g ship-release-skill
40
+ ```
41
+
42
+ ```bash
43
+ ship-release-skill
44
+ ```
45
+
46
+ - **Claude Code plugin marketplace:** run these inside Claude Code.
47
+
48
+ ```
49
+ /plugin marketplace add joezhuo2/ship-release-skill
50
+ /plugin install ship-release@ship-release
51
+ ```
52
+
53
+ Restart Claude Code afterwards. The skill needs `git` and the
54
+ [GitHub CLI](https://cli.github.com) (`gh`), and `npm` for npm packages.
55
+
56
+ ## What it does
57
+
58
+ | Step | What happens |
59
+ |------|--------------|
60
+ | Pick the version | Uses the one you gave, or proposes patch / minor / major from the commits since the last tag. |
61
+ | Preflight | Clean tree, default branch or a release branch, up to date, tag is free, `gh` and `npm` logged in, version not on npm, tests pass. |
62
+ | Bump manifests | Greps the old version and bumps `package.json`, lockfile, `.claude-plugin/plugin.json`, `marketplace.json`, `pyproject.toml`, `Cargo.toml` and version constants. |
63
+ | Changelog | Adds a dated section in the file's own format, written from the commits. |
64
+ | README | Updates hardcoded version badges and pinned install lines; leaves dynamic badges alone. |
65
+ | Confirm | Shows the version, files and changelog section, and asks once before anything goes public. |
66
+ | Commit, land, tag | Release commit in the repo's style, pushed directly or through a pull request, then an annotated tag. Never `--force`. |
67
+ | Pull request route | On a branch, in a worktree or with a protected default branch: pre-PR check, open the PR, fix conflicts, wait for checks, merge, then remove the worktree and branch. |
68
+ | GitHub release | Waits for a tag-triggered release workflow if the repo has one, otherwise `gh release create` with the changelog section. |
69
+ | npm | Publishes unless a workflow does or the package is private, then checks the registry shows the new version. |
70
+ | Report | Version, tag, release URL, npm URL, and anything skipped or failed. |
71
+
72
+ After a push it only fixes forward: no moved tags, no force-push, no `npm unpublish`.
73
+
74
+ ## Usage
75
+
76
+ Ask in plain words, in the project you want to release:
77
+
78
+ ```
79
+ ship a patch release
80
+ ```
81
+
82
+ ```
83
+ release v0.3.0
84
+ ```
85
+
86
+ Or call the skill directly:
87
+
88
+ ```
89
+ /ship-release:ship-release minor
90
+ ```
91
+
92
+ ## Files
93
+
94
+ | Path | Purpose |
95
+ |------|---------|
96
+ | `skills/ship-release/SKILL.md` | The release procedure Claude follows. |
97
+ | `.claude-plugin/` | Plugin manifest and marketplace entry. |
98
+ | `bin/install.js` | The `npx ship-release-skill` installer. |
99
+ | `test.js` | Self-test: versions agree and the skill is well formed. |
100
+
101
+ ## Development
102
+
103
+ ```bash
104
+ npm test
105
+ ```
106
+
107
+ ## License
108
+
109
+ [MIT](LICENSE)
package/bin/install.js ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ const { execSync } = require('child_process');
3
+
4
+ for (const cmd of [
5
+ 'claude plugin marketplace add joezhuo2/ship-release-skill',
6
+ 'claude plugin install ship-release@ship-release',
7
+ ]) {
8
+ console.log(`> ${cmd}`);
9
+ try {
10
+ execSync(cmd, { stdio: 'inherit' });
11
+ } catch {
12
+ console.error(`Failed: ${cmd}. Is the Claude Code CLI installed and on PATH?`);
13
+ process.exit(1);
14
+ }
15
+ }
16
+ console.log('ship-release is installed. Restart Claude Code, then ask Claude to "ship a release".');
package/package.json CHANGED
@@ -1,6 +1,28 @@
1
1
  {
2
2
  "name": "ship-release-skill",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.2",
4
+ "description": "Claude Code skill that ships a release: bump manifests, changelog, README badges, tag, GitHub release, npm publish and check.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/joezhuo2/ship-release-skill.git"
9
+ },
10
+ "bin": {
11
+ "ship-release-skill": "bin/install.js"
12
+ },
13
+ "files": [
14
+ "bin",
15
+ "skills",
16
+ ".claude-plugin"
17
+ ],
18
+ "scripts": {
19
+ "test": "node test.js"
20
+ },
21
+ "keywords": [
22
+ "claude",
23
+ "claude-code",
24
+ "claude-plugin",
25
+ "skill",
26
+ "release"
27
+ ]
28
+ }
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: ship-release
3
+ description: Use when the user asks to release, ship, publish, cut or tag a version of a project ("release v0.2.0", "ship a patch", "bump and publish"). Bumps every version manifest, updates CHANGELOG and README badges, commits, lands it directly or through a pull request (pre-PR check, conflict fixes, merge, worktree cleanup), tags, creates the GitHub release, and publishes to or verifies npm.
4
+ argument-hint: "[version | patch | minor | major]"
5
+ ---
6
+
7
+ # ship-release
8
+
9
+ Release the current project end to end. Requested version or bump: $ARGUMENTS
10
+
11
+ Run the steps in order. Stop and report as soon as a step fails; never skip ahead.
12
+
13
+ ## 1. Pick the version
14
+
15
+ - Last release: `git describe --tags --abbrev=0` (no tag yet means this is the first release; use the manifest version).
16
+ - If the user gave a version or `patch` / `minor` / `major`, use it.
17
+ - Otherwise propose one from `git log <last-tag>..HEAD --oneline`: breaking change is major (minor while on 0.x), new feature is minor, anything else is patch. Ask once.
18
+ - Keep the repo's tag style (`v1.2.3` or `1.2.3`), taken from the existing tags. Default `v`.
19
+
20
+ ## 2. Preflight
21
+
22
+ All of these must pass before any file changes:
23
+
24
+ - `git status --porcelain` is clean, or holds only changes meant for this release. Ask about anything else.
25
+ - After `git fetch`, you are on the default branch and not behind its upstream. On any other branch, or in a linked worktree (`git worktree list`), the release goes through the PR route in step 7.
26
+ - The tag does not exist: `git tag -l <tag>` and `git ls-remote --tags origin <tag>` are both empty.
27
+ - `gh auth status` succeeds.
28
+ - If `package.json` exists and is not `"private": true`: `npm whoami` succeeds and `npm view <name>@<version> version` finds nothing.
29
+ - The project's tests pass (`npm test`, or whatever the README or CI uses).
30
+
31
+ ## 3. Bump every manifest
32
+
33
+ Find every place the old version lives:
34
+
35
+ ```bash
36
+ git grep -nF "<old-version>" -- . ':!CHANGELOG.md' ':!*lock*'
37
+ ```
38
+
39
+ Usual places:
40
+
41
+ | File | How |
42
+ |------|-----|
43
+ | `package.json`, `package-lock.json` | `npm version <new> --no-git-tag-version` |
44
+ | `.claude-plugin/plugin.json` | `version` |
45
+ | `.claude-plugin/marketplace.json` | `version` of each plugin entry, if present |
46
+ | `pyproject.toml`, `setup.py`, `__version__` | edit |
47
+ | `Cargo.toml` | edit, then `cargo check` to refresh `Cargo.lock` |
48
+ | `manifest.json`, version constants in source | edit |
49
+
50
+ Read each grep hit before changing it: bump the project's own version, not a dependency that happens to share the number. Run the grep again afterwards; every remaining hit needs a reason.
51
+
52
+ ## 4. Changelog
53
+
54
+ - Follow the format the file already uses. If there is no `CHANGELOG.md`, create one in Keep a Changelog format.
55
+ - Add `## [<new>] - <YYYY-MM-DD>` above the previous release, built from `git log <last-tag>..HEAD`.
56
+ - Group as Added / Changed / Fixed. Write what changed for the user, not commit subjects. Leave out version bumps and merge commits.
57
+ - If there is an `[Unreleased]` section, move its entries into the new section and leave the heading empty.
58
+ - Update the compare links at the bottom if the file has them.
59
+
60
+ ## 5. README
61
+
62
+ - Dynamic badges (`img.shields.io/npm/v/...`, `github/v/release/...`) update themselves. Leave them.
63
+ - Update hardcoded versions: static badges (`badge/version-1.2.3-...`), install lines pinned to `@1.2.3` or `#v1.2.3`, "current version" text.
64
+ - If the release adds a command, option or install step the README does not mention, add it.
65
+
66
+ ## 6. Check, then confirm
67
+
68
+ - Run the tests again.
69
+ - npm package: `npm pack --dry-run` and read the file list. No secrets, no missing files.
70
+ - `git diff --stat` and read the diff for secrets (tokens, `.env`, keys).
71
+ - Show the user the version, the changed files and the new changelog section. Ask once before step 7, unless they already told you to release without asking. Everything after this point is public and cannot be undone.
72
+
73
+ ## 7. Commit, land, tag
74
+
75
+ Stage only the release files. Use the message style of earlier release commits (`git log --oneline -20`); default `Release v<new>`.
76
+
77
+ Pick one route to get the commit onto the default branch:
78
+
79
+ - **Direct:** you are on the default branch, it is not protected and the repo does not release through PRs. `git push origin <branch>`.
80
+ - **PR:** anything else. Follow the PR route below.
81
+
82
+ Then tag the commit that is on the default branch: `git tag -a <tag> -m "<tag>"` and `git push origin <tag>`. Never `--tags`, never `--force`.
83
+
84
+ ### PR route
85
+
86
+ 1. **Branch.** If you are on the default branch, `git switch -c release/v<new>` before committing. Otherwise keep the branch you are on.
87
+ 2. **Pre-PR check.** All must pass before the push:
88
+ - `git fetch origin`, then `git merge origin/<default>`. Resolve conflicts as in step 4 below.
89
+ - `git diff origin/<default>...HEAD --stat` lists only files meant for this release. Read the diff for secrets and leftover debug code.
90
+ - The tests pass on the merged result.
91
+ - `gh pr list --head <branch>` shows no open PR for this branch. If one exists, reuse it.
92
+ 3. **Open the PR.** `git push -u origin <branch>`, then `gh pr create --base <default> --title "Release v<new>" --body-file <file>` with the new changelog section as the body.
93
+ 4. **Fix conflicts.** `gh pr view --json mergeable,mergeStateStatus`. If it reports `CONFLICTING`:
94
+ - `git fetch origin && git merge origin/<default>`. Never rebase or force-push a pushed branch.
95
+ - Version manifests take the new version. In the changelog, keep the entries from both sides, the new section on top.
96
+ - In code, keep the intent of both sides. If you cannot tell what the other side meant, stop and ask.
97
+ - Run the tests, commit the merge, push.
98
+ 5. **Checks.** `gh pr checks --watch`. If one fails, read `gh run view --log-failed`, fix, push, and watch again.
99
+ 6. **Merge.** Use the method earlier PRs used (`gh pr list --state merged --limit 5 --json mergeCommit,title`); default `gh pr merge --squash --delete-branch`. In a linked worktree leave out `--delete-branch` and run `git push origin --delete <branch>` afterwards. If a review is required, stop and ask the user for it. Never `--admin`.
100
+ 7. **Sync.** In the main checkout: `git switch <default>` and `git pull --ff-only`. This is the commit to tag.
101
+ 8. **Delete the worktree, if the branch lived in one.** From the main checkout:
102
+ - `git worktree remove <path>`. No `--force`: if git refuses, show the user the files left in it and ask.
103
+ - `git branch -d <branch>`. After a squash merge git refuses; confirm `gh pr view <number> --json state` says `MERGED`, then use `-D`.
104
+ - `git worktree prune`.
105
+
106
+ ## 8. GitHub release
107
+
108
+ Read `.github/workflows/` first.
109
+
110
+ - A workflow that runs on tag push and creates the release: do not create one yourself. `gh run watch` it, then `gh release view <tag>`.
111
+ - Otherwise: write the new changelog section to a temp file and run `gh release create <tag> --title <tag> --notes-file <file> --verify-tag`. Add `--prerelease` for `-rc`, `-beta` or `-alpha` versions.
112
+
113
+ ## 9. npm
114
+
115
+ Skip if there is no `package.json` or it is private.
116
+
117
+ - A workflow that runs `npm publish`: wait for it instead of publishing yourself.
118
+ - Otherwise `npm publish` from the tagged commit. Add `--access public` for a scoped package's first publish and `--tag next` for prereleases.
119
+ - If npm asks for a one-time password or browser login, stop and ask the user to run `npm publish` themselves. Never ask for or type their password or token.
120
+ - Verify: `npm view <name>@<new> version` prints the version. The registry can lag; retry for up to a minute. Then check `npm view <name> dist-tags.latest`.
121
+
122
+ ## 10. Report
123
+
124
+ Give the version, the tag, the release URL, the npm URL, and anything skipped, failed or not verified.
125
+
126
+ ## When something goes wrong
127
+
128
+ - Before the push: fix it and amend freely.
129
+ - After the push: never move or delete a pushed tag, never force-push, never `npm unpublish`. Fix forward with a patch release.
130
+ - PR merged but not tagged: tag the merge commit on the default branch and carry on from there. Do not open a second PR.
131
+ - Tag pushed but `npm publish` failed: fix the cause and publish again from the tagged commit. Do not retag.
132
+ - Release workflow failed: read `gh run view --log-failed`, fix forward, and tell the user what state the tag, the release and the registry are in.