Build and release
Skill ats4321/claude-engineering-skills/skills/build-and-release
Build systems, packaging, and release discipline for any repo. Load when building, packaging, publishing, or deploying; when discovering how a repo builds (npm/pnpm scripts, pyproject, Makefile, cargo); when working with entry points and editable installs; when publishing multi-package or aliased npm artifacts and coordinating dist-tags; when deployment shape (static vs server) constrains the build; or when verifying a build before declaring a task done. Includes release checklists and dry-run discipline.From its SKILL.md
npx -y skills add ats4321/claude-engineering-skills --skill build-and-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
- 0 stars0 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
12.9 KB, ~3.1k tokens by cl100k_base, as published. Nobody here has run it
Build and Release
Purpose
Discover how any repository builds, packages, and ships — then release without forgetting the steps that live only in maintainers' heads (dist-tags, alias packages, deployment-shape constraints). The doctrine: verify the build like a user would consume it; a release is not done when the command exits 0, it is done when the artifact is confirmed installable/servable in its published form.
When to Use / When NOT to Use
Use when:
- Entering an unfamiliar repo and needing to build/run/package it.
- Publishing packages — especially multi-package monorepos, alias/umbrella packages, or anything with dist-tags.
- Setting up or fixing entry points (
[project.scripts],binfields) and editable installs. - The deployment target constrains the build (static export vs server runtime).
- Declaring a build-touching task "done" (run the verification checklist first).
Do NOT use when:
- The build fails because of a dependency version → load
dependency-management. - The build needs env vars/secrets at build time and you don't know which → load
configuration-management. - Tests fail (not the build) → load
validation-and-testing. - You're deciding WHETHER to ship a change at all → load
change-control. - First contact with a repo overall → load
codebase-onboarding; this skill covers the build layer specifically.
Core Methodology
Step 1 — Discover the build system
Identify it from marker files (see Discovery Commands), then read the actual commands:
Which marker file exists at repo root?
├── package.json → read "scripts" verbatim; check for pnpm-workspace.yaml /
│ "workspaces" (monorepo) and "bin" (CLI entry points).
│ Lock file tells you the package manager: pnpm-lock.yaml → pnpm,
│ package-lock.json → npm, yarn.lock → yarn. Use THAT one.
├── pyproject.toml → read [build-system] (setuptools? hatchling?),
│ [project.scripts] (console entry points), optional-dependencies.
│ Dev install: pip install -e . (or -e ".[dev]")
├── Cargo.toml → cargo build / cargo test; [[bin]] targets.
├── Makefile / justfile → read targets; they often wrap the real commands.
└── None of the above → check README "Setup"/"Development" section;
check .github/workflows (absent in many local-first repos — then the
README IS the CI, treat its commands as the contract).
Never invent commands. Run what the repo declares (npm run build, not npx <bundler> directly).
Step 2 — Map entry points and install mode
- Python:
[project.scripts]maps command →module:function(e.g.prism = "prism.server:run"). Editable install (pip install -e .) makes source edits live without reinstall — the default dev mode for CLI/server projects. - Node:
binin package.json; monorepos may expose the same CLI from several packages. - Confirm the entry point actually resolves after install: run
<command> --help(or start the server) as the smoke test.
Step 3 — Understand the artifact set BEFORE publishing
For anything published:
- List every artifact one release produces. Monorepos may publish multiple packages; some projects publish the same code under alias names so
npx <shortname>works. - All co-versioned artifacts ship at the SAME version in the SAME release session — even when only one changed. A version skew between an umbrella package and its scoped implementation is a broken install for someone.
- Enumerate the dist-tags in play (
latest,alpha, custom) and which packages need them moved. Write this list down — tag moves on alias packages are the classic forgotten step. - Find the project's own release doc (repo CLAUDE.md, RELEASING.md, CONTRIBUTING.md) and follow it over your habits.
Step 4 — Respect the deployment shape
- Determine the shape: static export (files on a CDN), server runtime, container, installed CLI.
- The shape constrains the build: a static deployment cannot run server-dependent build/start steps — strip them from package.json rather than carrying dead scripts that imply capabilities the target doesn't have.
- Verify in the shape's own terms: static → serve the output directory and click through; server → boot it and hit an endpoint; CLI → install the built artifact somewhere clean and run it.
Step 5 — Release checklist (execute in order)
- Working tree clean; on the intended branch/commit.
- Version bumped consistently across ALL co-versioned packages.
- Build passes from clean state (
pnpm run build/python3 -m pip install -e .in fresh venv). - Tests pass (
vitest run/pytest/npm test— whatever the repo declares). - Dry-run publish executed and its file list reviewed (
npm publish --dry-run, or the repo'spublish:dryscript;python3 -m buildthen inspect the sdist/wheel). General dry-run/irreversible-command discipline is owned bychange-controlstep 5. - Publish ALL artifacts in the set (including aliases), same version.
- Move dist-tags on EVERY package in the set — check the aliases twice.
- Post-publish verification:
npm view <pkg>@<tag> versionper package, or install the published artifact in a clean environment and run the entry point. - Tag/record the release commit.
Step 6 — "Done" gate for any build-touching change
Before declaring done: clean build + tests + the entry point smoke test (Step 2.3). "It compiled" is not "it ships".
Discovery Commands
# Identify the build system
ls package.json pyproject.toml setup.py Cargo.toml Makefile justfile pnpm-workspace.yaml 2>/dev/null
cat package.json | grep -A 20 '"scripts"'
grep -A 5 "\[build-system\]" pyproject.toml
grep -A 5 "\[project.scripts\]" pyproject.toml
# Monorepo layout
cat pnpm-workspace.yaml 2>/dev/null
grep -rn '"name"\|"version"' --include=package.json . | grep -v node_modules | head -20
find . -maxdepth 3 -name package.json -not -path "*/node_modules/*"
# Which package manager (use the one whose lock file exists)
ls pnpm-lock.yaml package-lock.json yarn.lock 2>/dev/null
# Entry points
grep -rn '"bin"' --include=package.json . | grep -v node_modules
grep -B2 -A5 "project.scripts" pyproject.toml
# Release conventions the repo already wrote down
ls RELEASING.md CONTRIBUTING.md CLAUDE.md docs/release* 2>/dev/null
git log --oneline -20 | grep -iE "release|publish|bump|dist-tag"
# Published-state inspection (npm)
npm view <package> versions --json
npm view <package> dist-tags
npm dist-tag ls <package>
# Dry runs (never invent flags — these are standard)
npm publish --dry-run
npm pack --dry-run # lists files that would ship
python3 -m build # then: tar tf dist/*.tar.gz
# Deployment shape hints
grep -n "output\|export" next.config.* 2>/dev/null
grep -n '"build"\|"start"' package.json
Failure Modes & Anti-patterns
| Symptom | Mistake | Correction |
|---|---|---|
npx <alias>@latest installs stale version | Published the main package, forgot dist-tags on aliases | Enumerate the full artifact set + tag matrix BEFORE publishing; move tags on every package; verify each with npm view. |
| Alias package resolves different version than scoped one | Publishing only the changed package | All co-versioned packages ship together at the same version, always. |
| "Build works" but user's install is broken | Verified only in a dirty dev environment | Clean-state build + install the published/packed artifact and run its entry point. |
| Deploy fails on static host | Server-dependent scripts left in package.json for a static target | Match build steps to deployment shape; delete steps the shape can't execute. |
| Wrong lockfile churn / phantom deps | Using npm in a pnpm repo (or vice versa) | The lock file names the package manager; use that one only. |
| Release step forgotten every time | Steps live in a maintainer's head | Follow the repo's written release doc; if missing, write the Step 5 checklist into the repo. |
| Published a package with junk files | No dry run | npm pack --dry-run / publish:dry and READ the file list before real publish. |
| CLI command not found after install | Entry point declared but never smoke-tested | pip install -e . then run <cmd> --help as the standard gate. |
Repository Examples
ruflo — multi-package + dist-tag coordination (as of 2026-07-04)
~/ruflo: pnpm-workspace TypeScript monorepo (v3/ contains @claude-flow/cli, shared, guidance, hooks, memory, security). One release publishes THREE npm packages at identical versions: @claude-flow/cli (canonical scoped artifact), claude-flow (umbrella so npx claude-flow@latest works), and ruflo (thin alias wrapper). The repo's own CLAUDE.md encodes the rules: publish all three even for CLI-only changes, then set dist-tags (alpha/latest/v3alpha) on ALL aliases post-publish — e.g. npm dist-tag add [email protected] latest — and explicitly marks the ruflo dist-tag "EASY TO FORGET". The failure mode is real, not theoretical: commit "fix: @claude-flow/browser peer dep, dist-tags, bump to alpha.3" records an actual dist-tag/peer-dep slip. Build/test/dry-run commands: pnpm run build, vitest run, publish:dry.
asver — deployment shape constrains the build (as of 2026-07-04)
~/asver: Next.js 16.2.10 static-deployment project (npm run dev/build/start/lint). Commit "Remove server build from package.json for static deployment": the static shape forbids server-dependent build steps, so they were stripped rather than carried as dead weight. (Interpretation of intent partly inferred from the commit message — hypothesis, requires verification against the diff.)
prism / ragit / agentix — editable installs and entry points (as of 2026-07-04)
- prism:
pip install -e .; entry pointprism = "prism.server:run"boots uvicorn on0.0.0.0:8000; tests viapytest tests/. - ragit:
python3 -m pip install -e .; entry pointragit = "ragit.cli:main"(verified directly in pyproject.toml); setuptools backend. - agentix: hatchling backend;
pip install -e ".[dev]"; runtime additionally requiresollama pull llama3.2andollama pull nomic-embed-text— a reminder that "the build" can include non-package artifacts (models) the README must document.
orphy / NYTW — declared scripts are the contract (as of 2026-07-04)
orphy: Vite + React 18.3, npm run dev/build/preview. NYTW: Next.js 16 + Node CLI, quiz tests via npm test in quiz/. Zero CI/CD in any of these repos — the README/package.json commands ARE the release process, which raises (not lowers) the bar for running them manually before declaring done.
Validation Criteria
You applied this skill correctly if:
- You can name the build system, package manager, and every declared build/test/publish command without guessing.
- Before publishing, you produced a written artifact-set + dist-tag matrix, and after publishing,
npm view <pkg> dist-tags(or ecosystem equivalent) confirms every entry. - Every co-versioned artifact shows the identical version in the registry.
- You ran a dry-run publish/pack and reviewed the shipped file list.
- The entry point was executed from a clean install (not your dev tree) as the final gate.
- Build steps match the deployment shape; no dead server steps in static targets and vice versa.
Provenance & Maintenance
- Sources: ~/ruflo, ~/asver, ~/prism, ~/ragit, ~/agentix, ~/orphy, ~/NYTW — investigated 2026-07-04. ragit's entry point/build backend re-read directly during authoring; other repos' facts from the 2026-07-04 verified fact pack (directories read-restricted during authoring: "verified 2026-07-04, not re-read").
- Assumptions: asver's motivation for stripping server build steps is partly inferred and marked as such; ruflo dist-tag examples quote its CLAUDE.md as of the fact-pack date.
- Re-verification commands:
grep -rn "dist-tag" ~/ruflo/CLAUDE.md cat ~/ruflo/pnpm-workspace.yaml git -C ~/asver log --oneline | grep -i static grep -A 3 "project.scripts" ~/ragit/pyproject.toml ~/prism/pyproject.toml npm view claude-flow dist-tags && npm view ruflo dist-tags - Likely to drift: ruflo's package set and tag names (alpha/v3alpha are release-phase-specific); the example version
3.5.51; asver's Next.js version; whether any repo gains CI (which would change the "README is the CI" framing). - Maintenance checklist: re-run re-verification; confirm the three-package ruflo set still exists before citing it; refresh version numbers in examples; confirm the "zero CI/CD" cross-cutting claim still holds.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.