Skip block in YAML files in GitLab based on condition - gitlab

I have a repo in GitLab. It contains a .gitlab-ci.yaml than has a variable called VERSION. I use this variable in regular .yaml files in the project as:
...
version: ${VERSION}
...
I want to make this YAML code block be omitted (or perhaps replaced by an empty string) if a specific version is provided.
For example,
gitlab.ci-yml:
variables:
VERSION: 7
A regular YAML file:
app1:
name: my-app
version: ${VERSION}
I want this block in the regular YAML file be skipped if version is 8. How can I do that?
GitLab version: 13.12
UPDATE
My YAML block app1 also has enabled: true attribute. Is there a way to put a conditional statement instead of that true? For example,
app1:
name: my-app
enabled: # SOME CONDITIONAL STATEMENT HERE
version: ${VERSION}

You should be able to make use of rules:if to specify when you want the job to run.
So in your particular case you would add this to your job (adding indentation spacing as needed):
rules:
- if: '$VERSION != 8'
alternatively, you can specify that when it matches, not to run it:
rules:
- if: '$VERSION == 8'
when: never

Related

Gitlab CI: How can I select 'include' ref dynamically?

I need include yml file with logic that if branch with same name exist in other project then include yml from this branch, else include yml from master branch.
Is there a way to make that?
I think about using dynamic variable, but I don't know how to set it before include and after access to triggered ref name
include:
- project: my_other_project
ref: $branch_name_that_equals_current_branch_or_master_branch
file: my.yml
Check which variable you are using. According to the docs you can only use certain variables like predefined variables or those set manually when triggering the pipeline. Unfortunately you cannot use variables defined in the variables block.
So, your example will work if you use one of the variables mentioned here.
include:
- project: my_other_project
ref: $CI_COMMIT_REF_NAME
file: my.yml
For instance.
See
Use variables with include
Where variables can be used
In your yaml file
variables:
REF: master
stages:
- build
build:
stage: build
only:
refs:
- $REF
script:
- echo "Building branch $REF"

GitLab Templating: Multiple before_script blocks in default?

This doesn't work correctly:
template1.yml
default:
before_script:
- echo "hello from one"
template2.yml
default:
before_script:
- echo "hello from two"
.gitlab-ci.yml (the actual pipeline)
include:
- project: 'templates'
file:
- 'template1.yml'
- 'template2.yml'
build1:
stage: build
script:
- echo "hello from the pipeline"
output (note the output from template1 is missing):
Hello from two
hello from the pipeline
I understand that GitLab may believe that there is 'ambiguity' in the ordering when merging blocks in to before_script, but it could use the order specified in the 'include'
section of the pipeline.
Does anyone know of a way that I can arbitrarily include templates in my pipeline in such a way that they can contribute to the default 'before_script' block?
It all must run sequentially in the same container (be in the same 'stage')
For example, using yaml anchors requires us to specify the names of the anchors rather than just the file that the anchors were in, so that doesn't work...

CI_PROJECT_DIR not respected in gitlab CI rules

Consider the following pipeline:
image: alpine
stages:
- test
this-does-not-run:
stage: test
rules:
- if: $CI_PROJECT_DIR == "/builds/test"
script:
- echo "It works!"
this-runs:
stage: test
rules:
- if: $CI_PROJECT_DIR != "/builds/test"
script:
- echo "It doesn't work! CI_PROJECT_DIR- $CI_PROJECT_DIR"
And assume my repo is called test. The output of this CI will always be:
It doesn't work! CI_PROJECT_DIR- /builds/test
Obviously $CI_PROJECT_DIR == /builds/test, so I would expect the output to be It works!. Am I missing something, or is $CI_PROJECT_DIR not respected in rules?
The problem here is that variables in rules: must be expanded (evaluated by) the GitLab server at pipeline creation time, but $CI_PROJECT_DIR is determined by the runner's builds_dir setting, which is only known by the runner at runtime when the job actually runs:
References to unavailable variables are left intact. In this case, the runner attempts to expand the variable value at runtime. For example, a variable like CI_BUILDS_DIR is known by the runner only at runtime.
That is to say, like CI_BUILDS_DIR, you can't use CI_PROJECT_DIR or other runtime-only variables in rules:if:. Instead, you should use a variable that is known to the gitlab server at pipeline creation time, such as CI_PROJECT_NAME CI_PROJECT_ID, CI_PROJECT_URL, CI_PROJECT_PATH_SLUG or similar.
Try to wrap the expression in quotes. Afaik this is an expression and you would need to wrap it.
Eg:
rules:
- if: '$CI_PROJECT_DIR == "/builds/test"'
If you only have variables, then from experience you don't need to wrap it.
Eg:
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

How to use the project namespace in the environment URL of GitLab CI?

I'd like to parameterize the environment URL of one of my GitLab CI job in a project which belongs to a subgroup.
If for example I have:
CI_PROJECT_PATH = mygroup/mysubgroup/myproject
CI_PROJECT_NAMESPACE = mygroup/mysubgroup
CI_PROJECT_NAME = myproject
I'd like to have the URL to be something like https://mygroup.gitlab.com/-/mysubgroup/myproject/-/jobs/12345/artifacts/public/index.html.
But I cannot find a way to do this since there is no predefined variable for the "sub-namespace" (here mysubgroup) and there is no variable substitution in environment.url as far as I can see.
I tried in my gitlab-ci.yml things like that:
build:
stage: build
image: bash:latest
script:
- export # print the available variables
environment:
name: test
url: ${CI_SERVER_PROTOCOL}://${CI_PROJECT_ROOT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_PATH#${CI_PROJECT_ROOT_NAMESPACE}/}/-/jobs/$CI_JOB_ID/artifacts/public/index.html
but the result is https://mygroup.gitlab.com/-/${CI_PROJECT_PATH#myproject/}/-/jobs/12345/artifacts/public/index.html.
References:
https://stackoverflow.com/a/58402821/1064669
https://gitlab.com/gitlab-org/gitlab/-/issues/350902
job:environment:url is directly processed by gitlab, which does not support this kind of parameter expansion.
You'll need to use bash or a similar shell for this to work as intended:
build:
stage: build
image: bash:latest
script:
- echo "DEPLOY_URL=${CI_SERVER_PROTOCOL}://${CI_PROJECT_ROOT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_PATH#${CI_PROJECT_ROOT_NAMESPACE}/}/-/jobs/$CI_JOB_ID/artifacts/public/index.html" > deploy.env
- cat deploy.env
artifacts:
reports:
dotenv: deploy.env
environment:
name: test
url: $DEPLOY_URL
Based on the example given here: https://docs.gitlab.com/ee/ci/environments/#example-of-setting-dynamic-environment-urls
I think you need to escape the inner curly braces like this: (${CI_PROJECT_ROOT_NAMESPACE} should become $`{CI_PROJECT_ROOT_NAMESPACE`})
So the whole thing becomes:
url: ${CI_SERVER_PROTOCOL}://${CI_PROJECT_ROOT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_PATH#$`{CI_PROJECT_ROOT_NAMESPACE`}/}/-/jobs/$CI_JOB_ID/artifacts/public/index.html

How to limit a job in gitlab ci to a tag matching a pattern?

I want to be able to trigger a deployment to a special server every time a tag matching a pattern is pushed.
I use the following job definition:
# ...
deploy to stage:
image: ruby:2.2
stage: deploy
environment:
name: foo-bar
script:
- apt-get update -yq
- apt-get install -y ruby-dev
- gem install dpl
# - ...
only:
- tags
Now my question: how can I limit this to tags that have a certain name, for example starting with "V", so that I can push a tag "V1.0.0" and have a certain job running?
Only accepts regex patterns so for your use case it would be:
only:
- /^V.*$/
except:
- branches
- triggers
Since only / except are now being deprecated, you should now prefer the rules keyword
Things get pretty simple, here's the equivalent using rules:
rules:
# Execute only when tagged starting with V followed by a digit
- if: $CI_COMMIT_TAG =~ /^V\d.*/
The best way to do is filtering by the Gitlab CI/CD variables matching your pattern
only
variables:
- $CI_COMMIT_TAG =~ /^my-custom-tag-prefix-.*/
As the documentation says:
CI_COMMIT_TAG: The commit tag name. Present only when building tags.
rules should help you here.
Below would restrict the job to run only if its triggered due to GIT Tag matching the pattern for e.g. V1.0.0 or V1.14.45 (see + after \d)
rules:
- if: '$CI_COMMIT_TAG =~ /^V\d+.\d+.\d+$/'
when: manual

Resources