Search code examples
githubpathgithub-actionspull-request

GitHub Workflow - get the path that triggered a pull request


I am working on a mono repository that contains multiple projects, each solution being in a different folder. What I'm trying to achieve is to run a scan action on a folder if changes were made to code in that folder. I thought of setting all the paths to each solution in the pull_request paths trigger and then based on the path that triggered the workflow run the scan on that folder.

I was thinking of doing something like this:

name: scan

on:
  pull_request:
    paths:
      - 'path/to/folder/*'
      - 'path/to/anotherfolder/*'

jobs:
  output_path:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Determine triggering path
        id: determine_path
        run: |
          # Get the list of paths being monitored
          monitored_paths=$(echo "${{ github.event.pull_request.paths }}" | tr -d '[] ')

          # Loop through each path
          for path in $monitored_paths; do
            # Check if the modified files include this path
            if echo "${{ github.event.pull_request.changed_files }}" | grep -q "$path"; then
              # Set the output variables and exit the loop
              echo "::set-output name=triggering_path::$path"
              break
            fi
          done
      - name: Output path
        run: |
          echo "The following path triggered this job: ${{ steps.determine_path.outputs.triggering_path }}"```

Solution

  • Currently there is no way of getting the paths in the trigger of the pull request event, so I've hard-coded the same paths in an environment variable so they are easily accessible from the action steps. Then I compare all the paths of the files changed in the pull request to the paths in the environment variable and stop at the first match and save it as output in 'triggering_path'.

    I make the assumption that one should not make changes in multiple folders/projects simultaneously, so at any time only one path should trigger the pull request event.

    I've ended up solving it in the following way:

    name: scan
    on:
      pull_request:
        branches:
          - main
        types:
          - opened
          - synchronize
        paths: ["path/to/folder/*", "path/to/anotherfolder/*"]
    
    env:
      paths: 'path/to/folder/, path/to/anotherfolder/'
    
    jobs:
      output_path:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout code
            uses: actions/checkout@v2
    
          - name: Get changed files
            id: changes
            run: |
              echo "files=$(git diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | xargs)" >> $GITHUB_OUTPUT
    
          - name: Determine triggering path and sonar project key
            id: determine_path
            shell: bash
            run: |
              # Show paths
              echo "Paths: ${{ env.paths }}"
    
              # Get the list of paths being monitored
              monitored_paths=$(echo "${{ env.paths }}" | tr "," " ")
              echo "Monitored paths: $monitored_paths"
              echo "Changed files: ${{ steps.changes.outputs.files }}"
              echo "If you see here files that you have not modified, please update your branch with changes from main."
    
              # Loop through each path
              for path in $monitored_paths
              do
                # Check if the modified files include this path
                if echo "${{ steps.changes.outputs.files }}" | grep -q "$path"; then
                  # Set the output variable and exit the loop
                  echo "triggering_path is $path"
                  echo "triggering_path=$path" >> $GITHUB_OUTPUT
                  break
                fi
              done
    

    Then you can use the output from the determine_path by using the expression ${{ steps.determine_path.outputs.triggering_path }}