Skip to content

Release Process

Jonathan D.A. Jewell edited this page Jul 11, 2026 · 1 revision

Release Process

Statistikles is released to the Julia General registry. This page summarises the maintainer runbook (docs/RELEASING.adoc) and the two workflows that automate it: .github/workflows/TagBot.yml and .github/workflows/release.yml.

If you are installing rather than releasing, see Installation.

The model in one paragraph

Releases go through JuliaRegistrator (opens the registry pull request) and TagBot (turns a merged registry PR into a GitHub tag + release). A separate Release workflow then builds a source tarball, an SPDX SBOM, and SLSA provenance, and attaches them to that release. You never create tags by hand — Registrator and TagBot own the tag. version in Project.toml is the single source of truth.

The moving parts

Piece Responsibility
Project.toml version The version being released. You bump this; everything else follows.
JuliaRegistrator (@JuliaRegistrator bot) Opens a PR against JuliaRegistries/General registering the new version.
General registry AutoMerge Merges that PR automatically once its guideline checks pass.
.github/workflows/TagBot.yml Reacts to the merged registry PR and creates the vX.Y.Z git tag + GitHub Release.
.github/workflows/release.yml Builds + attaches the source tarball, SPDX SBOM, and SLSA provenance.

One-time setup (first release only)

  1. Install the Registrator GitHub Apphttps://github.com/apps/juliateam-registrator on the hyperpolymath/statistikles repo (or the whole org). Any registered Julia user can also trigger registration by commenting; the app just makes it frictionless.
  2. Confirm Project.toml is registry-ready — a name, a stable uuid, and a complete [compat] block. Already true for Statistikles.
  3. No secrets required. TagBot runs on the default GITHUB_TOKEN; there is no Documenter site, so no SSH deploy key is needed.

Cutting a release — step by step

1. Bump the version

Edit Project.toml and raise version per semver:

version = "0.1.0"   # -> e.g. "0.1.1" (patch), "0.2.0" (minor), "1.0.0" (major)

While pre-1.0, a breaking change bumps the minor (0.1.x → 0.2.0) and a non-breaking change bumps the patch (0.1.0 → 0.1.1) — the convention AutoMerge enforces for 0.x packages.

2. Keep [compat] complete

AutoMerge refuses a release unless every non-stdlib dependency has a [compat] entry with an upper bound. Add a matching [compat] line in the same commit whenever you add or update a dependency. Standard libraries shipped with Julia (Dates, LinearAlgebra, Printf, Random, UUIDs, and Statistics on Julia ≥ 1.10) still take a [compat] entry of "1".

3. Merge to main (green)

Open a PR with the version bump and merge it to main. The Base ruleset requires the "E2E — Julia Test Suite" status check, so the PR cannot merge red. The commit you register next must be on main.

4. Trigger registration

On the merge commit on main (or the merged PR), comment:

@JuliaRegistrator register

To include release notes, add them under the trigger line:

@JuliaRegistrator register

Release notes:
## Highlights
- ...

Within a minute the bot replies with a link to the opened JuliaRegistries/General pull request.

5. Let AutoMerge do its work

The registry PR runs AutoMerge's guideline checks and merges on its own when they pass. A brand-new package's first registration additionally waits a 3-day period before AutoMerge; subsequent releases merge in minutes. If a check fails, the PR comment says exactly what to fix — correct it in-repo and re-comment @JuliaRegistrator register.

6. TagBot cuts the release

Once the registry PR merges, JuliaTagBot comments on this repository, firing .github/workflows/TagBot.yml. TagBot creates the vX.Y.Z git tag and a GitHub Release. The workflow only reacts to JuliaTagBot's comment or a manual dispatch:

# .github/workflows/TagBot.yml
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'

It uses the JuliaRegistries TagBot action with the default token (token: ${{ secrets.GITHUB_TOKEN }}) and no ssh deploy key. You can also run it manually from Actions → TagBot → Run workflow to backfill.

7. Attach artifacts (tarball + SBOM + provenance)

Because TagBot creates the tag using the default GITHUB_TOKEN, GitHub's recursive-workflow prevention suppresses the tag-push event, so release.yml does not start on its own. Finish the release one of two ways:

Default (no secrets): run it manually.

  1. Go to Actions → Release → Run workflow.
  2. Set tag to the vX.Y.Z TagBot just created and run it.

Optional (full automation): give TagBot a deploy key. Add an SSH deploy key (public key as a repo Deploy key with write access, private key as the DOCUMENTER_KEY secret) and add ssh: ${{ secrets.DOCUMENTER_KEY }} under the TagBot step's with:. A deploy-key push (unlike a GITHUB_TOKEN push) fires release.yml automatically, so step 7 needs no manual run.

What the Release workflow produces

.github/workflows/release.yml runs four jobs — build, changelog, release, and provenance — and attaches these assets:

Asset Produced by
statistikles-<version>.tar.gz git archive of the tag (source distribution)
statistikles-<version>.spdx.json anchore/sbom-action (syft), SPDX-JSON SBOM
<artifact>.intoto.jsonl slsa-github-generator SLSA v1 provenance over the two files above
Release notes body git-cliff changelog for the tag

Implementation details worth knowing:

  • Real SLSA subjects. The build job runs sha256sum <tarball> <sbom> into checksums.txt, then base64 -w0 encodes it into the hashes output that the SLSA generator consumes as base64-subjects — not an empty string.
  • Triggers. release.yml runs on push: tags: ['v*'] or workflow_dispatch with a tag input. Under the default token flow you use the manual dispatch; the push: tags trigger exists for the optional deploy-key setup. Either way nothing runs until a real version is registered.
  • git-cliff is version-pinned (GIT_CLIFF_VERSION: '2.13.1') because the release assets are version-stamped; the versionless latest/download/… path would 404 and fail the changelog job.
  • Prerelease detection. A tag containing -rc, -beta, or -alpha is published as a GitHub prerelease.
  • SLSA isolation. Provenance runs in the separate reusable workflow slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml, as SLSA Build L3 requires.

First-registration caveats (AutoMerge requirements)

The General registry AutoMerges a new package only when all of these hold:

  • Name ≥ 5 chars, starts with a letter, not confusingly similar to an existing package. Statistikles (12 chars) is fine.
  • UUID is fixed in Project.toml (cc532b54-de7e-466e-8dd9-45d18a432455) — never change it between releases.
  • [compat] completeness — every non-stdlib dependency and julia has an upper-bounded entry.
  • Version rule — first registration is a normal starting version (0.1.0); later versions increase and follow the 0.x breaking rule.
  • Standalone, loadable source — the registered commit is on main, the package loads (julia --project=. -e 'using Statistikles'), and the repo is public.
  • New-package waiting period — the very first version waits 3 days; this is normal.

First-release checklist

  • version bumped in Project.toml (semver; 0.x breaking-change rule)
  • [compat] complete for every dependency + julia
  • PR merged to main with "E2E — Julia Test Suite" green
  • Registrator GitHub App installed on the repo (one-time)
  • @JuliaRegistrator register commented on the merge commit
  • Registry PR AutoMerged (allow the 3-day wait on the first package)
  • TagBot created the vX.Y.Z tag + GitHub Release
  • Release workflow run (Actions → Release → tag = vX.Y.Z) so the tarball, SBOM, and SLSA provenance are attached

Troubleshooting

Symptom Fix
Registrator bot never replied App not installed, or you commented on a non-main commit. Install the app; comment on a main commit.
Registry PR did not AutoMerge Read the PR's AutoMerge comment — usually a missing [compat] bound or the 3-day new-package wait. Fix and re-register.
TagBot did not run Confirm the registry PR merged, then run Actions → TagBot → Run workflow.
Release has notes but no tarball/SBOM/provenance Expected under the default token flow — run Actions → Release → Run workflow with the tag, or adopt the deploy-key upgrade in step 7.

Out of scope

Container image releases and the guix.scm package are tracked separately and are not part of this registry release flow. See Installation for the container build.

See also

Clone this wiki locally