Home > other >  Loop through folders that have changes in a PR
Loop through folders that have changes in a PR

Time:02-11

In a github workflow (.yaml) script, I'm wondering how to loop through any folders that have changes as part of a particular PR.

For instance, suppose I have this structure:

Dir1\File1.txt
Dir2\File2.txt
Dir3\File3.txt
Dir4\File4.txt

If a PR has changes to File2.txt and File4.txt, I want a workflow that will loop thru and do something in folders: Dir2 and Dir4.

I know of a way to do this for specific folders, but I don't want to have to specify all of the folders that exist in my source, i.e. this works for a list of specified directories:

   - name: myJob
        run: |
          myDirectories=("Dir1" "Dir2" "Dir3" "Dir4")
      
          for i in "${myDirectories[@]}"
          do
            if git diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep -c "^$i/"; then
              ...do something...
            fi
          done

Thank you.

CodePudding user response:

Easiest solution will be to use this action: https://github.com/tj-actions/changed-files/

You can do things like:

- name: Get specific changed files
        id: changed-files-specific
        uses: tj-actions/[email protected]
        with:
          files: |
            Dir*\*

- name: Run step if any of the listed files above change
        if: steps.changed-files-specific.outputs.any_changed == 'true'
        run: |
          for file in ${{ steps.changed-files-specific.outputs. all_changed_files }}; do
            echo "$file was modified"
          done

CodePudding user response:

I don't know about GitHub workflows, but you can achieve want you want just using bash. You need to modify the sample you provided in your question to use find * -type d to get a (recursive) list of all subdirectories. So instead of for i in "${myDirectories[@]}" you just use for i in $(find * -type d).

Additionally, you could keep track of which directories you already handled and skip their subdirectories, if that is what you want (there is probably a better/faster way to do this, but this is what I could come up with):

handledDirs=()

for dir in $(find * -type d); do
    if ...; then # check if $dir contains changes
        for e in "${handledDirs[@]}"; do
            [[ "$dir" == "$e"* ]] && continue 2
        done
        handledDirs =("$dir")

        # do something with $dir
    fi
done
  • Related