CI Integration¶
Vertagus talks to source control by running the git executable. It makes no
API calls to GitHub, GitLab, or any other host, and reads no platform-specific
environment variables, so it runs anywhere a git binary and a working checkout
are available.
What differs between platforms is not vertagus but the checkout their CI systems hand you. Two properties matter:
- Can the job push?
create-tagandcreate-aliaseswrite tags to the remote. - How much history was cloned? The
semverbumper reads commit messages since the last version tag.
Push credentials¶
vertagus create-tag ends in a git push of the new tag to the configured
remote. The job therefore needs credentials with write access to the repository.
GitLab's default CI_JOB_TOKEN cannot push to the repository — it is
scoped to reading the source and talking to the registry. The runner bakes
that token into the origin URL, so a push fails with 403 Forbidden even
though the clone succeeded.
Create a project access token
with the write_repository scope and at least the Maintainer role, store it
as a masked CI/CD variable, and point the remote at it:
tag:
stage: release
image: python:3.11
variables:
GIT_DEPTH: 0
rules:
- if: $CI_COMMIT_BRANCH =~ /^(release|hotfix)\//
before_script:
- pip install vertagus
- git remote set-url origin
"https://oauth2:${VERTAGUS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
script:
- vertagus create-tag -c vertagus.yaml -s prod
If your tags match a protected tag
pattern — v* is a common default — the token's identity must also be
allowed to create them, or the push is rejected regardless of scope.
The default GITHUB_TOKEN can push once the job is granted write
permission:
jobs:
tag:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install vertagus
- run: vertagus create-tag -c vertagus.yaml -s prod
Tag protection rules and required rulesets apply the same way GitLab's protected tags do.
When a push is rejected, vertagus reports git's own stderr alongside a reminder
of these causes, so a 403 in a pipeline log should point at the fix directly.
Clone depth¶
CI checkouts are shallow by default — GitLab CI uses GIT_DEPTH: 20, and
actions/checkout fetches a single commit. Two vertagus behaviours depend on
history being present:
vertagus bumpwith thesemverbumper reads every commit message since the last version tag. On a truncated clone it sees only the commits that were fetched, and computes too small a bump — silently, because a short history is indistinguishable from a quiet release.- The tag-based
version_strategyfinds the highest version by querying the remote, so it always sees every tag. If the tag it picks is older than the clone depth, vertagus fetches that one tag on demand rather than failing, but the commit range it then walks is still bounded by the clone.
Set the depth to unlimited in any job that runs bump, or that runs
create-tag with a semver bumper:
Jobs that only run validate against a target branch do not need full history:
the branch-based version_strategy reads a single manifest file out of
origin/<branch>, which one git fetch satisfies.
Detached HEAD¶
Both platforms check out a detached HEAD rather than a branch. Vertagus does not
depend on the current branch name — tags are created at an explicit commit, and
the branch used for validation comes from --target-branch / the -b flag. Pass
the platform's own variable:
Choosing a remote¶
Vertagus pushes to the remote named by remote_name in the scm block, which
defaults to origin — the name both platforms give the remote they configure.
Set it explicitly only if your job adds a second remote to push tags somewhere
other than where the code was cloned from.