GitLab CI and poetry-dynamic-versioning
All notes in this series:
- (1) Poetry: Fixing dubious ownership error
- (2) Poetry: build.py example
- (3) Poetry: Automatically generate package version from git commit
- (4) Poetry: Fix warning about sources
- (5) Poetry: Running Black and isort with pre-commit hooks
- (6) Poetry: Fixing permission error when upgrading dulwich
- (7) NiceGUI with Click, Poetry, auto-reload and classes
- (8) Poetry: Offline installation of packages
- (9) Run Poetry command as systemd service
- (10) GitLab CI and poetry-dynamic-versioning
- (11) Poetry: install alpha builds
tl;dr: The branch
variable in poetry-dynamic-versioning does not work if your Git repository has a detached HEAD, which is likely to be the case under GitLab. Fortunately, there is an easy fix.
The poetry-dynamic-versioning plugin provides a branch
variable which is the name of the current branch, or if that fails, None
:
branch
(string or None)
Assuming branch is not None
, this allows you to change the build version depending upon the branch. For example to have untagged builds on the main
branch be alpha
, and all other branches be dev
:
format-jinja = """
{%- if distance == 0 -%}
{{- base -}}
{%- elif branch == "main" -%}
{{- bump_version(base) }}.alpha{{ distance }}+g{{commit}}
{%- else -%}
{{- base }}.dev{{ distance }}+g{{commit}}
{%- endif -%}
"""
This works locally, but unfortunately under GitLab CI the branch
variable returns None
, preventing it from working.
Verifying branch
is None
under GitLab CI §
You can verify this with the following:
format-jinja = """
TEST_{{- branch -}}_TEST
"""
This will fail locally and on GitLab CI, because TEST_<blah>_TEST
is not a valid Python version. But crucially, it will fail differently!
Assuming you are running it on the branch main
:
- Locally it will fail with
TEST_main_TEST
. - On GitLab CI it will fail with
TEST_None_TEST
.
Investigating why we get None
under GitLab CI §
Looking at the plugin source, the plugin gets the Version
object from dunamai. Following through in the dunamai source, it gets the branch
variable from Git:
code, msg = _run_cmd("git symbolic-ref --short HEAD", path, codes=[0, 128])
if code == 128:
branch = None
else:
branch = msg
If we try this out manually in GitLab CI, we see the issue:
$ git symbolic-ref --short HEAD
fatal: ref HEAD is not a symbolic ref
The Git command is failing, which explains why branch
is defaulting to None
under GitLab CI.
It fails because Git is checking out a commit, rather than a branch, and so it has a “detached head”.
For example, see this GitLab tutorial:
Checking out 7226fc70 as detached HEAD (ref is main)...
Fixing the detached head in GitLab §
This can be fixed by calling the following in GitLab CI:
git checkout "$CI_COMMIT_REF_NAME"
Call it in before_script
(or wherever makes more sense), and it will ensure the checkout does not have a detached HEAD. This will allow git symbolic-ref --short HEAD
to get the branch name, and in poetry-dynamic-verisoning, the branch
variable will be populated correctly.
Appendix §
Attempted fix with GIT_DEPTH: 0
§
The Dunamai README warns that it needs access to the full version history, and suggests using GIT_DEPTH: 0
in GitLab. However, in my testing this didn’t seem to address the issue of Git performing a detched HEAD clone. For example, with the following in .gitlab-ci.yml
:
variables:
GIT_DEPTH: 0
CI_DEBUG_TRACE: "true"
A detached HEAD clone still occurs in the GitLab job log:
Created fresh repository.
Checking out ac3b2af1 as test-git-depth...
++ echo 'Checking out ac3b2af1 as test-git-depth...'
++ git checkout -f -q ac3b2af1ac7c21afe393ab1238ec35cc8ffcd48c
A potential better fix? §
It may also be possible to avoid the deatched HEAD situation by changing your GitLab workflow(?). Further reading and investigation required.
All notes in this series:
- (1) Poetry: Fixing dubious ownership error
- (2) Poetry: build.py example
- (3) Poetry: Automatically generate package version from git commit
- (4) Poetry: Fix warning about sources
- (5) Poetry: Running Black and isort with pre-commit hooks
- (6) Poetry: Fixing permission error when upgrading dulwich
- (7) NiceGUI with Click, Poetry, auto-reload and classes
- (8) Poetry: Offline installation of packages
- (9) Run Poetry command as systemd service
- (10) GitLab CI and poetry-dynamic-versioning
- (11) Poetry: install alpha builds