Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Releasing

CHANGELOG.md drives the releases. It follows the Keep a Changelog format: a ## [Unreleased] section at the top, then one ## [X.Y.Z] - YYYY-MM-DD section per released version, newest first. There is no release command to run and no tag to push: writing a new version section and pushing it to main is the release.

Day to day

Record every user-visible change under ## [Unreleased], in the same commit as the change, grouped under the usual Keep a Changelog headings (### Added, ### Changed, ### Fixed, ### Removed…).

Pushes that do not add a version section only run the checks described in Continuous integration.

Cutting a release

  1. Rename the [Unreleased] section to the new version and today’s date, and add a fresh, empty [Unreleased] section above it:

    # Changelog
    
    ## [Unreleased]
    
    ## [0.2.0] - 2026-12-01
    
    ### Added
    - Three display modes: grid, loupe with a filmstrip, full screen
    
  2. Bump the version in Cargo.toml to the same number (version = "0.2.0"), then run cargo check so that Cargo.lock records it too. CI builds with --locked and fails on an outdated Cargo.lock.

  3. Commit both files and push to main, directly or by merging a merge request.

What CI does

The pipeline of a push to main reads the topmost version heading of CHANGELOG.md, ignoring [Unreleased]. That heading must be exactly ## [X.Y.Z] - YYYY-MM-DD: any other level-2 heading in its place (a typo in the date, missing brackets) fails the pipeline rather than being skipped. If the tag vX.Y.Z for that version does not exist yet, the push is a release, and the pipeline:

  1. Runs the usual checks.
  2. Checks that the version in Cargo.toml equals X.Y.Z and that X.Y.Z is greater than every existing vX.Y.Z tag, and fails otherwise.
  3. Builds Linux, Windows and macOS release binaries (see Continuous integration).
  4. Uploads the release archives to the project’s generic package registry.
  5. Creates the tag vX.Y.Z on the pushed commit and the GitLab Release, whose notes are the ## [X.Y.Z] section of the changelog and whose assets link to the uploaded archives.

The new tag starts a pipeline of its own, which deploys the documentation (see below).

When the tag already exists, the version is considered released and the push only runs the checks. That makes later pushes safe: they never release the same version twice.

When a release fails

The tag is created only after the builds and the uploads have succeeded. If any earlier step fails, for example on a version mismatch, nothing is tagged: fix the problem, push to main again, and the release runs again.

If the last job, release:publish, fails after the tag was created but before the GitLab Release exists, retry that job: it notices the tag on its own commit and creates the missing release. A new push would not help, because it treats a tagged version as released.

Do not create vX.Y.Z tags by hand. CI treats an existing tag as an already released version, so a hand-made tag would skip the builds and the GitLab Release.

Documentation

The documentation site at https://julienbltt.gitlab.io/image-toolkit/ is deployed by the pipeline of each release tag. It therefore describes the latest released version, not the work in progress on main.

To republish it between releases, for example after fixing a typo, run the manual documentation job from the latest pipeline on main. Keep in mind that it publishes the state of main, including any documentation of unreleased features.

Do not re-run the documentation job of an older tag’s pipeline: it would put that older version of the site back online.