Files
computer-playbook/docs/contributing/actions/release.md
T
kevinveenbirkenbachandClaude Opus 5 71888d86af refactor(ci): prefix workflows by trigger
The workflow directory mixed entry points, reusable stages and scheduled jobs into one flat list sorted by topic, so the first question about any file - what starts it - was the one the name did not answer. Every workflow now carries one of three prefixes, derived from its on: block: cron- for a schedule trigger, call- for one only reachable through workflow_call, entry- for everything a repository event or a human starts. Scheduled workflows additionally carry an alarm clock as the first character of their name.

Two lints keep it that way. One derives the expected prefix from the triggers and compares it against the file name; it flagged all 17 offenders before the rename and none after. The other resolves every .github/workflows/<file> string in the repository against the directory, which is what a rename silently breaks in Markdown links, Python constants and shell API URLs alike.

Renaming pulled 69 pre-existing comments into the comment lint's changed-file scope. The vendored CodeQL template got the nocheck marker its scorecard sibling already carried, two workflow headers moved above name: where they count as file headers, and the remaining banners were deleted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 17:05:51 +02:00

4.7 KiB

Release 🚀

Contributor guidance for cutting a tagged release of Infinito.Nexus. For local-deploy and edit/redeploy guidance see deploy.md. For commit-message conventions see commit.md.

Versioning 🔢

Release tags follow Semantic Versioning with a leading v: v<MAJOR>.<MINOR>.<PATCH> (for example v7.0.0).

Component Bump when
MAJOR A change is incompatible with prior inventories, on-disk role-meta layout, deploy CLI, or stored runtime state.
MINOR New roles, new CLI surfaces, or a non-breaking schema extension lands.
PATCH Bug fixes, doc fixes, or test-only changes that do not move public surface.

Pre-release suffixes (-rc1, -alpha2, +build.5) MAY be appended; the archive CLI preserves them in archived filenames.

Active Window vs. Archive 🗂️

CHANGELOG.md at the repository root holds the most recent releases inline. Older releases live one-file-per-version under docs/changelog/, linked from the ## Older Releases section at the bottom of the active changelog.

The active window has a default retention of 7 entries. A higher count is fine for short bursts of releases, but the active changelog SHOULD stay short enough that scrolling it is cheap.

Cutting a Release ✂️

  1. Update CHANGELOG.md: prepend a new ## [<version>] - <YYYY-MM-DD> section with the change set, written in the same style as the existing entries. When the release ships package metadata, also update packaging/debian/changelog and the %changelog section of packaging/fedora/infinito-nexus.spec with the corresponding entries.

  2. Trim CHANGELOG.md and mirror its kept entries into the package changelogs:

    python -m cli.contributing.changelog.archive
    

    The CLI keeps the most recent 7 entries (override with --keep N) and processes each of the following files:

    • CHANGELOG.md is trimmed; every older entry is written to its own file under docs/changelog/ named <padded-semver>-<release-date>.md, and the ## Older Releases index at the bottom of the active changelog is rebuilt from the archive directory listing so it never drifts away from what is on disk.
    • packaging/debian/changelog and the %changelog section of packaging/fedora/infinito-nexus.spec are regenerated from the kept CHANGELOG.md entries, with a trailing notice that points at docs.infinito.nexus for further releases and a plain-text list of the archived versions and their dates (no links).

    Pass --dry-run to preview without writing.

  3. Run make test locally and confirm everything is green.

  4. Commit the changelog and any archive additions in a single commit with subject Release version <MAJOR>.<MINOR>.<PATCH> (matching the historical convention).

  5. Tag the commit: git tag -a v<MAJOR>.<MINOR>.<PATCH> -m "Release version <MAJOR>.<MINOR>.<PATCH>".

  6. Push the branch and the tag with git-sign-push, running it outside the sandbox.

CI on Tag Push 🤖

A v* tag push fans out into two CI workflows:

Workflow Purpose
call-release-version.yml Backfills CI images for the version tag if missing, retags them to release tags, and publishes the version-specific image set.
cron-release-highest.yml Decides whether the new version is the highest published version and, if so, advances the latest floating tag.

Both run from the trusted workflow ref and check out the version tag for the actual build payload, so the release artefacts match the tagged commit byte-for-byte.

Idempotence 🔁

The archive CLI is byte-idempotent. Re-running it on an already-processed tree leaves every file unchanged: CHANGELOG.md is rewritten only when its target content differs from disk, the per-release archive files are never overwritten, and the package changelogs are only rewritten when the regenerated content differs from disk. This makes it safe to run from a pre-commit hook, a release script, or by hand without keeping track of state.