CI and releases
Shared checks and archives
The CI workflow (.github/workflows/ci.yml) runs on pushes to main and pull
requests targeting main. Pull requests check GitHub’s merge commit, so the
result covers the proposed change combined with the base branch. CI has
read-only repository permissions and does not publish releases or tags.
CI and the manual release workflow call the same reusable Build binaries
workflow (.github/workflows/build.yml). It runs:
make check
go test -race ./...
make release-check
make check covers formatting, vet, Go tests, CLI smoke checks, and a Linux
amd64 cross-build. make release-check tests the release scripts. The shared
workflow then builds all four archives on one ubuntu-24.04 Linux runner, using
the Go version from go.mod, CGO_ENABLED=0, trimmed paths, and an explicit
binary version:
richt-VERSION-linux-amd64.tar.gz
richt-VERSION-linux-arm64.tar.gz
richt-VERSION-darwin-amd64.tar.gz
richt-VERSION-darwin-arm64.tar.gz
The workflow extracts the Linux amd64 archive outside the checkout and checks its version/help, inventory validation/display, config-only diff, private saved plan, application of prepared bytes after deleting the inventory/template, file permissions, persisted success, and skipping successful tasks during continuation. Only this native Linux amd64 archive gets a runtime smoke test. The other targets are compilation results. These checks do not prove macOS runtime behavior or real RPM, systemd, root, SSH, or SELinux behavior; see Linux validation for separate disposable-host acceptance.
Each run uploads the four archives as the Actions artifact binaries. Ordinary
CI versions use ci-RUN_NUMBER-COMMIT_SHA; they are build labels rather than
published release versions. An archive contains one directory matching its
filename stem, holding richt and README.md. Windows is deferred to
KRG-92
.
This workflow produces no DEB, RPM, or Docker artifacts.
Publish a release
The workflow must first be present on the default branch for GitHub to offer
its manual run form. Use Actions → Release binaries → Run workflow on
main. These instructions describe publication; they do not assert that a
release has already been published.
- Commit and push the intended changes. Prefer a reviewed commit SHA as the source. No version change in a source file is needed.
- Enter
versionwithout a leadingv, usingX.Y.Zor a prerelease such asX.Y.Z-rc.1. Build metadata (+...) is not accepted. Setsource_refto a branch, tag, or commit; it defaults tomain. - Preparation validates the version and resolves
source_refto one exact commit SHA. All checks and builds use that SHA. An existingvVERSIONtag must already point to that commit; the workflow never moves it. - After the full shared checks, build, and native smoke test succeed, the
publication job verifies the local set of four archives and generates
SHA256SUMS. It creates a draft release with all four archives and the checksum file, then publishes only after that upload command succeeds. GitHub createsvVERSIONat the resolved commit if needed. Prerelease versions are marked as prereleases. - Inspect the published assets and verify the downloaded archive using the installation instructions . Record any additional real-platform validation in the release notes.
Only the final publication job has contents: write; source checks and builds
have read-only permissions and no publication credentials. Publication uses
artifacts from its own workflow run and does not rebuild code. No personal
access token is required. Runs for the same version are serialized.
The workflow rejects an existing release, including a draft, and never overwrites assets. If publication fails after creating a draft, inspect its assets and source commit before either completing publication manually or deleting the incomplete draft and rerunning. Investigate a tag mismatch; do not move the tag to make a rerun pass. Published source changes require a new version.
Required repository protection
Workflow files alone do not enforce merge policy. Configure branch protection
or a ruleset for main separately: require pull requests, require the unique
aggregate status check CI, and require branches to be up to date with
main before merging. The aggregate check must pass only after the shared
checks, archive build, and smoke test succeed. Confirm the check appears after
the workflow’s first run before selecting it in repository settings. This
guide does not assert that those repository settings are already configured.
Reproduce locally
From a checkout, install Go as specified in go.mod, Make, and Python 3.9 or
newer (CI uses Python 3.12). Run the same checks and archive builder:
make check
go test -race ./...
make release-check
python3 scripts/release/package.py --version X.Y.Z --output-dir dist
Replace X.Y.Z with a valid version label. The package script cross-compiles
all four targets. On Linux amd64, smoke-test the resulting native archive:
python3 scripts/release/smoke.py \
--archive dist/richt-X.Y.Z-linux-amd64.tar.gz --version X.Y.Z
The smoke test must run on the archive’s native platform. It uses a temporary
directory and config-only resources without root or managed host access.
make release-archives VERSION=X.Y.Z is a shortcut for the package command.
SHA256SUMS is generated by the publication workflow, not the local package
script. Reproducing this process does not promise byte-identical archives
across different toolchain versions or build environments.