Skip to content

Commit a69d62a

Browse files
Ensure no unexpected labels are introduced (#9614)
* feat(ci): Ensure no unexpected labels are introduced Block pull request until a maintainer clean it up. Co-authored-by: Sarah Chen <[email protected]>
1 parent 1830e5c commit a69d62a

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Contributor Checklist
88

99
- Format the title [according the contribution guidelines](https://github.com/DataDog/dd-trace-java/blob/master/CONTRIBUTING.md#title-format)
10-
- Assign the `type:` and (`comp:` or `inst:`) labels in addition to [any usefull labels](https://github.com/DataDog/dd-trace-java/blob/master/CONTRIBUTING.md#labels)
10+
- Assign the `type:` and (`comp:` or `inst:`) labels in addition to [any useful labels](https://github.com/DataDog/dd-trace-java/blob/master/CONTRIBUTING.md#labels)
1111
- Don't use `close`, `fix` or any [linking keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) when referencing an issue.
1212
Use `solves` instead, and assign the PR [milestone](https://github.com/DataDog/dd-trace-java/milestones) to the issue
1313
- Update the [CODEOWNERS](https://github.com/DataDog/dd-trace-java/blob/master/.github/CODEOWNERS) file on source file addition, move, or deletion

.github/workflows/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ _Action:_ Check the pull request complies with [the contribution guidelines](htt
2828

2929
_Recovery:_ Manually verify the guideline compliance.
3030

31+
### check-pull-request-labels [🔗](check-pull-request-labels.yaml)
32+
33+
_Trigger:_ When creating or updating a pull request.
34+
35+
_Action:_ Check the pull request did not introduce unexpected label.
36+
37+
_Recovery:_ Update the pull request or add a comment to trigger the action again.
38+
3139
### draft-release-notes-on-tag [🔗](draft-release-notes-on-tag.yaml)
3240

3341
_Trigger:_ When creating a tag, or manually (providing a tag)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Validate PR Label Format
2+
on:
3+
pull_request:
4+
types: [opened, edited, ready_for_review, labeled]
5+
6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.ref }}
8+
cancel-in-progress: true
9+
10+
jobs:
11+
check_pr_labels:
12+
name: Check pull request labels
13+
permissions:
14+
issues: write
15+
pull-requests: write
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Check pull request labels
19+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # 8.0.0
20+
with:
21+
github-token: ${{ secrets.GITHUB_TOKEN }}
22+
script: |
23+
// Skip draft pull requests
24+
if (context.payload.pull_request.draft) {
25+
return
26+
}
27+
// Define valid label categories
28+
const validCategories = [
29+
'type:',
30+
'comp:',
31+
'inst:',
32+
'tag:',
33+
'performance:', // To refactor to 'ci: ' in the future
34+
'run-tests:' // Unused since GitLab migration
35+
]
36+
// Look for invalid labels
37+
const invalidLabels = context.payload.pull_request.labels
38+
.map(label => label.name)
39+
.filter(label => validCategories.every(prefix => !label.startsWith(prefix)))
40+
const hasInvalidLabels = invalidLabels.length > 0
41+
// Get existing comments to check for blocking comment
42+
const comments = await github.rest.issues.listComments({
43+
issue_number: context.payload.pull_request.number,
44+
owner: context.repo.owner,
45+
repo: context.repo.repo
46+
})
47+
const commentMarker = '<!-- dd-trace-java-check-pr-labels-workflow -->'
48+
const blockingComment = comments.data.find(comment => comment.body.includes(commentMarker))
49+
// Create or update blocking comment if there are invalid labels
50+
if (hasInvalidLabels) {
51+
const commentBody = '**PR Blocked - Invalid Label**\n\n' +
52+
`The pull request introduced unexpected labels:\n\n` +
53+
invalidLabels.map(label => `* \`${label}\``).join('\n') + '\n\n' +
54+
'**This PR is blocked until:**\n' +
55+
'1. The invalid labels are deleted, and\n' +
56+
'2. A maintainer deletes this comment to unblock the PR\n\n' +
57+
'**Note:** Simply removing labels from the pull request is not enough - a maintainer must remove the label and delete this comment to remove the block.\n\n' +
58+
commentMarker
59+
60+
if (blockingComment) {
61+
// Update existing blocking comment
62+
await github.rest.issues.updateComment({
63+
comment_id: blockingComment.id,
64+
owner: context.repo.owner,
65+
repo: context.repo.repo,
66+
body: commentBody
67+
})
68+
} else {
69+
// Create new blocking comment
70+
await github.rest.issues.createComment({
71+
issue_number: context.payload.pull_request.number,
72+
owner: context.repo.owner,
73+
repo: context.repo.repo,
74+
body: commentBody
75+
})
76+
}
77+
blockingComment = true
78+
}
79+
if (blockingComment) {
80+
// Block the PR by failing the workflow
81+
core.setFailed(`PR blocked: Invalid labels detected: (${invalidLabels.join(', ')}). A maintainer must delete the blocking comment after fixing the labels to allow merging.`)
82+
}

0 commit comments

Comments
 (0)