Skip to content

Commit d5d5b24

Browse files
authored
Add get-changed-files action (#23)
1 parent 0647fe9 commit d5d5b24

17 files changed

Lines changed: 37867 additions & 76 deletions

File tree

common/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
"main": "lib/index.js",
1010
"scripts": {
1111
"clean": "rimraf lib",
12-
"build": "tsc",
13-
"test": "jest --config ../jest.config.js"
12+
"build": "tsc"
1413
},
1514
"devDependencies": {
1615
"minimatch": "^10.0.1"

common/src/constants.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
export const inputs = {
3+
GH_TOKEN: 'gh-token',
4+
OUTPUT: 'output',
5+
PATHS: 'paths',
6+
} as const;
7+
8+
export const outputs = {
9+
RESULT: 'result',
10+
} as const;

common/src/fs-utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { mkdirSync } from 'fs';
2+
import { dirname as getDirName } from 'path';
3+
4+
export function ensureDir(path: string): void {
5+
mkdirSync(getDirName(path), { recursive: true });
6+
}

common/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
export * from './common-utils';
2+
export * from './constants';
3+
export * from './fs-utils';
24
export * from './path-utils';
35
export * from './pr-utils';

common/src/path-utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as core from '@actions/core'
12
import { MinimatchOptions, minimatch } from "minimatch";
23

34
const NEGATION = '!';
@@ -12,6 +13,16 @@ function match(path: string, pattern: string): boolean {
1213
export function filterPaths(
1314
paths: string[],
1415
patterns: string[],
16+
): string[] {
17+
core.debug('patterns: ' + JSON.stringify(patterns, undefined, 2));
18+
const filteredPaths = filterPathsImpl(paths, patterns);
19+
core.info(`${filteredPaths.length} filtered paths: ${JSON.stringify(filteredPaths, undefined, 2)}`);
20+
return filteredPaths;
21+
}
22+
23+
function filterPathsImpl(
24+
paths: string[],
25+
patterns: string[],
1526
): string[] {
1627
return paths.filter(path => {
1728
return patterns.reduce((prevResult, pattern) => {

common/src/pr-utils.ts

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,72 @@
11

22
import * as core from '@actions/core'
3-
import { context } from '@actions/github'
3+
import { context, getOctokit } from '@actions/github'
44
import { execCommand } from './common-utils';
55

66
export async function getPrRevisionRange(): Promise<{
77
head: string;
88
base: string;
99
}> {
10-
return getRange().then((r) => {
10+
return getPrRevisionRangeImpl().then((r) => {
1111
core.info(`Base commit: ${r.base}`);
1212
core.info(`Head commit: ${r.head}`);
1313
return r;
1414
});
1515
}
1616

17-
function normalizeCommit(commit: string) {
18-
return commit === '0000000000000000000000000000000000000000' ? 'HEAD^' : commit;
19-
}
20-
21-
export async function getRange(): Promise<{
17+
async function getPrRevisionRangeImpl(): Promise<{
2218
head: string;
2319
base: string;
2420
}> {
2521
switch (context.eventName) {
2622
case 'pull_request':
27-
const baseBranch = context.payload.pull_request?.base?.ref;
28-
await execCommand(`git fetch origin`);
23+
const baseBranch = context.payload.pull_request?.base?.ref;
24+
await execCommand(`git fetch origin`);
25+
26+
return {
27+
base: await execCommand(`git rev-parse origin/${baseBranch}`),
28+
head: context.payload.pull_request?.head?.sha,
29+
};
30+
31+
case 'push':
32+
33+
return {
34+
base: normalizeCommit(context.payload.before),
35+
head: context.payload.after,
36+
};
37+
default:
38+
throw new Error(`This action only supports pull requests and pushes, ${context.eventName} events are not supported.`);
39+
}
40+
}
41+
function normalizeCommit(commit: string) {
42+
return commit === '0000000000000000000000000000000000000000' ? 'HEAD^' : commit;
43+
}
44+
45+
export async function getChangedFiles(token: string): Promise<string[]> {
46+
return getChangedFilesImpl(token).then((files) => {
47+
core.info(`${files.length} changed files: ${JSON.stringify(files, undefined, 2)}`)
48+
return files;
49+
});
50+
}
2951

30-
return {
31-
base: await execCommand(`git rev-parse origin/${baseBranch}`),
32-
head: context.payload.pull_request?.head?.sha,
33-
};
52+
async function getChangedFilesImpl(token: string): Promise<string[]> {
53+
try {
54+
const octokit = getOctokit(token);
3455

35-
case 'push':
56+
if (context.payload.pull_request == null) {
57+
core.setFailed('Getting changed files only works on pull request events.');
58+
return [];
59+
}
3660

37-
return {
38-
base: normalizeCommit(context.payload.before),
39-
head: context.payload.after,
40-
};
41-
default:
42-
throw new Error(`This action only supports pull requests and pushes, ${context.eventName} events are not supported.`);
61+
const files = await octokit.paginate(octokit.rest.pulls.listFiles, {
62+
owner: context.repo.owner,
63+
repo: context.repo.repo,
64+
pull_number: context.payload.pull_request.number,
65+
});
66+
67+
return files.map(file => file.filename);
68+
} catch (error) {
69+
core.setFailed(`Getting changed files failed with error: ${error}`);
70+
return [];
4371
}
4472
}

get-changed-files/action.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: get-changed-files
2+
description: Filters the list of files changed in a PR with path globs and saves the list to file
3+
4+
inputs:
5+
6+
gh-token:
7+
description: GitHub access token (GITHUB_TOKEN)
8+
required: true
9+
10+
paths:
11+
description: Semicolon separated globs
12+
required: false
13+
14+
output:
15+
description: Output file path
16+
required: true
17+
18+
19+
runs:
20+
using: node16
21+
main: dist/index.js
22+
23+
outputs:
24+
result:
25+
description: A file with the list of files in JSON format

0 commit comments

Comments
 (0)