Skip to content
Back to skills

Release

ASecurity

Cut and publish a Gerillass release — version bump, changelog, tag, GitHub release, npm publish, and post-publish verification. Use when the user asks to release, publish, ship a version, or push a fix out to npm.

  • 171 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
developmentgorubybashnodegitapisecuritydocumentation

Works with

  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 19, 2026

npx -y skills add selfishprimate/gerillass --skill release --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Release?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Release
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/selfishprimate-release/badge)](https://www.skillsdirectory.com/skills/selfishprimate-release)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: release
description: Cut and publish a Gerillass release — version bump, changelog, tag, GitHub release, npm publish, and post-publish verification. Use when the user asks to release, publish, ship a version, or push a fix out to npm.
---

# Release Gerillass

The repository and the npm package are separate things. Fixing `main` changes
nothing for anyone using the library — the fix reaches users only when a new
version is published. Never stop at the git tag.

Take the target version from the user. If they did not name one, propose one and
confirm before touching anything:

- **patch** for dependency, security and bugfix work. This is what almost every
  release here has been, including dependency restructuring (see 1.2.6, 1.3.3).
- **minor** for a new mixin or function.
- **major** for a change that breaks a call that worked, such as a removed
  member or a changed argument order. 2.0.0 was the module migration; 3.0.0
  replaced the gradient mixins.

Every release publishes to **both** registries, npm (step 6) and RubyGems
(step 6b). Every **major** release also rewrites the site's announcement band
(step 3c). Both are rules the maintainer set; do not skip either.

## 1. Verify the tree before anything else

```bash
npm test                    # must pass: specs, smoke test and the manifest suite
yarn audit                  # must be zero across all severities
node tools/audit.js         # the SILENT bucket must be empty
node tools/check-docs.js    # the docs must not claim a count the repo lacks
node tools/check-wiki.js    # names what the wiki page has to cover
git status --short          # know exactly what is going out
```

The library must no longer trip the two deprecations the module migration was
about. This must print nothing:

```bash
npx sass --load-path=scss test/smoke.scss 2>&1 >/dev/null | grep -E 'DEPRECATION.*(import|global-builtin)'
```

A plain `grep DEPRECATION` will still find something, and that is expected: Sass
is deprecating its own `if()`, which the library calls in 21 places. Use `npx`,
not a system `sass` — an older one has nothing to say about `if()` and will make
a stale tree look clean.

If `dependencies` in `package.json` is non-empty, stop and fix that first — it is
the single most consequential defect this package can ship. See CLAUDE.md.

## 2. Bump and document

Edit `version` in `package.json`, then add an entry at the top of
`CHANGELOG.md`, directly above the previous version heading. Match the existing
bullet style exactly:

```markdown
## 1.3.4

- **Security:** ...
- **Added:** ...
- **Updated:** ...
- **Removed:** ...
- **Fixed:** ...
```

Write what changed for a **user of the library**, not what changed in the repo.

## 3. Confirm the tarball

```bash
npm pack --dry-run
```

`llms.txt` is generated too, and its links are the one thing no test can check,
because they point at sites this repository does not build:

```bash
node tools/check-links.js
```

Run it on **every** release, not only ones that add a member: a page published
on the documentation site since the last release should stop linking to source.
v2.1.0 shipped with `line-clamp` pointing at a page that did not exist, because
this step was a loop to copy and it was skipped.

Expect 114 files, an 82 kB tarball (3.0.0): everything under `scss/`, the generated
`gerillass.json` and `SKILL.md`, plus `README.md`, `LICENSE.md` and
`package.json`. If `test/`, `meta/`, `tools/`, `yarn.lock` or
`node_modules` appear, `.npmignore` is broken — stop and fix it.

The source zip and tarball GitHub attaches to the release are a different
package. They are built with `git archive` from the tag, and `.npmignore` does
not reach them; `export-ignore` in `.gitattributes` does. They are meant to hold
the library's buildable source, not only what npm ships, so check them against
their own list:

```bash
node tools/check-archive.js
```

It must pass before tagging. An unexpected entry means something was committed
that `.gitattributes` does not keep out, which is how `site/` was headed for the
first release after 2.1.0 without anyone deciding it.

## 3b. Write the wiki page for the other repositories

A release is not finished when npm has it. `gerillass.com` and
`docs.gerillass.com` are separate repositories whose sessions cannot see this
one, and a changelog does not tell them which control on which page to touch.

Add `wiki/vX.Y.Z.md`, following `wiki/README.md` and an existing file.
`node tools/check-wiki.js` lists exactly which members it has to name, worked
out from the manifest at the previous tag, and fails until the page covers all
of them. A hook runs it too, so bumping the version in step 2 before writing
the page will block. Do not
restate the API: `gerillass.json` already holds it and is verified. Write what
is not in there.

If the release adds or changes a member, the page must cover:

- **the playground member `<select>` on `gerillass.com`**, which needs every
  new mixin adding by hand, and the version `<select>`, which needs the new
  version;
- **which documentation pages to write or update** on `docs.gerillass.com`;
- **the measurement behind each member**. This is the part with no other home,
  and it is what a documentation page should be built on.

## 3c. The site, which advertises the release

`gerillass.com` and its documentation live under `site/`, and several places on
it name the version. A release that updates the library and not these leaves
the site advertising the old one, or linking to a download that does not exist.

| Where | How it follows the version | What to do |
|---|---|---|
| Header badge under the logo | `site/src/release.js` reads `VERSION` from the root `package.json` | nothing to edit; confirm it after a build |
| Both download buttons | `DOWNLOAD_URL` in the same file, `archive/refs/tags/vX.Y.Z.zip` | the link is a 404 until the tag is pushed, so **deploy the site only after step 4** |
| Playground version menu | reads the npm registry; `FALLBACK` in `site/src/components/Playground/versions.js` is the seed used when that fails | add the version to `versions` and `latest` **after npm has it** (step 7), not before |
| Stargazers row | a committed snapshot | `npm run supporters --prefix site` |
| Playground starter snippets | `demos.json`, generated from `site/content/docs/*.mdx` and the root `gerillass.json` | `npm run playground-demos --prefix site` when a documented example or a page description changed, and whenever a mixin is added |
| Documentation pages | `site/content/docs/*.mdx` | compile every example against the previous tag and `HEAD`; for each member whose behaviour changed, read its argument table and footnotes for claims that are no longer true |
| Announcement banner | hand-written in `site/src/components/Announcement/index.jsx` | **every major release**: name the version, say in one sentence what breaks, link `MIGRATION.md`. A rule since 17 September 2026. Leave it for a minor or patch |

Confirm the badge and the download link in the build before tagging:

```bash
npm run build --prefix site
grep -o "X.Y.Z" site/dist/index.html | sort | uniq -c
grep -o 'archive/refs/tags/v[^"]*' site/dist/index.html
```

After the tag is pushed, check that the link resolves:

```bash
git ls-remote --tags https://github.com/selfishprimate/gerillass.git | grep vX.Y.Z
```

## 4. Commit, tag, push

```bash
git add package.json CHANGELOG.md
git commit                       # subject: "Release vX.Y.Z"
git tag -a vX.Y.Z -m "vX.Y.Z"    # tag format is vX.Y.Z — no dot after the v
git push origin main
git push origin vX.Y.Z
```

The default branch is `main`, protected against force-push and deletion but open
to direct pushes.

## 5. GitHub release

```bash
gh release create vX.Y.Z --repo selfishprimate/gerillass \
  --title "vX.Y.Z" --latest --notes-file <file>
```

Reuse the changelog entry as the notes, and end with a compare link:
`https://github.com/selfishprimate/gerillass/compare/vPREV...vX.Y.Z`

## 6. Publish to npm

```bash
npm whoami       # must print selfishprimate
npm publish
```

The account has **2FA enabled**, so `npm publish` fails with `EOTP`. The
one-time code is a credential — do not ask for it and do not type it. Tell the
maintainer to run this themselves:

```bash
npm publish --otp=<code>
```

## 6b. Publish to RubyGems

The gem is the same release: `gerillass.gemspec` reads its version from
`package.json`, so there is nothing to bump. It ships `scss/`, `gerillass.json`,
`SKILL.md`, `lib/`, `LICENSE.md` and `README.md` and has no runtime
dependencies. The two agent files are committed build output and the gem takes
them as they are.

**Build it from the tag, never from a branch.** 2.3.1 was built from a branch
that already held a commit made after `v2.3.1`, and the gem shipped three
warning messages that differ from the npm package of the same version. A
version cannot be pushed twice, so a difference like that stays until the next
release. Build in a worktree of the tag, outside the repository so no `.gem` is
left at the root, and check what is in it before pushing:

```bash
out="$(mktemp -d)"
git worktree add "$out/src" vX.Y.Z
(cd "$out/src" && gem build gerillass.gemspec --output "$out/gerillass-X.Y.Z.gem")
git worktree remove "$out/src"
ruby -e 'require "rubygems/package"; s = Gem::Package.new(ARGV[0]).spec
  puts s.version, s.runtime_dependencies.inspect, s.files.size,
       s.files.reject { |f| f.start_with?("scss/") }' "$out/gerillass-X.Y.Z.gem"
```

Expect `X.Y.Z`, `[]`, one file per `scss/` partial plus seven, and those seven
being `gerillass.json`, `SKILL.md`, `LICENSE.md`, `README.md` and the three
files under `lib/`.

Then compare it with what npm published for the same version. Every command
must print nothing:

```bash
gem unpack "$out/gerillass-X.Y.Z.gem" --target "$out/gem"
mkdir "$out/npm" && (cd "$out/npm" && tar -xzf "$(npm pack gerillass@X.Y.Z --silent)")
diff -r "$out/gem/gerillass-X.Y.Z/scss" "$out/npm/package/scss"
diff "$out/gem/gerillass-X.Y.Z/gerillass.json" "$out/npm/package/gerillass.json"
diff "$out/gem/gerillass-X.Y.Z/SKILL.md" "$out/npm/package/SKILL.md"
```

The macOS system Ruby is too old for the integrations; use Homebrew's
(`/opt/homebrew/opt/ruby/bin`). The gemspec is kept to ASCII on purpose: RubyGems
reads it in the locale's encoding and a literal non-ASCII character fails to
load. `rubygems_mfa_required` is set, so the push needs a one-time code, and
signing in (`gem signin`) is the maintainer's to do. Tell them to run:

```bash
gem push "$out/gerillass-X.Y.Z.gem" --otp=<code>
```

## 7. Verify what actually shipped

npm reports "may take a few minutes to become available", so the registry lags
the publish. Poll rather than assuming:

```bash
until [ "$(npm view gerillass version)" = "X.Y.Z" ]; do sleep 10; done
npm view gerillass@X.Y.Z dependencies      # MUST be empty
npm view gerillass@X.Y.Z dist.shasum       # must match the shasum npm pack printed
```

Then confirm the consumer experience end to end:

```bash
cd "$(mktemp -d)" && npm init -y >/dev/null && npm install gerillass@X.Y.Z
ls node_modules | grep -v '^\.'            # expect gerillass and nothing else
npm audit
```

Then seed the playground's `FALLBACK` with the new version, as in step 3c, and
build the site.

Report the published version, the dependency count a consumer now installs, and
the audit result. If any Dependabot alerts or PRs were resolved by this release,
close them and say so.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.