mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-30 11:07:33 +00:00
The 3.0.9 release preparation omitted stable from the initial push instructions and left the local branch on the previous release. Add an agent reminder and a release checklist covering both local and remote stable refs. Document fast-forward preparation, publishing master/stable/the version tag together, and comparing remote branch tips with the peeled tag. Keep stable on release commits rather than later development commits, exclude prereleases, and prohibit moving published tags. This documentation change does not publish or move release refs. Validation: reviewed commands against the repository branch and annotated-tag workflow; git diff --check passed. No runtime code changed. Assisted-by: GPT-6
132 lines
7.2 KiB
Markdown
132 lines
7.2 KiB
Markdown
# Publish releases with native Nix CI
|
|
|
|
All CI workflows and their support files live in `.ngit/nix/workflows/`.
|
|
`default.nix` groups commands by workflow and job; the root flake exports them
|
|
as `ngit-ci.commands`, so YAML selects each command by its job and step names. A `v*` tag push runs
|
|
`release.yaml`: a pure static-musl archive build and a container layout build,
|
|
followed by OCI publication, a pull-and-run verification, and NIP-82 publication.
|
|
The publisher copies the exact predecessor archive/layout; it does not rebuild
|
|
release products. The container builder preserves the repository Dockerfile
|
|
and `scripts/build-container-layout.sh`. Its base-image pulls retain that
|
|
Dockerfile's existing update policy.
|
|
|
|
Publisher and container jobs begin with explicit tool builds. Their closures
|
|
are shared through the provider cache before runtime commands start; credentials
|
|
are used only by the publisher step. These commands pin Git, Python, ngit, Cargo
|
|
and container tooling. The separate `release-ngit` input must support both release and container
|
|
publication; `checks.x86_64-linux.release-cli` verifies its required flags.
|
|
Checks and publishers share `.ngit/nix/workflows/release-ngit.nix`: on x86_64 Linux it installs
|
|
the SHA-256-pinned static v3.0.3 release archive, avoiding a lengthy LTO rebuild
|
|
in every fresh guest. The upstream source package disables its own tests, so
|
|
recompiling it added no CLI test coverage. Other platforms retain the pinned
|
|
source package. The archive pin trusts the upstream release build; it is not a
|
|
claim of locally reproduced binaries. Keep the archive version/hash and source
|
|
fallback revision aligned when updating this tooling.
|
|
Container build and verification jobs reuse the deployment test's job-owned
|
|
Docker daemon. They require a disposable root VM with the kernel facilities
|
|
listed in their workflow requirements, and clean up the daemon on exit.
|
|
|
|
Rust CI, archive builds, container builds and Cargo publication require at
|
|
least 4 GiB of guest RAM, including container verification.
|
|
These are provider-selection floors, not memory caps.
|
|
|
|
Review the provider summary at the top of the final job log when tuning these
|
|
minimums: observed guest RAM includes the guest OS, and swap activity or OOM
|
|
kills signal pressure. Compare cold dependency builds with cached runs and
|
|
leave headroom; a successful run alone does not measure peak memory.
|
|
|
|
Configure the repository `NGIT_PUBLISHER_NBUNKSEC` secret. Only the OCI and
|
|
NIP-82 publisher jobs request it, and pass its private
|
|
`$NGIT_CI_SECRETS_DIR/NGIT_PUBLISHER_NBUNKSEC` file directly to ngit. No secret
|
|
value enters a Nix derivation, output artifact, or command argument. The
|
|
existing `.ngit/release.yaml` and `.ngit/containers.yaml` retain the publication
|
|
metadata, relays and Blossom servers. Archive contents are reproducible with
|
|
a fixed tar timestamp; the NIP-82 release date comes from the actual Git tag.
|
|
|
|
Every release command requires an explicit tag context and fetches that tag from
|
|
the Nostr repository. Ordinary tag pushes check the Cargo version and both
|
|
the checkout and peeled tag against the signed `NGIT_CI_COMMIT_SHA`. A moved tag fails before
|
|
publication. Branch or pull-request contexts cannot publish.
|
|
|
|
## Stable release checklist
|
|
|
|
1. Finish implementation changes and their changelog entries before the release
|
|
commit. Run CI on the exact implementation commit and require successful Rust
|
|
CI and container deployment checks; a successful push is not a CI result.
|
|
2. Prepare the final version commit: update `Cargo.toml`, the root package entry
|
|
in `Cargo.lock`, and `nix/module.nix`; the flake derives its version from Cargo.
|
|
Move Unreleased notes into a dated release section, with Security before
|
|
Fixed and any operator security guidance under Security. Validate locked Cargo
|
|
metadata, Nix module parsing, formatting, and the diff.
|
|
3. Prepare an annotated version tag and fast-forward the **local** `stable`
|
|
branch to that same commit. Inspect branch/worktree state first; if `stable`
|
|
has diverged, resolve that explicitly instead of forcing it. If further fixes
|
|
are needed before publication, rerun CI and keep the release commit last.
|
|
4. When publication is authorized, push **all three refs**: `master`, `stable`,
|
|
and the exact version tag. A tag push starts release publication.
|
|
5. Verify the remote branches and peeled tag point to the intended release
|
|
commit, then check the release and crate publication workflows separately.
|
|
Do not report publication complete just because Git accepted the refs.
|
|
|
|
For a new stable release, with a clean tree on `master` at the reviewed release
|
|
commit, replace `vX.Y.Z` with the version being released:
|
|
|
|
```sh
|
|
release_tag=vX.Y.Z
|
|
# Check local and remote branch state before preparing the refs.
|
|
git fetch origin
|
|
git status -sb
|
|
git worktree list
|
|
git tag -a "$release_tag" -m "ngit-grasp $release_tag"
|
|
git switch stable
|
|
git merge --ff-only master
|
|
git switch master
|
|
|
|
# All three must resolve to the same commit before publication.
|
|
git rev-parse master stable "${release_tag}^{commit}"
|
|
|
|
# Run only when publication is authorized.
|
|
git push origin master stable "refs/tags/$release_tag"
|
|
git ls-remote origin refs/heads/master refs/heads/stable \
|
|
"refs/tags/$release_tag" "refs/tags/$release_tag^{}"
|
|
```
|
|
|
|
An annotated tag's direct ref identifies the tag object; compare its peeled
|
|
`^{}` result with the branch commit IDs. If the local tag was already prepared,
|
|
verify it instead of recreating it. Never move a published version tag. This is
|
|
one push invocation, not a guarantee of atomic updates across Nostr relays and
|
|
Git servers: inspect any partial failure and finish only the missing updates.
|
|
|
|
`stable` tracks the latest stable release commit, not subsequent development or
|
|
documentation commits on `master`. Prerelease tags do not advance `stable`.
|
|
|
|
## Manual container backfill
|
|
|
|
Replay `.ngit/nix/workflows/container_backfill.yaml` from a commit containing
|
|
this workflow with an explicit `refs/tags/v<version>` context. The current
|
|
reviewed command fetches only that historical tag, validates its Cargo version,
|
|
and extracts its source into the job's private workspace. It builds and
|
|
publishes only the exact OCI version tag, preserving `latest` and prerelease
|
|
aliases, then pulls and verifies the image. It does not publish a crate or
|
|
NIP-82 release.
|
|
|
|
This is the deliberate exception to ordinary release source matching: the
|
|
signed allocation commit supplies the workflow, tools and publisher while
|
|
the named historical tag supplies the Dockerfile and build context. A separate
|
|
predecessor provenance artifact records the version, ref, historical source
|
|
commit and allocation commit. The publisher refetches the tag and checks that
|
|
record before copying the layout and publishing. Historical source never
|
|
supplies the credentialed publisher code. Tags are neither moved nor created.
|
|
|
|
Crates.io publication remains independent; see
|
|
[publishing the crate](publish-crate.md). For nonpublishing validation run:
|
|
|
|
```sh
|
|
nix build .#checks.x86_64-linux.release-cli .#checks.x86_64-linux.release-scripts
|
|
```
|
|
|
|
These checks inspect CLI compatibility and exercise release guards, secret
|
|
handling and artifact fan-in using fake external commands. They do not publish
|
|
or perform a full Docker release run. Providers must allow enough predecessor
|
|
artifact bytes for the OCI layout (including extracted archive transport).
|