diff --git a/.github/workflows/pull-request-verification.yml b/.github/workflows/pull-request-verification.yml
index 71fd091..66e001c 100644
--- a/.github/workflows/pull-request-verification.yml
+++ b/.github/workflows/pull-request-verification.yml
@@ -71,6 +71,23 @@ jobs:
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@v2
+ - 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
+
test-change-type:
runs-on: ubuntu-latest
steps:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f6e799..e32fba0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
# Changelog
+## v2.6.0
+- [Support local changes](https://github.com/dorny/paths-filter/pull/53)
+
## v2.5.3
- [Fixed mapping of removed/deleted change status from github API](https://github.com/dorny/paths-filter/pull/51)
- [Fixed retrieval of all changes via Github API when there are 100+ changes](https://github.com/dorny/paths-filter/pull/50)
diff --git a/README.md b/README.md
index 554d327..893fc6b 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,10 @@ doesn't allow this because they doesn't work on a level of individual jobs or st
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)
+- **Local changes**
+ - Workflow triggered by any event when `base` input parameter is set to `HEAD`
+ - Changes are detected against current HEAD
+ - Untracked files are ignored
## Example
```yaml
@@ -62,6 +66,7 @@ For more scenarios see [examples](#examples) section.
# What's New
+- Support local changes
- Fixed retrieval of all changes via Github API when there are 100+ changes
- Paths expressions are now evaluated using [picomatch](https://github.com/micromatch/picomatch) library
- Support workflows triggered by any event
@@ -304,6 +309,35 @@ jobs:
```
+
+ Local changes: Detect staged and unstaged local changes
+
+```yaml
+on:
+ push:
+ branches: # Push to following branches will trigger the workflow
+ - master
+ - develop
+ - release/**
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ # Some action which 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: dorny/paths-filter@v2
+ id: filter
+ with:
+ base: HEAD
+ filters: ... # Configure your filters
+```
+
+
## Advanced options
diff --git a/dist/index.js b/dist/index.js
index 76ddc47..ea54600 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -3811,11 +3811,12 @@ 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.getChanges = exports.getChangesInLastCommit = exports.NULL_SHA = void 0;
+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(__webpack_require__(807));
const core = __importStar(__webpack_require__(470));
const file_1 = __webpack_require__(258);
exports.NULL_SHA = '0000000000000000000000000000000000000000';
+exports.HEAD = 'HEAD';
async function getChangesInLastCommit() {
core.startGroup(`Change detection in last commit`);
let output = '';
@@ -3850,6 +3851,20 @@ async function getChanges(ref) {
return parseGitDiffOutput(output);
}
exports.getChanges = getChanges;
+async function getChangesOnHead() {
+ // Get current changes - both staged and unstaged
+ core.startGroup(`Change detection on HEAD`);
+ let output = '';
+ try {
+ output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', 'HEAD'])).stdout;
+ }
+ finally {
+ fixStdOutNullTermination();
+ core.endGroup();
+ }
+ return parseGitDiffOutput(output);
+}
+exports.getChangesOnHead = getChangesOnHead;
async function getChangesSinceMergeBase(ref, initialFetchDepth) {
if (!(await hasCommit(ref))) {
// Fetch and add base branch
@@ -4675,6 +4690,11 @@ function getConfigFileContent(configPath) {
return fs.readFileSync(configPath, { encoding: 'utf8' });
}
async function getChangedFiles(token, base, initialFetchDepth) {
+ // if base is 'HEAD' only local uncommitted changes will be detected
+ // This is the simplest case as we don't need to fetch more commits or evaluate current/before refs
+ if (base === git.HEAD) {
+ return await git.getChangesOnHead();
+ }
if (github.context.eventName === 'pull_request' || github.context.eventName === 'pull_request_target') {
const pr = github.context.payload.pull_request;
if (token) {
@@ -4692,7 +4712,7 @@ async function getChangedFilesFromGit(base, initialFetchDepth) {
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`),
+ (core.warning(`'ref' field is missing in event payload - using current branch, tag or commit SHA`),
await git.getCurrentRef());
const baseRef = git.getShortName(base) || defaultRef;
if (!baseRef) {
@@ -4700,11 +4720,11 @@ async function getChangedFilesFromGit(base, initialFetchDepth) {
}
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 base is commit SHA we 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`);
+ core.warning(`'before' field is missing in event payload - changes will be detected from last commit`);
return await git.getChangesInLastCommit();
}
const baseSha = isBaseRefSha ? baseRef : beforeSha;
diff --git a/src/git.ts b/src/git.ts
index 6a0ac91..f34a5cc 100644
--- a/src/git.ts
+++ b/src/git.ts
@@ -3,6 +3,7 @@ import * as core from '@actions/core'
import {File, ChangeStatus} from './file'
export const NULL_SHA = '0000000000000000000000000000000000000000'
+export const HEAD = 'HEAD'
export async function getChangesInLastCommit(): Promise {
core.startGroup(`Change detection in last commit`)
@@ -39,6 +40,20 @@ export async function getChanges(ref: string): Promise {
return parseGitDiffOutput(output)
}
+export async function getChangesOnHead(): Promise {
+ // Get current changes - both staged and unstaged
+ core.startGroup(`Change detection on HEAD`)
+ let output = ''
+ try {
+ output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', 'HEAD'])).stdout
+ } finally {
+ fixStdOutNullTermination()
+ core.endGroup()
+ }
+
+ return parseGitDiffOutput(output)
+}
+
export async function getChangesSinceMergeBase(ref: string, initialFetchDepth: number): Promise {
if (!(await hasCommit(ref))) {
// Fetch and add base branch
diff --git a/src/main.ts b/src/main.ts
index 56718f2..6464367 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -55,6 +55,12 @@ function getConfigFileContent(configPath: string): string {
}
async function getChangedFiles(token: string, base: string, initialFetchDepth: number): Promise {
+ // if base is 'HEAD' only local uncommitted changes will be detected
+ // This is the simplest case as we don't need to fetch more commits or evaluate current/before refs
+ if (base === git.HEAD) {
+ return await git.getChangesOnHead()
+ }
+
if (github.context.eventName === 'pull_request' || github.context.eventName === 'pull_request_target') {
const pr = github.context.payload.pull_request as Webhooks.WebhookPayloadPullRequestPullRequest
if (token) {
@@ -75,7 +81,7 @@ async function getChangedFilesFromGit(base: string, initialFetchDepth: number):
const pushRef =
git.getShortName(github.context.ref) ||
- (core.warning(`'ref' field is missing in PUSH event payload - using current branch, tag or commit SHA`),
+ (core.warning(`'ref' field is missing in event payload - using current branch, tag or commit SHA`),
await git.getCurrentRef())
const baseRef = git.getShortName(base) || defaultRef
@@ -88,11 +94,11 @@ async function getChangedFilesFromGit(base: string, initialFetchDepth: number):
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 base is commit SHA we 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`)
+ core.warning(`'before' field is missing in event payload - changes will be detected from last commit`)
return await git.getChangesInLastCommit()
}