From 37a6d38b2d2d8f4ba2c561800df73f2842db9cbb Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Wed, 7 Apr 2021 22:32:59 +0200 Subject: [PATCH 1/7] Add ref input parameter --- action.yml | 6 ++++++ dist/index.js | 45 ++++++++++++++++++++++++++++----------------- src/git.ts | 36 ++++++++++++++++++++++-------------- src/main.ts | 11 ++++++----- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/action.yml b/action.yml index b25aa5e..f8a96e1 100644 --- a/action.yml +++ b/action.yml @@ -9,6 +9,12 @@ inputs: working-directory: description: 'Relative path under $GITHUB_WORKSPACE where the repository was checked out.' required: false + ref: + description: | + Git reference (e.g. branch name) from which the changes will be detected. + This option is ignored if action is triggered by pull_request event. + default: ${{ github.ref }} + required: false base: description: | Git reference (e.g. branch name) against which the changes will be detected. Defaults to repository default branch (e.g. master). diff --git a/dist/index.js b/dist/index.js index 2090549..5843c32 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3865,34 +3865,44 @@ async function getChangesOnHead() { return parseGitDiffOutput(output); } exports.getChangesOnHead = getChangesOnHead; -async function getChangesSinceMergeBase(base, ref, initialFetchDepth) { +async function getChangesSinceMergeBase(base, head, initialFetchDepth) { let baseRef; + let headRef; async function hasMergeBase() { - return (baseRef !== undefined && (await exec_1.default('git', ['merge-base', baseRef, ref], { ignoreReturnCode: true })).code === 0); + if (baseRef === undefined || headRef === undefined) { + return false; + } + return (await exec_1.default('git', ['merge-base', baseRef, headRef], { ignoreReturnCode: true })).code === 0; } let noMergeBase = false; - core.startGroup(`Searching for merge-base ${base}...${ref}`); + core.startGroup(`Searching for merge-base ${base}...${headRef}`); try { baseRef = await getFullRef(base); + headRef = await getFullRef(head); if (!(await hasMergeBase())) { - await exec_1.default('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, ref]); - if (baseRef === undefined) { - baseRef = await getFullRef(base); - if (baseRef === undefined) { - await exec_1.default('git', ['fetch', '--tags', '--depth=1', 'origin', base, ref], { + await exec_1.default('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, head]); + if (baseRef === undefined || headRef === undefined) { + baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : await getFullRef(base); + headRef = headRef !== null && headRef !== void 0 ? headRef : await getFullRef(head); + if (baseRef === undefined || headRef === undefined) { + await exec_1.default('git', ['fetch', '--tags', '--depth=1', 'origin', base, head], { ignoreReturnCode: true // returns exit code 1 if tags on remote were updated - we can safely ignore it }); - baseRef = await getFullRef(base); + baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : await getFullRef(base); + headRef = headRef !== null && headRef !== void 0 ? headRef : await getFullRef(head); if (baseRef === undefined) { throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`); } + if (headRef === undefined) { + throw new Error(`Could not determine what is ${head} - fetch works but it's not a branch or tag`); + } } } let depth = initialFetchDepth; let lastCommitCount = await getCommitCount(); while (!(await hasMergeBase())) { depth = Math.min(depth * 2, Number.MAX_SAFE_INTEGER); - await exec_1.default('git', ['fetch', `--deepen=${depth}`, 'origin', base, ref]); + await exec_1.default('git', ['fetch', `--deepen=${depth}`, 'origin', base, head]); const commitCount = await getCommitCount(); if (commitCount === lastCommitCount) { core.info('No more commits were fetched'); @@ -3910,10 +3920,10 @@ async function getChangesSinceMergeBase(base, ref, initialFetchDepth) { finally { core.endGroup(); } - let diffArg = `${baseRef}...${ref}`; + let diffArg = `${baseRef}...${headRef}`; if (noMergeBase) { core.warning('No merge base found - change detection will use direct .. comparison'); - diffArg = `${baseRef}..${ref}`; + diffArg = `${baseRef}..${headRef}`; } // Get changes introduced on ref compared to base core.startGroup(`Change detection ${diffArg}`); @@ -4690,6 +4700,7 @@ async function run() { process.chdir(workingDirectory); } const token = core.getInput('token', { required: false }); + const ref = core.getInput('ref', { required: false }); const base = core.getInput('base', { required: false }); const filtersInput = core.getInput('filters', { required: true }); const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput; @@ -4700,7 +4711,7 @@ async function run() { return; } const filter = new filter_1.Filter(filtersYaml); - const files = await getChangedFiles(token, base, initialFetchDepth); + const files = await getChangedFiles(token, base, ref, initialFetchDepth); const results = filter.match(files); exportResults(results, listFiles); } @@ -4720,7 +4731,7 @@ function getConfigFileContent(configPath) { } return fs.readFileSync(configPath, { encoding: 'utf8' }); } -async function getChangedFiles(token, base, initialFetchDepth) { +async function getChangedFiles(token, base, ref, 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) { @@ -4735,14 +4746,14 @@ async function getChangedFiles(token, base, initialFetchDepth) { return await git.getChangesInLastCommit(); } else { - return getChangedFilesFromGit(base, initialFetchDepth); + return getChangedFilesFromGit(base, ref, initialFetchDepth); } } -async function getChangedFilesFromGit(base, initialFetchDepth) { +async function getChangedFilesFromGit(base, head, initialFetchDepth) { var _a; 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 ref = git.getShortName(github.context.ref) || + const ref = git.getShortName(head || github.context.ref) || (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; diff --git a/src/git.ts b/src/git.ts index ca652e8..ddf6ff3 100644 --- a/src/git.ts +++ b/src/git.ts @@ -54,30 +54,38 @@ export async function getChangesOnHead(): Promise { return parseGitDiffOutput(output) } -export async function getChangesSinceMergeBase(base: string, ref: string, initialFetchDepth: number): Promise { +export async function getChangesSinceMergeBase(base: string, head: string, initialFetchDepth: number): Promise { let baseRef: string | undefined + let headRef: string | undefined async function hasMergeBase(): Promise { - return ( - baseRef !== undefined && (await exec('git', ['merge-base', baseRef, ref], {ignoreReturnCode: true})).code === 0 - ) + if (baseRef === undefined || headRef === undefined) { + return false + } + return (await exec('git', ['merge-base', baseRef, headRef], {ignoreReturnCode: true})).code === 0 } let noMergeBase = false - core.startGroup(`Searching for merge-base ${base}...${ref}`) + core.startGroup(`Searching for merge-base ${base}...${headRef}`) try { baseRef = await getFullRef(base) + headRef = await getFullRef(head) if (!(await hasMergeBase())) { - await exec('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, ref]) - if (baseRef === undefined) { - baseRef = await getFullRef(base) - if (baseRef === undefined) { - await exec('git', ['fetch', '--tags', '--depth=1', 'origin', base, ref], { + await exec('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, head]) + if (baseRef === undefined || headRef === undefined) { + baseRef = baseRef ?? (await getFullRef(base)) + headRef = headRef ?? (await getFullRef(head)) + if (baseRef === undefined || headRef === undefined) { + await exec('git', ['fetch', '--tags', '--depth=1', 'origin', base, head], { ignoreReturnCode: true // returns exit code 1 if tags on remote were updated - we can safely ignore it }) - baseRef = await getFullRef(base) + baseRef = baseRef ?? (await getFullRef(base)) + headRef = headRef ?? (await getFullRef(head)) if (baseRef === undefined) { throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`) } + if (headRef === undefined) { + throw new Error(`Could not determine what is ${head} - fetch works but it's not a branch or tag`) + } } } @@ -85,7 +93,7 @@ export async function getChangesSinceMergeBase(base: string, ref: string, initia let lastCommitCount = await getCommitCount() while (!(await hasMergeBase())) { depth = Math.min(depth * 2, Number.MAX_SAFE_INTEGER) - await exec('git', ['fetch', `--deepen=${depth}`, 'origin', base, ref]) + await exec('git', ['fetch', `--deepen=${depth}`, 'origin', base, head]) const commitCount = await getCommitCount() if (commitCount === lastCommitCount) { core.info('No more commits were fetched') @@ -103,10 +111,10 @@ export async function getChangesSinceMergeBase(base: string, ref: string, initia core.endGroup() } - let diffArg = `${baseRef}...${ref}` + let diffArg = `${baseRef}...${headRef}` if (noMergeBase) { core.warning('No merge base found - change detection will use direct .. comparison') - diffArg = `${baseRef}..${ref}` + diffArg = `${baseRef}..${headRef}` } // Get changes introduced on ref compared to base diff --git a/src/main.ts b/src/main.ts index de33bc2..c5b92de 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,6 +19,7 @@ async function run(): Promise { } const token = core.getInput('token', {required: false}) + const ref = core.getInput('ref', {required: false}) const base = core.getInput('base', {required: false}) const filtersInput = core.getInput('filters', {required: true}) const filtersYaml = isPathInput(filtersInput) ? getConfigFileContent(filtersInput) : filtersInput @@ -31,7 +32,7 @@ async function run(): Promise { } const filter = new Filter(filtersYaml) - const files = await getChangedFiles(token, base, initialFetchDepth) + const files = await getChangedFiles(token, base, ref, initialFetchDepth) const results = filter.match(files) exportResults(results, listFiles) } catch (error) { @@ -55,7 +56,7 @@ function getConfigFileContent(configPath: string): string { return fs.readFileSync(configPath, {encoding: 'utf8'}) } -async function getChangedFiles(token: string, base: string, initialFetchDepth: number): Promise { +async function getChangedFiles(token: string, base: string, ref: 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) { @@ -70,18 +71,18 @@ 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 { - return getChangedFilesFromGit(base, initialFetchDepth) + return getChangedFilesFromGit(base, ref, initialFetchDepth) } } -async function getChangedFilesFromGit(base: string, initialFetchDepth: number): Promise { +async function getChangedFilesFromGit(base: string, head: string, initialFetchDepth: number): Promise { const defaultRef = github.context.payload.repository?.default_branch const beforeSha = github.context.eventName === 'push' ? (github.context.payload as Webhooks.WebhookPayloadPush).before : null const ref = - git.getShortName(github.context.ref) || + git.getShortName(head || github.context.ref) || (core.warning(`'ref' field is missing in event payload - using current branch, tag or commit SHA`), await git.getCurrentRef()) From 02eeef4973b96cab5ff4eb3cebba165690498a13 Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Wed, 7 Apr 2021 22:41:22 +0200 Subject: [PATCH 2/7] Fix `undefined` instead of ref in log output --- dist/index.js | 10 +++++----- src/git.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 5843c32..ea9a243 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3875,21 +3875,21 @@ async function getChangesSinceMergeBase(base, head, initialFetchDepth) { return (await exec_1.default('git', ['merge-base', baseRef, headRef], { ignoreReturnCode: true })).code === 0; } let noMergeBase = false; - core.startGroup(`Searching for merge-base ${base}...${headRef}`); + core.startGroup(`Searching for merge-base ${base}...${head}`); try { baseRef = await getFullRef(base); headRef = await getFullRef(head); if (!(await hasMergeBase())) { await exec_1.default('git', ['fetch', '--no-tags', `--depth=${initialFetchDepth}`, 'origin', base, head]); if (baseRef === undefined || headRef === undefined) { - baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : await getFullRef(base); - headRef = headRef !== null && headRef !== void 0 ? headRef : await getFullRef(head); + baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : (await getFullRef(base)); + headRef = headRef !== null && headRef !== void 0 ? headRef : (await getFullRef(head)); if (baseRef === undefined || headRef === undefined) { await exec_1.default('git', ['fetch', '--tags', '--depth=1', 'origin', base, head], { ignoreReturnCode: true // returns exit code 1 if tags on remote were updated - we can safely ignore it }); - baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : await getFullRef(base); - headRef = headRef !== null && headRef !== void 0 ? headRef : await getFullRef(head); + baseRef = baseRef !== null && baseRef !== void 0 ? baseRef : (await getFullRef(base)); + headRef = headRef !== null && headRef !== void 0 ? headRef : (await getFullRef(head)); if (baseRef === undefined) { throw new Error(`Could not determine what is ${base} - fetch works but it's not a branch or tag`); } diff --git a/src/git.ts b/src/git.ts index ddf6ff3..809249d 100644 --- a/src/git.ts +++ b/src/git.ts @@ -65,7 +65,7 @@ export async function getChangesSinceMergeBase(base: string, head: string, initi } let noMergeBase = false - core.startGroup(`Searching for merge-base ${base}...${headRef}`) + core.startGroup(`Searching for merge-base ${base}...${head}`) try { baseRef = await getFullRef(base) headRef = await getFullRef(head) From 58ed00ec486f0395621febf08b0b667ad53d469e Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Sun, 11 Apr 2021 20:49:05 +0200 Subject: [PATCH 3/7] Update README --- README.md | 11 ++++++++--- dist/index.js | 2 +- src/git.ts | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e78b1a0..1c963a8 100644 --- a/README.md +++ b/README.md @@ -66,13 +66,11 @@ For more scenarios see [examples](#examples) section. # What's New +- Add `ref` input parameter - Add `list-files: csv` format - Configure matrix job to run for each folder with changes using `changes` output - Improved listing of matching files with `list-files: shell` and `list-files: escape` options -- 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 For more information see [CHANGELOG](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) @@ -111,6 +109,13 @@ For more information see [CHANGELOG](https://github.com/dorny/paths-filter/blob/ # Default: repository default branch (e.g. master) base: '' + # Git reference (e.g. branch name) from which the changes will be detected. + # Useful when workflow can be triggered only on default branch (e.g. repository_dispatch event) + # but you want to get changes on different branch. + # This option is ignored if action is triggered by pull_request event. + # default: ${{ github.ref }} + ref: + # How many commits are initially fetched from base branch. # If needed, each subsequent fetch doubles the # previously requested number of commits until the merge-base diff --git a/dist/index.js b/dist/index.js index ea9a243..5682bc6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3920,6 +3920,7 @@ async function getChangesSinceMergeBase(base, head, initialFetchDepth) { finally { core.endGroup(); } + // Three dots '...' change detection - finds merge-base and compares against it let diffArg = `${baseRef}...${headRef}`; if (noMergeBase) { core.warning('No merge base found - change detection will use direct .. comparison'); @@ -3929,7 +3930,6 @@ async function getChangesSinceMergeBase(base, head, initialFetchDepth) { core.startGroup(`Change detection ${diffArg}`); let output = ''; try { - // Three dots '...' change detection - finds merge-base and compares against it output = (await exec_1.default('git', ['diff', '--no-renames', '--name-status', '-z', diffArg])).stdout; } finally { diff --git a/src/git.ts b/src/git.ts index 809249d..df56308 100644 --- a/src/git.ts +++ b/src/git.ts @@ -111,6 +111,7 @@ export async function getChangesSinceMergeBase(base: string, head: string, initi core.endGroup() } + // Three dots '...' change detection - finds merge-base and compares against it let diffArg = `${baseRef}...${headRef}` if (noMergeBase) { core.warning('No merge base found - change detection will use direct .. comparison') @@ -121,7 +122,6 @@ export async function getChangesSinceMergeBase(base: string, head: string, initi core.startGroup(`Change detection ${diffArg}`) let output = '' try { - // Three dots '...' change detection - finds merge-base and compares against it output = (await exec('git', ['diff', '--no-renames', '--name-status', '-z', diffArg])).stdout } finally { fixStdOutNullTermination() From e8f370c19768d3e2df0498b0754683e6b3432b76 Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Sun, 11 Apr 2021 20:58:42 +0200 Subject: [PATCH 4/7] Run PR workflow on PR to any branch --- .github/workflows/pull-request-verification.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request-verification.yml b/.github/workflows/pull-request-verification.yml index 9d95fc3..b3f6952 100644 --- a/.github/workflows/pull-request-verification.yml +++ b/.github/workflows/pull-request-verification.yml @@ -4,7 +4,7 @@ on: paths-ignore: [ '*.md' ] branches: - master - - develop + - '**' jobs: build: From 8d029eb508d742d6aaa9260abef0cea2798f9539 Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Sun, 11 Apr 2021 21:15:30 +0200 Subject: [PATCH 5/7] Fix change detection in PR when pullRequest.changed_files was incorrect --- dist/index.js | 85 +++++++++++++++++++++++++++--------------------- src/main.ts | 90 +++++++++++++++++++++++++++++---------------------- 2 files changed, 100 insertions(+), 75 deletions(-) diff --git a/dist/index.js b/dist/index.js index 5682bc6..9914fa9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4792,47 +4792,58 @@ 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.info(`Number of changed_files is ${pullRequest.changed_files}`); - const client = new github.GitHub(token); - const pageSize = 100; - const files = []; - for (let page = 1; (page - 1) * pageSize < pullRequest.changed_files; page++) { - core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, page: ${page}, per_page: ${pageSize})`); - const response = await client.pulls.listFiles({ - owner: github.context.repo.owner, - repo: github.context.repo.repo, - pull_number: pullRequest.number, - page, - per_page: pageSize - }); - for (const row of response.data) { - 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. - // Rename is replaced by delete of original filename and add of new filename - if (row.status === file_1.ChangeStatus.Renamed) { - files.push({ - filename: row.filename, - status: file_1.ChangeStatus.Added - }); - files.push({ - // 'previous_filename' for some unknown reason isn't in the type definition or documentation - filename: row.previous_filename, - status: file_1.ChangeStatus.Deleted - }); + try { + const client = new github.GitHub(token); + const per_page = 100; + const files = []; + for (let page = 1;; page++) { + core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, page: ${page}, per_page: ${per_page})`); + const response = await client.pulls.listFiles({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + pull_number: pullRequest.number, + per_page, + page + }); + if (response.status !== 200) { + throw new Error(`Fetching list of changed files from GitHub API failed with error code ${response.status}`); } - else { - // Github status and git status variants are same except for deleted files - const status = row.status === 'removed' ? file_1.ChangeStatus.Deleted : row.status; - files.push({ - filename: row.filename, - status - }); + if (response.data.length === 0) { + break; + } + core.info(`Received ${response.data.length} items`); + for (const row of response.data) { + 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. + // Rename is replaced by delete of original filename and add of new filename + if (row.status === file_1.ChangeStatus.Renamed) { + files.push({ + filename: row.filename, + status: file_1.ChangeStatus.Added + }); + files.push({ + // 'previous_filename' for some unknown reason isn't in the type definition or documentation + filename: row.previous_filename, + status: file_1.ChangeStatus.Deleted + }); + } + else { + // Github status and git status variants are same except for deleted files + const status = row.status === 'removed' ? file_1.ChangeStatus.Deleted : row.status; + files.push({ + filename: row.filename, + status + }); + } } } + core.info(`Found ${files.length} changed files`); + return files; + } + finally { + core.endGroup(); } - core.endGroup(); - return files; } function exportResults(results, format) { core.info('Results:'); diff --git a/src/main.ts b/src/main.ts index c5b92de..5f6d4b3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -132,47 +132,61 @@ async function getChangedFilesFromApi( pullRequest: Webhooks.WebhookPayloadPullRequestPullRequest ): Promise { core.startGroup(`Fetching list of changed files for PR#${pullRequest.number} from Github API`) - core.info(`Number of changed_files is ${pullRequest.changed_files}`) - const client = new github.GitHub(token) - const pageSize = 100 - const files: File[] = [] - for (let page = 1; (page - 1) * pageSize < pullRequest.changed_files; page++) { - core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, page: ${page}, per_page: ${pageSize})`) - const response = await client.pulls.listFiles({ - owner: github.context.repo.owner, - repo: github.context.repo.repo, - pull_number: pullRequest.number, - page, - per_page: pageSize - }) - for (const row of response.data) { - 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. - // Rename is replaced by delete of original filename and add of new filename - if (row.status === ChangeStatus.Renamed) { - files.push({ - filename: row.filename, - status: ChangeStatus.Added - }) - files.push({ - // 'previous_filename' for some unknown reason isn't in the type definition or documentation - filename: (row).previous_filename as string, - status: ChangeStatus.Deleted - }) - } else { - // Github status and git status variants are same except for deleted files - const status = row.status === 'removed' ? ChangeStatus.Deleted : (row.status as ChangeStatus) - files.push({ - filename: row.filename, - status - }) + try { + const client = new github.GitHub(token) + const per_page = 100 + const files: File[] = [] + + for (let page = 1; ; page++) { + core.info(`Invoking listFiles(pull_number: ${pullRequest.number}, page: ${page}, per_page: ${per_page})`) + const response = await client.pulls.listFiles({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + pull_number: pullRequest.number, + per_page, + page + }) + + if (response.status !== 200) { + throw new Error(`Fetching list of changed files from GitHub API failed with error code ${response.status}`) + } + + if (response.data.length === 0) { + break + } + + core.info(`Received ${response.data.length} items`) + for (const row of response.data) { + 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. + // Rename is replaced by delete of original filename and add of new filename + if (row.status === ChangeStatus.Renamed) { + files.push({ + filename: row.filename, + status: ChangeStatus.Added + }) + files.push({ + // 'previous_filename' for some unknown reason isn't in the type definition or documentation + filename: (row).previous_filename as string, + status: ChangeStatus.Deleted + }) + } else { + // Github status and git status variants are same except for deleted files + const status = row.status === 'removed' ? ChangeStatus.Deleted : (row.status as ChangeStatus) + files.push({ + filename: row.filename, + status + }) + } } } - } - core.endGroup() - return files + core.info(`Found ${files.length} changed files`) + return files + } finally { + core.endGroup() + } } function exportResults(results: FilterResults, format: ExportFormat): void { From d0507d9a8aa31040a20f22b35e8317d8b8501070 Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Sun, 11 Apr 2021 21:39:09 +0200 Subject: [PATCH 6/7] Improve log output --- dist/index.js | 5 +++-- src/main.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/index.js b/dist/index.js index 9914fa9..914be19 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4712,6 +4712,7 @@ async function run() { } const filter = new filter_1.Filter(filtersYaml); const files = await getChangedFiles(token, base, ref, initialFetchDepth); + core.info(`Detected ${files.length} changed files`); const results = filter.match(files); exportResults(results, listFiles); } @@ -4808,10 +4809,11 @@ async function getChangedFilesFromApi(token, pullRequest) { 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`); if (response.data.length === 0) { + core.info('All changed files has been fetched from GitHub API'); break; } - core.info(`Received ${response.data.length} items`); for (const row of response.data) { core.info(`[${row.status}] ${row.filename}`); // There's no obvious use-case for detection of renames @@ -4838,7 +4840,6 @@ async function getChangedFilesFromApi(token, pullRequest) { } } } - core.info(`Found ${files.length} changed files`); return files; } finally { diff --git a/src/main.ts b/src/main.ts index 5f6d4b3..466d695 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,6 +33,7 @@ async function run(): Promise { const filter = new Filter(filtersYaml) 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) { @@ -151,11 +152,12 @@ async function getChangedFilesFromApi( throw new Error(`Fetching list of changed files from GitHub API failed with error code ${response.status}`) } + core.info(`Received ${response.data.length} items`) if (response.data.length === 0) { + core.info('All changed files has been fetched from GitHub API') break } - core.info(`Received ${response.data.length} items`) for (const row of response.data) { core.info(`[${row.status}] ${row.filename}`) // There's no obvious use-case for detection of renames @@ -182,7 +184,6 @@ async function getChangedFilesFromApi( } } - core.info(`Found ${files.length} changed files`) return files } finally { core.endGroup() From 24a74833ccdb0468e67c6be0310701c3259c8ea9 Mon Sep 17 00:00:00 2001 From: Michal Dorner Date: Sun, 11 Apr 2021 21:48:05 +0200 Subject: [PATCH 7/7] Update CHANGELOG for v2.10.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 153f0ac..70cf18b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v2.10.0 +- [Add ref input parameter](https://github.com/dorny/paths-filter/pull/82) +- [Fix change detection in PR when pullRequest.changed_files is incorrect](https://github.com/dorny/paths-filter/pull/83) + ## v2.9.3 - [Fix change detection when base is a tag](https://github.com/dorny/paths-filter/pull/78)