gitlab-ci.yml "changes" are ignored on "new branch" first push into gitlab CI
Problem to solve
Consider the following use case:
- User wishes to run a specific job ONLY if a specific set of files change.
- EXAMPLE: build a docker image ONLY if
Dockerfilechanges
So they leverage changes as per: https://docs.gitlab.com/ee/ci/yaml/#onlychangesexceptchanges
Example:
build docker image:
stage: docker_build
only:
refs: ['branches']
changes:
- .gitlab-ci_docker_build.yml
- Dockerfile
- Pipfile
- Pipfile.lock
except: ['master']
script:
- >> do the docker build stuff <<To explain the example:
.gitlab-ci_docker_build.ymlis its own file (it is included by the main.gitlab-ci.yml, I contain a VAR that defines some docker build tags required, so if the user bumps the version, we'd like to rebuild the docker imageDockerfileobviously if the docker build script itself changes, rebuildPipfile(.lock)for Python projects, if the application project dependencies change, rebuild the docker with all the new/updated packages
The expectation here is:
- If a developer pushes application code changes, DO NOT rebuild the docker image. (these are MOST of the commit/push/MR scenarios, so we don't want to needlessly build a docker image over-and-over ;o)
- If a developer pushes application package requirement changes (
Pipfile(.lock)), DO rebuild the docker image. - If a developer changes how docker is built
Dockerfileor bumps the docker version in.gitlab-ci_docker_build.yml, DO rebuild the docker image.
As per https://docs.gitlab.com/ee/ci/yaml/#using-changes-with-new-branches-and-tags, it clearly states: Using changes with new branches and tags
When pushing a new branch or a new tag to GitLab, the policy always evaluates to true and GitLab will create a job. This feature is not connected with merge requests yet and, because GitLab is creating pipelines before a user can create a merge request, it is unknown what the target branch is at this point.
The annoyance here is this workflow:
- On a branch, developer makes application changes that SHOULD NOT result in docker rebuild.
- They edit/commit/etc locally, then PUSH
- Pipeline runs and UNDESIRABLY runs the docker build jobs (because of the above caveat) - this is a "new branch", and so all jobs are run regardless of the
changesdirective. - Subsequent commits/pushes, and merge to master are all handled as expected. (my example above excludes master as there is a different job that controls a docker build on master)
Intended users
Developers & DevOps
Proposal
Either:
A) consider if we can control/fix/prevent this "new branch" aspect
B) add configuration that allows changes to compare to its own reference
Permissions and Security
TBD
Documentation
TBD
Testing
Would impact current behaviour/expectations of changes (there may be counter-example use cases where this behaviour is DESIRED).
What does success look like, and how can we measure that?
Workflow described above flows without UNDESIRED item. (that is, there is a way for "changes" to actually work on "new branch" initial push)
To repeat the workflow for EXPECTED/DESIRED:
- On a branch, developer makes application changes that SHOULD NOT result in docker rebuild.
- They edit/commit/etc locally, then PUSH
- Pipeline runs as usual (but docker builds DO NOT run)
- Subsequent commits/pushes, and merge to master are all handled as expected.
Compare with:
- On a branch, developer makes <CHANGE_THAT_SHOULD_TRIGGER_DOCKER_BUILD> (as per above list)
- They edit/commit/etc locally, then PUSH
- Pipeline runs as usual and docker builds DO run
- Subsequent commits/pushes, and merge to master are all handled as expected.
What is the type of buyer?
TBD