Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e25be3c6d | |||
| 1c36b4cc18 | |||
| f3ceefdc7e | |||
| 61f87a10cd | |||
| b82ff81ffb |
@@ -1,32 +0,0 @@
|
||||
name: "Build"
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore: [ '*.md' ]
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
- run: |
|
||||
npm install
|
||||
npm run all
|
||||
|
||||
self-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
filters: '.github/filters.yml'
|
||||
- name: filter-test
|
||||
if: steps.filter.outputs.any != 'true' || steps.filter.outputs.error == 'true'
|
||||
run: exit 1
|
||||
@@ -1,152 +0,0 @@
|
||||
name: "Pull Request Verification"
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore: [ '*.md' ]
|
||||
branches:
|
||||
- master
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
- run: |
|
||||
npm install
|
||||
npm run all
|
||||
- name: Check dist is up to date
|
||||
run: |
|
||||
if [ -n "$(git diff --name-only dist/)" ]; then
|
||||
echo "::error::dist/index.js is out of date. Run 'npm run all' and commit the result."
|
||||
git diff --stat dist/
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test-inline:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: read
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
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-external:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: read
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
filters: '.github/filters.yml'
|
||||
- name: filter-test
|
||||
if: steps.filter.outputs.any != 'true' || steps.filter.outputs.error == 'true'
|
||||
run: exit 1
|
||||
|
||||
test-without-token:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
token: ''
|
||||
filters: '.github/filters.yml'
|
||||
- name: filter-test
|
||||
if: steps.filter.outputs.any != 'true' || steps.filter.outputs.error == 'true'
|
||||
run: exit 1
|
||||
|
||||
test-wd-without-token:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
path: somewhere
|
||||
- uses: ./somewhere
|
||||
id: filter
|
||||
with:
|
||||
token: ''
|
||||
working-directory: somewhere
|
||||
filters: '.github/filters.yml'
|
||||
- name: filter-test
|
||||
if: steps.filter.outputs.any != 'true' || steps.filter.outputs.error == 'true'
|
||||
run: exit 1
|
||||
|
||||
test-local-changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- run: echo "NEW FILE" > local
|
||||
- run: git add local
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
base: HEAD
|
||||
filters: |
|
||||
local:
|
||||
- local
|
||||
- name: filter-test
|
||||
if: steps.filter.outputs.local != 'true'
|
||||
run: exit 1
|
||||
- name: count-test
|
||||
if: steps.filter.outputs.local_count != 1
|
||||
run: exit 1
|
||||
|
||||
test-change-type:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: configure GIT user
|
||||
run: git config user.email "john@nowhere.local" && git config user.name "John Doe"
|
||||
- name: modify working tree
|
||||
run: touch add.txt && rm README.md && echo "TEST" > LICENSE
|
||||
- name: commit changes
|
||||
run: git add -A && git commit -a -m 'testing this action'
|
||||
- uses: ./
|
||||
id: filter
|
||||
with:
|
||||
token: ''
|
||||
list-files: shell
|
||||
filters: |
|
||||
added:
|
||||
- added: "add.txt"
|
||||
deleted:
|
||||
- deleted: "README.md"
|
||||
modified:
|
||||
- modified: "LICENSE"
|
||||
any:
|
||||
- added|deleted|modified: "*"
|
||||
- name: Print 'added_files'
|
||||
run: echo ${{steps.filter.outputs.added_files}}
|
||||
- name: Print 'modified_files'
|
||||
run: echo ${{steps.filter.outputs.modified_files}}
|
||||
- name: Print 'deleted_files'
|
||||
run: echo ${{steps.filter.outputs.deleted_files}}
|
||||
- name: filter-test
|
||||
if: |
|
||||
steps.filter.outputs.added != 'true'
|
||||
|| steps.filter.outputs.deleted != 'true'
|
||||
|| steps.filter.outputs.modified != 'true'
|
||||
|| steps.filter.outputs.any != 'true'
|
||||
|| steps.filter.outputs.added_files != 'add.txt'
|
||||
|| steps.filter.outputs.modified_files != 'LICENSE'
|
||||
|| steps.filter.outputs.deleted_files != 'README.md'
|
||||
run: exit 1
|
||||
Vendored
+43
-71
@@ -42,29 +42,18 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.Filter = exports.SUPPORTED_PREDICATE_QUANTIFIERS = exports.PredicateQuantifier = void 0;
|
||||
exports.isPredicateQuantifier = isPredicateQuantifier;
|
||||
exports.Filter = exports.isPredicateQuantifier = exports.SUPPORTED_PREDICATE_QUANTIFIERS = exports.PredicateQuantifier = void 0;
|
||||
const jsyaml = __importStar(__nccwpck_require__(1917));
|
||||
const picomatch_1 = __importDefault(__nccwpck_require__(8569));
|
||||
// Minimatch options used in all matchers
|
||||
@@ -106,6 +95,7 @@ exports.SUPPORTED_PREDICATE_QUANTIFIERS = Object.values(PredicateQuantifier);
|
||||
function isPredicateQuantifier(x) {
|
||||
return exports.SUPPORTED_PREDICATE_QUANTIFIERS.includes(x);
|
||||
}
|
||||
exports.isPredicateQuantifier = isPredicateQuantifier;
|
||||
class Filter {
|
||||
// Creates instance of Filter and load rules from YAML if it's provided
|
||||
constructor(yaml, filterConfig) {
|
||||
@@ -206,34 +196,15 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.HEAD = exports.NULL_SHA = void 0;
|
||||
exports.getChangesInLastCommit = getChangesInLastCommit;
|
||||
exports.getChanges = getChanges;
|
||||
exports.getChangesOnHead = getChangesOnHead;
|
||||
exports.getChangesSinceMergeBase = getChangesSinceMergeBase;
|
||||
exports.parseGitDiffOutput = parseGitDiffOutput;
|
||||
exports.listAllFilesAsAdded = listAllFilesAsAdded;
|
||||
exports.getCurrentRef = getCurrentRef;
|
||||
exports.getShortName = getShortName;
|
||||
exports.isGitSha = isGitSha;
|
||||
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 = __nccwpck_require__(1514);
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const file_1 = __nccwpck_require__(4014);
|
||||
@@ -251,6 +222,7 @@ async function getChangesInLastCommit() {
|
||||
}
|
||||
return parseGitDiffOutput(output);
|
||||
}
|
||||
exports.getChangesInLastCommit = getChangesInLastCommit;
|
||||
async function getChanges(base, head) {
|
||||
const baseRef = await ensureRefAvailable(base);
|
||||
const headRef = await ensureRefAvailable(head);
|
||||
@@ -268,6 +240,7 @@ async function getChanges(base, head) {
|
||||
}
|
||||
return parseGitDiffOutput(output);
|
||||
}
|
||||
exports.getChanges = getChanges;
|
||||
async function getChangesOnHead() {
|
||||
// Get current changes - both staged and unstaged
|
||||
core.startGroup(`Change detection on HEAD`);
|
||||
@@ -281,6 +254,7 @@ async function getChangesOnHead() {
|
||||
}
|
||||
return parseGitDiffOutput(output);
|
||||
}
|
||||
exports.getChangesOnHead = getChangesOnHead;
|
||||
async function getChangesSinceMergeBase(base, head, initialFetchDepth) {
|
||||
let baseRef;
|
||||
let headRef;
|
||||
@@ -354,6 +328,7 @@ async function getChangesSinceMergeBase(base, head, initialFetchDepth) {
|
||||
}
|
||||
return parseGitDiffOutput(output);
|
||||
}
|
||||
exports.getChangesSinceMergeBase = getChangesSinceMergeBase;
|
||||
function parseGitDiffOutput(output) {
|
||||
const tokens = output.split('\u0000').filter(s => s.length > 0);
|
||||
const files = [];
|
||||
@@ -365,6 +340,7 @@ function parseGitDiffOutput(output) {
|
||||
}
|
||||
return files;
|
||||
}
|
||||
exports.parseGitDiffOutput = parseGitDiffOutput;
|
||||
async function listAllFilesAsAdded() {
|
||||
core.startGroup('Listing all files tracked by git');
|
||||
let output = '';
|
||||
@@ -383,11 +359,12 @@ async function listAllFilesAsAdded() {
|
||||
filename: path
|
||||
}));
|
||||
}
|
||||
exports.listAllFilesAsAdded = listAllFilesAsAdded;
|
||||
async function getCurrentRef() {
|
||||
core.startGroup(`Get current git ref`);
|
||||
try {
|
||||
const branch = (await (0, exec_1.getExecOutput)('git', ['branch', '--show-current'])).stdout.trim();
|
||||
if (branch) {
|
||||
const branch = (await (0, exec_1.getExecOutput)('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim();
|
||||
if (branch && branch !== 'HEAD') {
|
||||
return branch;
|
||||
}
|
||||
const describe = await (0, exec_1.getExecOutput)('git', ['describe', '--tags', '--exact-match'], { ignoreReturnCode: true });
|
||||
@@ -400,6 +377,7 @@ async function getCurrentRef() {
|
||||
core.endGroup();
|
||||
}
|
||||
}
|
||||
exports.getCurrentRef = getCurrentRef;
|
||||
function getShortName(ref) {
|
||||
if (!ref)
|
||||
return '';
|
||||
@@ -411,9 +389,11 @@ function getShortName(ref) {
|
||||
return ref.slice(tags.length);
|
||||
return ref;
|
||||
}
|
||||
exports.getShortName = getShortName;
|
||||
function isGitSha(ref) {
|
||||
return /^[a-z0-9]{40}$/.test(ref);
|
||||
}
|
||||
exports.isGitSha = isGitSha;
|
||||
async function hasCommit(ref) {
|
||||
return (await (0, exec_1.getExecOutput)('git', ['cat-file', '-e', `${ref}^{commit}`], { ignoreReturnCode: true })).exitCode === 0;
|
||||
}
|
||||
@@ -486,7 +466,7 @@ const statusMap = {
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.csvEscape = csvEscape;
|
||||
exports.csvEscape = void 0;
|
||||
// Returns filename escaped for CSV
|
||||
// Wraps file name into "..." only when it contains some potentially unsafe character
|
||||
function csvEscape(value) {
|
||||
@@ -502,6 +482,7 @@ function csvEscape(value) {
|
||||
// another double quote
|
||||
return `"${value.replace(/"/g, '""')}"`;
|
||||
}
|
||||
exports.csvEscape = csvEscape;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -512,12 +493,12 @@ function csvEscape(value) {
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.backslashEscape = backslashEscape;
|
||||
exports.shellEscape = shellEscape;
|
||||
exports.shellEscape = exports.backslashEscape = void 0;
|
||||
// Backslash escape every character except small subset of definitely safe characters
|
||||
function backslashEscape(value) {
|
||||
return value.replace(/([^a-zA-Z0-9,._+:@%/-])/gm, '\\$1');
|
||||
}
|
||||
exports.backslashEscape = backslashEscape;
|
||||
// Returns filename escaped for usage as shell argument.
|
||||
// Applies "human readable" approach with as few escaping applied as possible
|
||||
function shellEscape(value) {
|
||||
@@ -538,6 +519,7 @@ function shellEscape(value) {
|
||||
// Contains some unsafe characters but no single quote
|
||||
return `'${value}'`;
|
||||
}
|
||||
exports.shellEscape = shellEscape;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -563,23 +545,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const fs = __importStar(__nccwpck_require__(7147));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
@@ -653,7 +625,7 @@ async function getChangedFiles(token, base, ref, initialFetchDepth) {
|
||||
case 'pull_request_review_comment':
|
||||
case 'pull_request_target': {
|
||||
if (ref) {
|
||||
core.warning(`'ref' input parameter is ignored when 'base' is set to HEAD`);
|
||||
core.warning(`'ref' input parameter is ignored when action is triggered by pull request event`);
|
||||
}
|
||||
if (base) {
|
||||
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`);
|
||||
@@ -668,7 +640,7 @@ async function getChangedFiles(token, base, ref, initialFetchDepth) {
|
||||
// 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');
|
||||
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();
|
||||
@@ -738,7 +710,7 @@ async function getChangedFilesFromGit(base, head, initialFetchDepth) {
|
||||
}
|
||||
// Uses github REST api to get list of files changed in PR
|
||||
async function getChangedFilesFromApi(token, pullRequest) {
|
||||
core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from Github API`);
|
||||
core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from GitHub API`);
|
||||
try {
|
||||
const client = github.getOctokit(token);
|
||||
const per_page = 100;
|
||||
|
||||
+2
-2
@@ -166,8 +166,8 @@ export async function listAllFilesAsAdded(): Promise<File[]> {
|
||||
export async function getCurrentRef(): Promise<string> {
|
||||
core.startGroup(`Get current git ref`)
|
||||
try {
|
||||
const branch = (await getExecOutput('git', ['branch', '--show-current'])).stdout.trim()
|
||||
if (branch) {
|
||||
const branch = (await getExecOutput('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim()
|
||||
if (branch && branch !== 'HEAD') {
|
||||
return branch
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -92,7 +92,7 @@ async function getChangedFiles(token: string, base: string, ref: string, initial
|
||||
case 'pull_request_review_comment':
|
||||
case 'pull_request_target': {
|
||||
if (ref) {
|
||||
core.warning(`'ref' input parameter is ignored when 'base' is set to HEAD`)
|
||||
core.warning(`'ref' input parameter is ignored when action is triggered by pull request event`)
|
||||
}
|
||||
if (base) {
|
||||
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`)
|
||||
@@ -107,7 +107,7 @@ async function getChangedFiles(token: string, base: string, ref: string, initial
|
||||
// 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')
|
||||
core.info('GitHub token is not available - changes will be detected using git diff')
|
||||
const baseSha = github.context.payload.pull_request?.base.sha
|
||||
const defaultBranch = github.context.payload.repository?.default_branch
|
||||
const currentRef = await git.getCurrentRef()
|
||||
@@ -194,7 +194,7 @@ async function getChangedFilesFromGit(base: string, head: string, initialFetchDe
|
||||
|
||||
// Uses github REST api to get list of files changed in PR
|
||||
async function getChangedFilesFromApi(token: string, pullRequest: PullRequest): Promise<File[]> {
|
||||
core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from Github API`)
|
||||
core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from GitHub API`)
|
||||
try {
|
||||
const client = github.getOctokit(token)
|
||||
const per_page = 100
|
||||
|
||||
Reference in New Issue
Block a user