chore: remove obsolete manual-publish paths (release.sh, /publish skill)

Releases now go through .github/workflows/release.yml, which builds the bundles
and publishes the npm thin-installer. The old manual paths published the root
(non-bundled) package, which would break Node < 22.5 users — remove them so they
can't be run by accident. CLAUDE.md + add-lang updated to point at the workflow.
scripts/extract-release-notes.mjs is kept (the workflow uses it).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby McHenry
2026-05-21 15:57:12 -05:00
parent 6bc745b196
commit 630c60f852
4 changed files with 17 additions and 212 deletions
+4 -4
View File
@@ -189,8 +189,8 @@ Read each `parse-run.mjs` summary printed by `run-all.sh`: tool calls, file
- **CHANGELOG.md**: add an `## [Unreleased]` section at the top (above the
latest version) with `### Added` → a user-perspective bullet, e.g.
*"CodeGraph now indexes **<Lang>** (`.ext`) — functions, classes, imports, and
call edges."* If `## [Unreleased]` already exists, append under it. (`/publish`
folds this into the next versioned block at release time.)
call edges."* If `## [Unreleased]` already exists, append under it. (It's
folded into the next versioned block at release time.)
### Step 10 — Report (do NOT commit)
@@ -204,8 +204,8 @@ Summarize for review:
- **Gaps / follow-ups** (node types not yet mapped, resolution edges missing,
framework routes, etc.).
Hand the changes to the user. **Do not** run `git commit`/`push`,
`npm publish`, or `scripts/release.sh`.
Hand the changes to the user. **Do not** run `git commit`/`push` or publish —
releases go through the GitHub Actions Release workflow.
## Notes
- The A/B spawns real **paid** `claude -p` runs (opus, `--max-budget-usd`),
-136
View File
@@ -1,136 +0,0 @@
---
name: publish
description: Publishes a new minor or major release of this npm package (codegraph). Reads the latest version from npm, generates a user-perspective CHANGELOG entry from commits since the last tag, bumps package.json, publishes to npm, and creates the matching GitHub release. Use when the user runs /publish or asks to cut, ship, or publish a release / new version.
---
# Publish a release
Cut a **minor or major** release: generate the changelog, bump, publish to npm, and create the GitHub release. Patch releases are intentionally not offered here.
This skill performs the actual publish (npm publish, git push, GitHub release) — that is the whole point of invoking it, so the general "hand the user the commands" rule does **not** apply inside `/publish`. The **confirmation gate in Step 5 is the safeguard**: never run a step past it without explicit approval.
Run from the repo root.
## Workflow
Copy this checklist and work through it in order:
```
- [ ] 1. Preflight: branch, sync, auth
- [ ] 2. Read base version from npm, compute candidates
- [ ] 3. Ask the user: minor or major
- [ ] 4. Generate the CHANGELOG entry from commits since the last tag
- [ ] 5. CONFIRMATION GATE — show changelog + plan, get explicit approval
- [ ] 6. Write CHANGELOG.md, bump, build
- [ ] 7. Commit + push
- [ ] 8. npm publish
- [ ] 9. scripts/release.sh (GitHub release)
- [ ] 10. Verify on the npm registry
```
### Step 1 — Preflight
```bash
git rev-parse --abbrev-ref HEAD # expect: main
git fetch origin
git status --porcelain # working tree should be clean
git rev-list --left-right --count origin/main...HEAD # "<behind> <ahead>"
npm whoami # npm auth (publish will fail without it)
gh auth status # gh auth (release.sh needs it)
```
- If not on `main`, stop and ask the user to confirm releasing from this branch.
- If behind origin, `git pull --ff-only` so the final push is a fast-forward.
- If the tree has **unrelated** uncommitted changes, stop and ask — the release commit only stages 3 files, but a dirty tree usually means something's mid-flight.
- If `npm whoami` or `gh auth status` fails, stop and tell the user to authenticate.
### Step 2 — Base version + candidates
The latest **published** version is the source of truth, not local `package.json`.
```bash
PKG=$(node -p "require('./package.json').name")
BASE=$(npm view "$PKG" version)
node -e "const [a,b]=process.argv[1].split('.').map(Number);console.log('minor ->',a+'.'+(b+1)+'.0');console.log('major ->',(a+1)+'.0.0')" "$BASE"
```
Note if local `package.json` differs from `BASE` (an unpublished bump) — surface it, but still base the new version on npm.
### Step 3 — Ask minor or major
Use the **AskUserQuestion** tool with the two computed candidates as options (show the resulting version in each label, e.g. "minor → 0.8.0"). Set the new version from the answer.
### Step 4 — Generate the changelog entry
```bash
LAST=$(git describe --tags --abbrev=0 --match 'v*' 2>/dev/null)
git log --no-merges "${LAST}..HEAD" --pretty=format:'%h %s'
```
Read the commit subjects; for any whose user impact is unclear, inspect the diff (`git show <hash>` or `git diff "${LAST}..HEAD" -- <path>`). Then **write the entry yourself** following the repo's conventions in `CLAUDE.md` → "Writing changelog entries":
- Header: `## [X.Y.Z] - YYYY-MM-DD` (get the date with `date +%F`).
- Group under `### Added`, `### Changed`, `### Fixed`, `### Removed`, `### Deprecated`, `### Security`**omit empty sections**.
- Write from the **user's perspective** (observable capability/symptom), not the implementation. Collapse noisy commits ("fix typo", "address review") into the feature they belong to or drop them.
- Plan the bottom link reference: `[X.Y.Z]: https://github.com/colbymchenry/codegraph/releases/tag/vX.Y.Z`.
Do not write to any file yet — draft it for review first.
### Step 5 — CONFIRMATION GATE
Show the user, in chat:
1. The new version (`BASE``X.Y.Z`, minor/major).
2. The full drafted changelog entry.
3. The exact actions Steps 69 will take (commit + push + npm publish + GitHub release).
Then **STOP**. Proceed only on explicit approval ("yes" / "proceed"). If the user requests prose changes, revise the draft and re-show. Do not run any command below until approved.
### Step 6 — Write changelog, bump, build
1. Use the **Edit** tool to insert the drafted `## [X.Y.Z]` block at the **top** of `CHANGELOG.md` (under the intro, above the previous version), and add the link reference with the other `[x.y.z]:` links at the bottom.
2. Bump (also updates `package-lock.json`; `--allow-same-version` keeps re-runs safe):
```bash
npm version X.Y.Z --no-git-tag-version --allow-same-version
```
3. Build (fail fast before any push/publish):
```bash
npm run build
```
### Step 7 — Commit + push
`release.sh` tags HEAD, so the bump must be committed first.
```bash
git add package.json package-lock.json CHANGELOG.md
git commit -m "release: X.Y.Z"
git push
```
### Step 8 — Publish to npm
```bash
npm publish --access public
```
### Step 9 — GitHub release
`scripts/release.sh` reads the `## [X.Y.Z]` block from CHANGELOG.md, tags `vX.Y.Z`, pushes the tag, and creates the GitHub release. It is idempotent.
```bash
./scripts/release.sh
```
### Step 10 — Verify
Confirm against the **registry**, not the website (the website caches):
```bash
npm view "$PKG" version # must equal X.Y.Z
```
Report the release URL (`scripts/release.sh` prints it) and the published version.
## If something fails midway
Re-running is safe: `npm version --allow-same-version` no-ops if already bumped, `git commit` skips if nothing's staged (check `git diff --cached --quiet`), `git push` no-ops if up to date, and `scripts/release.sh` skips tag/release steps already done. Re-run from the failed step.
+13 -4
View File
@@ -116,19 +116,28 @@ When asked for an entry for a new version:
### Release flow (the user runs these)
Releases are built and published by the **GitHub Actions "Release" workflow**
(`.github/workflows/release.yml`). It bundles a Node runtime per platform
(`scripts/build-bundle.sh`) and publishes both the GitHub Release and the npm
thin-installer (`scripts/pack-npm.sh`: a shim package + per-platform packages).
Publishing manually is **wrong** now — a plain `npm publish` ships the root
package (non-bundled), which breaks anyone on Node < 22.5.
After the changelog entry is written and `package.json` is bumped:
```bash
git add package.json package-lock.json CHANGELOG.md
git commit -m "release: X.Y.Z (<one-line summary>)"
git push
npm publish
./scripts/release.sh # idempotent: tags vX.Y.Z, pushes, creates GitHub Release with notes from CHANGELOG.md
```
`scripts/release.sh` is safe to re-run after a partial failure — it skips steps already done (tag exists locally, tag on origin, release published). It extracts release notes from `CHANGELOG.md` by matching the `## [X.Y.Z]` block.
Then trigger **Actions → Release → Run workflow** (on `main`). It reads the
version from `package.json`, builds every platform bundle on one runner, creates
the GitHub Release with notes from the matching `CHANGELOG.md` section, and
publishes to npm. Requires the `NPM_TOKEN` repo secret.
**Do not run `npm publish`, `git push`, `git tag`, or `./scripts/release.sh` yourself** — these are publish actions on shared state. Write the file, hand the user the commands.
**Do not run `npm publish`, `git push`, or `git tag` yourself** — these are
publish actions on shared state. Write the files, hand the user the commands.
## House rules
-68
View File
@@ -1,68 +0,0 @@
#!/usr/bin/env bash
# Tag the current commit with the version in package.json and publish a
# matching GitHub Release whose body is the corresponding CHANGELOG.md entry.
#
# Run AFTER you have:
# - bumped package.json
# - added a `## [X.Y.Z] - YYYY-MM-DD` block at the top of CHANGELOG.md
# - committed, pushed to origin, and run `npm publish`
#
# Idempotent: safe to re-run after a partial failure. Skips steps that are
# already done (tag created, tag pushed, release published).
#
# Usage: ./scripts/release.sh
set -euo pipefail
cd "$(dirname "$0")/.."
VERSION=$(node -p "require('./package.json').version")
TAG="v${VERSION}"
REPO=$(git remote get-url origin | sed -E 's|.*github\.com[:/]||; s|\.git$||')
if [ -z "${REPO}" ]; then
echo "error: could not derive owner/repo from origin remote URL" >&2
exit 1
fi
if ! grep -q "^## \[${VERSION}\]" CHANGELOG.md; then
echo "error: no '## [${VERSION}]' entry found in CHANGELOG.md" >&2
exit 1
fi
# Extract notes with paragraph unwrapping — GitHub Releases render with
# GFM hard-breaks, so the CHANGELOG's hard-wrapped lines would show as
# visible `<br>` breaks otherwise. The helper joins continuation lines
# into a single line per bullet.
NOTES=$(node scripts/extract-release-notes.mjs "${VERSION}")
if [ -z "${NOTES}" ]; then
echo "error: failed to extract changelog notes for ${VERSION}" >&2
exit 1
fi
if git rev-parse "${TAG}" >/dev/null 2>&1; then
echo "✓ tag ${TAG} already exists locally"
else
echo "→ tagging ${TAG}"
git tag "${TAG}"
fi
if git ls-remote --exit-code --tags origin "${TAG}" >/dev/null 2>&1; then
echo "✓ tag ${TAG} already on origin"
else
echo "→ pushing ${TAG} to origin"
git push origin "${TAG}"
fi
if gh release view "${TAG}" --repo "${REPO}" >/dev/null 2>&1; then
echo "✓ release ${TAG} already published"
else
echo "→ creating GitHub Release ${TAG} on ${REPO}"
gh release create "${TAG}" \
--repo "${REPO}" \
--title "${TAG}" \
--notes "${NOTES}"
fi
echo "done: https://github.com/${REPO}/releases/tag/${TAG}"