Execute a script before the branch is deleted in GitLab-CI - gitlab

GitLab-CI executes the stop-environment script in dynamic environments after the branch has been deleted. This effectively forces you to put all the teardown logic into the .gitlab-ci.yml instead of a script that .gitlab-ci.yml just calls.
Does anyone know a workaround for this? I have a shell script that removes the deployment. This script is part of the repository and can also be called locally (i.e. not onli in an CI environment). I want GitLab-CI to call this script when removing a dynamic environment but it's obviously not there anymore when the branch has been deleted. I also cannot put this script to the artifacts as it is generated before the build by a configure script and contains secrets. It would be great if one could execute the teardown script before the branch is deleted.
Here's a relevant excerpt from the .gitlab-ci.yml
deploy_dynamic_staging:
stage: deploy
variables:
SERVICE_NAME: foo-service-$CI_BUILD_REF_SLUG
script:
- ./configure
- make deploy.staging
environment:
name: staging/$CI_BUILD_REF_SLUG
on_stop: stop_dynamic_staging
except:
- master
stop_dynamic_staging:
stage: deploy
variables:
GIT_STRATEGY: none
script:
- make teardown # <- this fails
when: manual
environment:
name: staging/$CI_BUILD_REF_SLUG
action: stop

Probably not ideal, but you can curl the script using the gitlab API before running it:
curl \
-X GET https://gitlab.example. com/raw/master/script.sh\
-H 'PRIVATE-TOKEN: ${GITLAB_TOKEN}' > script.sh

GitLab-CI executes the stop-environment script in dynamic environments after the branch has been deleted.
That includes:
An on_stop action, if defined, is executed.
With GitLab 15.1 (June 2022), you can skip that on_top action:
Force stop an environment
In 15.1, we added a force option to the stop environment API call.
This allows you to delete an active environment without running the specified on_stop jobs in cases where running these defined actions is not desired.
See Documentation and Issue.

Related

who to read .git-ci.yml file

I'm very new to the Git lab, try to understand the .gitlab-ci.yml file. i would be thanksfull if someone could help me with this, what will all this command do, and where it will be installed all this packages, inside a docker container?
staging:
stage: staging
script:
- apt-get update -qy
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=$HEROKU_STAGING_APP --api-key=$HEROKU_STAGING_API_KEY --skip-cleanup
only:
- main
Let me try to explain.
.git-ci.yml is the default file which would be read by GitLab for creation and execution of the pipeline whenever there are changes in the repository (new commit, new branch, new tag etc)
Now regarding the specific to the question, this defines a job which would be executed as part of staging stage, actual sequence would depend on how many stages are defined in your file and where this staging appears in the sequence. (Please refer stages: in your file.
Now by default all the jobs will be run on the runner. These runners are identified by the tags, as I don't see any tags in your particular job its bit difficult to comment on.
You may have an explicit image tag in your job for e.g. image: openjdk:17-alpine to run the job on a particular container.
So, whatever commands are written in the script: block, would get executed on
Either the runner where the job would be launched
Or, the container launched by using the image tag
I hope, it help you to understand the basic execution.

Problems with Gitlab CI/CD on local machine

I'm using gitlab-runner to run CI/CD locally.
It works properly when I specify all jobs in .gitlab-ci.yml like
stages:
- test
test1:
stage: test
script:
- echo "ok"
and run gitlab-runner exec shell test1
In general, I'd like to store different jobs in different files. For example, I make test-pipeline.yml with jobs that relates to the test stage in the folder named .gitlab.
The .gitlab-ci.yml contains only to rows
include:
local: .gitlab/test-pipeline.yml
I commit and push changes to the remote repo and it works there but the command gitlab-runner exec shell job_name fails because it can't find such job.
Perhaps, I have to edit some of gitlab-runner's config but it's not obviously.
Has anybody faced with the same problem?
Thanks in advance!
gitlab-runner exec has many limitations. It does not have all the same features of the regular gitlab-runner. One such limitation is that it does not support the include: statement.
So, you won't be able to use gitlab-runner exec against this kind of config file that uses include:.

Call specific runner for Git script

How I can call a specific runner for CI job. Problem: I have default runners and now I have to install my local runner and run tests on it. But I haven't a possibility to turn off runners on the Git because the whole project builds on remote drivers.
You can use tags to tag a runner, when you register it. And you can specify that your job will only run on runners with this tags.
eg. you tagged your runner with 'fancy-example' than you can use it like
build:
tags:
- fancy-example
script:
- echo Hello
See the gitLab docs for more detailed examples and explanations:
https://docs.gitlab.com/ce/ci/yaml/README.html#tags

How to trigger only specific stage of pipeline with gitlab API?

I have gitlab project with ci file:
stages:
- build
- run
build:
stage: build
script:
- (some stuff)
tags:
- my_runner_tag
except:
- triggers
when: manual
run:
stage: run
script:
- (some stuff)
tags:
- my_runner_tag
except:
- triggers
when: manual
Jobs are created on every source code change, and they can be run only manually, using gitlab interface.
Now, i want to have possibility to trigger stage run with Gitlab API. Trying:
curl -X POST \
> -F token=xxxxxxxxxxxxxxx \
> -F ref=master \
> https://gitlab.xxxxx.com/api/v4/projects/5/trigger/pipeline
Returns:
{"message":{"base":["No stages / jobs for this pipeline."]}}
Seems, like i have to define stage to trigger, but i can't find a way to pass it via api call.
you are using the wrong endpoint, to do it, you need to follow the path below
list all of your pipelines and get the newest one
GET /projects/:id/pipelines
list the jobs from this pipeline
GET /projects/:id/pipelines/:pipeline_id/jobs
After that you can trigger your job
POST /projects/:id/jobs/:job_id/play
you are telling your build to run at all times except for the time they are being triggered (api call is also considered as a trigger).
change your job definition to the following:
run:
stage: run
script:
- (some stuff)
tags:
- my_runner_tag
when: manual

CircleCI: Trigger test post-hook only on certain branches

I have a circle.yml file that looks something like this:
general:
branches:
only:
- master
- develop
- /release-[0-9]+(\.[0-9]+)*/
test:
pre:
- docker-compose run $SERVICE npm install
override:
- docker-compose run $SERVICE npm test
post:
- docker-compose run SPECIFIC_COMMAND // this should only trigger for branches that fall under /release-[0-9]+(\.[0-9]+)*/
- docker-compose stop
Unit tests run when merging to master, develop, or /release-[0-9]+(\.[0-9]+)*/.
However, there's a certain command in the post-hook under tests that I would only like to trigger when merging into /release-[0-9]+(\.[0-9]+)*/. This command must run before the final one, docker-compose stop, which is why I haven't used a deployment block.
Turns out this isn't quite possible in the test block (unlike the branches or deployment blocks).
The best way around this was to place the conditional logic in a shell script that accessed the $CIRCLE_BRANCH environment variable. The shell script in turn would be triggered all the time.

Resources