Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "changes" output variable to support matrix job configuration #59

Merged
merged 1 commit into from
Dec 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/pull-request-verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
45 changes: 41 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ 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.
- Use: `act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04`


# 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
Expand Down Expand Up @@ -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: ''
Expand All @@ -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

Expand Down Expand Up @@ -230,6 +232,41 @@ jobs:
```
</details>

<details>
<summary>Use change detection to configure matrix job</summary>

```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
- ...
```
</details>

## Change detection workflows

<details>
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
10 changes: 10 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}]`);
Expand All @@ -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) {
Expand Down
10 changes: 10 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}]`)
Expand All @@ -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()
}

Expand Down