mirror of
https://github.com/dorny/paths-filter.git
synced 2025-06-08 00:59:04 +00:00
Enable custom ref and base on PRs
This commit is contained in:
parent
8c7f485a57
commit
b0bc141e31
6 changed files with 156 additions and 15 deletions
79
.github/workflows/pull-request-verification.yml
vendored
79
.github/workflows/pull-request-verification.yml
vendored
|
@ -135,3 +135,82 @@ jobs:
|
|||
|| steps.filter.outputs.modified_files != 'LICENSE'
|
||||
|| steps.filter.outputs.deleted_files != 'README.md'
|
||||
run: exit 1
|
||||
|
||||
test-baseref-changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
base: ${{ github.base_ref }}
|
||||
ref: ${{ github.sha }}
|
||||
filters: |
|
||||
error:
|
||||
- not_existing_path/**/*
|
||||
any:
|
||||
- "**/*"
|
||||
- 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-custom-nostatus:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: |
|
||||
base=${{ github.base_ref }}
|
||||
compare=${{ github.sha }}
|
||||
git fetch origin $base:$base
|
||||
echo 'customchanges<<EOF' >> $GITHUB_ENV
|
||||
git diff --name-only $base..$compare >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
files: ${{ env.customchanges }}
|
||||
filters: |
|
||||
error:
|
||||
- not_existing_path/**/*
|
||||
any:
|
||||
- "**/*"
|
||||
- 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-custom-withstatus:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: |
|
||||
base=${{ github.base_ref }}
|
||||
compare=${{ github.sha }}
|
||||
git fetch origin $base:$base
|
||||
echo 'customchanges<<EOF' >> $GITHUB_ENV
|
||||
git diff --name-status $base..$compare >> $GITHUB_ENV
|
||||
echo 'EOF' >> $GITHUB_ENV
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
files: ${{ env.customchanges }}
|
||||
filters: |
|
||||
error:
|
||||
- not_existing_path/**/*
|
||||
any:
|
||||
- "**/*"
|
||||
- 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
|
11
README.md
11
README.md
|
@ -18,7 +18,7 @@ don't allow this because they don't work on a level of individual jobs or steps.
|
|||
- Workflow triggered by **[pull_request](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request)**
|
||||
or **[pull_request_target](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request_target)** event
|
||||
- Changes are detected against the pull request base branch
|
||||
- Uses GitHub REST API to fetch a list of modified files
|
||||
- Uses GitHub REST API to fetch a list of modified files, if base or ref are not provided.
|
||||
- **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)**
|
||||
|
@ -40,6 +40,8 @@ don't allow this because they don't work on a level of individual jobs or steps.
|
|||
- Workflow triggered by any event when `base` input parameter is set to `HEAD`
|
||||
- Changes are detected against the current HEAD
|
||||
- Untracked files are ignored
|
||||
- **Input Files**
|
||||
- Input list of string to `customfiles` input parameter and get the filtered results. In case you want to generate list of files elsewhere.
|
||||
|
||||
## Example
|
||||
|
||||
|
@ -107,14 +109,12 @@ For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob
|
|||
# introduced by the current branch are considered.
|
||||
# All files are considered as added if there is no common ancestor with
|
||||
# base branch or no previous commit.
|
||||
# This option is ignored if action is triggered by pull_request event.
|
||||
# Default: repository default branch (e.g. master)
|
||||
base: ''
|
||||
|
||||
# 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.
|
||||
# This option is ignored if action is triggered by pull_request event.
|
||||
# default: ${{ github.ref }}
|
||||
ref:
|
||||
|
||||
|
@ -150,6 +150,11 @@ For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob
|
|||
# changes using git commands.
|
||||
# Default: ${{ github.token }}
|
||||
token: ''
|
||||
|
||||
# Optionally provide a list of files you ahve generated elsewhere.
|
||||
# Performs the glob matching against these files instead. Negates
|
||||
# all other inputs less filters & list-files.
|
||||
customfiles: ''
|
||||
```
|
||||
|
||||
## Outputs
|
||||
|
|
|
@ -36,6 +36,12 @@ inputs:
|
|||
Backslash escapes every potentially unsafe character.
|
||||
required: true
|
||||
default: none
|
||||
files:
|
||||
description: |
|
||||
Custom input for files changed if you do your diff elsewhere.
|
||||
Accepts a newline separated list of files, with optional leading status code, as per output of git diff --name-only or git diff --name-status
|
||||
If no status supplied sets status to unmerged. Is set then only filers and list-files inputs are effective.
|
||||
required: false
|
||||
initial-fetch-depth:
|
||||
description: |
|
||||
How many commits are initially fetched from base branch.
|
||||
|
|
39
dist/index.js
vendored
39
dist/index.js
vendored
|
@ -178,7 +178,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.isGitSha = exports.getShortName = exports.getCurrentRef = exports.listAllFilesAsAdded = exports.parseGitDiffOutput = exports.getChangesSinceMergeBase = exports.getChangesOnHead = exports.getChanges = exports.getChangesInLastCommit = exports.HEAD = exports.NULL_SHA = void 0;
|
||||
exports.statusMap = exports.isGitSha = exports.getShortName = exports.getCurrentRef = exports.listAllFilesAsAdded = exports.parseGitDiffOutput = exports.getChangesSinceMergeBase = exports.getChangesOnHead = exports.getChanges = exports.getChangesInLastCommit = exports.HEAD = exports.NULL_SHA = void 0;
|
||||
const exec_1 = __importDefault(__nccwpck_require__(7757));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const file_1 = __nccwpck_require__(4014);
|
||||
|
@ -307,7 +307,7 @@ function parseGitDiffOutput(output) {
|
|||
const files = [];
|
||||
for (let i = 0; i + 1 < tokens.length; i += 2) {
|
||||
files.push({
|
||||
status: statusMap[tokens[i]],
|
||||
status: exports.statusMap[tokens[i]],
|
||||
filename: tokens[i + 1]
|
||||
});
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ function fixStdOutNullTermination() {
|
|||
// Otherwise things like ::set-output wouldn't work.
|
||||
core.info('');
|
||||
}
|
||||
const statusMap = {
|
||||
exports.statusMap = {
|
||||
A: file_1.ChangeStatus.Added,
|
||||
C: file_1.ChangeStatus.Copied,
|
||||
D: file_1.ChangeStatus.Deleted,
|
||||
|
@ -536,6 +536,7 @@ async function run() {
|
|||
if (workingDirectory) {
|
||||
process.chdir(workingDirectory);
|
||||
}
|
||||
const customfiles = core.getInput('files', { required: false });
|
||||
const token = core.getInput('token', { required: false });
|
||||
const ref = core.getInput('ref', { required: false });
|
||||
const base = core.getInput('base', { required: false });
|
||||
|
@ -543,12 +544,14 @@ async function run() {
|
|||
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput;
|
||||
const listFiles = core.getInput('list-files', { required: false }).toLowerCase() || 'none';
|
||||
const initialFetchDepth = parseInt(core.getInput('initial-fetch-depth', { required: false })) || 10;
|
||||
const files = customfiles
|
||||
? parseFilesInput(customfiles.split(/\r?\n/))
|
||||
: await getChangedFiles(token, base, ref, initialFetchDepth);
|
||||
if (!isExportFormat(listFiles)) {
|
||||
core.setFailed(`Input parameter 'list-files' is set to invalid value '${listFiles}'`);
|
||||
return;
|
||||
}
|
||||
const filter = new filter_1.Filter(filtersYaml);
|
||||
const files = await getChangedFiles(token, base, ref, initialFetchDepth);
|
||||
core.info(`Detected ${files.length} changed files`);
|
||||
const results = filter.match(files);
|
||||
exportResults(results, listFiles);
|
||||
|
@ -557,6 +560,28 @@ async function run() {
|
|||
core.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
function parseFilesInput(customfiles) {
|
||||
const files = [];
|
||||
for (let i = 0; i + 1 < customfiles.length; i += 1) {
|
||||
var filearray = customfiles[i].split(/\s+/);
|
||||
if (filearray.length == 1) {
|
||||
var filestatus = 'U';
|
||||
var filename = filearray[0];
|
||||
}
|
||||
else if (filearray.length == 2) {
|
||||
var filestatus = filearray[0];
|
||||
var filename = filearray[1];
|
||||
}
|
||||
else {
|
||||
throw new Error(`Line '${i + 1}' in custom file: '${customfiles[i]}' is not parseable.`);
|
||||
}
|
||||
files.push({
|
||||
status: git.statusMap[filestatus],
|
||||
filename: filename
|
||||
});
|
||||
}
|
||||
return files;
|
||||
}
|
||||
function isPathInput(text) {
|
||||
return !(text.includes('\n') || text.includes(':'));
|
||||
}
|
||||
|
@ -579,12 +604,12 @@ 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 (prEvents.includes(github.context.eventName) && !ref && !base) {
|
||||
if (ref) {
|
||||
core.warning(`'ref' input parameter is ignored when 'base' is set to HEAD`);
|
||||
core.warning(`'ref' input parameter is ignored when 'base' is not also set on PR events.`);
|
||||
}
|
||||
if (base) {
|
||||
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`);
|
||||
core.warning(`'base' input parameter is ignored when 'ref' is not also set on PR events.`);
|
||||
}
|
||||
const pr = github.context.payload.pull_request;
|
||||
if (token) {
|
||||
|
|
|
@ -260,7 +260,7 @@ function fixStdOutNullTermination(): void {
|
|||
core.info('')
|
||||
}
|
||||
|
||||
const statusMap: {[char: string]: ChangeStatus} = {
|
||||
export const statusMap: {[char: string]: ChangeStatus} = {
|
||||
A: ChangeStatus.Added,
|
||||
C: ChangeStatus.Copied,
|
||||
D: ChangeStatus.Deleted,
|
||||
|
|
34
src/main.ts
34
src/main.ts
|
@ -18,6 +18,7 @@ async function run(): Promise<void> {
|
|||
process.chdir(workingDirectory)
|
||||
}
|
||||
|
||||
const customfiles = core.getInput('files', {required: false})
|
||||
const token = core.getInput('token', {required: false})
|
||||
const ref = core.getInput('ref', {required: false})
|
||||
const base = core.getInput('base', {required: false})
|
||||
|
@ -26,13 +27,16 @@ async function run(): Promise<void> {
|
|||
const listFiles = core.getInput('list-files', {required: false}).toLowerCase() || 'none'
|
||||
const initialFetchDepth = parseInt(core.getInput('initial-fetch-depth', {required: false})) || 10
|
||||
|
||||
const files = customfiles
|
||||
? parseFilesInput(customfiles.split(/\r?\n/))
|
||||
: await getChangedFiles(token, base, ref, initialFetchDepth)
|
||||
|
||||
if (!isExportFormat(listFiles)) {
|
||||
core.setFailed(`Input parameter 'list-files' is set to invalid value '${listFiles}'`)
|
||||
return
|
||||
}
|
||||
|
||||
const filter = new Filter(filtersYaml)
|
||||
const files = await getChangedFiles(token, base, ref, initialFetchDepth)
|
||||
core.info(`Detected ${files.length} changed files`)
|
||||
const results = filter.match(files)
|
||||
exportResults(results, listFiles)
|
||||
|
@ -41,6 +45,28 @@ async function run(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
function parseFilesInput(customfiles: string[]): File[] {
|
||||
const files: File[] = []
|
||||
for (let i = 0; i + 1 < customfiles.length; i += 1) {
|
||||
var filearray = customfiles[i].split(/\s+/)
|
||||
if (filearray.length == 1) {
|
||||
var filestatus = 'U'
|
||||
var filename = filearray[0]
|
||||
} else if (filearray.length == 2) {
|
||||
var filestatus = filearray[0]
|
||||
var filename = filearray[1]
|
||||
} else {
|
||||
throw new Error(`Line '${i + 1}' in custom file: '${customfiles[i]}' is not parseable.`)
|
||||
}
|
||||
|
||||
files.push({
|
||||
status: git.statusMap[filestatus],
|
||||
filename: filename
|
||||
})
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
function isPathInput(text: string): boolean {
|
||||
return !(text.includes('\n') || text.includes(':'))
|
||||
}
|
||||
|
@ -68,12 +94,12 @@ async function getChangedFiles(token: string, base: string, ref: string, initial
|
|||
}
|
||||
|
||||
const prEvents = ['pull_request', 'pull_request_review', 'pull_request_review_comment', 'pull_request_target']
|
||||
if (prEvents.includes(github.context.eventName)) {
|
||||
if (prEvents.includes(github.context.eventName) && !ref && !base) {
|
||||
if (ref) {
|
||||
core.warning(`'ref' input parameter is ignored when 'base' is set to HEAD`)
|
||||
core.warning(`'ref' input parameter is ignored when 'base' is not also set on PR events.`)
|
||||
}
|
||||
if (base) {
|
||||
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`)
|
||||
core.warning(`'base' input parameter is ignored when 'ref' is not also set on PR events.`)
|
||||
}
|
||||
const pr = github.context.payload.pull_request as Webhooks.WebhookPayloadPullRequestPullRequest
|
||||
if (token) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue