From 62c3dc087c04d040aa95979886981eaff3bc2a0a Mon Sep 17 00:00:00 2001 From: Daniil Samoylov Date: Wed, 11 Sep 2024 18:42:00 +1200 Subject: [PATCH] Update README and support outputting a list of files per status --- README.md | 285 +++++++++++++++++++++++++------------------------ dist/index.mjs | 8 +- src/main.ts | 9 +- 3 files changed, 156 insertions(+), 146 deletions(-) diff --git a/README.md b/README.md index 525e0899..606b8a4b 100644 --- a/README.md +++ b/README.md @@ -23,19 +23,19 @@ don't allow this because they don't work on a level of individual jobs or steps. - Requires [pull-requests: read](https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs) permission - **Feature branches:** - Workflow triggered by **[push](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#push)** - or any other **[event](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows)** + or any other **[event](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows)** - The `base` input parameter must not be the same as the branch that triggered the workflow - Changes are detected against the merge-base with the configured base branch or the default branch - Uses git commands to detect changes - repository must be already [checked out](https://github.com/actions/checkout) - **Master, Release, or other long-lived branches:** - Workflow triggered by **[push](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#push)** event - when `base` input parameter is the same as the branch that triggered the workflow: + when `base` input parameter is the same as the branch that triggered the workflow: - Changes are detected against the most recent commit on the same branch before the push - Workflow triggered by any other **[event](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows)** - when `base` input parameter is commit SHA: + when `base` input parameter is commit SHA: - Changes are detected against the provided `base` commit - Workflow triggered by any other **[event](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows)** - when `base` input parameter is the same as the branch that triggered the workflow: + when `base` input parameter is the same as the branch that triggered the workflow: - Changes are detected from the last commit - Uses git commands to detect changes - repository must be already [checked out](https://github.com/actions/checkout) - **Local changes** @@ -46,7 +46,7 @@ don't allow this because they don't work on a level of individual jobs or steps. ## Example ```yaml -- uses: AurorNZ/paths-filter@v4 +- uses: AurorNZ/paths-filter@v5 id: changes with: filters: | @@ -54,7 +54,7 @@ don't allow this because they don't work on a level of individual jobs or steps. - 'src/**' # run only if some file in 'src' folder was changed -- if: steps.changes.outputs.src == 'true' +- if: steps.changes.outputs.src run: ... ``` @@ -62,9 +62,9 @@ For more scenarios see [examples](#examples) section. ## Notes -- Paths expressions are evaluated using [picomatch](https://github.com/micromatch/picomatch) library. +- Paths expressions are evaluated using [micromatch](https://github.com/micromatch/micromatch) library. Documentation for path expression format can be found on the project GitHub page. -- Picomatch [dot](https://github.com/micromatch/picomatch#options) option is set to true. +- Micromatch [dot](https://github.com/micromatch/micromatch#options) option is set to true. Globbing will also match 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. @@ -72,18 +72,16 @@ For more scenarios see [examples](#examples) section. ## What's New -- Add `ref` input parameter -- Add `list-files: csv` format -- 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 -- Paths expressions are now evaluated using [picomatch](https://github.com/micromatch/picomatch) library +- Paths expressions are now evaluated using [micromatch](https://github.com/micromatch/micromatch) library +- Action outputs now contain results by file status, e.g. `${key}_added`, `${key}_modified`, `${key}_deleted` and others +- The action no longer outputs `'false'` values to allow for loose checks -For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) +For more information, see [CHANGELOG](https://github.com/AurorNZ/paths-filter/blob/master/CHANGELOG.md) ## Usage ```yaml -- uses: AurorNZ/paths-filter@v4 +- uses: AurorNZ/paths-filter@v5 with: # Defines filters applied to detected changed files. # Each filter has a name and a list of rules. @@ -158,9 +156,10 @@ For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob - For each filter, it sets output variable named by the filter to the text: - `'true'` - if **any** of changed files matches any of filter rules - - `'false'` - if **none** of changed files matches any of filter rules + - `undefined` - if **none** of changed files matches any of filter rules - For each filter, it sets an output variable with the name `${FILTER_NAME}_count` to the count of matching files. -- If enabled, for each filter it sets an output variable with the name `${FILTER_NAME}_files`. It will contain a list of all files matching the filter. +- For each filter, it sets an output variable with the name `${FILTER_NAME}_${FILE_CHANGE_STATUS}` to allow for files with certain file status (`added`, `copied`, `deleted`, `modified` or `unmerged`). For example, `backend_modified`. +- If enabled, for each filter it sets an output variable with the name `${FILTER_NAME}_files`. It will contain a list of all files matching the filter. This also enables outputing a list of files per file status, e.g. `${FILTER_NAME}_${FILE_CHANGE_STATUS}_files` - `changes` - JSON array with names of all filters matching any of the changed files. ## Examples @@ -175,30 +174,30 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: AurorNZ/paths-filter@v4 - id: filter - with: - filters: | - backend: - - 'backend/**' - frontend: - - 'frontend/**' - - # run only if 'backend' files were changed - - name: backend tests - if: steps.filter.outputs.backend == 'true' - run: ... - - # run only if 'frontend' files were changed - - name: frontend tests - if: steps.filter.outputs.frontend == 'true' - run: ... - - # run if 'backend' or 'frontend' files were changed - - name: e2e tests - if: steps.filter.outputs.backend == 'true' || steps.filter.outputs.frontend == 'true' - run: ... + - uses: actions/checkout@v4 + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + filters: | + backend: + - 'backend/**' + frontend: + - 'frontend/**' + + # run only if 'backend' files were changed + - name: backend tests + if: steps.filter.outputs.backend + run: ... + + # run only if 'frontend' files were changed + - name: frontend tests + if: steps.filter.outputs.frontend + run: ... + + # run if 'backend' or 'frontend' files were changed + - name: e2e tests + if: steps.filter.outputs.backend || steps.filter.outputs.frontend + run: ... ``` @@ -219,20 +218,20 @@ jobs: backend: ${{ steps.filter.outputs.backend }} frontend: ${{ steps.filter.outputs.frontend }} steps: - # For pull requests it's not necessary to checkout the code - - uses: AurorNZ/paths-filter@v4 - id: filter - with: - filters: | - backend: - - 'backend/**' - frontend: - - 'frontend/**' + # For pull requests it's not necessary to checkout the code + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + filters: | + backend: + - 'backend/**' + frontend: + - 'frontend/**' # JOB to build and test backend code backend: needs: changes - if: ${{ needs.changes.outputs.backend == 'true' }} + if: ${{ needs.changes.outputs.backend }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -241,7 +240,7 @@ jobs: # JOB to build and test frontend code frontend: needs: changes - if: ${{ needs.changes.outputs.frontend == 'true' }} + if: ${{ needs.changes.outputs.frontend }} runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -265,13 +264,13 @@ jobs: # 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: AurorNZ/paths-filter@v4 - id: filter - with: - filters: | - package1: src/package1 - package2: src/package2 + # For pull requests it's not necessary to checkout the code + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + filters: | + package1: src/package1 + package2: src/package2 # JOB to build and test each of modified packages build: @@ -307,11 +306,11 @@ jobs: permissions: pull-requests: read steps: - - uses: actions/checkout@v4 - - uses: AurorNZ/paths-filter@v4 - id: filter - with: - filters: ... # Configure your filters + - uses: actions/checkout@v4 + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + filters: ... # Configure your filters ``` @@ -328,16 +327,16 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - with: - # This may save additional git fetch roundtrip if - # merge-base is found within latest 20 commits - fetch-depth: 20 - - uses: AurorNZ/paths-filter@v4 - id: filter - with: - base: develop # Change detection against merge-base with this branch - filters: ... # Configure your filters + - uses: actions/checkout@v4 + with: + # This may save additional git fetch roundtrip if + # merge-base is found within latest 20 commits + fetch-depth: 20 + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + base: develop # Change detection against merge-base with this branch + filters: ... # Configure your filters ``` @@ -356,16 +355,16 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: AurorNZ/paths-filter@v4 - id: filter - with: - # Use context to get the branch where commits were pushed. - # If there is only one long-lived branch (e.g. master), - # you can specify it directly. - # If it's not configured, the repository default branch is used. - base: ${{ github.ref }} - filters: ... # Configure your filters + - uses: actions/checkout@v4 + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + # Use context to get the branch where commits were pushed. + # If there is only one long-lived branch (e.g. master), + # you can specify it directly. + # If it's not configured, the repository default branch is used. + base: ${{ github.ref }} + filters: ... # Configure your filters ``` @@ -384,18 +383,18 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - # Some action that modifies files tracked by git (e.g. code linter) - - uses: johndoe/some-action@v1 - - # Filter to detect which files were modified - # Changes could be, for example, automatically committed - - uses: AurorNZ/paths-filter@v4 - id: filter - with: - base: HEAD - filters: ... # Configure your filters + - uses: actions/checkout@v4 + + # Some action that modifies files tracked by git (e.g. code linter) + - uses: johndoe/some-action@v1 + + # Filter to detect which files were modified + # Changes could be, for example, automatically committed + - uses: AurorNZ/paths-filter@v5 + id: filter + with: + base: HEAD + filters: ... # Configure your filters ``` @@ -406,11 +405,11 @@ jobs: Define filter rules in own file ```yaml -- uses: AurorNZ/paths-filter@v4 - id: filter - with: - # Path to file where filters are defined - filters: .github/filters.yaml +- uses: AurorNZ/paths-filter@v5 + id: filter + with: + # Path to file where filters are defined + filters: .github/filters.yaml ``` @@ -419,19 +418,19 @@ jobs: Use YAML anchors to reuse path expression(s) inside another rule ```yaml -- uses: AurorNZ/paths-filter@v4 - id: filter - with: - # &shared is YAML anchor, - # *shared references previously defined anchor - # src filter will match any path under common, config and src folders - filters: | - shared: &shared - - common/** - - config/** - src: - - *shared - - src/** +- uses: AurorNZ/paths-filter@v5 + id: filter + with: + # &shared is YAML anchor, + # *shared references previously defined anchor + # src filter will match any path under common, config and src folders + filters: | + shared: &shared + - common/** + - config/** + src: + - *shared + - src/** ``` @@ -440,24 +439,25 @@ jobs: Consider if file was added, modified or deleted ```yaml -- uses: AurorNZ/paths-filter@v4 - id: filter - with: - # Changed file can be 'added', 'modified', or 'deleted'. - # By default, the type of change is not considered. - # Optionally, it's possible to specify it using nested - # dictionary, where the type of change composes the key. - # Multiple change types can be specified using `|` as the delimiter. - filters: | - shared: &shared - - common/** - - config/** - addedOrModified: - - added|modified: '**' - allChanges: - - added|deleted|modified: '**' - addedOrModifiedAnchors: - - added|modified: *shared +- uses: AurorNZ/paths-filter@v5 + id: filter + with: + filters: | + files: + - '**' + +# Changed file can be 'added', 'modified', 'deleted', 'copied', 'unmerged', +- name: added tests + if: steps.filter.outputs.files_added + run: ... + +- name: added or modified tests + if: steps.filter.outputs.files_added || steps.filter.outputs.files_modified + run: ... + +- name: all changes + if: steps.filter.outputs.files_added || steps.filter.outputs.files_modified || steps.filter.outputs.files_deleted + run: ... ``` @@ -468,7 +468,7 @@ jobs: Passing list of modified files as command line args in Linux shell ```yaml -- uses: AurorNZ/paths-filter@v4 +- uses: AurorNZ/paths-filter@v5 id: filter with: # Enable listing of files matching each filter. @@ -478,14 +478,15 @@ jobs: list-files: shell # In this example changed files will be checked by linter. - # It doesn't make sense to lint deleted files. - # Therefore we specify we are only interested in added or modified files. filters: | markdown: - - added|modified: '*.md' + - '*.md' + +# It doesn't make sense to lint deleted files. +# Therefore we specify we are only interested in added or modified files. - name: Lint Markdown - if: ${{ steps.filter.outputs.markdown == 'true' }} - run: npx textlint ${{ steps.filter.outputs.markdown_files }} + if: ${{ steps.filter.outputs.markdown_added || steps.filter.outputs.markdown_modified }} + run: npx textlint ${{ steps.filter.outputs.markdown_added_files }} ${{ steps.filter.outputs.markdown_modified_files }} ``` @@ -494,7 +495,7 @@ jobs: Passing list of modified files as JSON array to another action ```yaml -- uses: AurorNZ/paths-filter@v4 +- uses: AurorNZ/paths-filter@v5 id: filter with: # Enable listing of files matching each filter. @@ -505,12 +506,12 @@ jobs: # In this example all changed files are passed to the following action to do # some custom processing. filters: | - changed: + all: - '**' - name: Lint Markdown uses: johndoe/some-action@v1 with: - files: ${{ steps.filter.outputs.changed_files }} + files: ${{ steps.filter.outputs.all_files }} ``` @@ -521,4 +522,4 @@ jobs: ## License -The scripts and documentation in this project are released under the [MIT License](https://github.com/dorny/paths-filter/blob/master/LICENSE) +The scripts and documentation in this project are released under the [MIT License](https://github.com/AurorNZ/paths-filter/blob/master/LICENSE) diff --git a/dist/index.mjs b/dist/index.mjs index 68e259dc..1684aa5c 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -29684,10 +29684,14 @@ function exportResults(results, format) { } core3.setOutput(`${key}_count`, files.length); for (const status of Object.values(ChangeStatus)) { - const matches = files.some((x) => x.status === status); - if (matches) { + const matches = files.filter((x) => x.status === status); + if (matches.length > 0) { core3.setOutput(`${key}_${status.toLocaleLowerCase()}`, true); } + if (format !== "none") { + const filesValue = serializeExport(files, format); + core3.setOutput(`${key}_${status.toLocaleLowerCase()}_files`, filesValue); + } } if (format !== "none") { const filesValue = serializeExport(files, format); diff --git a/src/main.ts b/src/main.ts index 4d379823..77a620d5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -251,10 +251,15 @@ function exportResults(results: FilterResults, format: ExportFormat): void { core.setOutput(`${key}_count`, files.length) for (const status of Object.values(ChangeStatus)) { - const matches = files.some(x => x.status === status) - if (matches) { + const matches = files.filter(x => x.status === status) + if (matches.length > 0) { core.setOutput(`${key}_${status.toLocaleLowerCase()}`, true) } + + if (format !== 'none') { + const filesValue = serializeExport(files, format) + core.setOutput(`${key}_${status.toLocaleLowerCase()}_files`, filesValue) + } } if (format !== 'none') {