Compare commits

...

19 Commits

Author SHA1 Message Date
Christopher Pfohl
60cda67c57
Merge 8b332e46d8 into de90cc6fb3 2024-03-04 20:23:57 +01:00
Michal Dorner
de90cc6fb3
Update dist and CHANGELOG for v3.0.2 2024-03-02 23:11:12 +01:00
Michal Dorner
cf89abdbae
Merge pull request #224 from petermetz/feat-filter-predicate-quantifier
feat: add config parameter for predicate quantifier
2024-03-02 22:28:32 +01:00
Peter Somogyvari
f90d5265d6
feat: add config parameter for predicate quantifier
Setting the new 'predicate-quantifier' configuration parameter to 'every'
makes it so that all the patterns have to match a file for it to be
considered changed.

This can be leveraged to ensure that you only build & test software changes
that have real impact on the behavior of the code, e.g. you can set up your
build to run when Typescript/Rust/etc. files are changed but markdown
changes in the diff will be ignored and you consume less resources to build.

The default behavior does not change by the introduction of this feature
so upgrading can be done safely knowing that existing workflows will not
break.

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
2024-02-22 12:48:55 -08:00
Michal Dorner
ebc4d7e9eb
Update CHANGELOG for v3.0.1 2024-02-15 09:20:42 +01:00
Michal Dorner
45f16f1875
Merge pull request #133 from frouioui/main
Compare base and ref when token is empty
2024-02-15 09:15:48 +01:00
Michal Dorner
5da0e4c086
Merge branch 'master' 2024-02-15 09:13:51 +01:00
Michal Dorner
1441771bbf
Update README.md
Add info about v3 release to What's New section
2024-01-25 08:13:18 +01:00
Michal Dorner
0bc4621a31
Bump major version to v3
Node version has been updated to 20 which might be a breaking change.
2024-01-25 07:48:07 +01:00
Michal Dorner
7267a8516b
Update CHANGELOG for v2.12.0 2024-01-24 22:53:50 +01:00
Michal Dorner
e36f1124bf
Merge pull request #215 from dorny/update-dependencies
Update all dependencies
2024-01-24 22:52:20 +01:00
Michal Dorner
2f74457227
Update all dependencies 2024-01-24 22:50:18 +01:00
Michal Dorner
67617953b4
Update examples in README to use checkout@v4 2024-01-24 15:51:01 +01:00
Michal Dorner
a35d8d6a33
Merge pull request #211 from chenrui333/node-20
chore(deps): bump checkout action to v4 and use setup-node to setup node and cache npm deps
2024-01-24 15:35:19 +01:00
Rui Chen
b5a5203f8b
chore(deps): bump checkout action to v4 and use setup-node to setup node and cache npm deps
Signed-off-by: Rui Chen <rui@chenrui.dev>
2023-12-08 20:07:04 -05:00
Christopher Pfohl
8b332e46d8
Merge pull request #1 from Crisfole/readme-troubleshooting
Add Troubleshooting Section to README
2023-06-07 10:11:35 -04:00
Christopher Pfohl
216456a5df
Add Troubleshooting Section to README
I bumped into this issue and solved it right as I was writing up the issue. Added it to the README here. I imagine you get a bunch of FAQs or bugs, this could be a great way to help prevent issues.
2023-06-07 10:10:55 -04:00
Florent Poinsard
245527a2ef Merge remote-tracking branch 'upstream/master' 2022-10-26 15:40:33 +02:00
Florent Poinsard
5266f0ac59 Compare base and ref when token is empty
Signed-off-by: Florent Poinsard <florent.poinsard@outlook.fr>
2022-04-19 14:29:04 +02:00
10 changed files with 32053 additions and 38560 deletions

View File

@ -1,4 +1,5 @@
name: "Build"
on:
push:
paths-ignore: [ '*.md' ]
@ -9,7 +10,11 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: |
npm install
npm run all
@ -17,7 +22,7 @@ jobs:
self-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ./
id: filter
with:

View File

@ -10,7 +10,11 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: |
npm install
npm run all
@ -20,7 +24,7 @@ jobs:
permissions:
pull-requests: read
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ./
id: filter
with:
@ -41,7 +45,7 @@ jobs:
permissions:
pull-requests: read
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ./
id: filter
with:
@ -53,7 +57,7 @@ jobs:
test-without-token:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ./
id: filter
with:
@ -66,7 +70,7 @@ jobs:
test-wd-without-token:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
path: somewhere
- uses: ./somewhere
@ -82,7 +86,7 @@ jobs:
test-local-changes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: echo "NEW FILE" > local
- run: git add local
- uses: ./
@ -102,7 +106,7 @@ jobs:
test-change-type:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: configure GIT user
run: git config user.email "john@nowhere.local" && git config user.name "John Doe"
- name: modify working tree

View File

@ -1,5 +1,15 @@
# Changelog
## v3.0.2
- [Add config parameter for predicate quantifier](https://github.com/dorny/paths-filter/pull/224)
## v3.0.1
- [Compare base and ref when token is empty](https://github.com/dorny/paths-filter/pull/133)
## v3.0.0
- [Update to Node.js 20](https://github.com/dorny/paths-filter/pull/210)
- [Update all dependencies](https://github.com/dorny/paths-filter/pull/215)
## v2.11.1
- [Update @actions/core to v1.10.0 - Fixes warning about deprecated set-output](https://github.com/dorny/paths-filter/pull/167)
- [Document need for pull-requests: read permission](https://github.com/dorny/paths-filter/pull/168)

View File

@ -46,7 +46,7 @@ don't allow this because they don't work on a level of individual jobs or steps.
## Example
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
@ -72,6 +72,7 @@ For more scenarios see [examples](#examples) section.
## What's New
- New major release `v3` after update to Node 20 [Breaking change]
- Add `ref` input parameter
- Add `list-files: csv` format
- Configure matrix job to run for each folder with changes using `changes` output
@ -83,7 +84,7 @@ For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob
## Usage
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
with:
# Defines filters applied to detected changed files.
# Each filter has a name and a list of rules.
@ -152,6 +153,22 @@ For more information, see [CHANGELOG](https://github.com/dorny/paths-filter/blob
# changes using git commands.
# Default: ${{ github.token }}
token: ''
# Optional parameter to override the default behavior of file matching algorithm.
# By default files that match at least one pattern defined by the filters will be included.
# This parameter allows to override the "at least one pattern" behavior to make it so that
# all of the patterns have to match or otherwise the file is excluded.
# An example scenario where this is useful if you would like to match all
# .ts files in a sub-directory but not .md files.
# The filters below will match markdown files despite the exclusion syntax UNLESS
# you specify 'every' as the predicate-quantifier parameter. When you do that,
# it will only match the .ts files in the subdirectory as expected.
#
# backend:
# - 'pkg/a/b/c/**'
# - '!**/*.jpeg'
# - '!**/*.md'
predicate-quantifier: 'some'
```
## Outputs
@ -175,8 +192,8 @@ jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
@ -220,7 +237,7 @@ jobs:
frontend: ${{ steps.filter.outputs.frontend }}
steps:
# For pull requests it's not necessary to checkout the code
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
@ -235,7 +252,7 @@ jobs:
if: ${{ needs.changes.outputs.backend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- ...
# JOB to build and test frontend code
@ -244,7 +261,7 @@ jobs:
if: ${{ needs.changes.outputs.frontend == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- ...
```
@ -266,7 +283,7 @@ jobs:
packages: ${{ steps.filter.outputs.changes }}
steps:
# For pull requests it's not necessary to checkout the code
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
@ -283,7 +300,7 @@ jobs:
package: ${{ fromJSON(needs.changes.outputs.packages) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- ...
```
@ -307,8 +324,8 @@ jobs:
permissions:
pull-requests: read
steps:
- uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: ... # Configure your filters
@ -328,12 +345,12 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
# This may save additional git fetch roundtrip if
# merge-base is found within latest 20 commits
fetch-depth: 20
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
base: develop # Change detection against merge-base with this branch
@ -356,8 +373,8 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
# Use context to get the branch where commits were pushed.
@ -384,14 +401,14 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Some action that 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
- uses: dorny/paths-filter@v3
id: filter
with:
base: HEAD
@ -406,7 +423,7 @@ jobs:
<summary>Define filter rules in own file</summary>
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
# Path to file where filters are defined
@ -419,7 +436,7 @@ jobs:
<summary>Use YAML anchors to reuse path expression(s) inside another rule</summary>
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
# &shared is YAML anchor,
@ -440,7 +457,7 @@ jobs:
<summary>Consider if file was added, modified or deleted</summary>
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
# Changed file can be 'added', 'modified', or 'deleted'.
@ -462,13 +479,39 @@ jobs:
</details>
<details>
<summary>Detect changes in folder only for some file extensions</summary>
```yaml
- uses: dorny/paths-filter@v3
id: filter
with:
# This makes it so that all the patterns have to match a file for it to be
# considered changed. Because we have the exclusions for .jpeg and .md files
# the end result is that if those files are changed they will be ignored
# because they don't match the respective rules excluding them.
#
# This can be leveraged to ensure that you only build & test software changes
# that have real impact on the behavior of the code, e.g. you can set up your
# build to run when Typescript/Rust/etc. files are changed but markdown
# changes in the diff will be ignored and you consume less resources to build.
predicate-quantifier: 'every'
filters: |
backend:
- 'pkg/a/b/c/**'
- '!**/*.jpeg'
- '!**/*.md'
```
</details>
### Custom processing of changed files
<details>
<summary>Passing list of modified files as command line args in Linux shell</summary>
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
# Enable listing of files matching each filter.
@ -494,7 +537,7 @@ jobs:
<summary>Passing list of modified files as JSON array to another action</summary>
```yaml
- uses: dorny/paths-filter@v2
- uses: dorny/paths-filter@v3
id: filter
with:
# Enable listing of files matching each filter.
@ -519,6 +562,16 @@ jobs:
- [test-reporter](https://github.com/dorny/test-reporter) - Displays test results from popular testing frameworks directly in GitHub
## Troubleshooting
If you are having trouble with this action check for your error message here to see if it can be resolved.
<details>
<summary>bad indentation of a mapping entry</summary>
This is most likely caused by invalid YAML, (a missing close quote, or mismatched indentation inside your `filters: |`. The easiest way to debug this is to copy your `filters: |` content into a file with yaml syntax highlighting.
</details>
## License
The scripts and documentation in this project are released under the [MIT License](https://github.com/dorny/paths-filter/blob/master/LICENSE)

View File

@ -1,4 +1,4 @@
import {Filter} from '../src/filter'
import {Filter, FilterConfig, PredicateQuantifier} from '../src/filter'
import {File, ChangeStatus} from '../src/file'
describe('yaml filter parsing tests', () => {
@ -117,6 +117,37 @@ describe('matching tests', () => {
expect(pyMatch.backend).toEqual(pyFiles)
})
test('matches only files that are matching EVERY pattern when set to PredicateQuantifier.EVERY', () => {
const yaml = `
backend:
- 'pkg/a/b/c/**'
- '!**/*.jpeg'
- '!**/*.md'
`
const filterConfig: FilterConfig = {predicateQuantifier: PredicateQuantifier.EVERY}
const filter = new Filter(yaml, filterConfig)
const typescriptFiles = modified(['pkg/a/b/c/some-class.ts', 'pkg/a/b/c/src/main/some-class.ts'])
const otherPkgTypescriptFiles = modified(['pkg/x/y/z/some-class.ts', 'pkg/x/y/z/src/main/some-class.ts'])
const otherPkgJpegFiles = modified(['pkg/x/y/z/some-pic.jpeg', 'pkg/x/y/z/src/main/jpeg/some-pic.jpeg'])
const docsFiles = modified([
'pkg/a/b/c/some-pics.jpeg',
'pkg/a/b/c/src/main/jpeg/some-pic.jpeg',
'pkg/a/b/c/src/main/some-docs.md',
'pkg/a/b/c/some-docs.md'
])
const typescriptMatch = filter.match(typescriptFiles)
const otherPkgTypescriptMatch = filter.match(otherPkgTypescriptFiles)
const docsMatch = filter.match(docsFiles)
const otherPkgJpegMatch = filter.match(otherPkgJpegFiles)
expect(typescriptMatch.backend).toEqual(typescriptFiles)
expect(otherPkgTypescriptMatch.backend).toEqual([])
expect(docsMatch.backend).toEqual([])
expect(otherPkgJpegMatch.backend).toEqual([])
})
test('matches path based on rules included using YAML anchor', () => {
const yaml = `
shared: &shared
@ -186,3 +217,9 @@ function modified(paths: string[]): File[] {
return {filename, status: ChangeStatus.Modified}
})
}
function renamed(paths: string[]): File[] {
return paths.map(filename => {
return {filename, status: ChangeStatus.Renamed}
})
}

55929
dist/index.js vendored

File diff suppressed because one or more lines are too long

14352
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,9 @@
{
"name": "paths-filter",
"version": "1.0.0",
"engines": {
"node": ">= 20"
},
"private": true,
"description": "Execute your workflow steps only if relevant files are modified.",
"main": "lib/main.js",
@ -27,27 +30,26 @@
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/github": "^2.2.0",
"@octokit/webhooks": "^7.6.2",
"picomatch": "^2.2.2"
"@actions/github": "6.0.0",
"picomatch": "^2.3.1"
},
"devDependencies": {
"@types/jest": "^27.4.0",
"@types/js-yaml": "^3.12.4",
"@types/minimatch": "^3.0.3",
"@types/node": "^14.0.5",
"@types/picomatch": "^2.2.1",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"@octokit/webhooks-types": "^7.3.1",
"@types/jest": "^29.5.11",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.11.6",
"@types/picomatch": "^2.3.3",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.17.0",
"eslint-plugin-github": "^4.3.6",
"eslint-plugin-jest": "^22.21.0",
"jest": "^27.4.7",
"jest-circus": "^27.4.6",
"js-yaml": "^3.14.0",
"prettier": "^2.0.5",
"ts-jest": "^27.1.3",
"typescript": "^3.9.3"
"eslint": "^8.56.0",
"eslint-plugin-github": "^4.10.1",
"eslint-plugin-jest": "^27.6.3",
"jest": "^29.7.0",
"jest-circus": "^29.7.0",
"js-yaml": "^4.1.0",
"prettier": "^2.8.8",
"ts-jest": "^29.1.2",
"typescript": "^5.3.3"
}
}

View File

@ -23,6 +23,48 @@ interface FilterRuleItem {
isMatch: (str: string) => boolean // Matches the filename
}
/**
* Enumerates the possible logic quantifiers that can be used when determining
* if a file is a match or not with multiple patterns.
*
* The YAML configuration property that is parsed into one of these values is
* 'predicate-quantifier' on the top level of the configuration object of the
* action.
*
* The default is to use 'some' which used to be the hardcoded behavior prior to
* the introduction of the new mechanism.
*
* @see https://en.wikipedia.org/wiki/Quantifier_(logic)
*/
export enum PredicateQuantifier {
/**
* When choosing 'every' in the config it means that files will only get matched
* if all the patterns are satisfied by the path of the file, not just at least one of them.
*/
EVERY = 'every',
/**
* When choosing 'some' in the config it means that files will get matched as long as there is
* at least one pattern that matches them. This is the default behavior if you don't
* specify anything as a predicate quantifier.
*/
SOME = 'some'
}
/**
* Used to define customizations for how the file filtering should work at runtime.
*/
export type FilterConfig = {readonly predicateQuantifier: PredicateQuantifier}
/**
* An array of strings (at runtime) that contains the valid/accepted values for
* the configuration parameter 'predicate-quantifier'.
*/
export const SUPPORTED_PREDICATE_QUANTIFIERS = Object.values(PredicateQuantifier)
export function isPredicateQuantifier(x: unknown): x is PredicateQuantifier {
return SUPPORTED_PREDICATE_QUANTIFIERS.includes(x as PredicateQuantifier)
}
export interface FilterResults {
[key: string]: File[]
}
@ -31,7 +73,7 @@ export class Filter {
rules: {[key: string]: FilterRuleItem[]} = {}
// Creates instance of Filter and load rules from YAML if it's provided
constructor(yaml?: string) {
constructor(yaml?: string, readonly filterConfig?: FilterConfig) {
if (yaml) {
this.load(yaml)
}
@ -43,7 +85,7 @@ export class Filter {
return
}
const doc = jsyaml.safeLoad(yaml) as FilterYaml
const doc = jsyaml.load(yaml) as FilterYaml
if (typeof doc !== 'object') {
this.throwInvalidFormatError('Root element is not an object')
}
@ -62,9 +104,14 @@ export class Filter {
}
private isMatch(file: File, patterns: FilterRuleItem[]): boolean {
return patterns.some(
rule => (rule.status === undefined || rule.status.includes(file.status)) && rule.isMatch(file.filename)
)
const aPredicate = (rule: Readonly<FilterRuleItem>): boolean => {
return (rule.status === undefined || rule.status.includes(file.status)) && rule.isMatch(file.filename)
}
if (this.filterConfig?.predicateQuantifier === 'every') {
return patterns.every(aPredicate)
} else {
return patterns.some(aPredicate)
}
}
private parseFilterItemYaml(item: FilterItemYaml): FilterRuleItem[] {

View File

@ -1,10 +1,17 @@
import * as fs from 'fs'
import * as core from '@actions/core'
import * as github from '@actions/github'
import type {Octokit} from '@octokit/rest'
import {Webhooks} from '@octokit/webhooks'
import {GetResponseDataTypeFromEndpointMethod} from '@octokit/types'
import {PushEvent, PullRequestEvent} from '@octokit/webhooks-types'
import {Filter, FilterResults} from './filter'
import {
isPredicateQuantifier,
Filter,
FilterConfig,
FilterResults,
PredicateQuantifier,
SUPPORTED_PREDICATE_QUANTIFIERS
} from './filter'
import {File, ChangeStatus} from './file'
import * as git from './git'
import {backslashEscape, shellEscape} from './list-format/shell-escape'
@ -26,19 +33,28 @@ async function run(): Promise<void> {
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 predicateQuantifier = core.getInput('predicate-quantifier', {required: false}) || PredicateQuantifier.SOME
if (!isExportFormat(listFiles)) {
core.setFailed(`Input parameter 'list-files' is set to invalid value '${listFiles}'`)
return
}
const filter = new Filter(filtersYaml)
if (!isPredicateQuantifier(predicateQuantifier)) {
const predicateQuantifierInvalidErrorMsg =
`Input parameter 'predicate-quantifier' is set to invalid value ` +
`'${predicateQuantifier}'. Valid values: ${SUPPORTED_PREDICATE_QUANTIFIERS.join(', ')}`
throw new Error(predicateQuantifierInvalidErrorMsg)
}
const filterConfig: FilterConfig = {predicateQuantifier}
const filter = new Filter(filtersYaml, filterConfig)
const files = await getChangedFiles(token, base, ref, initialFetchDepth)
core.info(`Detected ${files.length} changed files`)
const results = filter.match(files)
exportResults(results, listFiles)
} catch (error) {
core.setFailed(error.message)
core.setFailed(getErrorMessage(error))
}
}
@ -76,7 +92,7 @@ async function getChangedFiles(token: string, base: string, ref: string, initial
if (base) {
core.warning(`'base' input parameter is ignored when action is triggered by pull request event`)
}
const pr = github.context.payload.pull_request as Webhooks.WebhookPayloadPullRequestPullRequest
const pr = github.context.payload.pull_request as PullRequestEvent
if (token) {
return await getChangedFilesFromApi(token, pr)
}
@ -86,8 +102,11 @@ 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 from PRs merge commit')
return await git.getChangesInLastCommit()
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()
return await git.getChanges(base || baseSha || defaultBranch, currentRef)
} else {
return getChangedFilesFromGit(base, ref, initialFetchDepth)
}
@ -96,8 +115,7 @@ async function getChangedFiles(token: string, base: string, ref: string, initial
async function getChangedFilesFromGit(base: string, head: string, initialFetchDepth: number): Promise<File[]> {
const defaultBranch = github.context.payload.repository?.default_branch
const beforeSha =
github.context.eventName === 'push' ? (github.context.payload as Webhooks.WebhookPayloadPush).before : null
const beforeSha = github.context.eventName === 'push' ? (github.context.payload as PushEvent).before : null
const currentRef = await git.getCurrentRef()
@ -157,31 +175,28 @@ 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,
prNumber: Webhooks.WebhookPayloadPullRequestPullRequest
): Promise<File[]> {
core.startGroup(`Fetching list of changed files for PR#${prNumber.number} from Github API`)
async function getChangedFilesFromApi(token: string, pullRequest: PullRequestEvent): Promise<File[]> {
core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from Github API`)
try {
const client = new github.GitHub(token)
const client = github.getOctokit(token)
const per_page = 100
const files: File[] = []
core.info(`Invoking listFiles(pull_number: ${prNumber.number}, per_page: ${per_page})`)
core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, per_page: ${per_page})`)
for await (const response of client.paginate.iterator(
client.pulls.listFiles.endpoint.merge({
client.rest.pulls.listFiles.endpoint.merge({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
pull_number: prNumber.number,
pull_number: pullRequest.number,
per_page
})
) as AsyncIterableIterator<Octokit.Response<Octokit.PullsListFilesResponse>>) {
)) {
if (response.status !== 200) {
throw new Error(`Fetching list of changed files from GitHub API failed with error code ${response.status}`)
}
core.info(`Received ${response.data.length} items`)
for (const row of response.data) {
for (const row of response.data as GetResponseDataTypeFromEndpointMethod<typeof client.rest.pulls.listFiles>) {
core.info(`[${row.status}] ${row.filename}`)
// There's no obvious use-case for detection of renames
// Therefore we treat it as if rename detection in git diff was turned off.
@ -267,4 +282,9 @@ function isExportFormat(value: string): value is ExportFormat {
return ['none', 'csv', 'shell', 'json', 'escape'].includes(value)
}
function getErrorMessage(error: unknown): string {
if (error instanceof Error) return error.message
return String(error)
}
run()