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:
@@ -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`),
|
||||
|
||||
@@ -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 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.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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}"
|
||||
Reference in New Issue
Block a user