On my Gitlab CI/CD pipeline, is there a way I can get a list of the changed files?
Basically, I’ve got some linting set up - but the repository contains a number of separate files which don’t work together to form an application, they’re just individual files hosted in the same place.
I’d like to lint only files changed on commit/push. Is this possible?
I have the same question! From what I can tell (below), we’ll have to use the git command: git diff-tree --no-commit-id --name-only -r <commit hash> in our CI scripts to obtain the list of changed files, one per line, and then iterate over that list.
In case the pipeline runs on merge requests, one option it is to compare it with the target branch. git diff-tree --name-only --no-commit-id $CI_MERGE_REQUEST_TARGET_BRANCH_SHA
This command does not work for me.
I get the error fatal: ambiguous argument '{branch_name}': unknown revision or path not in the working tree., even though the merge request originates from this branch.
A quick git branch -a
returns * (HEAD detached at b487990)
Which explains why it does not work but I don’t understand why the head is detached in the first place.
I’ve been experimenting with this, but unless I’m missing something - this only seems to work for public repos. For a private repo it seems that I would need to set up some credentials - for example having an account with a key checked into the repo so I can pass it to the git command, which isn’t crazy but seems a little round-about and potentially insecure for a use case that will become more and more popular - taking action based on a change set, not the full file set.
None of the above really worked for me on a CI/CD pipeline in gitlab but what I ultimately did was very similar to what @loicm did, here’s the complete solution, these are the commands added to my .gitlab-ci.yml:
hi guys, I just wanted to drop my solution. It’s based on all the answers here so I wanted to share back, maybe it is useful for someone. I wanted to find all changed yaml files in my merge-request to run a job against it. Solution is pretty easy once you know it:
I’m glad someone posted a solution for this, and git diff-tree --name-only does work well… if you have git installed inside the Docker image! Turns out that some images don’t have git installed, and they run as a regular user, so you can’t (easily) install git to pull those file lists.
I ended up having to do some unholy hacks to workaround this problem… It would be great if there would be some variable that would contain the file list, or maybe even some artifact (because variables might be too small for larger lists)…
Basically: the runner has git installed and clones the repo. It could generate that file list and store it in a well-known file location to be reused inside the container…
However, it does require a $CI_PIPELINE_SOURCE of merge_request_event. The $CI_MERGE_REQUEST_DIFF_BASE_SHA is not available for push events, since they aren’t in the context of the MR.