I’m currently struggling to implement something my team would like to have for our CI:
We would like to run a certain job only for a tag that equals a certain variable in our CI.yml.
For example and to be precise, we want to run a deploy job only for the tag v1.0.0 when a CI variable VERSION is 1.0.0. Afterwards we would like to change it so the tag v1.0.0-rc1 or v1.0.0-rc2, etc. also runs the deploy step.
I’ve been running into a lot of problems even trying to get the basic setup working:
I can’t seem to be able to have the rules keyword even check for a variable with a leading “v”
Trying to combat that, i was trying to define a pattern to see how that would go and it can’t even get that to work
Has anybody been doing something similar? Any pointers on how we might be able to achieve what we’re aiming at?
What version are you on?
I’m using gitlab.com - i can link my test repository, if that is any helpful.
Add the CI configuration from .gitlab-ci.yml and other configuration if relevant (e.g. docker-compose.yml)
our version variable needs to be the in the format x.y.z without the leading “v”. Is that any important? It’s not currently being used in this example anyways. We would like to have the regex use that variable, but that seems impossible?
i changed the variable name of the pattern to $IS_VERSION_TAGGED
i changed what is being compared in the regex: We want to check the tag of the current commit, so i am using the gitlab CI variable for the tag
It results in the “deploy (release)” job always running, even on master without any tag.
Anything obvious i missed? And thanks a lot again!
To be honest I don’t know how it evaluates if the variable CI_COMMIT_TAG is not defined. Try to put another rule that checks if it is defined
# don't run if its not tag
- if: $CI_COMMIT_TAG == null
when: never
I don’t think it matters if the variable is leading with ‘v’ or not, but always put it in quotes in that case so it isn’t evaluated somewhere like integer instead of string.
Now it runs the snapshot job for the master branch (good) and
it runs the deploy job for the tag v1.0.0 (good).
But it also runs the deploy job for the tag v0.1.0 (bad) and
it even runs the deploy job for the tag peter (bad) which makes me think it does not care what exactly the tag contains.
Any more ideas?
Edit: To me it honestly feels like a bug in GitLab CI at this point…?
I tried that out and while it’s working in a way, it’s not really what i was going for: It seems like then the tag can only be the exact version - so it’s basically just ==? I tried the tag 1.0.0 which results in a deploy job. I also tried the tag 1a0.0 expecting the =~ operator would do a regex matching - but that did only trigger a snapshot job. Would make sense, because $VERSION does not include the / for it to become a regex?
But what we would like to have is a regex match so we can include the release candidate tagging. So i tried to extend your version:
I added a variable VSN_REGEX: '/v1\.0\.0/' because of your response saying i cannot use nested variables
I use that variable in the rule like this: if: '$CI_COMMIT_TAG && $CI_COMMIT_TAG =~ $VSN_REGEX'
I was hoping that would get it to work, but now it nevers runs the release job.
I tried changing my regex variable to be this, thinking i might do a mistake in matching the literal dot: VSN_REGEX: '/v1\\.0\\.0/' which does not help either.
It made me wonder if the problem is due to having the regex in a variable, like @balonik said earlier:
but even placing the regex - as in if: '$CI_COMMIT_TAG && $CI_COMMIT_TAG =~ /v1\\.0\\.0/' - in the rules does not make it work…
I think i screwed up my regex and will start investigating that first of all. If i can’t even get my hardcoded regex to work then there is no use trying to see what issues there are with trying to refactor variables out and so on.
Seem to me like there is not much for me to do in regards to my CI for now.
Can someboy tell me: Do i go and comment in those issues with my (shortened) use case? Or does that add unnecessary noise and i should only upvote the issues via the “thumbsup”-emoji?
Thanks again for your help, much appreciated! Although it was mostly my own stupidity with the regex pattern not being valid
I use regexps in rules too, they can work, but I wouldn’t put them in a variable. Does something like this get you a bit closer (you might want to tweak the reg exp here, I haven’t tested it):
I didn’t mean to say that regex’s don’t work in rules. Sorry if i made it sound like that!
What i meant is that my regex in the rule works perfectly fine now. It’s just that i now have to repeat the “version information” three times in different places in the CI.yml. That’s a lot worse than having one version variable at the top of the CI.yml, like we had before.
The “tagged version number” equals the expected version number. With your change we would lose that confidence and might accidently publish a build with $VERSION: 1.0.0 via tag v2.0.0
The missing release-candidate recognition is important to us and manly the reason we even change our rule from a simple $CI_COMMIT_TAG == $VERSION - but maybe you left that part out only for easier reading.
I will have to discuss with my team if we feel like the added maintenance / error chance of having our current version three times in our CI.yml is worth it to be able to recognize the release candidate tags. Maybe we will simply stick with the version from before until GitLab fixes the issues i linked earlier, because it’s just not worth it for us for now.
I knew about anchors but didn’t think far enough to use it in this situation. Very cool!
I am now using an anchor to not duplicate the rule with the pattern, just like you already showed:
.release-job:
tags:
- windows
rules:
- if: &version '$CI_COMMIT_TAG && $CI_COMMIT_TAG =~ /^v1\.0\.0(-rc.+)?$/'
when: always
.snapshot-job:
tags:
- windows
rules:
- if: *version
when: never
- when: always
It still has the disadvantage, that i have the version duplicated once though: At the top in the variable and in the line with the rule. I don’t think i can use anchors to “fix” that either, but i haven’t looked into that (yet).
The rest of your example was interesting to look at, but i don’t see any advantages over the extend-approach i’m currently using where i extend the “release” or “snapshot” job template, as necessary. Feel free to correct me if i’m missing something though !
Thanks again for the help, much appreciated! “As soon” as GitLab supports the two linked functionalities this approach will be a breeze to work with anyways.
So, taking your last question first "is there a difference between anchors and extends", the main difference is just that extends is specific to GtiLab and anchors are a YAML thing. In the example I gave there isn’t a meaningful difference. Once you start extending jobs and overriding variables etc. then it’s worth understanding how definitions are merged, but I doubt there’s much else.
For your other query, about duplicating the regex definition, it’s not clear to me why you need that other variable; but it may be that you can use an alias there too.
We use that $VERSION variable in the .gitlab-ci.yml to “set” the version of our build. So that variable is used for a few things like the file version of the build artifact, also in some Maven POM’s, while building an installer executable and maybe more i’m currently forgetting.
We like having that version only defined in one place for the whole project and bumping only that value up when working on a new version. That’s why it will be nice for us, when GitLab supports to refactor our rule to use the $VERSION variable that already “controls” all other pieces in our CI.