From 630c60f852e11e6441b8e43b1a13baaece77c0d8 Mon Sep 17 00:00:00 2001 From: Colby McHenry Date: Thu, 21 May 2026 15:57:12 -0500 Subject: [PATCH] chore: remove obsolete manual-publish paths (release.sh, /publish skill) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .claude/skills/add-lang/SKILL.md | 8 +- .claude/skills/publish/SKILL.md | 136 ------------------------------- CLAUDE.md | 17 +++- scripts/release.sh | 68 ---------------- 4 files changed, 17 insertions(+), 212 deletions(-) delete mode 100644 .claude/skills/publish/SKILL.md delete mode 100755 scripts/release.sh diff --git a/.claude/skills/add-lang/SKILL.md b/.claude/skills/add-lang/SKILL.md index 0e107a3..37cbdce 100644 --- a/.claude/skills/add-lang/SKILL.md +++ b/.claude/skills/add-lang/SKILL.md @@ -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 **** (`.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`), diff --git a/.claude/skills/publish/SKILL.md b/.claude/skills/publish/SKILL.md deleted file mode 100644 index 84c6d4b..0000000 --- a/.claude/skills/publish/SKILL.md +++ /dev/null @@ -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 # " " -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 ` or `git diff "${LAST}..HEAD" -- `). 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 6–9 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. diff --git a/CLAUDE.md b/CLAUDE.md index 3603c94..d5222f3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 ()" 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 diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 9edf846..0000000 --- a/scripts/release.sh +++ /dev/null @@ -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 `
` 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}"