release
Release markuplint — branch promotion, version bump (lerna fixed mode), tag push, publish workflow monitoring, npm-state verification, GitHub Release notes…
Skill by markuplint
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/markuplint-release
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: productivity, ci-cd, version-control
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/release
What's inside
- Skill name
release- Description
- Release markuplint — branch promotion, version bump (lerna fixed mode), tag push, publish workflow monitoring, npm-state verification, GitHub Release notes, and X post drafting. Use when asked to release, publish, or cut a new version.
- License
- MIT
- Metadata
- internal: true
- Instructions
- 320 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Preconditions - **Fixed versioning**: all packages share one version (`lerna.json` `version`). - **The release branch is not the development branch.** See [Branch model](#branch-model) — getting this wrong is the single most common mistake in this repository. - Pushing a `v*` tag triggers `.github/workflows/publish.yml`, which runs `lerna publish from-git` with a dist-tag derived from the version string (`-alpha.*` → `alpha`, `-beta.*` → `beta`, `-rc.*` → `rc`) via npm OIDC Trusted Publishing. A stable version goes to `latest`, unless its major is below the major currently on `latest` (`npm view markuplint@latest version`): then it goes to `v<major>`, so a maintenance release never moves `latest` back (4.18.4 was the first, published under `v4`). - **Publishing cannot be undone.** Confirm with the user at each gate. - **Run this in the user's main checkout, not in a worktree.** The worktree rule in the root `CLAUDE.md` is for topic-branch work; a release needs `main` checked out where the user runs `yarn release`, and a worktree holding `main` blocks the main checkout from switching to it. If this skill is invoked from a worktree session, stop before any checkout or merge and hand the steps to the user for the main checkout. - The exception is a maintenance release (see [Branch model](#branch-model)): it is cut on the line's own branch, so a worktree checked out on that branch works and keeps the main checkout on `dev`. In a worktree, `yarn release` needs the same prefix as `yarn build` — `NX_WORKSPACE_ROOT_PATH=<worktree-absolute-path> yarn release` — otherwise Lerna resolves the Nx workspace root to the main checkout and dies in `git diff --name-only <tag> -- ../../../packages/...` with "is outside repository". - The VS Code extension ships separately (`yarn vscode:package` to verify the VSIX build locally, then `yarn vscode:release`) and is out of scope here. # Branch model | Release type | Cut from | How work gets there | | --- | --- | --- | | **Stable** (`X.Y.Z`) | `main` | Merge `dev` (or the prerelease branch) into `main` first, then run `yarn release` on `main` | | **Prerelease** (`-rc.N` / `-beta.N` / `-alpha.N`) | A dedicated branch, e.g. `v5-rc`, `v5-alpha` | Branch off **the line being released**, run `yarn release:rc` there, then merge that branch back into that line | | **Maintenance** (`4.x.y`, a patch of a superseded major) | `v4` itself | Run `yarn release` on `v4`; `.husky/pre-commit` guards only `dev`, and `publish.yml` publishes it under the `v4` dist-tag. Nothing is merged back: `v4` is never merged into another line | | Development | `dev` (v5 line), `v6` (next major) | — never released from directly | Verify the claim rather than trusting this table if anything looks off: ```bash git log --oneline main --grep="chore(release)" # stable releases live on main git log --oneline v5-rc --grep="chore(release)" # rc.0–rc.4 live on v5-rc ``` Three consequences that matter: - **`main` looking "stale" is normal.** It carries the last released version until the next release. Merging into `main` *is* the release act, not a chore someone forgot. - **Never run `yarn release` on `dev`.** `.husky/pre-commit` rejects every commit on `dev`, and Lerna only passes `--no-verify` when `commitHooks` is `false` (it defaults to `true`), so the version commit is refused. `main` and the prerelease branches are not guarded. - **Prereleases are rare** — the v5 cycle is the only one so far. Keep using a dedicated branch for them; the v6 line will need the same, cut from `v6` (not from `dev`). ## Releasing while two lines are live `dev` (v5, the shipped major) and `v6` (the next major) are developed in parallel. Every one of the following is an open decision — **treat a request to release anything from the v6 line as blocked until the user has decided each point explicitly**, and say so rather than improvising: - **`publish.yml` does not build the native addon.** It runs `yarn build`, and `@markuplint/core` has no `build` script — only `build:napi` / `build:napi:debug` — so `lerna publish from-git` would ship `@markuplint/core` without its `*.node` binary, and no per-platform packages at all. Publishing cannot be undone, so a v6 publish is blocked until `publish.yml` cross-builds napi. - **The version namespace is shared.** `lerna.json` is at the same version on both branches and versioning is fixed-mode, so both lines derive their next version from conventional commits into the same `v*` tag namespace and the same CHANGELOG lineage. The v6 line cannot rely on automatic derivation to reach `6.0.0`; the target version is a decision, not an inference — the automatic derivation in step 4 applies to the v5 line only. - **dist-tags are a single slot per name.** The tag comes from the version string alone (`-alpha.*` → `alpha`, and so on), so a v6 prerelease and a v5 prerelease using the same suffix overwrite each other's tag. Run `npm dist-tag ls markuplint` before any prerelease and confirm which line owns which tag. - **Merging `v6` into `main` retires the v5 line in one step.** Per [What the `main` merge switches over](#what-the-main-merge-switches-over), that merge flips the production docs, the JSON Schema `$ref` URLs, and VS Code completion to v6 for every existing v5 user simultaneously. There is no staged path. Do not merge `v6` into `main` for a prerelease — use a dedicated prerelease branch, which leaves `main` alone. ## What the `main` merge switches over For a stable release, merging into `main` flips four user-facing surfaces at once. There is no way to stage them separately, so treat the merge as the point of no return: | Surface | Wiring | | --- | --- | | npm packages | the `v*` tag push fires `publish.yml` | | markuplint.dev (production docs) | `website/config.js` — no `NEXT_VERSION` ⇒ production URL, editUrl `main` | | JSON Schema | `config.schema.json` and every rule `schema.json` `$ref` a `raw.githubusercontent.com/.../main/...` URL | | VS Code completion | `vscode/package.json` — `markuplint.defaultConfig` `$ref` and `jsonValidation[0].url` point at that same schema | Website changes therefore reach production in the same step. Confirm with the user that the website is in a shippable state before merging. The merge also makes `crates/` part of the stable line. The `no-breaking-change-on-stable-line` rule of `.commitlintrc.js` tells the lines apart by `crates/Cargo.toml`, so from then on it is silent in every checkout: re-key it to whatever marks the next major before the first commit on the new stable line. # Steps ## 1. Determine the release type and target branch Ask the user only for the release channel (stable / rc / beta / alpha) if it is not already clear — the semver bump is derived, see step 4 — then pick the branch from [Branch model](#branch-model). Everything below writes `<release-branch>` for that branch. `git status` must be clean. Anything dirty: report and wait for instructions. ```bash git fetch origin git checkout <release-branch> git pull origin <release-branch> ``` For a **stable** release, merge the source branch in first and let the user review the diff before continuing: ```bash git merge origin/dev # or the prerelease branch, e.g. origin/v5-rc ``` For a **prerelease**, create the branch from the line being released if it does not exist yet — `git checkout -b v5-rc origin/dev` for the v5 line, `git checkout -b v6-alpha origin/v6` for the next major. Cutting a v6 prerelease from `dev` silently drops everything the v6 line adds. ## 2. Unmerged PRs ```bash gh pr list --base <source-branch> --state open ``` `<source-branch>` is the development branch the release draws from — `dev` for the v5 line, `v6` for the next major. Present anything that looks release-relevant; confirm whether to continue. (PRs target the development branch, not the release branch.) ## 3. Pre-checks `yarn lint-check`, `yarn build`, `yarn test` must all pass **in this session, on the release branch after the merge**. This is the only real gate: - On a release branch with a `crates/` directory, `yarn test` is not the whole gate: add `cargo fmt --check`, `cargo clippy --locked -- -D warnings`, and `cargo test --locked` (what `.github/workflows/rust.yml` enforces), and confirm `@markuplint/core` was built with `yarn build:napi` — `yarn build` alone does not produce the addon. - `.github/workflows/test.yml` also triggers on `push` to `dev`, so `gh run list --branch dev --workflow=test.yml` is real evidence for `dev`. It is not evidence for `main` or a prerelease branch — those still need this session's own `yarn lint-check`, `yarn build`, and `yarn test`, each run as its own command. For the v6 line, `test.yml` alone is not evidence either; `rust.yml` and `cargo-deny.yml` must be green too. - Yarn 4 does not run arbitrary pre/post lifecycle hooks, so the root `prerelease` script (build + test) is NOT executed by any `yarn release*` variant. - `publish.yml` does not run tests either — it installs, builds, and publishes. If the release touches any rule the benchmark covers, also run the pre-release checklist in the `bench-xref` skill (including its `--dry-run` review before `--write`). ## 4. Present release contents ```bash git describe --tags --abbrev=0 git log --oneline <last-tag>..HEAD ``` Show the current version (`lerna.json`). `yarn release` derives the next version from conventional commits automatically, so do **NOT** ask the user to choose a version bump — present the diff only as a "what's going in" check. On the stable line, also scan the range for a breaking-change marker. The `no-breaking-change-on-stable-line` rule of `.commitlintrc.js` blocks it at commit time only; for a commit merged on GitHub this scan is the one gate, and one hit makes `yarn release` cut a major, the number the next-major line owns: ```bash git log <last-tag>..HEAD --format=%s | grep -E '^[a-z]+(\([^)]*\))?!:' git log <last-tag>..HEAD --format=%B | grep -iE '^(\* +)?BREAKING[ -]CHANGE:' ``` Stop and present any hit. If the user decides to release anyway, pass the bump explicitly — `yarn release minor` (or `patch`): `lerna version` takes a positional bump over the recommendation of `--conventional-commits` and still generates the changelog. That changelog carries a "BREAKING CHANGES" section from the commit's note, so the minor release announces a breaking change; say so when presenting the choice. ## 5. Version bump (user-executed) Before handing over, remove `vscode/package-lock.json` if it exists. It is a gitignored leftover of an npm-based extension build (`vscode/scripts/install.mjs` deletes it only on success; a manual `vsce package` or an interrupted build leaves it behind). `lerna version` updates every per-package `package-lock.json` it finds and passes it to `git add`, which refuses ignored paths — the run then dies after every manifest and CHANGELOG has been rewritten and staged, one step short of the commit (v5.0.1).
From markuplint/markuplint, MIT.
More from markuplint/markuplint
- 0.817score
impl
markuplint
Implementation orchestrator — takes an agreed plan through implementation, carry-over approval, code review, security review, QA, docs consistency, lint/test…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
git
markuplint
Git operation rules for this repository — branch guard, commit granularity, package commit order, Conventional Commits message format, and pre-commit checks.
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
product-manager
markuplint
Review a diff of this repository from a Product Manager (PdM) perspective: documentation consistency (JSDoc placement, comment policy, README accuracy)…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
pr
markuplint
Create and push a pull request — pre-flight checks, base tracking, PR body drafting, conflict detection, and CI watch loop.
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
verify-docs
markuplint
Verify documentation claims (README, JSDoc) in spec-heavy packages — @markuplint/types (attribute value types; WHATWG/W3C/RFC/CSS/SVG grammars) and…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
qa-engineer
markuplint
Review a diff of this repository as a QA engineer: test quality (coverage, test-faking code, swallowed exceptions, conditional logic in tests, hardcoded…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
framework-parsers
markuplint
Create and maintain framework parser and spec packages for markuplint — package types, naming, and the architectural constraints that break the build or…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
pr-review
markuplint
Review an external pull request for the owner: check it against the intake conditions of CONTRIBUTING.md (eligible issue, required body sections, no burst of…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
doc
markuplint
Documentation policy — JSDoc-first; no code-derivable markdown.
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
list-rule-test
markuplint
List rule test IDs with filtering and stats.
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
issue
markuplint
Analyze or create a GitHub Issue and build a TDD resolution plan.
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
create-issue
markuplint
Investigate a problem to its root cause and file it as a GitHub Issue with the right labels and an As is / To be / Why / How body backed by primary sources.
SkillAFreshness: A★ 629Claude Code +9
Compare and alternatives
Featured in
Signals
- Stars
- 629
- Forks
- 70
- Open issues
- 52
- Last commit (this folder)
- Oct 22, 2026 (5 days ago)
- Last release
- Oct 21, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/markuplint/markuplint
- Website
- markuplint.dev
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from markuplint
- 0.817score
impl
markuplint
Implementation orchestrator — takes an agreed plan through implementation, carry-over approval, code review, security review, QA, docs consistency, lint/test…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
qa-engineer
markuplint
Review a diff of this repository as a QA engineer: test quality (coverage, test-faking code, swallowed exceptions, conditional logic in tests, hardcoded…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
product-manager
markuplint
Review a diff of this repository from a Product Manager (PdM) perspective: documentation consistency (JSDoc placement, comment policy, README accuracy)…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
pr-review
markuplint
Review an external pull request for the owner: check it against the intake conditions of CONTRIBUTING.md (eligible issue, required body sections, no burst of…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
verify-docs
markuplint
Verify documentation claims (README, JSDoc) in spec-heavy packages — @markuplint/types (attribute value types; WHATWG/W3C/RFC/CSS/SVG grammars) and…
SkillAFreshness: A★ 629Claude Code +9 - 0.811score
pr
markuplint
Create and push a pull request — pre-flight checks, base tracking, PR body drafting, conflict detection, and CI watch loop.
SkillAFreshness: A★ 629Claude Code +9
Cite this page
release skill. Agent Mart. https://agentmart.dev/skills/markuplint-release (last updated 2026-10-24)