Skip to content

Run it in GitLab CI

Goal: every merge to your default branch keeps a Release merge request up to date, and merging that request tags the commit that actually landed.

You need a project on GitLab, a stages: list you can add to, and a token.

1. Provide a token

colophon needs a forge token with api and write_repository. It uses it for the API calls, the release-branch push and the tag push.

It must not be CI_JOB_TOKEN. A tag pushed with CI_JOB_TOKEN does not fire downstream tag pipelines, so your goreleaser or publish jobs would never run.

Set it as a CI/CD variable named COLOPHON_TOKEN, masked and protected.

2. Add the component

include:
  - component: gitlab.com/phpboyscout/cicd/[email protected]
    inputs:
      stage: release
      branch: main

stages:
  - lint
  - test
  - release

That is the whole setup for the common case. The component adds two jobs:

Job What it does
colophon-publish A Release merge request has merged: resolve what landed on the target, tag that commit, create the release.
colophon-propose-next Re-cut the release branch from the target and open or update the Release merge request for the next release.

3. Leave the order alone

publish runs before propose, and the component enforces that with needs:. It is a correctness constraint rather than a preference.

After a Release merge request merges, the release commit is on the target branch but the tag does not exist yet. In that window colophon computes the same release again. A pipeline that proposed first would re-open a Release merge request for the version about to be tagged, publish would then tag it, and that merge request would sit open forever proposing a release that has already happened.

Inputs

Every input has a default; most projects set none of them.

Input Default Notes
image registry.gitlab.com/phpboyscout/images/release-tools:v0.1.3 Image carrying the colophon binary. Renovate keeps it current.
stage release One stage is enough. Declare it in your own stages:.
branch main Target branch to release from.
token $COLOPHON_TOKEN Needs api + write_repository. Never CI_JOB_TOKEN.
if $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH Gating rule for both jobs. Set it to match if you release from a non-default branch.
author_name colophon Identity on the release commit and tag.
author_email [email protected] See author_name.
release_branch derived Empty derives colophon/release/<branch>.
propose true Set false to publish only.
publish true Set false to propose only, which is the safe half: it opens a merge request and cuts no tag.

Try the safe half first

If you are migrating a project that already releases some other way, run propose on its own to begin with. It opens and updates a merge request and cuts no tag, so you can compare its answer against your existing tool without either of them acting.

include:
  - component: gitlab.com/phpboyscout/cicd/[email protected]
    inputs:
      stage: release
      publish: false

colophon plan is the even safer version of the same comparison, and runs on your laptop. See Getting started.

Running it outside the component

The component is a convenience. The commands underneath it take a token from <FORGE>_TOKEN in the environment, upper-cased from the forge name, so GITLAB_TOKEN for GitLab and GITHUB_TOKEN for GitHub.

GITLAB_TOKEN=$COLOPHON_TOKEN colophon publish --target main
GITLAB_TOKEN=$COLOPHON_TOKEN colophon propose --target main