diff --git a/.github/workflows/pull-request-verification.yml b/.github/workflows/pull-request-verification.yml
index 27627a9..b18d7ba 100644
--- a/.github/workflows/pull-request-verification.yml
+++ b/.github/workflows/pull-request-verification.yml
@@ -29,6 +29,9 @@ jobs:
- name: filter-test
if: steps.filter.outputs.any != 'true' || steps.filter.outputs.error == 'true'
run: exit 1
+ - name: changes-test
+ if: contains(fromJSON(steps.filter.outputs.changes), 'error') || !contains(fromJSON(steps.filter.outputs.changes), 'any')
+ run: exit 1
test-external:
runs-on: ubuntu-latest
diff --git a/README.md b/README.md
index 145ecc0..448a742 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ For more scenarios see [examples](#examples) section.
## Notes:
- Paths expressions are evaluated using [picomatch](https://github.com/micromatch/picomatch) library.
Documentation for path expression format can be found on project github page.
-- Micromatch [dot](https://github.com/micromatch/picomatch#options) option is set to true.
+- Picomatch [dot](https://github.com/micromatch/picomatch#options) option is set to true.
Globbing will match also paths where file or folder name starts with a dot.
- It's recommended to quote your path expressions with `'` or `"`. Otherwise you will get an error if it starts with `*`.
- Local execution with [act](https://github.com/nektos/act) works only with alternative runner image. Default runner doesn't have `git` binary.
@@ -66,6 +66,7 @@ For more scenarios see [examples](#examples) section.
# What's New
+- Configure matrix job to run for each folder with changes using `changes` output
- Improved listing of matching files with `list-files: shell` and `list-files: escape` options
- Support local changes
- Fixed retrieval of all changes via Github API when there are 100+ changes
@@ -122,9 +123,9 @@ For more information see [CHANGELOG](https://github.com/actions/checkout/blob/ma
# Enables listing of files matching the filter:
# 'none' - Disables listing of matching files (default).
# 'json' - Matching files paths are formatted as JSON array.
- # 'shell' - Space delimited list usable as command line argument list in linux shell.
+ # 'shell' - Space delimited list usable as command line argument list in Linux shell.
# If needed it uses single or double quotes to wrap filename with unsafe characters.
- # 'escape'- Space delimited list usable as command line argument list in linux shell.
+ # 'escape'- Space delimited list usable as command line argument list in Linux shell.
# Backslash escapes every potentially unsafe character.
# Default: none
list-files: ''
@@ -147,6 +148,7 @@ For more information see [CHANGELOG](https://github.com/actions/checkout/blob/ma
- `'true'` - if **any** of changed files matches any of filter rules
- `'false'` - if **none** of changed files matches any of filter rules
- If enabled, for each filter it sets output variable with name `${FILTER_NAME}_files`. It will contain list of all files matching the filter.
+- `changes` - JSON array with names of all filters matching any of changed files.
# Examples
@@ -230,6 +232,41 @@ jobs:
```
+
+Use change detection to configure matrix job
+
+```yaml
+jobs:
+ # JOB to run change detection
+ changes:
+ runs-on: ubuntu-latest
+ outputs:
+ # Expose matched filters as job 'packages' output variable
+ packages: ${{ steps.filter.outputs.changes }}
+ steps:
+ # For pull requests it's not necessary to checkout the code
+ - uses: dorny/paths-filter@v2
+ id: filter
+ with:
+ filters: |
+ package1: src/package1
+ package2: src/package2
+
+ # JOB to build and test each of modified packages
+ build:
+ needs: changes
+ strategy:
+ matrix:
+ # Parse JSON array containing names of all filters matching any of changed files
+ # e.g. ['package1', 'package2'] if both package folders contains changes
+ package: ${{ fromJson(needs.changes.outputs.packages) }}
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - ...
+```
+
+
## Change detection workflows
@@ -406,7 +443,7 @@ jobs:
# Enable listing of files matching each filter.
# Paths to files will be available in `${FILTER_NAME}_files` output variable.
# Paths will be escaped and space-delimited.
- # Output is usable as command line argument list in linux shell
+ # Output is usable as command line argument list in Linux shell
list-files: shell
# In this example changed files will be checked by linter.
diff --git a/action.yml b/action.yml
index d1321d6..41c15ba 100644
--- a/action.yml
+++ b/action.yml
@@ -37,6 +37,9 @@ inputs:
This option takes effect only when changes are detected using git against different base branch.
required: false
default: '10'
+outputs:
+ changes:
+ description: JSON array with names of all filters matching any of changed files
runs:
using: 'node12'
main: 'dist/index.js'
diff --git a/dist/index.js b/dist/index.js
index 953026b..3b17e87 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -4791,10 +4791,12 @@ async function getChangedFilesFromApi(token, pullRequest) {
}
function exportResults(results, format) {
core.info('Results:');
+ const changes = [];
for (const [key, files] of Object.entries(results)) {
const value = files.length > 0;
core.startGroup(`Filter ${key} = ${value}`);
if (files.length > 0) {
+ changes.push(key);
core.info('Matching files:');
for (const file of files) {
core.info(`${file.filename} [${file.status}]`);
@@ -4809,6 +4811,14 @@ function exportResults(results, format) {
core.setOutput(`${key}_files`, filesValue);
}
}
+ if (results['changes'] === undefined) {
+ const changesJson = JSON.stringify(changes);
+ core.info(`Changes output set to ${changesJson}`);
+ core.setOutput('changes', changesJson);
+ }
+ else {
+ core.info('Cannot set changes output variable - name already used by filter output');
+ }
core.endGroup();
}
function serializeExport(files, format) {
diff --git a/src/main.ts b/src/main.ts
index 176dafc..e2ccb65 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -175,10 +175,12 @@ async function getChangedFilesFromApi(
function exportResults(results: FilterResults, format: ExportFormat): void {
core.info('Results:')
+ const changes = []
for (const [key, files] of Object.entries(results)) {
const value = files.length > 0
core.startGroup(`Filter ${key} = ${value}`)
if (files.length > 0) {
+ changes.push(key)
core.info('Matching files:')
for (const file of files) {
core.info(`${file.filename} [${file.status}]`)
@@ -193,6 +195,14 @@ function exportResults(results: FilterResults, format: ExportFormat): void {
core.setOutput(`${key}_files`, filesValue)
}
}
+
+ if (results['changes'] === undefined) {
+ const changesJson = JSON.stringify(changes)
+ core.info(`Changes output set to ${changesJson}`)
+ core.setOutput('changes', changesJson)
+ } else {
+ core.info('Cannot set changes output variable - name already used by filter output')
+ }
core.endGroup()
}