Releases and CI
What runs on pull requests and on main, how a release is cut, and how the GitHub Action
and its binaries are published.
Continuous integration
Section titled “Continuous integration”.github/workflows/ci.yml runs on pull requests and on pushes to main:
| Job | Runs |
|---|---|
| Checks | checkout, setup-go (from go.mod), mise-action (tools from mise.toml), gitleaks-action, then one task step per check in task ci except the self-check. Every step runs even after one fails. |
| Self-check | task build, then the action from this checkout (uses: ./ with binary: ./bin/ci-parity) on this repository, and on the inline-tools fixture to check its outputs (task action:expect). On main, also a SARIF run uploaded to code scanning. |
| Code metrics | A step in Checks: task metrics:check fails when the README’s metrics table doesn’t match the code, so each change updates it with task metrics:readme. |
| Tests (macOS, Windows) | The unit, integration, end-to-end and performance tests on macos-latest and windows-latest. |
| Action download | On Linux, macOS and Windows, the published action, pinned by SHA with no binary or version input: it downloads the latest release, verifies it against checksums.txt and runs it on the inline-tools fixture and on this repository. Move the pin to each new release. |
| Check table | On pull requests, one comment listing every check’s result, updated on each push. |
| Badges | On main, one shields.io endpoint file per check, committed to the badges branch for the README’s status table. |
.github/workflows/labeler.yml labels pull requests by the paths they change
(.github/labeler.yml), and .github/workflows/pr-assign-author.yml assigns each new one
to its author, or a bot’s to the owner.
The “Protect main” ruleset requires squash-merged pull requests, signed commits, linear history, and the Checks, Self-check, Tests (macos-latest) and Tests (windows-latest) jobs; it blocks force pushes and deletion, and repository admins can bypass it. Action download isn’t required: it tests the published release, which a pull request can’t change, and it can fail for reasons outside the repository, such as a GitHub outage.
Every run: step calls task, and every third-party action is pinned to a full commit
SHA with a version comment. The repository checks its own workflows with ci-parity:
.ci-parity.yml and a .ci-parity-baseline.json with every workflow locked at 0.
The linters and formatters are pinned in mise.toml, never in go.mod. CI installs them
with a SHA-pinned jdx/mise-action; locally, mise install does. Each task lint:<group>
checks its tools are on PATH and names the one missing.
Docs site
Section titled “Docs site”.github/workflows/site.yml publishes docs/ to GitHub Pages at
https://ci-parity.is-a.dev/ on every push to main that changes docs/,
site/ or the workflow, and on demand.
The domain is a subdomain of is-a.dev: domains/ci-parity.json in
is-a-dev/register points it at
jimmykurian.github.io with a CNAME record, and the repository’s Pages settings name it as
the custom domain with HTTPS enforced. GitHub redirects the old
jimmykurian.github.io/ci-parity/ URLs to it.
- Build:
task site:installinstalls the site’s packages fromsite/pnpm-lock.yaml;task site:buildcopiesdocs/into the Starlight site withsite/scripts/sync-docs.mjsand builds it, failing on a broken link or anchor. The build uses no caches. - Deploy:
actions/deploy-pagespublishes the built site to thegithub-pagesenvironment; only that job can write to Pages. - Pull requests: the Checks job runs
task site:testandtask site:build, so a broken link fails before it reachesmain.
Preview locally with task site:dev, or task site:build then task site:preview.
Cutting a release
Section titled “Cutting a release”.github/workflows/release.yml runs on pushes to main:
- Release Please opens or updates one release pull request,
chore: release X.Y.Z, bumping.github/.release-please-manifest.json,CHANGELOG.mdand every line ofdocs/guides/getting-started.mdmarkedx-release-please-versionfrom the Conventional Commits since the last release. Before 1.0, afeatis a minor release and anything else listed (fix,perf,docs,refactor) a patch;chore,ci,build,testandstyleare hidden and cut no release. - It runs with
GITHUB_TOKEN, so the release pull request starts no checks on its own: close and reopen it, wait for the checks, then merge it. - Merging tags
vX.Y.Zand creates the GitHub Release as a draft (draftandforce-tag-creationin the Release Please config, so the tag exists at once). In the same workflow, goreleaser (.goreleaser.yaml) builds linux, darwin and windows on amd64 and arm64, with the version, commit and date stamped in, attachesci-parity_<version>_<os>_<arch>.tar.gz(zip on windows) andchecksums.txtto the draft (use_existing_draft), then publishes it. The latest release therefore always has its archives, which the action downloads; if the build fails, the release stays a draft that users don’t see. The build uses no caches. task release:floatmoves thev0tag to the release, souses: jimmykurian/ci-parity@v0follows it. Pre-releases don’t move it.- To update the Marketplace listing, edit the new release on GitHub, keep “Publish this Action to the GitHub Marketplace” ticked, and save.
task release:snapshot builds every archive into dist/ locally, and
task lint:release checks .goreleaser.yaml.
See also
Section titled “See also”Last reviewed: 2026-10-28