I'm trying to setup gitlab ci for my project.
My gitlab-ci script looks like:
stages:
- build
before_script:
- docker info
- chmod -R a+x scripts
build:
stage: build
script:
- pwd
- ./scripts/ci-prepare.sh
- ./scripts/dotnet-build.sh
- ./scripts/dotnet-tests.sh
- ./scripts/dotnet-publish.sh
- ./scripts/docker-publish-ci.sh
after_script:
- ./scripts/ci-success.sh
In build log I have this information:
Total tests: 6. Passed: 5. Failed: 1. Ommited: 0.
But event tests fails the build process is finished with success exit code.
Why?
I have no configured allow_failure option.
I added set -e in bash scripts and it works properly.
Gitlab CI checks the exit code of a command or script to decide if it has failed or succeeded.
A successful command returns a 0. All other exit codes are considered as an error.
I don't know what kind of software you are using for your tests - I think you should just return the exit code of your tests in your scripts.
Related
I had created a specific runner for my gitlab project,
its taking too long to run the pipeline.
Its is getting stuck in Cypress test mainly.
After "All Specs passed" it will not move forward.
- build
- test
build:
stage: build
image: gradle:jdk11
script:
- gradle --no-daemon build
artifacts:
paths:
- build/distributions
expire_in: 1 day
when: always
junit-test:
stage: test
image: gradle:jdk11
dependencies: []
script:
- gradle test
timeout: 5m
cypress-test:
stage: test
image: registry.gitlab.com/sahajsoft/gurukul2022/csv-parser-srijan:latestSrigin2
dependencies:
- build
script:
- unzip -q build/distributions/csv-parser-srijan-1.0-SNAPSHOT.zip -d build/distributions
- sh build/distributions/csv-parser-srijan-1.0-SNAPSHOT/bin/csv-parser-srijan &
- npm install --save-dev cypress-file-upload
- npx cypress run --browser chrome
A recommended approach is to try and replicate your script (from your pipeline) locally, from your computer.
It will allow to check:
how long those commands take
if there is any interactive step, where a command might expect a user entry, and wait for stdin.
The second point would explain why, in an unattended environment like a pipeline one, "it will not move forward".
My deploy script is an extremely simple Git pull. I have a bash script that does git pull that’s part of my source code. The issue is that if the git pull fails for any reason, it’s still showing a successful deployment.
The .gitlab-ci.yml:
stages:
- 'deploy'
deploy to staging:
stage: 'deploy'
script: '/home/myuser/scripts/deployment/deploy_staging.sh'
tags:
- staging
only:
- staging
The deploy_staging.sh:
script=$(basename $0)
logger "$script: script executed"
cd $HOME/mydirectory
git fetch
git pull
composer update
This issue lies in the fact that in order for a job to fail it checks the exit code of the command executed in your case
script: '/home/myuser/scripts/deployment/deploy_staging.sh'
The exit code of this command will be the result of 'composer update'
Since the exit code for a script is the exit code of the latest executed command, in your case
'composer update'
Meaning, this job will fail only if the command 'composer update' fails, disregarding the exit codes of the previous commands in your case 'git pull'
To fix this add "set -e" in the beginnig of your script. This will force the script to adapt a proper exit code by exiting the script when a command in the script fails
I am new to gitlab runner and trying to setup acceptance_stage after unit test passes.
The tests run on a windows machine when the job is triggered.
The job exits when tests pass, but the job stalls when test fails. I have only 1 test right now and I am planning to run multiple tests in parallel when this issue is fixed.
The test is triggered using maven command. (I have tweaked the test in such a way so that it fails.)The test fails on this command :
mvn verify -P rest-test-run -Denvironment="qa" -Dwebdriver.chrome.driver="C:\tools\chromedriver.exe"
and the job stalls and is unable to execute the next command.
Here is the sample yaml file that i am using to trigger acceptance stage:
stages:
- test
acceptance_tests:
stage: test
tags:
- playground
only:
- ci_cd_test
before_script:
- export POM_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
- cd ..
- git clone "git#gitlab.<project>" "<automation project name>" 2> /dev/null || (cd "<automation project name>" ; git pull)
- cd <webapp project name>
- export DB_URL=jdbc url
- export DB_USER=username
- export DB_PASSWORD=password
variables:
GIT_STRATEGY: none
script:
# flyway migrates
- java -Dfile.encoding=UTF-8 -jar <webapp project name>/target/<webapp project name>-$POM_VERSION.jar flyway migrate
# Bring up the app
- ./start.sh
# Run cucumber test
- cd ../<automation project name>
- mvn verify -P rest-test-run -Denvironment="qa" -Dwebdriver.chrome.driver="C:\tools\chromedriver.exe"
- cd ../<webapp project name>
# Stop the app
- ./stop.sh
I have also attached a screen shot of the stalling job.
Some troubleshooting ideas that I tried implementing:
upgraded surefireplugin(the version that I use in 2.22.0)
added a cleanup_job in yaml file
ran tests not in parallel
the above ideas did not solve the problem.
I'm using Gitlab CI, and so have been working on a fairly complex .gitlab-ci.yml file. The file has an after_script section which runs when the main task is complete, or the main task has failed somehow. Problem: I need to do different cleanup based on whether the main task succeeded or failed, but I can't find any Gitlab CI variable that indicates the result of the main task.
How can I tell, inside the after_script section, whether the main task has succeeded or failed?
Since gitlab-runner 13.5, you can use the CI_JOB_STATUS variable.
test_job:
# ...
after_script:
- >
if [ $CI_JOB_STATUS == 'success' ]; then
echo 'This will only run on success'
else
echo 'This will only run when job failed or is cancelled'
fi
See GitLab's documentation on predefined_variables: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
The accepted answer may apply to most situations, but it doesn't answer the original question and will only work if you only have one job per stage.
Note: There currently a feature request opened (issues/3116) to handle on_failure and on_success in after_script.
It could be possible to use variables to pass the job status to an after_script script, but this also has a feature request (issues/1926) opened to be able to share variables between before_script, script and after_script.
One workaround will be to write to a temporary file that will be accessed during the after_script block.
test_job:
stage: test
before_script:
- echo "FAIL" > .job_status
script:
- exit 1
- echo "SUCCESS" > .job_status
after_script:
- echo "$(cat .job_status)"
Instead of determining whether or not the task succeeded or failed in the after_script, I would suggest defining another stage, and using the when syntax, where you can use when: on_failure or when: on_success.
Example from the documentation:
stages:
- build
- cleanup_build
- test
- deploy
- cleanup
build_job:
stage: build
script:
- make build
cleanup_build_job:
stage: cleanup_build
script:
- cleanup build when failed
when: on_failure
test_job:
stage: test
script:
- make test
deploy_job:
stage: deploy
script:
- make deploy
when: manual
cleanup_job:
stage: cleanup
script:
- cleanup after jobs
when: always
Just another way to handle this if you want to setup if failure behavior.
scripts:
- ./script_that_fails.sh > /dev/null 2>&1 || FAILED=true
- if [ $FAILED ]
then ./do_something.sh
fi
Note: Other examples also worked for me, but I find this implementation more faster and suitable for me
I'm trying to use GitLab CI to build, test and deploy an Express app on a server (the Runner is running with the shell executor). However, the test:async and deploy_staging jobs do not terminate. But when checking the terminal inside GitLab, the Express server does indeed start. What gives ?
stages:
- build
- test
- deploy
### Jobs ###
build:
stage: build
script:
- npm install -q
- npm run build
- knex migrate:latest
- knex seed:run
artifacts:
paths:
- build/
- node_modules/
tags:
- database
- build
test:lint:
stage: test
script:
- npm run lint
tags:
- lint
# Run the Express server
test:async:
stage: test
script:
- npm start &
- curl http://localhost:3000
tags:
- server
deploy_staging:
stage: deploy
script:
- npm start
environment:
name: staging
url: my_url_here
tags:
- deployment
The npm start is just node build/bundle.js. The build script is using Webpack.
Note: solution works fine when using a gitlab runner with shell executor
Generally in Gitlab CI we run ordered jobs with specific tasks that should be executed one after the end of the other.
So for the job build we have the npm install -q command that runs and terminates with an exit status (0 exit status if the command was succesful), then runs the next command npm run build and so on until the job is terminated.
For the test job we have npm start & process that keeps running so the job wont be able to terminate.
The problem is that sometimes we need to have some process that need to run in background or having some process that keeps living between tasks. For example in some kind of test we need to keep the server running, something like that:
test:
stage: test
script:
- npm start
- npm test
in this case npm test will never start because npm statrt keeps running without terminating.
The solution is to use before_script where we run a shell script that keeps npm start process running then we call after_script to kill that npm start process
so on our .gitlab-ci.yml we write
test:
stage: test
before_script:
- ./serverstart.sh
script:
- npm test
after_script:
- kill -9 $(ps aux | grep '\snode\s' | awk '{print $2}')
and on the serverstart.sh
# !/bin/bash
# start the server and send the console and error logs on nodeserver.log
npm start > nodeserver.log 2>&1 &
# keep waiting until the server is started
# (in this case wait for mongodb://localhost:27017/app-test to be logged)
while ! grep -q "mongodb://localhost:27017/app-test" nodeserver.log
do
sleep .1
done
echo -e "server has started\n"
exit 0
thanks to that serverstart.sh script is terminated while keeping npm start process alive and help us by the way move to the job where we have npm test.
npm test terminates and pass to after script where we kill all nodejs process.
You are starting a background job during your test phase which never terminates - therefore the job runs forever.
The idea of the GitLab CI jobs are shortly-running tasks - like compiling, executing unit tests or gathering information such as code coverage - which are executed in a predefined order. In your case, the order is build -> test -> deploy; since the test job doesn't finish, deploy isn't even executed.
Depending on your environment, you will have to create a different job for deploying your node app. For example, you can push the build output to a remote server using a tool like scp or upload it to AWS; after that, you reference the final URL in the url: field in your .gitlab-ci.yml.