I want to set some variables by getting the values from a pom.xml file. These variables need to be global because they will be used in multiple stages and jobs.
According to the gitlab-ci documentation, I can set global variables in two differents ways:
using a variable statement:
variable:
pom_artifactID: $(grep -m1 '<artifactId>' pom.xml | cut -d '<' -f2 |cut -d '>' -f2)
Using a "before" script:
before_script:
- pom_artifactID=$(grep -m1 '<artifactId>' pom.xml | cut -d '<' -f2 |cut -d '>' -f2)
- pom_artifactVersion=$(grep -m1 '<version>' pom.xml | cut -d '<' -f2 |cut -d '>' -f2)
- pom_packaging=$(grep -m1 '<packaging>' pom.xml | cut -d '<' -f2 |cut -d '>' -f2)
- pom_finalName=$({ grep -m1 '<finalName>' pom.xml | cut -d '<' -f2 | cut -d '>' -f2; [ ${PIPESTATUS[0]} -eq 0 ] && true || echo ${pom_artifactID}-${pom_artifactVersion}.$pom_packaging}; })
The first doesn't work because gitlab-ci doesn't evaluate $(command), so pom_artifactID
becomes a literal "$(grep -m1 '' pom.xml | cut -d '<' -f2 |cut -d '>' -f2)"
The second doesn't work either because "before_script" relies on the "grep" command and some docker images used in my pipeline have an old version of grep.
There is another way to set global variables o pass variables between stages and jobs?
There is currently no way in GitLab to pass environment variable between stages or jobs.
But there is a request for that: https://gitlab.com/gitlab-org/gitlab/-/issues/22638
Current workaround is to use artifacts - basically pass files.
We had a similar use case - get Java app version from pom.xml
and pass it to various jobs later in the pipeline.
How we did it in .gitlab-ci.yml
:
stages:
- prepare
- package
variables:
VARIABLES_FILE: ./variables.txt # "." is required for image that have sh not bash
get-version:
stage: build
script:
- APP_VERSION=...
- echo "export APP_VERSION=$APP_VERSION" > $VARIABLES_FILE
artifacts:
paths:
- $VARIABLES_FILE
package:
stage: package
script:
- source $VARIABLES_FILE
- echo "Use env var APP_VERSION here as you like ..."
pom.xml
By the way it's better to treat xml.pom
as XML to extract values from pom.xml
rather than plain grep
, because XML elements can potentially span multiple lines.
There are at least a couple of options, examples:
xmllint
tool from libxml2-utils
get-version:
image: ubuntu
script:
- apt-get update
- apt-get install -y libxml2-utils
- APP_VERSION=`xmllint --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()' $POM_FILE`
python
xml processingget-version:
image: python3
script:
- APP_VERSION=$(python3 -c "import xml.etree.ElementTree as ET; print(ET.parse(open('pom.xml')).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With