Skip to content

Commit 1797451

Browse files
authored
ci(labels): automatic PR label management (#280)
1 parent 49564a5 commit 1797451

File tree

4 files changed

+149
-5
lines changed

4 files changed

+149
-5
lines changed

.github/pull_request_template.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
Please check the boxes below to confirm that you have followed the
77
required guidelines for contributions:
88

9+
- [ ] All commits are [signed](https://docs.github.com/en/authentication/managing-commit-signature-verification).
10+
- [ ] The title for this pull request is the same as the first commit's message and it follows the [conventional commits specification](https://www.conventionalcommits.org). See commit history for examples.
911
- [ ] If this pull request includes code changes, they were all properly tested. Automated tests were also included where possible.
1012
- [ ] If applicable, this pull request includes the relevant documentation for this change.
1113
- [ ] If this pull request is related to an existing issue, you can use the same description below but in any case include a [link to the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue) like `Fixes #ISSUE_NUMBER.` or `Closes #ISSUE_NUMBER.`.
12-
- [ ] All the commits in this pull request were squashed into a single commit. That commit is [signed](https://docs.github.com/en/authentication/managing-commit-signature-verification).
1314

1415
<!-- prettier-ignore-start -->
1516
<!-- markdownlint-disable-next-line MD041 -->

.github/release.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
changelog:
2+
exclude:
3+
labels:
4+
- no-release-notes
5+
categories:
6+
- title: "New Features :sparkles:"
7+
labels:
8+
- feat
9+
- title: "Bug Fixes :bug:"
10+
labels:
11+
- fix
12+
- title: "Dependency Upgrades :package:"
13+
labels:
14+
- dependencies
15+
- title: "Other Changes :broom:"
16+
labels:
17+
- "*"

.github/workflows/check-pr.yml

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
name: "Check PR"
3+
on: pull_request
4+
5+
permissions:
6+
pull-requests: write
7+
8+
jobs:
9+
check:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Check commits
13+
shell: bash
14+
run: |
15+
# Check the commits
16+
commits_json=$(curl -fsSL -H "Authorization: token ${GITHUB_TOKEN}" "${PR_COMMITS_URL}")
17+
echo -n 'Commits: '
18+
echo "${commits_json}" | jq '.'
19+
commit_count="$(echo "${commits_json}" | jq -r 'length')"
20+
# Check single commit
21+
if [ "${commit_count}" -eq 1 ] ; then
22+
commit_title="$(echo "${commits_json}" | jq -r '.[0].commit.message' | head -n 1)"
23+
echo "Commit title: ${commit_title}"
24+
if [[ "${commit_title}" != "${PR_TITLE}" ]] ; then
25+
>&2 echo 'Single commit must have same title as PR.'
26+
exit 1
27+
fi
28+
fi
29+
# Check that all commits are signed
30+
for ((i = 0 ; i < commit_count ; i++ )); do
31+
if [[ "$(echo "${commits_json}" | jq -r ".[${i}].commit.verification.verified")" == 'false' ]] ; then
32+
>&2 echo "Commit $(echo "${commits_json}" | jq -r ".[${i}].sha") must be signed."
33+
exit 1
34+
fi
35+
done
36+
env:
37+
PR_TITLE: ${{github.event.pull_request.title}}
38+
PR_COMMITS_URL: ${{github.event.pull_request.commits_url}}
39+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
40+
- name: Update PR labels
41+
shell: bash
42+
run: |
43+
# Check PR title is a conventional commit message
44+
regexp='^((build|chore|ci|docs|feat|fix|perf|refactor|style|test)(\([a-zA-Z0-9\-]+\))?)!?: .*$'
45+
if ! [[ "${PR_TITLE}" =~ ${regexp} ]] ; then
46+
>&2 echo 'Non conventional PR title.'
47+
exit 1
48+
fi
49+
scoped_type="${BASH_REMATCH[1]}"
50+
type="${BASH_REMATCH[2]}"
51+
add_labels=()
52+
remove_labels=()
53+
# Remove the labels we manage
54+
for label in build chore ci docs feat fix perf refactor test style ; do
55+
if [[ "${label}" == "${type}" ]]; then
56+
echo "Label to add: ${label}"
57+
# shellcheck disable=SC2076
58+
if [[ "${PR_LABELS}" =~ "\"${label}\"" ]] ; then
59+
echo "Label ${label} already present"
60+
else
61+
add_labels+=("${label}")
62+
fi
63+
else
64+
echo "Label to remove: ${label}"
65+
# shellcheck disable=SC2076
66+
if [[ "${PR_LABELS}" =~ "\"${label}\"" ]] ; then
67+
remove_labels+=("${label}")
68+
else
69+
echo "Label ${label} not present"
70+
fi
71+
fi
72+
done
73+
# If scope is dependency-related, add 'dependencies' label
74+
regexp2='^[a-zA-Z0-9]+\([a-zA-Z0-9\-]*deps\)$'
75+
if [[ "${scoped_type}" =~ ${regexp2} ]] ; then
76+
echo "Label to add: dependencies"
77+
# shellcheck disable=SC2076
78+
if [[ "${PR_LABELS}" =~ "\"dependencies\"" ]] ; then
79+
echo "Label dependencies already present"
80+
else
81+
add_labels+=('dependencies')
82+
fi
83+
# otherwise do not remove it since we are not the only ones to manage this label (e.g. dependabot)
84+
fi
85+
# For certain types/scopes, add 'no-release-notes' label
86+
if [[ "${type}" == 'chore' \
87+
|| "${type}" == 'ci' \
88+
|| "${type}" == 'docs' \
89+
|| "${type}" == 'style' \
90+
|| "${type}" == 'test' ]] ; then
91+
echo "Label to add: no-release-notes"
92+
# shellcheck disable=SC2076
93+
if [[ "${PR_LABELS}" =~ "\"no-release-notes\"" ]] ; then
94+
echo "Label no-release-notes already present"
95+
else
96+
add_labels+=('no-release-notes')
97+
fi
98+
else
99+
echo "Label to remove: no-release-notes"
100+
# shellcheck disable=SC2076
101+
if [[ "${PR_LABELS}" =~ "\"no-release-notes\"" ]] ; then
102+
remove_labels+=('no-release-notes')
103+
else
104+
echo "Label no-release-notes not present"
105+
fi
106+
fi
107+
# Update the labels
108+
function join_by { local IFS="$1"; shift; echo "$*"; }
109+
if [ ${#add_labels[@]} -eq 0 ] && [ ${#remove_labels[@]} -eq 0 ]; then
110+
echo 'No label to change'
111+
elif [ ${#add_labels[@]} -eq 0 ]; then
112+
echo "Removing labels: $(join_by , "${remove_labels[@]}")"
113+
gh pr edit "${PR_URL}" --remove-label "$(join_by , "${remove_labels[@]}")"
114+
elif [ ${#remove_labels[@]} -eq 0 ]; then
115+
echo "Adding labels: $(join_by , "${add_labels[@]}")"
116+
gh pr edit "${PR_URL}" --add-label "$(join_by , "${add_labels[@]}")"
117+
else
118+
echo "Adding labels: $(join_by , "${add_labels[@]}")"
119+
echo "Removing labels: $(join_by , "${remove_labels[@]}")"
120+
gh pr edit "${PR_URL}" --add-label "$(join_by , "${add_labels[@]}")" --remove-label "$(join_by , "${remove_labels[@]}")"
121+
fi
122+
env:
123+
PR_TITLE: ${{github.event.pull_request.title}}
124+
PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
125+
PR_URL: ${{github.event.pull_request.html_url}}
126+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

CONTRIBUTING.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ request. We then kindly ask that:
1919
- all code changes must be tested manually and automated tests should
2020
be included when possible.
2121
- all necessary documentation should be included as well.
22-
- commit messages must follow the [conventional commits specification](https://www.conventionalcommits.org).
22+
- the first commit's message on a pull request must follow the
23+
[conventional commits specification](https://www.conventionalcommits.org).
2324
See commit history for examples.
24-
- commits on a single pull request must be squashed together to keep
25-
make reviews easier.
26-
- commits must be signed (this is supported by most Git clients as
25+
- all commits must be signed (this is supported by most Git clients as
2726
well as the GitHub web UI, see link below).
2827

2928
## Resources
3029

3130
- [Managing commit signature verification](https://docs.github.com/en/authentication/managing-commit-signature-verification)
3231
- [Using Pull Requests](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests)
32+
- [Commit Message Format](https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md)

0 commit comments

Comments
 (0)