I've been battling with CircleCI and git tags and this is what I ended up with:
if [[ -n $(git branch --show-current) ]]; then git branch --show-currentelse git branch -a --contains $(git rev-parse --short HEAD) \ | sed '/HEAD/d' \ | sed 's/remotes\/origin\///g' \ | sed 's/\*//g' | sed 's/ *//g' \ | awk '!_[$0]++'fi
While it's a bit ugly, it does
- work for regular commits: it just uses git's
--show-current
flag and if that worked we need to look no further; both locally and on the CI container - work for tags: when the head is detached, it will get the remote branch name instead.
Caveats:
- This works fine as long as the tagged commits only appear on one branch. So if you're normally merging to say
dev
and from there viastaging
toproduction
, the original commit fromdev
will appear on all three branches, thereby breaking this code. But as long as you only ever tag the merge/PR commit - This requires to run
git fetch -a
to be run beforehand since the CI will only check out the default branch and the tagged commit so if the correct branch is neither of these it won't work
Some more explanation:
- I wanted to get the branch name, even when a CI build was triggered by a tag. In that case, the CircleCI
pipeline.git.branch
variable is not set nor can I easily get the branch name from git as the head is detached (as pointed out in many of the other questions). This means grepping the current branch (using the*
prefix) doesn't work either as on the CI, the current branch will be the detached head one. - The idea is to get all branches that include this commit (including remote ones); then remove the detached head result, get rid of all bits that aren't the actual branch name and de-duplicate