Run Gitlab CI job on merge to master for only changes - gitlab-ci

Is there a way to reliably execute a job on merge to master only when there are changes to the script? I'm using
vm-build:
image:
name: path_to_image
stage: vm-deploy
only:
changes:
- job.gitlab-ci.yml
refs:
- master
except:
- schedules
- triggers
script:
- ansible-playbook playbooks/pb_job.yml
tags:
- docker
but it seems to execute 'job' on different commits to master where job.gitlab-ci.yml hasn't changed. I haven't found a rhyme or reason to why though.

The following .gitlab-ci.yml runs only on changes to the file jobs.gitlab-ci.yml on the master branch:
myjob:
script:
- echo I am a CI job
only:
changes:
- job.gitlab-ci.yml
refs:
- master
It does not run on changes to any other file in the master branch.

Related

gitlab job is running even if there is no changes in the schedule pipeline

I set a schedule for my gitlab.yml file to run the pipeline. In my job I have set rules to run/not run the job. However, in my schedule the job is running no matter if any of my rules met.
here is the simplified yml file:
stages:
- build
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR : ""
DOCKER_NETWORK: "gitlab-network"
.docker_dind_service: &docker_dind_service
services:
- name: docker:20.10-dind
command: ["--insecure-registry", "my_server.net:7000"]
docker:custom:
stage: build
<<: *docker_dind_service
tags:
- docker_runner
image: docker
rules:
- if: '$FORCE_BUILD_DOCKER_IMAGE == "1"'
when: always
- changes:
- Dockerfile
- when: never
script:
- docker build -t my_image .
for the case above, the job is added to the schedule even though there is no change in my Dockerfile. I think I am lost, because when I do changes in my yml file and push it, this job is not added, which is right because there is no change in the Dockerfile. However, it is running for every scheduled pipeline.
Apparently according to the Gitlab documentation:
https://docs.gitlab.com/ee/ci/yaml/#using-onlychanges-without-pipelines-for-merge-requests
You should use rules: changes only with branch pipelines or merge request pipelines. You can use rules: changes with other pipeline types, but rules: changes always evaluates to true when there is no Git push event. Tag pipelines, scheduled pipelines, manual pipelines, and so on do not have a Git push event associated with them. A rules: changes job is always added to those pipelines if there is no if that limits the job to branch or merge request pipelines.

Gitlab pipeline on commit / after MR not on pipeline run

I wanna run pipeline only when someone commits into master or merges branch into master. have such a code:
commit_to_master_notification:
stage: build
script:
- echo "rest of script"
only:
refs:
- master
but when I just triger pipeline on master branch this job is stared. How to change it to start it only when someone commits into master or after merging code.
You can start testing with if rules, using predefined variables:
job:
script: echo "Only for master commits or merge"
rules:
- if $CI_COMMIT_BRANCH == "master"' || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"
...

Dynamic child pipelines and stop action not working

after adding dynamic child pipelines to our CI pipeline on stop action(eg. deleting branch), stopped working.
In stop job we are deleting created k8s resources, so its important to be executed.
What i noticed is that defining environment in child pipeline is probable cause(without environment section, on stop action is working).
Any ideas?
gitlab-ci.yaml looks like this
stages:
....
- deploy
- tests_prepare
- maintenance_tests
....
deploy_branch_to_k8s:
stage: deploy
only:
- branches
except:
- master
dependencies:
- build_api
environment:
name: branches/$CI_COMMIT_REF_NAME
on_stop: stop_deployed_branch_in_k8s
script:
- deploy to k8s
stop_deployed_branch_in_k8s:
stage: deploy
only:
- branches
except:
- master
when: manual
dependencies: []
variables:
GIT_STRATEGY: none
environment:
name: branches/$CI_COMMIT_REF_NAME
action: stop
script:
- delete k8s resources
generate_config_tests:
stage: tests_prepare
only:
- branches
except:
- master
dependencies:
- build_api
....
script:
- python3 ./utils/generate-jobs-config.py > generated-config.yml
artifacts:
paths:
- generated-config.yml
create_maintenance_tests_pipeline:
stage: maintenance_tests
only:
- branches
except:
- master
trigger:
strategy: depend
include:
- artifact: generated-config.yml
job: generate_config_tests
variables:
PARENT_PIPELINE_ID: $CI_PIPELINE_ID
generated-config.yml looks something like this
stages:
- tests
run_maintenance_test_job___TEST_NAME__:
stage: tests
retry: 2
environment:
name: branches/$CI_COMMIT_REF_NAME
needs:
- pipeline: $PARENT_PIPELINE_ID
job: generate_config_maintenance_tests
script:
- deploy a run tests in k8s
If I'm not wrong, you should skip the needs part altogether in the child pipeline, since it is only used for jobs in the same pipeline. Its upstream will be the parent pipeline anyway.

Gitlab run pipeline job only when previous job ran

I'm trying to create a pipeline with a production and a development deployment. In both environments the application should be built with docker. But only when something changed in the according directory.
For example:
When something changed in the frontend directory the frontend should be build and deployed
When something changed in the backend directory the backend should be build and deployed
At first I didn't had the needs: keyword. The pipeline always executed the deploy_backend and deploy_frontend even when the build jobs were not executed.
Now I've added the needs: keyword, but Gitlab says yaml invalid when there was only a change in one directory. When there is a change in both directories the pipeline works fine. When there for exaple a change in the README.md outside the 2 directories the says yaml invalid as well.
Does anyone knows how I can create a pipeline that only runs when there is a change in a specified directory and only runs the according deploy job when the build job has ran?
gitlab-ci.yml:
stages:
- build
- deploy
build_frontend:
stage: build
only:
refs:
- master
- development
changes:
- frontend/*
script:
- cd frontend
- docker build -t frontend .
build_backend:
stage: build
only:
refs:
- master
- development
changes:
- backend/*
script:
- cd backend
- docker build -t backend .
deploy_frontend_dev:
stage: deploy
only:
refs:
- development
script:
- "echo deploy frontend"
needs: ["build_frontend"]
deploy_backend_dev:
stage: deploy
only:
refs:
- development
- pipeline
script:
- "echo deploy backend"
needs: ["build_backend"]
The problem here is that your deploy jobs require the previous build jobs to actually exist.
However, by using the only.changes-rule, they only exist if actually something changed within those directories.
So when only something in the frontend-folder changed, the build_backend-Job is not generated at all. But the deploy_backend_dev job still is and then misses it's dependency.
A quick fix would be to add the only.changes configuration also to the deployment-jobs like this:
deploy_frontend_dev:
stage: deploy
only:
refs:
- development
changes:
- frontend/*
script:
- "echo deploy frontend"
needs: ["build_frontend"]
deploy_backend_dev:
stage: deploy
only:
refs:
- development
- pipeline
changes:
- backend/*
script:
- "echo deploy backend"
needs: ["build_backend"]
This way, both jobs will only be created if the dependent build job is created as well and the yaml will not be invalid.

GitlabCI pipeline run only with code from master

I need to run pipeline everytime there is a commit on non-master branch. The pipeline starts but the code is from master. I need the code from the changed branch
Pipeline is like this:
variables:
IMAGE_TAG: ${CI_PIPELINE_IID}
BASE_NAME: ${CI_COMMIT_REF_NAME}
stages:
- validate
- build
check_image:
stage: validate
tags:
- runner
script:
- cd ~/path/${BASE_NAME}-base && packer validate ${BASE_NAME}-base.json
except: ['master']
create_image:
stage: build
tags:
- runner
script:
- cd ~/path/${BASE_NAME}-base && packer build -force ${BASE_NAME}-base.json
except: ['master']
Nevermind. I figured it out. I was running gitlab-runner under custom user so the environment is already set. I just have to add before_script to checkout the desired branch.