-
Notifications
You must be signed in to change notification settings - Fork 0
123 lines (105 loc) · 4.49 KB
/
pr-title-labeler.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
name: PR Labeller
on:
pull_request:
types: [opened, edited]
jobs:
label-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.2.2
- name: Update PR labels and title
uses: actions/github-script@v7.0.1
with:
script: |
const prBody = context.payload.pull_request.body;
const shouldHaveLabels = new Set();
const labelMappings = {
'Bug fix': 'Bug',
'New feature': 'Feature',
'UI/UX improvement': 'UI/UX',
'Weather data processing': 'Data Processing',
'Optimisation': 'Optimisation',
'Security': 'Security',
'Documentation update': 'Documentation',
'Chore': 'Chore'
};
const titlePrefixMappings = {
'Bug': 'fix',
'Feature': 'feat',
'UI/UX': 'ui',
'Data Processing': 'data',
'Optimisation': 'perf',
'Security': 'security',
'Documentation': 'docs',
'Chore': 'chore'
};
const validPrefixes = Object.values(titlePrefixMappings);
// Determine which labels should be present
for (const [text, label] of Object.entries(labelMappings)) {
if (prBody && prBody.includes(`- [x] ${text}`)) {
shouldHaveLabels.add(label);
}
}
// Get current labels
const currentLabels = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
});
const currentLabelNames = new Set(currentLabels.data.map(l => l.name));
const allMappedLabels = new Set(Object.values(labelMappings));
// Remove labels that shouldn't be there
const labelsToRemove = [...currentLabelNames].filter(label =>
allMappedLabels.has(label) && !shouldHaveLabels.has(label)
);
for (const label of labelsToRemove) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
name: label
});
}
// Add missing labels
const labelsToAdd = [...shouldHaveLabels].filter(label =>
!currentLabelNames.has(label)
);
if (labelsToAdd.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number,
labels: labelsToAdd
});
}
// Update PR title with prefix
const selectedLabel = [...shouldHaveLabels][0];
if (selectedLabel) {
const prefix = titlePrefixMappings[selectedLabel].toLowerCase();
let currentTitle = context.payload.pull_request.title;
// Check if current title has any prefix (including non-standard ones)
const prefixMatch = currentTitle.match(/^([a-zA-Z]+):\s*(.*)/);
if (prefixMatch) {
const titleContent = prefixMatch[2];
// Only update if current prefix is not the correct one
const currentPrefix = prefixMatch[1].toLowerCase();
if (!validPrefixes.includes(currentPrefix) || currentPrefix !== prefix) {
const newTitle = `${prefix}: ${titleContent}`;
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
title: newTitle
});
}
} else {
// No prefix exists, add new one
const newTitle = `${prefix}: ${currentTitle}`;
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
title: newTitle
});
}
}