Home > Software engineering >  How to github action parallelize tests dynamically by folder?
How to github action parallelize tests dynamically by folder?

Time:04-01

I want to run a test through Github action for each PR.

My Github repository structure is

Root Dir

  • Sub Dirs
    • Child Dir
      • Java Module Dir
  • Sub Dirs
    • Child Dir
      • Java Module Dir
  • Sub Dirs
    • Child Dir
      • Java Module Dir
  • ...

In this situation I want to test only Java modules.

I don't want to create a repository as a multi-module project

The reason is that it is going to be used in combination with other languages, so it doesn't look good for the repository to look like it's based on Java.

Anyway, to run Java tests by subdirectory

Do I have to write that directory to the workflow file to run it?

Is it possible to dynamically find and execute Java-based directories?

(Java-based directories are probably prefixed with "Java-")

I set the matrix with GitHub action workflow The directory description was tested.

I want to dynamically directory Testing in Github Action

CodePudding user response:

You can dynamically create the input for the matrix in the first job and then use that as an input for the matrix in the second job.

For a project where all test directories are in a directory call tests, you could collect the directories like so:

collect_dirs:
  runs-on: ubuntu-latest
  outputs:
    dirs: ${{ steps.dirs.outputs.dirs }}
  steps:
    - uses: actions/checkout@v2
    - id: dirs
      run: echo "::set-output name=dirs::$(ls -d tests/*/ | jq --raw-input --slurp --compact-output 'split("\n")[:-1]')"

The tricky part here is how to construct the dirs output:

  • First, we list all directories in the directory tests/
  • Second, jq formats the output as a JSON array. For example, if the directory contains the subdirectories a, b, and c, then the output is set to ["a","b","c"].

In a second job, you can use the matrix based on that output:

run_tests:
  needs: collect_dirs
  runs-on: ubuntu-latest
  strategy:
    matrix:
      dir: ${{ fromJson(needs.collect_dirs.outputs.dirs) }}
  steps:
    - run: echo ${{ matrix.dir }}
  • Related