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
48 changes: 48 additions & 0 deletions .github/workflows/pull-request-verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,51 @@ jobs:
|| steps.filter.outputs.modified_files != 'LICENSE'
|| steps.filter.outputs.deleted_files != 'README.md'
run: exit 1

test-json-output:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create test files
run: |
mkdir -p frontend/src backend/src
touch frontend/src/app.ts frontend/src/index.ts
touch backend/src/main.ts
- name: Add files
run: git add .
- uses: ./
id: filter
with:
base: HEAD
filters: |
frontend:
- 'frontend/**'
backend:
- 'backend/**'
json-output: true
- name: Verify JSON output
run: |
# Verify frontend JSON
FRONTEND_FILES=$(cat /tmp/paths-filter/frontend.json)
EXPECTED_FRONTEND='[
"frontend/src/app.ts",
"frontend/src/index.ts"
]'
if [ "$(echo $FRONTEND_FILES | jq -c 'sort')" != "$(echo $EXPECTED_FRONTEND | jq -c 'sort')" ]; then
echo "Frontend files do not match expected output"
echo "Got: $FRONTEND_FILES"
echo "Expected: $EXPECTED_FRONTEND"
exit 1
fi

# Verify backend JSON
BACKEND_FILES=$(cat /tmp/paths-filter/backend.json)
EXPECTED_BACKEND='[
"backend/src/main.ts"
]'
if [ "$(echo $BACKEND_FILES | jq -c 'sort')" != "$(echo $EXPECTED_BACKEND | jq -c 'sort')" ]; then
echo "Backend files do not match expected output"
echo "Got: $BACKEND_FILES"
echo "Expected: $EXPECTED_BACKEND"
exit 1
fi
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ For more information, see [CHANGELOG](https://github.com/tapihdev/paths-filter/b
# - '!**/*.jpeg'
# - '!**/*.md'
predicate-quantifier: 'some'

# Enable JSON output for filter results
json-output: 'false'

# Directory where JSON files will be written when json-output is true
# Defaults to "/tmp/paths-filter"
json-output-dir: 'path-filter-results'
```

## Outputs
Expand Down Expand Up @@ -552,6 +559,31 @@ jobs:

</details>

### JSON Output Format

When `json-output` is set to `true`, the action will create individual JSON files for each filter in the specified `json-output-dir` (defaults to "/tmp/paths-filter"). For example:

```json
// /tmp/paths-filter/frontend.json
[
"frontend/src/app.ts",
"frontend/src/index.ts"
]
```

Example usage:
```yaml
- uses: tapihdev/paths-filter@v3
with:
filters: |
frontend:
- 'frontend/**'
backend:
- 'backend/**'
json-output: true
json-output-dir: '/path/to/output' # Optional, defaults to "/tmp/paths-filter"
```

## See also

- [test-reporter](https://github.com/tapihdev/test-reporter) - Displays test results from popular testing frameworks directly in GitHub
Expand Down
8 changes: 8 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ inputs:
Backslash escapes every potentially unsafe character.
required: false
default: none
json-output:
description: 'Enable JSON output for filter results'
required: false
default: 'false'
json-output-dir:
description: 'Directory where JSON files will be written. Defaults to "path-filter-results"'
required: false
default: '/tmp/paths-filter'
initial-fetch-depth:
description: |
How many commits are initially fetched from base branch.
Expand Down
18 changes: 18 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36595,6 +36595,8 @@ async function run() {
const base = core.getInput('base', { required: false });
const filtersInput = core.getInput('filters', { required: true });
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput;
const jsonOutput = core.getBooleanInput('json-output', { required: false }) || false;
const jsonOutputDir = core.getInput('json-output-dir', { required: false }) || 'path-filter-results';
const listFiles = core.getInput('list-files', { required: false }).toLowerCase() || 'none';
const initialFetchDepth = parseInt(core.getInput('initial-fetch-depth', { required: false })) || 10;
const predicateQuantifier = core.getInput('predicate-quantifier', { required: false }) || filter_1.PredicateQuantifier.SOME;
Expand All @@ -36613,6 +36615,9 @@ async function run() {
core.info(`Detected ${files.length} changed files`);
const results = filter.match(files);
exportResults(results, listFiles);
if (jsonOutput) {
await exportResultsToJson(results, jsonOutputDir);
}
}
catch (error) {
core.setFailed(getErrorMessage(error));
Expand Down Expand Up @@ -36819,6 +36824,19 @@ function getErrorMessage(error) {
return error.message;
return String(error);
}
async function exportResultsToJson(results, outputDir) {
try {
await fs.promises.mkdir(outputDir, { recursive: true });
for (const [key, files] of Object.entries(results)) {
const filterPath = `${outputDir}/${key}.json`;
await fs.promises.writeFile(filterPath, JSON.stringify(files.map(file => file.filename), null, 2));
core.info(`Filter results written to JSON file: ${filterPath}`);
}
}
catch (error) {
core.warning(`Failed to write JSON output files: ${getErrorMessage(error)}`);
}
}
run();


Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ async function run(): Promise<void> {
const base = core.getInput('base', {required: false})
const filtersInput = core.getInput('filters', {required: true})
const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput
const jsonOutput = core.getBooleanInput('json-output', {required: false}) || false
const jsonOutputDir = core.getInput('json-output-dir', {required: false}) || 'path-filter-results'
const listFiles = core.getInput('list-files', {required: false}).toLowerCase() || 'none'
const initialFetchDepth = parseInt(core.getInput('initial-fetch-depth', {required: false})) || 10
const predicateQuantifier = core.getInput('predicate-quantifier', {required: false}) || PredicateQuantifier.SOME
Expand All @@ -53,6 +55,10 @@ async function run(): Promise<void> {
core.info(`Detected ${files.length} changed files`)
const results = filter.match(files)
exportResults(results, listFiles)

if (jsonOutput) {
await exportResultsToJson(results, jsonOutputDir)
}
} catch (error) {
core.setFailed(getErrorMessage(error))
}
Expand Down Expand Up @@ -287,4 +293,25 @@ function getErrorMessage(error: unknown): string {
return String(error)
}

async function exportResultsToJson(results: FilterResults, outputDir: string): Promise<void> {
try {
await fs.promises.mkdir(outputDir, {recursive: true})

for (const [key, files] of Object.entries(results)) {
const filterPath = `${outputDir}/${key}.json`
await fs.promises.writeFile(
filterPath,
JSON.stringify(
files.map(file => file.filename),
null,
2
)
)
core.info(`Filter results written to JSON file: ${filterPath}`)
}
} catch (error) {
core.warning(`Failed to write JSON output files: ${getErrorMessage(error)}`)
}
}

run()