Lh release
Prepare and publish a LeanHarness release end-to-end through the changesets/action pipeline. Use when the user invokes /lh-release or asks to release, deploy, or publish LeanHarness.From its SKILL.md
npx -y skills add fernandonetom/lean-harness --skill lh-releaseAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
8.4 KB, as published. Nobody here has run it
lh-release
Purpose
Prepare and publish a LeanHarness release end-to-end through the changesets/action pipeline.
This is a project-local skill (.claude/skills/lh-release/), not generated by the lh init pipeline. It is only for the LeanHarness repository itself.
Release Pipeline Overview
The release pipeline uses Changesets with the changesets/action@v1 GitHub Action:
Feature branch (with .changeset/*.md)
→ Push → CI runs
→ Create PR → CI on PR + changeset check
→ Merge PR (rebase) → CI on main
→ changesets/action creates "Version Packages" PR
→ CI on version PR
→ Merge version PR → auto-publish to npm + GitHub Release
Prerequisites
- Git repository with a
mainbranch changesetsconfigured in the projectghCLI authenticated and available (gh auth status)claudeCLI authenticated and available (required for plugin manifest validation:claude plugin validate,claude plugin tag,claude plugin marketplace add)- Clean working tree (no uncommitted changes)
NPM_TOKENconfigured in GitHub repository secrets
Steps
Step 1: Validate Environment
Run:
pnpm run build && pnpm run typecheck && pnpm run test
Then:
git status # must be clean
gh auth status # must be authenticated
Validate Claude Code plugin manifests (requires claude CLI installed and authenticated):
claude plugin validate hosts/claude-code --strict
node scripts/sync-plugin-version.mjs --check
claude plugin tag hosts/claude-code --dry-run
If any check fails, report the issue and do not proceed.
Step 2: Fetch Latest Main
git fetch origin main
Step 3: Analyze Commits Since Main
git log origin/main..HEAD --oneline
git diff --stat origin/main
Read packages/cli/CHANGELOG.md for current state and last release version.
Step 4: Determine Recommended Version
Based on commit analysis:
- patch (recommended) — bug fixes, patches, docs, internal refactors
- minor — new features, backward-compatible changes
- major — breaking changes, architectural changes
Look for: BREAKING CHANGE: → major, feat: → minor, fix:/chore:/docs: → patch.
Step 5: Ask User for Version
Present the analysis. Use AskUserQuestion tool:
{
"header": "Version bump",
"question": "Which version should this release be?",
"options": [
{ "label": "patch (Recommended)", "description": "Bug fixes, docs, internal changes" },
{ "label": "minor", "description": "New features, backward-compatible changes" },
{ "label": "major", "description": "Breaking API or architectural changes" }
]
}
Step 6: Run Changeset
pnpm run changeset
Follow the CLI prompts. If no changesets exist, inform the user and abort.
Step 7: Commit and Push
git add .changeset/
git commit -m "chore: add changeset"
git push origin HEAD
Step 8: Create Pull Request
gh pr create --base main --title "Release v<VERSION>" --body "$(generate_pr_body)"
Use the PR template at the bottom of this document.
Step 9: Wait for CI on PR
gh pr checks --watch
Required checks (from .github/workflows/ci.yml):
- Build & Test (Node 22 and 24)
- Changeset Check
Do NOT proceed with failing checks.
Step 10: Merge PR (Rebase)
gh pr merge --rebase --delete-branch
Always use --rebase — do NOT squash or merge-commit. Changeset files must remain in the commit graph.
Step 11: Wait for CI on Main
gh run list --branch main --limit 5
gh run watch <run-id>
Step 12: Monitor for Version Packages PR
After main CI passes, changesets/action@v1 (.github/workflows/release.yml) automatically creates/updates a "Version Packages" PR.
Monitor:
gh pr list --search "Version Packages" --state open
Step 13: Check Version Packages PR
gh pr view <version-pr-number>
Verify:
packages/cli/package.jsonversion bump is correct (fixed alongsidehosts/claude-code/package.json)packages/cli/CHANGELOG.mdentry is accuratehosts/claude-code/.claude-plugin/plugin.jsonversion matchespackages/cli/package.json(required for Claude Code plugin registry).claude-plugin/marketplace.jsonversion matchespackages/cli/package.json(required for Claude Code plugin registry)- Changeset files consumed (deleted from
.changeset/)
If plugin.json or marketplace.json were NOT bumped, investigate and abort: this indicates sync-plugin-version.mjs did not run as part of version-packages, a regression that must be fixed before merging.
Step 14: Wait for CI on Version PR
gh pr checks <version-pr-number> --watch
Step 15: Merge Version PR
gh pr merge <version-pr-number> --rebase --delete-branch
Merging triggers the changesets/action workflow on main (.github/workflows/release.yml), which:
- Publishes to npm via
NPM_TOKEN(viachangesets/action) - If publish succeeds (
steps.changesets.outputs.published == 'true'), the workflow's own explicit steps then:- Create two git tags:
v{version}andlh--v{version}(Claude Code plugin version-tag format) - Create a GitHub Release with changelog notes extracted by
scripts/extract-changelog-entry.mjs - Push both tags to origin
- Create two git tags:
If steps.changesets.outputs.published is false, nothing was published in that run and no tags/release are created (correct, expected behavior — this happens when there are no version changes).
Historical note on missing tags: Git tags for versions 1.0.0 through 1.5.2 do not exist in this repository's history. The root cause was a bug in the previous release workflow where tag/release creation never fired. These versions were successfully published to npm but have no corresponding git tags or GitHub Releases. For changelog and git describe continuity, consider backfilling a v1.5.2 tag against its actual merge commit using git tag -a v1.5.2 <commit-sha> && git push origin v1.5.2. Earlier versions (1.0.0–1.5.1) are not worth reconstructing.
Step 16: Verify Release
Run all four checks:
npm info @feneto/lh version
gh release list --limit 3
git ls-remote --tags origin | grep -E "v[0-9]|lh--v"
claude plugin marketplace add fernandonetom/lean-harness
Confirm:
- npm package version matches the released version
- GitHub Release is created with correct changelog notes
- Both
v{version}andlh--v{version}git tags exist on origin - Claude Code plugin marketplace resolves the plugin at the tagged commit
PR Template
## Release Summary
[Generated from changeset]
## Changes
[Bullet list of changes from changeset]
## Checklist
- [ ] Tests pass
- [ ] Typecheck passes
- [ ] Documentation updated (if applicable)
- [ ] CHANGELOG updated
If .github/PULL_REQUEST_TEMPLATE.md exists, use it and append release notes.
Error Handling
- No changesets generated: No version bump needed.
- Git conflicts: Re-fetch and rebase.
git fetch origin main && git rebase origin/main. - PR creation fails: Report error, provide manual PR link.
- gh not authenticated: Prompt user to
gh auth login. - CI fails: Do NOT proceed. Fix, amend, re-push.
- Version Packages PR not created: Check
NPM_TOKENsecret and GitHub Action permissions in.github/workflows/release.yml. - No git tag / GitHub Release appears after a publish: Check the workflow run's
steps.changesets.outputs.publishedvalue in the Actions log. If it isfalse, nothing was actually published in that run (correct, expected behavior — no changes detected). Only investigate further if it wastrueand the tag/release steps are missing from the log entirely.
Rules
- Do not proceed if working tree is not clean.
- Always run
pnpm run build && pnpm run typecheck && pnpm run testbefore creating a changeset. - Do not force-push during release.
- Preserve all changeset content exactly as generated.
- Never skip CI waiting steps.
- Always use
--rebasefor merges — squash and merge-commit destroy changeset files. - This is an internal LeanHarness project skill. It is NOT shipped to end users.