fuzzi
fuzzi

Reputation: 2277

Is there a way to trigger a GH Action for each directory updated?

I'm trying to create a GH Action workflow, that Zips the directory that is updated, and then pushes each Zip file to a Source, with different configuration flags (e.g. name flag will be different for each zip file).

E.g. Let's say I have 4 directories.. dir1/ dir2/ dir3/ dir4/ If I update code in dir2 and dir4, then I want my GH Action to Zip up both of those, and perform an action where I'm pushing both directories to a source, as well as configuring different settings for both.

An idea that I had for this is to trigger 2 runs of the GH Action, 1 run for dir2 where it is zipped, and pushed. And trigger a second run for dir4 to zip and push.
This would use the [working-directory](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaultsrun) attribute to capture which directory needs to be zipped.

I'm not sure how to trigger a run of the GitHub Action per directory updated. Any help on this would be greatly appreciated!

Also open to other solutions on how to achieve what I'm looking for, where I'm able to zip and perform the rest of the workflow, for each directory that has been updated.

Upvotes: 5

Views: 3686

Answers (2)

bmiselis
bmiselis

Reputation: 412

The @aknosis answer is a rock-solid foundation. However, it doesn't work as-is (the jobs part). Based on this file, I've provided a working solution:

jobs:
  find-out-changes:
    runs-on: ubuntu-latest
    outputs:
      changed_directories: ${{ steps.set-output.outputs.changed_directories }}  # The `dirs` doesn't exist in the outputs of changed-files@v35 action.
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Get changed files
        id: changed-files
        uses: tj-actions/changed-files@v35
        with:
          dir_names: true
          dir_names_max_depth: 2  # This is optional. If not provided, full subdirectories' paths will be provided. Use it if you need to trim the output. See docs for details: https://github.com/tj-actions/changed-files/tree/main#inputs.
          json: true
          quotepath: false

      - name: 'Set output in the matrix format'
        id: set-output
        run: echo "changed_directories={\"dir\":${{ steps.changed-files.outputs.all_changed_files }}}" >> "$GITHUB_OUTPUT"

  do-stuff:
    runs-on: ubuntu-latest
    if: ${{ needs.find-out-changes.outputs.changed_directories != '' }}  # Without it, the strategy parser will fail if the changed_directories is empty.
    strategy:
      matrix: ${{fromJson(needs.find-out-changes.outputs.changed_directories)}}
    needs:
      - find-out-changes
    steps:
      - uses: actions/checkout@v3
      - run: zip ${{ matrix.dir }} etc.

Upvotes: 6

aknosis
aknosis

Reputation: 4318

You can achieve this in a single workflow.

  1. Use the paths key to run jobs based on directory changes
  2. Get the changed directory info into JSON format so data can be acted upon
  3. Execute the same job via matrix that does your zip and push magic

Note: this is all pseudocode, it gives you an idea but it likely isn't syntactically correct

  1. This will run this GHA workflow anytime one of those directories are updated. See Pattern Matching Cheat Sheet
on:
  push:
    branches:
      - 'main'
    paths:
      - 'dir1/**'
      - 'dir2/**'

Pattern Matching Cheat Sheet

This will run this GHA workflow anytime one of those directories are updated.

  1. This requires two jobs, one to pull the data for knowing what directories did change. Then another job is the actual meat and potatoes of what you are trying to accomplish.

The first job find-out-changes uses an existing action that will output the relevant data. The second job do-stuff will run once for each directory that was output from find-out-changes.

jobs:
  find-out-changes:
    runs-on: ubuntu-latest
    outputs:
      dirs: ${{ steps.changed-files.dirs }}
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Get changed files
        id: changed-files
        uses: tj-actions/changed-files@v35
        with:
          dir_names: true

  do-stuff:
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{fromJson(needs.find-out-changes.outputs.dirs)}}
    needs:
      - find-out-changes
    steps:
      - uses: actions/checkout@v3
      - run: zip ${{ matrix.dir }} etc.

Upvotes: 3

Related Questions