We often use the value of $CI_BUILD_REF_NAME in our .gitlab-ci.yml files, mostly for Docker image tags and review app environment URLs. All would be well and good with this, but most people at our company name branches like <username>/foo, or feature/bar. This means that:
The ref name can't be used as a docker image tag, since / is an illegal character there. We ended up adding this to most of our projects' .gitlab-ci.yml files to work around this:
The ref name can't be used as a review app subdomain directly. We couldn't find any way to make this work, so we're just managing branch deployment URLs outside GitLab.
Proposal
Add a $CI_BUILD_REF_SLUG to the build context which is just the $CI_BUILD_REF_NAME with all letters lowercased, and all non-alphanumeric characters replaced with a dash. So a feature/foo branch would get a slug like feature-foo, and a tag named macOS/v1.0.0 would be slugified as macos-v1-0-0.
Designs
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
Any reason this couldn't all be done with a one-to-three line shell script in perl, python or ruby that lives in a tools directory in your project? (Ie, why do it inside gitlab?)
This issue must affect tons of projects globally, anybody who has based their workflow on git flow or has for any other reason named branches that don't already adhere to the [a-z0-9-]+pattern (which in my experience is very common) will end up needing this few lines of code to use the ref name for docker tags/URLs/etc. — in our case that one before_script line is copy-pasted into around 10-20 projects at the moment, which of course is already not nice, but I'm sure that globally there's hundreds (if not thousands) of projects with similar code.
The more important problem is: it seemed to us that when setting an environment URL in the config, it's just not possible to run any code that we could use to compute the slug ourselves. See this part specifically:
These parameters can use any of the defined CI variables
And artifact names, cache keys (along with probably other things I don't know about) work the same way; they can can via some non-shell magic access the existing/defined variables, but nothing else. My point is, this definitely adds some value to providing precomputed variations (or at least one of them ) of the base variables.
Thanks for the mention @ayufan. An environment variable containing a domain/url-safe build-ref is definitely worth having, and solves the common case here.
However, it should be possible for the dynamic environment url to be constructed and set in the script, using arbitrary rules and code. We can't introduce variables covering every possible use case.
Using environment variables set in the script block would be extremely messy so I propose we use files for it, like so:
I don't know enough about what's happening in the background to know if we'd have to stipulate that the file be included in the artifacts for this to work or not.
One note on $CI_BUILD_REF_SLUG: it is imperative that if 'foo/bar' becomes 'foo-bar', 'foo-bar' should become 'foo--bar', and so on. Having foo:bar and foo/bar both become foo-bar is also problematic.
@nick.thomas It can be problematic, but I don't think this is the correct issue for such considerations. I'd much rather see GitLab follow the Python philosophy (with issues like this at least) that goes like
People using this software are all consenting adults
If someone uses these slugs (whose straightforward behavior would of course be well-documented), and for some incredible reason pushes both feature/make-foo-do-bar and feature-make-foo-do-bar, why not just let them fail? This is a highly unlikely (and not that disastrous) scenario, which could keep the feature from turning from
$CI_BUILD_REF_NAME with letters lowercased, and non-alphanumeric characters changed to a dash
to
$CI_BUILD_REF_NAME with letters lowercased, and non-alphanumeric characters changed to a dash, except for dashes, which are replaced with two dashes, and two non-alphanumeric characters in a row, which are [???]
Not only would it keep the feature easier to implement & maintain, but as a customer, I'd also prefer the easy to learn behavior instead of the foolproof one.
@ayufan I probably can't commit the time this cycle, unfortunately.
One thought - if the slug is mostly designed with being placed into URLs in mind, why not urlencode? It's standard and regular and non-colliding, although foo%2fbar isn't as pretty as foo-bar.
For what it's worth #1 (closed): % is not a legal character in Docker tags.
For what it's worth #2 (closed): if we had to choose between managing environment URLs outside GitLab (currently we're posting them to a slack channel after deployment is done) or having them URL encoded, we'd keep using the former option.
So dealing with odd characters is important, but some deploy targets, like Openshift, also limit the length of app names and URLs. In Openshift's case, it's 24 characters total. So if you want the project name and branch name in the app name, it gets tight really quickly. It's unrealistic to expect everyone to name their branches with only a few characters. I can't think of any good proposal to generalize length limitations though. One ugly option would be to have some syntax like ${CI_PROJECT_NAME:0:13}-${CI_BUILD_REF_SLUG:0:10} or ${CI_PROJECT_NAME:0:17}-${CI_BUILD_REF:0:6}. Used like:
Just realized my comment above is less of an issue for Openshift if you create a new Openshift project for each GitLab project, then the app name doesn't need to include $CI_PROJECT_NAME and you can use the full $CI_BUILD_REF_SLUG up to 24 characters. That's a lot more reasonable, although will still run into problems.
I'm also interested in other use cases we need to solve where$CI_BUILD_REF_SLUG is useful but $CI_ENVIRONMENT_SLUG would not be suitable / present. I'd say I'm still in favour of having it, but I wonder if the immediacy of the requirement is lessened.
I would just like a means to dynamically construct the URL. It's easy enough to spin up a new EC2 instances and get the public DNS. This is great in sandbox accounts for anything not going directly to production. However getting the host name on a new instance to match the build ref name requires you run your own DNS server to resolve the host name.