Skip to content

Commit 3a765b3

Browse files
committed
feat(github-actions): automatically apply the target: feature label for pull requests targeting non-releasable branches (#2852)
Closes #2851 PR Close #2852
1 parent 8304cff commit 3a765b3

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

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

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import * as core from '@actions/core';
22
import {context} from '@actions/github';
3-
import {Octokit} from '@octokit/rest';
3+
import {Octokit, RestEndpointMethodTypes} from '@octokit/rest';
44
import {Commit, parseCommitMessage} from '../../../ng-dev/commit-message/parse.js';
5-
import {managedLabels} from '../../../ng-dev/pr/common/labels/index.js';
5+
import {managedLabels, targetLabels} from '../../../ng-dev/pr/common/labels/index.js';
66
import {ANGULAR_ROBOT, getAuthTokenFor, revokeActiveInstallationToken} from '../../utils.js';
77
import {ManagedRepositories} from '../../../ng-dev/pr/common/labels/base.js';
88

9+
/** The type of the response data for a the pull request get method on from octokit. */
10+
type PullRequestGetData = RestEndpointMethodTypes['pulls']['get']['response']['data'];
11+
/** A Regex matcher to match releasable branch patterns. */
12+
const releasableBranchMatcher = /(main|\d+\.\d+\.x)/;
13+
914
class PullRequestLabeling {
1015
/** Run the commit message based labelling process. */
1116
static run = async () => {
@@ -26,6 +31,8 @@ class PullRequestLabeling {
2631
labels = new Set<string>();
2732
/** All commits in the PR */
2833
commits: Commit[] = [];
34+
/** The pull request information from the github API. */
35+
pullRequestMetadata?: PullRequestGetData;
2936

3037
private constructor(private git: Octokit) {}
3138

@@ -35,6 +42,14 @@ class PullRequestLabeling {
3542
await this.initialize();
3643
core.info(`PR #${context.issue.number}`);
3744

45+
await this.commitMessageBasedLabeling();
46+
await this.pullRequestMetadataLabeling();
47+
}
48+
49+
/**
50+
* Perform labeling based on the commit messages for the pull request.
51+
*/
52+
async commitMessageBasedLabeling() {
3853
// Add or Remove label as appropriate for each of the supported label and commit messaage
3954
// combinations.
4055
for (const {commitCheck, name, repositories} of Object.values(managedLabels)) {
@@ -62,6 +77,31 @@ class PullRequestLabeling {
6277
}
6378
}
6479

80+
/**
81+
* Perform labeling based on the metadata for the pull request from the Github API.
82+
*/
83+
async pullRequestMetadataLabeling() {
84+
// If we are unable to get pull request metadata, we can shortcut and exit early.
85+
if (this.pullRequestMetadata === undefined) {
86+
return;
87+
}
88+
/** The base reference string, or target branch of the pull request. */
89+
const baseRef = this.pullRequestMetadata.base.ref;
90+
91+
if (!releasableBranchMatcher.test(baseRef)) {
92+
if (this.labels.has(targetLabels.TARGET_FEATURE.name)) {
93+
core.info(
94+
`The target branch (${baseRef}) is not a releasable branch, already has "target: feature" label`,
95+
);
96+
} else {
97+
core.info(
98+
`The target branch (${baseRef}) is not a releasable branch, adding "target: feature" label`,
99+
);
100+
await this.addLabel(targetLabels.TARGET_FEATURE.name);
101+
}
102+
}
103+
}
104+
65105
/** Add the provided label to the pull request. */
66106
async addLabel(label: string) {
67107
const {number: issue_number, owner, repo} = context.issue;
@@ -97,6 +137,10 @@ class PullRequestLabeling {
97137
await this.git.issues
98138
.listLabelsOnIssue({issue_number: number, owner, repo})
99139
.then((resp) => resp.data.forEach(({name}) => this.labels.add(name)));
140+
141+
await this.git.pulls.get({owner, repo, pull_number: number}).then(({data}) => {
142+
this.pullRequestMetadata = data;
143+
});
100144
}
101145
}
102146

github-actions/pull-request-labeling/main.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43411,6 +43411,7 @@ async function revokeActiveInstallationToken(githubOrToken) {
4341143411

4341243412
//
4341343413
var _a;
43414+
var releasableBranchMatcher = /(main|\d+\.\d+\.x)/;
4341443415
var PullRequestLabeling = class {
4341543416
constructor(git) {
4341643417
this.git = git;
@@ -43421,6 +43422,10 @@ var PullRequestLabeling = class {
4342143422
async run() {
4342243423
await this.initialize();
4342343424
core.info(`PR #${import_github2.context.issue.number}`);
43425+
await this.commitMessageBasedLabeling();
43426+
await this.pullRequestMetadataLabeling();
43427+
}
43428+
async commitMessageBasedLabeling() {
4342443429
for (const { commitCheck, name, repositories } of Object.values(managedLabels)) {
4342543430
if (!repositories.includes(import_github2.context.repo.repo)) {
4342643431
continue;
@@ -43439,6 +43444,20 @@ var PullRequestLabeling = class {
4343943444
}
4344043445
}
4344143446
}
43447+
async pullRequestMetadataLabeling() {
43448+
if (this.pullRequestMetadata === void 0) {
43449+
return;
43450+
}
43451+
const baseRef = this.pullRequestMetadata.base.ref;
43452+
if (!releasableBranchMatcher.test(baseRef)) {
43453+
if (this.labels.has(targetLabels.TARGET_FEATURE.name)) {
43454+
core.info(`The target branch (${baseRef}) is not a releasable branch, already has "target: feature" label`);
43455+
} else {
43456+
core.info(`The target branch (${baseRef}) is not a releasable branch, adding "target: feature" label`);
43457+
await this.addLabel(targetLabels.TARGET_FEATURE.name);
43458+
}
43459+
}
43460+
}
4344243461
async addLabel(label) {
4344343462
const { number: issue_number, owner, repo } = import_github2.context.issue;
4344443463
try {
@@ -43455,6 +43474,9 @@ var PullRequestLabeling = class {
4345543474
await this.git.paginate(this.git.issues.listLabelsForRepo, { owner, repo }).then((labels) => labels.filter((l) => l.name.startsWith("area: ")).forEach((l) => this.repoAreaLabels.add(l.name)));
4345643475
await this.git.paginate(this.git.pulls.listCommits, { owner, pull_number: number, repo }).then((commits) => this.commits = commits.map(({ commit }) => parseCommitMessage(commit.message)));
4345743476
await this.git.issues.listLabelsOnIssue({ issue_number: number, owner, repo }).then((resp) => resp.data.forEach(({ name }) => this.labels.add(name)));
43477+
await this.git.pulls.get({ owner, repo, pull_number: number }).then(({ data }) => {
43478+
this.pullRequestMetadata = data;
43479+
});
4345843480
}
4345943481
};
4346043482
_a = PullRequestLabeling;

0 commit comments

Comments
 (0)