only:changes in combination with recommended merge_request produces unexpected runs
Summary
When wanting to work with 'only:changes' the documentation rightfully suggests to use 'merge_requests' so that builds run detached knowing the set of changed files for the entire MR. Omitting merge_requests makes the pipeline not consistently run on forced pushes due to detection issues.
However if, for example, I mark a file with 'only:changes: Dockerfile' and 'only:refs: merge_requests', then this works fine for the merge request itself, but when the merge request is merged into master, and the pipeline is supposed to be run for master it does not anymore, as the only:refs:merge_requests is no longer matching.
Initially, one would have no 'only:refs' set, and so the pipeline would always run (on detected changes). The only work-around for this I can come up with, is extending 'only:refs' with 'branches, tags, merge_requests' to ensure that the pipeline 'always' correctly runs.
I think a side effect here also is, that if you have a job that is intended to be always run, no matter what (in my case, a linter) using merge_requests on the other jobs, splits the pipeline into two (one job for just the merge request on the branch, the rest of the pipeline on the merge_request), but I think that is just a UI uglyness, and can may need its own ticket. I think it may be more subtle then that. After doing the aforementioned work-around, the branch does get all tasks executed, but the merge_request is missing the linter (which I thought would always be run). After thinking about it, it makes sense, the merge_request is a separated pipeline, only matching those.
To visualize this, see the following screenshot, which has the MR missing the first step (the linting).
I think this could be solved by extending only/except with 'also'? which would supplement the existing implementation. e.g.
only:
- tags
- /^testing/*/
except:
- branches
- /^testing/*/
also:
- merge_requests
This means the job would run on all tags, never on branches, nor on refs starting with testing (as the first one gets overwritten), and also on merge_requests.
The only downside is, is that the pipeline gets executed twice for the exact same commits, but see issue #27574 for that.