Skip to content

Commit f06ef68

Browse files
feat(github-actions): add auto labeling by path to github labeler action
This adds the ability to add additional labels automatically if a specific path is matched in the pull request commits.
1 parent e126086 commit f06ef68

File tree

11 files changed

+16993
-3833
lines changed

11 files changed

+16993
-3833
lines changed

.github/local-actions/branch-manager/main.js

Lines changed: 7 additions & 1 deletion
Large diffs are not rendered by default.

.github/local-actions/labels-sync/main.js

Lines changed: 7 additions & 1 deletion
Large diffs are not rendered by default.

github-actions/branch-manager/main.js

Lines changed: 7 additions & 1 deletion
Large diffs are not rendered by default.

github-actions/pull-request-labeling/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ ts_project(
1818
"//github-actions:utils",
1919
"//ng-dev/commit-message",
2020
"//ng-dev/pr/common/labels",
21+
"//ng-dev/pr/config",
22+
"//ng-dev/utils",
2123
],
2224
)
2325

@@ -27,6 +29,9 @@ esbuild_checked_in(
2729
":lib",
2830
],
2931
entry_point = "lib/main.ts",
32+
external = [
33+
"pnpapi",
34+
],
3035
format = "esm",
3136
platform = "node",
3237
target = "node22",

github-actions/pull-request-labeling/lib/main.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import {context} from '@actions/github';
33
import {Octokit, RestEndpointMethodTypes} from '@octokit/rest';
44
import {Commit, parseCommitMessage} from '../../../ng-dev/commit-message/parse.js';
55
import {actionLabels, managedLabels, targetLabels} from '../../../ng-dev/pr/common/labels/index.js';
6+
import {assertValidPullRequestConfig, PullRequestConfig} from '../../../ng-dev/pr/config/index.js';
67
import {ANGULAR_ROBOT, getAuthTokenFor, revokeActiveInstallationToken} from '../../utils.js';
78
import {ManagedRepositories} from '../../../ng-dev/pr/common/labels/base.js';
9+
import {getConfig, NgDevConfig} from '../../../ng-dev/utils/config.js';
810

911
/** The type of the response data for a the pull request get method on from octokit. */
1012
type PullRequestGetData = RestEndpointMethodTypes['pulls']['get']['response']['data'];
@@ -17,7 +19,9 @@ class PullRequestLabeling {
1719
const token = await getAuthTokenFor(ANGULAR_ROBOT);
1820
const git = new Octokit({auth: token});
1921
try {
20-
const inst = new this(git);
22+
const config = await getConfig();
23+
assertValidPullRequestConfig(config);
24+
const inst = new this(git, config);
2125
await inst.run();
2226
} finally {
2327
await revokeActiveInstallationToken(git);
@@ -32,8 +36,13 @@ class PullRequestLabeling {
3236
commits: Commit[] = [];
3337
/** The pull request information from the github API. */
3438
pullRequestMetadata?: PullRequestGetData;
39+
/** The files changed in the pull request */
40+
pullRequestFiles?: RestEndpointMethodTypes['pulls']['listFiles']['response']['data'];
3541

36-
private constructor(private git: Octokit) {}
42+
private constructor(
43+
private git: Octokit,
44+
private config: NgDevConfig<{pullRequest: PullRequestConfig}>,
45+
) {}
3746

3847
/** Run the action, and revoke the installation token on completion. */
3948
async run() {
@@ -43,6 +52,7 @@ class PullRequestLabeling {
4352

4453
await this.commitMessageBasedLabeling();
4554
await this.pullRequestMetadataLabeling();
55+
await this.pathBasedLabeling();
4656
}
4757

4858
/**
@@ -107,6 +117,28 @@ class PullRequestLabeling {
107117
}
108118
}
109119

120+
/**
121+
* Perform labeling based on the paths of the files in the pull request.
122+
*/
123+
async pathBasedLabeling() {
124+
const managedLabelByPath = this.config.pullRequest.managedLabelByPath;
125+
if (managedLabelByPath === undefined || this.pullRequestFiles === undefined) {
126+
return;
127+
}
128+
129+
for (const [path, labels] of Object.entries(managedLabelByPath)) {
130+
for (const file of this.pullRequestFiles) {
131+
if (file.filename.startsWith(path)) {
132+
for (const label of labels) {
133+
if (!this.labels.has(label)) {
134+
await this.addLabel(label);
135+
}
136+
}
137+
}
138+
}
139+
}
140+
}
141+
110142
/** Remove the provided label to the pull request. */
111143
async removeLabel(label: string) {
112144
const {number: issue_number, owner, repo} = context.issue;
@@ -159,6 +191,10 @@ class PullRequestLabeling {
159191
await this.git.pulls.get({owner, repo, pull_number: number}).then(({data}) => {
160192
this.pullRequestMetadata = data;
161193
});
194+
195+
await this.git.pulls.listFiles({owner, repo, pull_number: number}).then(({data}) => {
196+
this.pullRequestFiles = data;
197+
});
162198
}
163199
}
164200

0 commit comments

Comments
 (0)