Skip to content
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
76 changes: 45 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ don't allow this because they don't work on a level of individual jobs or steps.
- 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)
- **[Merge queue](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue):**
- Workflow triggered by **[merge_group](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#merge_group)**
- The `base` and `ref` input parameters default to commit hashes from the event
unless explicitly specified.
- 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:
Expand All @@ -48,7 +53,7 @@ don't allow this because they don't work on a level of individual jobs or steps.
## Example

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: changes
with:
filters: |
Expand All @@ -74,7 +79,7 @@ For more scenarios see [examples](#examples) section.

## What's New

- New major release `v3` after update to Node 20 [Breaking change]
- New major release `v4` after update to Node 24 [Breaking change]
- Add `ref` input parameter
- Add `list-files: csv` format
- Configure matrix job to run for each folder with changes using `changes` output
Expand All @@ -84,7 +89,7 @@ For more scenarios see [examples](#examples) section.
## Usage

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
with:
# Defines filters applied to detected changed files.
# Each filter has a name and a list of rules.
Expand All @@ -104,6 +109,8 @@ For more scenarios see [examples](#examples) section.
# Branch, tag, or commit SHA against which the changes will be detected.
# If it references the same branch it was pushed to,
# changes are detected against the most recent commit before the push.
# If it is empty and action is triggered by merge_group event,
# the base commit in the event will be used.
# Otherwise, it uses git merge-base to find the best common ancestor between
# current branch (HEAD) and base.
# When merge-base is found, it's used for change detection - only changes
Expand All @@ -117,6 +124,8 @@ For more scenarios see [examples](#examples) section.
# Git reference (e.g. branch name) from which the changes will be detected.
# Useful when workflow can be triggered only on the default branch (e.g. repository_dispatch event)
# but you want to get changes on a different branch.
# If this is empty and action is triggered by merge_group event,
# the head commit in the event will be used.
# This option is ignored if action is triggered by pull_request event.
# default: ${{ github.ref }}
ref:
Expand Down Expand Up @@ -154,14 +163,14 @@ For more scenarios see [examples](#examples) section.
# Default: ${{ github.token }}
token: ''

# Optional parameter to override the default behavior of file matching algorithm.
# Optional parameter to override the default behavior of file matching algorithm.
# By default files that match at least one pattern defined by the filters will be included.
# This parameter allows to override the "at least one pattern" behavior to make it so that
# all of the patterns have to match or otherwise the file is excluded.
# An example scenario where this is useful if you would like to match all
# .ts files in a sub-directory but not .md files.
# The filters below will match markdown files despite the exclusion syntax UNLESS
# you specify 'every' as the predicate-quantifier parameter. When you do that,
# all of the patterns have to match or otherwise the file is excluded.
# An example scenario where this is useful if you would like to match all
# .ts files in a sub-directory but not .md files.
# The filters below will match markdown files despite the exclusion syntax UNLESS
# you specify 'every' as the predicate-quantifier parameter. When you do that,
# it will only match the .ts files in the subdirectory as expected.
#
# backend:
Expand Down Expand Up @@ -192,8 +201,8 @@ jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: step-security/paths-filter@v3
- uses: actions/checkout@v6
- uses: step-security/paths-filter@v4
id: filter
with:
filters: |
Expand Down Expand Up @@ -237,7 +246,7 @@ jobs:
frontend: ${{ steps.filter.outputs.frontend }}
steps:
# For pull requests it's not necessary to checkout the code
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
filters: |
Expand All @@ -252,7 +261,7 @@ jobs:
if: ${{ needs.changes.outputs.backend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- ...

# JOB to build and test frontend code
Expand All @@ -261,7 +270,7 @@ jobs:
if: ${{ needs.changes.outputs.frontend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- ...
```

Expand All @@ -283,7 +292,7 @@ jobs:
packages: ${{ steps.filter.outputs.changes }}
steps:
# For pull requests it's not necessary to checkout the code
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
filters: |
Expand All @@ -300,7 +309,7 @@ jobs:
package: ${{ fromJSON(needs.changes.outputs.packages) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- ...
```

Expand All @@ -317,15 +326,21 @@ on:
branches: # PRs to the following branches will trigger the workflow
- master
- develop
# Optionally you can use the action in the merge queue
# if your repository enables the feature.
merge_group:
branches:
- master
- develop
jobs:
build:
runs-on: ubuntu-latest
# Required permissions
permissions:
pull-requests: read
steps:
- uses: actions/checkout@v4
- uses: step-security/paths-filter@v3
- uses: actions/checkout@v6
- uses: step-security/paths-filter@v4
id: filter
with:
filters: ... # Configure your filters
Expand All @@ -345,12 +360,12 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
# This may save additional git fetch roundtrip if
# merge-base is found within latest 20 commits
fetch-depth: 20
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
base: develop # Change detection against merge-base with this branch
Expand All @@ -373,8 +388,8 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: step-security/paths-filter@v3
- uses: actions/checkout@v6
- uses: step-security/paths-filter@v4
id: filter
with:
# Use context to get the branch where commits were pushed.
Expand All @@ -401,14 +416,14 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

# 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: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
base: HEAD
Expand All @@ -423,7 +438,7 @@ jobs:
<summary>Define filter rules in own file</summary>

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
# Path to file where filters are defined
Expand All @@ -436,7 +451,7 @@ jobs:
<summary>Use YAML anchors to reuse path expression(s) inside another rule</summary>

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
# &shared is YAML anchor,
Expand All @@ -457,7 +472,7 @@ jobs:
<summary>Consider if file was added, modified or deleted</summary>

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
# Changed file can be 'added', 'modified', or 'deleted'.
Expand All @@ -483,7 +498,7 @@ jobs:
<summary>Detect changes in folder only for some file extensions</summary>

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
# This makes it so that all the patterns have to match a file for it to be
Expand Down Expand Up @@ -511,7 +526,7 @@ jobs:
<summary>Passing list of modified files as command line args in Linux shell</summary>

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
# Enable listing of files matching each filter.
Expand All @@ -537,7 +552,7 @@ jobs:
<summary>Passing list of modified files as JSON array to another action</summary>

```yaml
- uses: step-security/paths-filter@v3
- uses: step-security/paths-filter@v4
id: filter
with:
# Enable listing of files matching each filter.
Expand All @@ -557,4 +572,3 @@ jobs:
```

</details>

66 changes: 41 additions & 25 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,33 +635,49 @@ async function getChangedFiles(token, base, ref, initialFetchDepth) {
}
return await git.getChangesOnHead();
}
const prEvents = ['pull_request', 'pull_request_review', 'pull_request_review_comment', 'pull_request_target'];
if (prEvents.includes(github.context.eventName)) {
if (ref) {
core.warning(`'ref' input parameter is ignored when 'base' is set to HEAD`);
}
if (base) {
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`);
}
const pr = github.context.payload.pull_request;
if (token) {
return await getChangedFilesFromApi(token, pr);
}
if (github.context.eventName === 'pull_request_target') {
// pull_request_target is executed in context of base branch and GITHUB_SHA points to last commit in base branch
// Therefor it's not possible to look at changes in last commit
// At the same time we don't want to fetch any code from forked repository
throw new Error(`'token' input parameter is required if action is triggered by 'pull_request_target' event`);
switch (github.context.eventName) {
// To keep backward compatibility, commits in GitHub pull request event
// take precedence over manual inputs.
case 'pull_request':
case 'pull_request_review':
case 'pull_request_review_comment':
case 'pull_request_target': {
if (ref) {
core.warning(`'ref' input parameter is ignored when 'base' is set to HEAD`);
}
if (base) {
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`);
}
const pr = github.context.payload.pull_request;
if (token) {
return await getChangedFilesFromApi(token, pr);
}
if (github.context.eventName === 'pull_request_target') {
// pull_request_target is executed in context of base branch and GITHUB_SHA points to last commit in base branch
// Therefore it's not possible to look at changes in last commit
// At the same time we don't want to fetch any code from forked repository
throw new Error(`'token' input parameter is required if action is triggered by 'pull_request_target' event`);
}
core.info('Github token is not available - changes will be detected using git diff');
const baseSha = (_a = github.context.payload.pull_request) === null || _a === void 0 ? void 0 : _a.base.sha;
const defaultBranch = (_b = github.context.payload.repository) === null || _b === void 0 ? void 0 : _b.default_branch;
const currentRef = await git.getCurrentRef();
return await git.getChanges(base || baseSha || defaultBranch, currentRef);
}
// To keep backward compatibility, manual inputs take precedence over
// commits in GitHub merge queue event.
case 'merge_group': {
const mergeGroup = github.context.payload;
if (!base) {
base = mergeGroup.merge_group.base_sha;
}
if (!ref) {
ref = mergeGroup.merge_group.head_sha;
}
break;
}
core.info('Github token is not available - changes will be detected using git diff');
const baseSha = (_a = github.context.payload.pull_request) === null || _a === void 0 ? void 0 : _a.base.sha;
const defaultBranch = (_b = github.context.payload.repository) === null || _b === void 0 ? void 0 : _b.default_branch;
const currentRef = await git.getCurrentRef();
return await git.getChanges(base || baseSha || defaultBranch, currentRef);
}
else {
return getChangedFilesFromGit(base, ref, initialFetchDepth);
}
return getChangedFilesFromGit(base, ref, initialFetchDepth);
}
async function getChangedFilesFromGit(base, head, initialFetchDepth) {
var _a;
Expand Down
Loading
Loading