Harness Score uses a two-workflow release pipeline. A maintainer prepares and
merges the version changes, the Prepare release workflow creates a tagged
draft with polished notes, and publishing that draft triggers Publish
release. Registry authentication uses OIDC or the built-in GITHUB_TOKEN;
there are no long-lived publishing secrets in the repository.
Every user-facing PR must include a changeset with the bump type, an English description, and explicit contributor credit when the change came from an outside contributor. For example:
---
'harness-score': patch
---
Describe the user-visible change.
Thanks to [@handle](https://github.com/handle) for contributing this change.From a clean release branch based on main, run:
npm run release:prepare -- --summary "One sentence explaining why this release matters."This command:
- runs
changeset version; - mirrors the package version into every project-specific release surface;
- runs tests, lint, the L4 self-scan, and the documentation build; and
- writes a preview to
.release/release-notes-vX.Y.Z.md.
The synchronized surfaces are:
packages/cli/package.json;TOOL_VERSIONinpackages/cli/src/score.ts;packages/cli/jsr.json;- the
packages/cliworkspace entry inpackage-lock.json; action.ymlandaction/action.yml, which must remain byte-identical; and- the version input documented in
action/README.md.
Review the diff and the rendered notes, then open and merge a
release: vX.Y.Z PR. Do not create the tag before that PR is merged.
If a release intentionally has no changeset, bump
packages/cli/package.json, run node scripts/sync-version.mjs, run the four
release gates, and generate the notes explicitly:
npm run release:notes -- --summary "One sentence explaining why this release matters."After the version PR is merged, open Actions → Prepare release → Run
workflow on main and provide:
version: the exact stableX.Y.Zpackage version;title: a short title without the version; andsummary: a one-sentence introduction for the release notes.
The workflow reruns every release gate, validates all synchronized versions,
generates structured notes from the matching changelog section, preserves
contributor credits, refuses existing tags/releases, creates vX.Y.Z at the
validated main commit, and opens a draft GitHub Release.
Open the draft and verify its title and rendered notes. Select Publish this Action to the GitHub Marketplace, with Code quality as the primary category and Continuous integration as the secondary category, then publish the release.
The Marketplace selection is the only manual publication gate. GitHub's
Marketplace publication flow
exposes it only in the release UI, not through the Releases or Actions APIs.
The repository must stay public, keep action.yml at the root, and keep its
Action name unique.
Publishing the draft triggers
release.yml. It fails closed unless the tag,
package, changelog, Action metadata, release-note structure, and every required
contributor credit agree. It then publishes in parallel to:
- npm as
harness-score, using Trusted Publishing/OIDC; - GitHub Packages as
@paladini/harness-score, usingGITHUB_TOKEN; and - JSR as
@paladini/harness-score, using OIDC.
Only after all three registry jobs succeed does the workflow move the stable
major Action tag (v1 for a v1.x.y release) to the immutable release tag.
The final job independently verifies npm, GitHub Packages, JSR, the GitHub
Release, the stable Action tag, the Marketplace's advertised latest release,
and the Pages deployment for the release commit, with retries for propagation.
If one publication job fails, fix its one-time configuration and use Re-run failed jobs. Do not re-run every successful registry job: registries reject publishing the same immutable version twice.
The pipeline accepts stable releases only. Add an explicit prerelease policy before publishing an alpha, beta, or release candidate.
- npm: on the
package settings page,
configure a Trusted Publisher for repository
paladini/harness-scoreand workflowrelease.yml. - GitHub Packages: repository Actions workflow permissions must allow
writes. The workflow grants only
packages: writeto that job. - JSR: claim
@paladini/harness-scoreonce at jsr.io/new. JSR deliberately publishes the TypeScript source selected bypackages/cli/jsr.json; npm and GitHub Packages publish the built package. Their public API remains the same, but the artifacts are not byte-identical.
- Cursor Marketplace: resubmit at
cursor.com/marketplace/publish only
when
plugins/cursor/.cursor-plugin/plugin.jsonmetadata changed. The Cursor plugin has its own version andplugins/cursor/CHANGELOG.md. - Claude Code: its marketplace is this repository. When Claude plugin
content changes, bump
plugins/claude-code/.claude-plugin/plugin.json; a merge tomainis the release. - Documentation:
pages.ymldeploys every push tomain. Verify the public site separately; a green package workflow does not prove that Pages is current.
See also the release skill and the
pr-release-audit skill.