6 Commits

Author SHA1 Message Date
Michal Dorner
189a1963db update CHANGELOG.md 2020-10-16 12:27:18 +02:00
Michal Dorner
77a8129fcb improve logging 2020-10-16 12:24:39 +02:00
Michal Dorner
9379d51f46 mention commit SHA in docs for base parameter 2020-10-16 11:49:15 +02:00
Michal Dorner
beaf26afca Allow change detection on all event types 2020-10-16 11:44:38 +02:00
Michal Dorner
9bd03c0d68 Update CHANGELOG.md 2020-10-06 13:40:13 +02:00
Michal Dorner
9553dabbd8 Remove usage of --no-auto-gc option (#42)
* Remove usage of --no-auto-gc option

This option is not supported in git versions < 2.23.
Older git versions might be used in self-hosted runners.

* Update CHANGELOG
2020-10-06 13:38:18 +02:00
6 changed files with 78 additions and 47 deletions

View File

@@ -1,5 +1,11 @@
# Changelog
## v2.5.0
- [Support workflows triggered by any event](https://github.com/dorny/paths-filter/pull/44)
## v2.4.2
- [Fixed compatibility with older (<2.23) versions of git](https://github.com/dorny/paths-filter/pull/42)
## v2.4.0
- [Support pushes of tags or when tag is used as base](https://github.com/dorny/paths-filter/pull/40)
- [Use git log to detect changes from PRs merge commit if token is not available](https://github.com/dorny/paths-filter/pull/40)

View File

@@ -9,18 +9,27 @@ doesn't allow this because they doesn't work on a level of individual jobs or st
## Supported workflows:
- Pull requests:
- Action triggered by **[pull_request](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request)**
- **Pull requests:**
- 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 list of modified files
- Feature branches:
- Action triggered by **[push](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#push)** event
- Changes are detected against the merge-base with configured base branch
- **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)**
- The `base` input parameter must not be the same as the branch that triggered the workflow
- Changes are detected against the merge-base with configured base branch or 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:
- Action triggered by **[push](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#push)** event
- Changes are detected against the most recent commit on the same branch before the push
- **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 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:
- 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 same as the branch that triggered the workflow:
- Changes are detected from last commit
- Uses git commands to detect changes - repository must be already [checked out](https://github.com/actions/checkout)
## Example
@@ -49,6 +58,8 @@ For more scenarios see [examples](#examples) section.
# What's New
- Support workflows triggered by any event
- Fixed compatibility with older (<2.23) versions of git
- Support for tag pushes and tags as a base reference
- Fixes for various edge cases when event payload is incomplete
- Supports local execution with [act](https://github.com/nektos/act)
@@ -56,10 +67,6 @@ For more scenarios see [examples](#examples) section.
- Detects only changes introduced by feature branch. Later modifications on base branch are ignored.
- Filter by type of file change:
- Optionally consider if file was added, modified or deleted
- Custom processing of changed files:
- Optionally export paths of all files matching the filter
- Output can be space-delimited or in JSON format
- Improved documentation and logging
For more information see [CHANGELOG](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
@@ -85,7 +92,7 @@ For more information see [CHANGELOG](https://github.com/actions/checkout/blob/ma
# Filters syntax is documented by example - see examples section.
filters: ''
# Branch or tag against which the changes will be detected.
# Branch, tag or commit SHA against which the changes will be detected.
# If it references same branch it was pushed to,
# changes are detected against the most recent commit before the push.
# Otherwise it uses git merge-base to find best common ancestor between

View File

@@ -26,4 +26,10 @@ describe('git utility function tests (those not invoking git)', () => {
expect(git.getShortName('tags/v1')).toBe('tags/v1')
expect(git.getShortName('v1')).toBe('v1')
})
test('isGitSha(ref) returns true only for 40 characters of a-z and 0-9', () => {
expect(git.isGitSha('8b399ed1681b9efd6b1e048ca1c5cba47edf3855')).toBeTruthy()
expect(git.isGitSha('This_is_very_long_name_for_a_branch_1111')).toBeFalsy()
expect(git.isGitSha('master')).toBeFalsy()
})
})

40
dist/index.js vendored
View File

@@ -3811,7 +3811,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getShortName = exports.getCurrentRef = exports.listAllFilesAsAdded = exports.parseGitDiffOutput = exports.getChangesSinceMergeBase = exports.getChanges = exports.getChangesInLastCommit = exports.NULL_SHA = void 0;
exports.isGitSha = exports.getShortName = exports.getCurrentRef = exports.listAllFilesAsAdded = exports.parseGitDiffOutput = exports.getChangesSinceMergeBase = exports.getChanges = exports.getChangesInLastCommit = exports.NULL_SHA = void 0;
const exec_1 = __importDefault(__webpack_require__(807));
const core = __importStar(__webpack_require__(470));
const file_1 = __webpack_require__(258);
@@ -3833,7 +3833,7 @@ async function getChanges(ref) {
if (!(await hasCommit(ref))) {
// Fetch single commit
core.startGroup(`Fetching ${ref} from origin`);
await exec_1.default('git', ['fetch', '--depth=1', '--no-tags', '--no-auto-gc', 'origin', ref]);
await exec_1.default('git', ['fetch', '--depth=1', '--no-tags', 'origin', ref]);
core.endGroup();
}
// Get differences between ref and HEAD
@@ -3873,7 +3873,7 @@ async function getChangesSinceMergeBase(ref, initialFetchDepth) {
let deepen = initialFetchDepth;
let lastCommitsCount = await countCommits();
do {
await exec_1.default('git', ['fetch', `--deepen=${deepen}`, '--no-tags', '--no-auto-gc']);
await exec_1.default('git', ['fetch', `--deepen=${deepen}`, '--no-tags']);
const count = await countCommits();
if (count <= lastCommitsCount) {
core.info('No merge base found - all files will be listed as added');
@@ -3960,6 +3960,10 @@ function getShortName(ref) {
return ref;
}
exports.getShortName = getShortName;
function isGitSha(ref) {
return /^[a-z0-9]{40}$/.test(ref);
}
exports.isGitSha = isGitSha;
async function hasCommit(ref) {
core.startGroup(`Checking if commit for ${ref} is locally available`);
try {
@@ -4679,34 +4683,34 @@ async function getChangedFiles(token, base, initialFetchDepth) {
core.info('Github token is not available - changes will be detected from PRs merge commit');
return await git.getChangesInLastCommit();
}
else if (github.context.eventName === 'push') {
return getChangedFilesFromPush(base, initialFetchDepth);
}
else {
throw new Error('This action can be triggered only by pull_request, pull_request_target or push event');
return getChangedFilesFromGit(base, initialFetchDepth);
}
}
async function getChangedFilesFromPush(base, initialFetchDepth) {
async function getChangedFilesFromGit(base, initialFetchDepth) {
var _a;
const push = github.context.payload;
const defaultRef = (_a = push.repository) === null || _a === void 0 ? void 0 : _a.default_branch;
const pushRef = git.getShortName(push.ref) ||
const defaultRef = (_a = github.context.payload.repository) === null || _a === void 0 ? void 0 : _a.default_branch;
const beforeSha = github.context.eventName === 'push' ? github.context.payload.before : null;
const pushRef = git.getShortName(github.context.ref) ||
(core.warning(`'ref' field is missing in PUSH event payload - using current branch, tag or commit SHA`),
await git.getCurrentRef());
const baseRef = git.getShortName(base) || defaultRef;
if (!baseRef) {
throw new Error("This action requires 'base' input to be configured or 'repository.default_branch' to be set in the event payload");
}
// If base references same branch it was pushed to,
// we will do comparison against the previously pushed commit
if (baseRef === pushRef) {
if (!push.before) {
const isBaseRefSha = git.isGitSha(baseRef);
const isBaseSameAsPush = baseRef === pushRef;
// If base is commit SHA will do comparison against the referenced commit
// Or If base references same branch it was pushed to, we will do comparison against the previously pushed commit
if (isBaseRefSha || isBaseSameAsPush) {
if (!isBaseRefSha && !beforeSha) {
core.warning(`'before' field is missing in PUSH event payload - changes will be detected from last commit`);
return await git.getChangesInLastCommit();
}
const baseSha = isBaseRefSha ? baseRef : beforeSha;
// If there is no previously pushed commit,
// we will do comparison against the default branch or return all as added
if (push.before === git.NULL_SHA) {
if (baseSha === git.NULL_SHA) {
if (defaultRef && baseRef !== defaultRef) {
core.info(`First push of a branch detected - changes will be detected against the default branch ${defaultRef}`);
return await git.getChangesSinceMergeBase(defaultRef, initialFetchDepth);
@@ -4716,8 +4720,8 @@ async function getChangedFilesFromPush(base, initialFetchDepth) {
return await git.listAllFilesAsAdded();
}
}
core.info(`Changes will be detected against the last previously pushed commit on same branch (${pushRef})`);
return await git.getChanges(push.before);
core.info(`Changes will be detected against commit (${baseSha})`);
return await git.getChanges(baseSha);
}
// Changes introduced by current branch against the base branch
core.info(`Changes will be detected against the branch ${baseRef}`);

View File

@@ -21,7 +21,7 @@ export async function getChanges(ref: string): Promise<File[]> {
if (!(await hasCommit(ref))) {
// Fetch single commit
core.startGroup(`Fetching ${ref} from origin`)
await exec('git', ['fetch', '--depth=1', '--no-tags', '--no-auto-gc', 'origin', ref])
await exec('git', ['fetch', '--depth=1', '--no-tags', 'origin', ref])
core.endGroup()
}
@@ -64,7 +64,7 @@ export async function getChangesSinceMergeBase(ref: string, initialFetchDepth: n
let deepen = initialFetchDepth
let lastCommitsCount = await countCommits()
do {
await exec('git', ['fetch', `--deepen=${deepen}`, '--no-tags', '--no-auto-gc'])
await exec('git', ['fetch', `--deepen=${deepen}`, '--no-tags'])
const count = await countCommits()
if (count <= lastCommitsCount) {
core.info('No merge base found - all files will be listed as added')
@@ -153,6 +153,10 @@ export function getShortName(ref: string): string {
return ref
}
export function isGitSha(ref: string): boolean {
return /^[a-z0-9]{40}$/.test(ref)
}
async function hasCommit(ref: string): Promise<boolean> {
core.startGroup(`Checking if commit for ${ref} is locally available`)
try {

View File

@@ -62,19 +62,19 @@ async function getChangedFiles(token: string, base: string, initialFetchDepth: n
}
core.info('Github token is not available - changes will be detected from PRs merge commit')
return await git.getChangesInLastCommit()
} else if (github.context.eventName === 'push') {
return getChangedFilesFromPush(base, initialFetchDepth)
} else {
throw new Error('This action can be triggered only by pull_request, pull_request_target or push event')
return getChangedFilesFromGit(base, initialFetchDepth)
}
}
async function getChangedFilesFromPush(base: string, initialFetchDepth: number): Promise<File[]> {
const push = github.context.payload as Webhooks.WebhookPayloadPush
const defaultRef = push.repository?.default_branch
async function getChangedFilesFromGit(base: string, initialFetchDepth: number): Promise<File[]> {
const defaultRef = github.context.payload.repository?.default_branch
const beforeSha =
github.context.eventName === 'push' ? (github.context.payload as Webhooks.WebhookPayloadPush).before : null
const pushRef =
git.getShortName(push.ref) ||
git.getShortName(github.context.ref) ||
(core.warning(`'ref' field is missing in PUSH event payload - using current branch, tag or commit SHA`),
await git.getCurrentRef())
@@ -85,17 +85,21 @@ async function getChangedFilesFromPush(base: string, initialFetchDepth: number):
)
}
// If base references same branch it was pushed to,
// we will do comparison against the previously pushed commit
if (baseRef === pushRef) {
if (!push.before) {
const isBaseRefSha = git.isGitSha(baseRef)
const isBaseSameAsPush = baseRef === pushRef
// If base is commit SHA will do comparison against the referenced commit
// Or If base references same branch it was pushed to, we will do comparison against the previously pushed commit
if (isBaseRefSha || isBaseSameAsPush) {
if (!isBaseRefSha && !beforeSha) {
core.warning(`'before' field is missing in PUSH event payload - changes will be detected from last commit`)
return await git.getChangesInLastCommit()
}
const baseSha = isBaseRefSha ? baseRef : beforeSha
// If there is no previously pushed commit,
// we will do comparison against the default branch or return all as added
if (push.before === git.NULL_SHA) {
if (baseSha === git.NULL_SHA) {
if (defaultRef && baseRef !== defaultRef) {
core.info(`First push of a branch detected - changes will be detected against the default branch ${defaultRef}`)
return await git.getChangesSinceMergeBase(defaultRef, initialFetchDepth)
@@ -105,8 +109,8 @@ async function getChangedFilesFromPush(base: string, initialFetchDepth: number):
}
}
core.info(`Changes will be detected against the last previously pushed commit on same branch (${pushRef})`)
return await git.getChanges(push.before)
core.info(`Changes will be detected against commit (${baseSha})`)
return await git.getChanges(baseSha)
}
// Changes introduced by current branch against the base branch