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 `Dockerfile` changes 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.yml` is 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 image * `Dockerfile` obviously if the docker build script itself changes, rebuild * `Pipfile(.lock)` for Python projects, if the application project dependencies change, rebuild the docker with all the new/updated packages The _expectation_ here is: 1. 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) 2. If a developer pushes application package requirement changes (`Pipfile(.lock)`), DO rebuild the docker image. 3. If a developer changes how docker is built `Dockerfile` or 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: 1. On a branch, developer makes application changes that SHOULD NOT result in docker rebuild. 2. They edit/commit/etc locally, then PUSH 3. 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 `changes` directive. 4. 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: 1. On a branch, developer makes application changes that SHOULD NOT result in docker rebuild. 2. They edit/commit/etc locally, then PUSH 3. Pipeline runs as usual (but *docker builds DO NOT run*) 4. Subsequent commits/pushes, and merge to master are all handled as expected. Compare with: 1. On a branch, developer makes <CHANGE_THAT_SHOULD_TRIGGER_DOCKER_BUILD> (as per above list) 2. They edit/commit/etc locally, then PUSH 3. Pipeline runs as usual and *docker builds DO run* 4. Subsequent commits/pushes, and merge to master are all handled as expected. ### What is the type of buyer? TBD ### Links / references * https://docs.gitlab.com/ee/ci/yaml/#onlychangesexceptchanges * https://docs.gitlab.com/ee/ci/yaml/#using-changes-with-new-branches-and-tags * https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
issue