How to execute an if condition within a yaml in gitlab ci - bash

I have a script and a condition where the branch name changes based on which branch you're using.
test:ui:with_sauce:
...
script:
- export MASTER_URL=https://masterurlexample.io
- export TEST_PREVIEW_APP=$CI_COMMIT_REF_SLUG
- cd $MAVEN_DIRECTORY
- if [ "$CI_COMMIT_BRANCH" == "master" || "$EMULATE_BRANCH" == "master" ]; then
export TEST_PREVIEW_APP=$MASTER_URL;
fi;
- echo "Testing on $TEST_PREVIEW_APP"
- echo "starting test"
- sleep 30
- mvn -U $MAVEN_CLI_OPTS ...
When this job runs I don't believe the condition doesn't execute.
/bin/bash: line 210: [: missing `]'
/bin/bash: line 210: : command not found
Not sure if it's looking for specific quotes around the variables.

Either write the expression in a single line or use a multiline string - |.
There's also a small issue with your bash (you need [[ and ]])
- |
if [[ "$CI_COMMIT_BRANCH" == "master" || "$EMULATE_BRANCH" == "master" ]]; then
export TEST_PREVIEW_APP=$MASTER_URL
fi
- ...
or
- if [[ "$CI_COMMIT_BRANCH" == "master" || "$EMULATE_BRANCH" == "master" ]]; then export TEST_PREVIEW_APP=$MASTER_URL; fi

Related

GitLab CI rules:if match condition which fails in Bash

In .gitlab-ci.yml we do have a rule matching a value with regex match. Why is rule-regex job running with if: $EMPTY_VAR =~ "some-value" when Bash tells this condition is false?
If I set EMPTY_VAR: 'x' no job runs.
variables:
EMPTY_VAR: ''
default:
image: container-registry.ubs.net/alpine:3.12.3
# Runs against expectation and prints 'expected false'
rule-regex:
rules:
- if: $EMPTY_VAR =~ "some-value"
script:
- echo "Job has run with EMPTY_VAR='${EMPTY_VAR}'"
- |
if [[ $EMPTY_VAR =~ "some-value" ]]; then
echo "expected true"
else
echo "expected false"
fi
# Does not run as expected
rule-equal:
rules:
- if: $EMPTY_VAR == "some-value"
script:
- echo "Job has run with EMPTY_VAR='${EMPTY_VAR}'"
You can try this
- if: $EMPTY_VAR =~ /^some-value.*/
https://docs.gitlab.com/ee/ci/jobs/job_control.html#compare-a-variable-to-a-regex-pattern

Iterate over files in bash, in Jenkins pipeline, fails with MissingPropertyException

I have Pipeline job in Jenkins and there is a step that executes this bash script:
sh """
$ANDROID_HOME/platform-tools/adb pull /sdcard/Pictures/screenshots
if [ "$DEFAULT_LOCALE" = "en" ]
then
DEFAULT_LOCALE="en-US"
fi
if [ "${env.UPDATE_BASE}" == "true" ] || [ ! -d "${env.CACHE_HOME}/${env.BRANCH}" ]; then
if [ ! -d "${env.CACHE_HOME}/${env.BRANCH}" ]; then
mkdir -p ${env.CACHE_HOME}/${env.BRANCH}
fi
for imgfile in screenshots/*.png; do
if [[ $imgfile == *"_${env.DEFAULT_LOCALE}-"*.png ]]; then
cp -rf screenshots/$imgfile ${env.CACHE_HOME}/${env.BRANCH}
fi
done
else
rm -f screenshots/*_${env.DEFAULT_LOCALE}-*.png
cp -rf ${env.CACHE_HOME}/${env.BRANCH}/* screenshots
fi
"""
However, when the pipeline reaches this step, it fails with this error:
groovy.lang.MissingPropertyException: No such property: imgfile for class: groovy.lang.Binding
What is wrong in the script?
If all your variables are shell variables then you should use triple single quotes.
If you have a mix of shell and Groovy variables (or only Groovy ones) then you should use triple double quotes.
In order to defer the evaluation of the shell variables in the latter case, you need to escape their dollar signs using one of these forms (I'm not sure which):
if [[ \$imgfile == *"_${env.DEFAULT_LOCALE}-"*.png ]]; then
or
if [[ \\$imgfile == *"_${env.DEFAULT_LOCALE}-"*.png ]]; then
or
if [[ ${'$'}imgfile == *"_${env.DEFAULT_LOCALE}-"*.png ]]; then

How can I ensure the relevant command is run based on arguments passed in BASH?

I'm writing my first bash script that will do some visual testing using wraith. I've stripped down the code to make it easier to read.
What I'm trying to write:
- The BASH command accepts an argument - 1, 2 or 3. i.e. regressiontest 1
- server will be assigned the argument passed
- alias config will be assigned to wraith capture configs/capture-staging-1.yaml, wraith capture configs/capture-staging-2.yaml or
wraith capture configs/capture-staging-3.yaml
- The echo statement is written to a txt file.
The script works as expected. The only issue is:
If run regressiontest 1, all good, runs wraith capture configs/capture-staging-1.yaml as expected.
I run regressiontest 2, I would expect it to run wraith capture configs/capture-staging-2.yaml but seems to run wraith capture configs/capture-staging-1.yaml again.
It seems to be running using the previous config file. If I close and open terminal again, it works as expected but if I run the same command with a different argument consecutively it seems to always run the first command I use.
What am I doing wrong?
I'm new to BASH scripts and am having trouble googling to find an answer
function regressiontest {
regressionfolder=~/path/to/folder
cd $regressionfolder
alias config
if [ $# -eq 0 ]; then
echo "No arguments provided - USAGE: regressiontest <server>"
return 0
else
server=$1
fi
if [ $server != 1 ] && [ $server != 2 ] && [ $server != 3 ]; then
echo "Visual Regression Testing argument invalid - USAGE: regressiontest <server>"
return 0
elif [ $server == 1 ]; then
server="1"
alias config='wraith capture configs/capture-staging-1.yaml'
elif [ $server == 2 ]; then
server="2"
alias config='wraith capture configs/capture-staging-2.yaml'
elif [ $server == 3 ]; then
server="3"
alias config='wraith capture configs/capture-staging-3.yaml'
fi
echo "https://website-staging-$server/" > data/server.txt
config
}
Any help would be much appreciated.
Thanks, All
Moe
You are thinking right, but making things harder than need be. Your initial part of the script is fine, though I would validate that the cd succeeds, e.g.
regressionfolder=~/path/to/folder
cd "$regressionfolder" || {
printf "error: unable to change to %s\n" "$regressionfolder" >&2
return 1
}
(note: a return of 1 generally indicates error and always double-quote your variables)
After your check on "$server" != 1 ... all you need to do is set your alias with $server as the number. No additional if ... elif ... are required, e.g.
if [ "$server" != 1 ] && [ "$server" != 2 ] && [ "$server" != 3 ]; then
echo "Visual Regression Testing argument invalid - USAGE: regressiontest <server>"
return 1
fi
alias config="wraith capture configs/capture-staging-$server.yaml"
config
}
(note: always double-quote variables withing [...])
Eliminate the alias
There is no need for the alias, you can simply run:
wraith capture configs/capture-staging-$server.yaml
Putting it altogether, you could do something similar to:
function regressiontest {
regressionfolder="$HOME/path/to/folder"
cd "$regressionfolder" || {
printf "error: unable to change to %s\n" "$regressionfolder" >&2
return 1
}
if [ $# -eq 0 ]; then
echo "No arguments provided - USAGE: regressiontest <server>"
return 1
else
server=$1
fi
if [ "$server" != 1 ] && [ "$server" != 2 ] && [ "$server" != 3 ]; then
printf "Visual Regression Testing argument invalid - "
printf "USAGE: regressiontest <server>\n"
return 1
fi
wraith capture "configs/capture-staging-$server.yaml"
}
(note: also the use of "$HOME" instead of ~. While ~ will expand on the command line, you will quickly run into problems using it within scripts)
Use a case Statement
A shorter more condensed version of your function using case ... esac would probably be a bit better, e.g.
function regressiontest {
regressionfolder="$HOME/path/to/folder"
cd "$regressionfolder" || {
printf "error: unable to change to %s\n" "$regressionfolder" >&2
return 1
}
case "$server" in
[123] ) wraith capture "configs/capture-staging-$server.yaml";;
* ) printf "Visual Regression Testing argument invalid - "
printf "USAGE: regressiontest <server>\n"
return 1;;
esac
}
I don't think you want to declare aliases, but store commands for later execution; just remove the "alias" from alias config='…' and at the end call it via $config.

bash script fails with binary operator expected

I have a bash script which checks for a paticular string and proceeds further but seems to be getting some error with binary operator expected
local artifacts=$(realpath artifacts)/middle-end
local env
local account_id=${1}
local branch_name=${2}
local user_environments=${3}
local gitlab_user_id=${4}
env=$(ci/scripts/get-details-env.py -m "${user_environments}" -u "${user_id}")
# Deploy to int1 from develop
echo "$branch_name"
if [ "${branch_name}" == "develop" ]; then
env=brt-int;
fi
if [ "${branch_name}" =~ ^brt-rc-.* ]; then
env=brt-uat;
fi
mkdir -p ${artifacts}
cd middle-end
ln -s ${NODE_PATH} ./node_modules
npm run build
I know what your problem is, you must be using the new test operator [[. [http://mywiki.wooledge.org/BashFAQ/031][bash new test details]
if [[ "${branch_name}" =~ ^atf-rc-.* ]]; then
env=atf-stage1;
fi

Running script conditionally does not work in travis.yml, why?

The following causes travis to not build at all. When I try to validate the travis.yml file, it complains that the line just above the if statement is missing a - character at column 3, but the error has to do with the if statement below.
Do I have to move the if statement out to a script?
# Deploy
after_success:
- ./tools/docker-push-container.sh
- if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
You're making some assumptions about YAML syntax that are causing you problems. If you "exend" a line of YAML by indenting subsequent lines, like this:
- The quick brown fox
jumped over the
lazy dog.
It is exactly like you instead wrote this:
- The quick brown fox jumped over the lazy dog.
This means that your shell fragment, which you've written as:
- if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
Actually becomes:
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then ./.travis/success_message.sh fi
And if you try run that line in the shell, you get:
sh: -c: line 1: syntax error: unexpected end of file
If you want to include a multi-line shell script in your YAML document, your best bet is probably to use the verbatim block operator, |, like this:
- |
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
Which will result, as intended, in:
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh
fi
Alternatively, you could just make proper use of semicolons:
- if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then
./.travis/success_message.sh;
fi
Note the new ; before the terminal fi. This results in:
if [ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]; then ./.travis/success_message.sh; fi
...which is perfectly valid shell syntax.
I tried the above solution by larsks but, it did not work for me and could be because in bash when you use && and || you need to separate the conditions.
I had the following (according to above solution)
- if [ $TRAVIS_PULL_REQUEST == false && $TRAVIS_BRANCH == "development" ]; then
echo "# Bump version and flyway migrate db";
else
echo "Skip version increment!";
fi
And I also checked the .travis.yml in Travis Lint and it shows as valid but, according to bash the above can be separated as shown below, also mentioned in this SO Question and I changed to following
- if [ $TRAVIS_PULL_REQUEST == false ] && [ $TRAVIS_BRANCH == "development" ]; then
echo "# Bump version and flyway migrate db";
else
echo "Skip version increment!";
fi
And travis build worked. It kind of make sense because above is valid way to use && and || in bash. Just sharing in case someone else come across a similar issue.
Raf's solution worked for me with separating the conditionals with []
[ $TRAVIS_PULL_REQUEST == false ] && [ $TRAVIS_BRANCH == "develop" ];
None of the suggested workarounds worked for me, I used this instead:
- if [[ ( "$TRAVIS_OS_NAME" == "osx" ) && ( "$TOXENV" == "py36" ) ]]; then brew update; fi

Resources