Skip to content

Commit be965d4

Browse files
committed
Create pr-title-bot.yml
1 parent 33d88e4 commit be965d4

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

.github/workflows/pr-title-bot.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: PR Title Bot
2+
3+
on:
4+
pull_request_target:
5+
types:
6+
- opened
7+
- synchronize
8+
- reopened
9+
10+
permissions:
11+
pull-requests: write
12+
contents: read
13+
14+
concurrency:
15+
group: pr-title-bot-${{ github.event.pull_request.number }}
16+
cancel-in-progress: true
17+
18+
jobs:
19+
rewrite:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- name: Rewrite title and label from plugin diff
23+
env:
24+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25+
REPO: ${{ github.repository }}
26+
PR_NUMBER: ${{ github.event.pull_request.number }}
27+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
28+
run: |
29+
set -euo pipefail
30+
31+
files=$(gh api "repos/$REPO/pulls/$PR_NUMBER/files" --paginate \
32+
--jq '.[] | select(.filename | startswith("plugins/")) | "\(.status)\t\(.filename)\t\(.sha)"')
33+
34+
if [[ -z "$files" ]]; then
35+
echo "No plugin files changed; skipping."
36+
exit 0
37+
fi
38+
39+
plugin_paths=$(printf '%s\n' "$files" | cut -f2 | awk -F/ '{print $1"/"$2}' | sort -u)
40+
plugin_count=$(printf '%s\n' "$plugin_paths" | grep -c .)
41+
42+
if [[ "$plugin_count" -ne 1 ]]; then
43+
echo "PR touches $plugin_count plugin directories; skipping title rewrite."
44+
exit 0
45+
fi
46+
47+
plugin_path=$plugin_paths
48+
line=$(printf '%s\n' "$files" | awk -F'\t' -v p="$plugin_path" '$2==p {print; exit}')
49+
status=$(printf '%s' "$line" | cut -f1)
50+
submodule_sha=$(printf '%s' "$line" | cut -f3)
51+
52+
case "$status" in
53+
added)
54+
verb="Add"
55+
label="plugin-addition"
56+
other_label="plugin-update"
57+
;;
58+
modified)
59+
verb="Update"
60+
label="plugin-update"
61+
other_label="plugin-addition"
62+
;;
63+
*)
64+
echo "Unhandled file status '$status' for $plugin_path; skipping."
65+
exit 0
66+
;;
67+
esac
68+
69+
submodule_url=$(gh api "repos/$REPO/contents/.gitmodules?ref=$HEAD_SHA" --jq '.content' | base64 -d \
70+
| awk -v p="$plugin_path" '
71+
$0 ~ ("\\[submodule \"" p "\"\\]") { found=1; next }
72+
found && /^\[submodule/ { found=0 }
73+
found && /url[ \t]*=/ { sub(/^[ \t]*url[ \t]*=[ \t]*/, ""); print; exit }
74+
')
75+
76+
if [[ -z "$submodule_url" ]]; then
77+
echo "Could not resolve submodule URL for $plugin_path; skipping."
78+
exit 0
79+
fi
80+
81+
sub_repo=$(printf '%s' "$submodule_url" | sed -E 's#^https://github\.com/([^/]+/[^/]+?)(\.git)?/?$#\1#')
82+
83+
common_name=$(gh api "repos/$sub_repo/contents/plugin.json?ref=$submodule_sha" --jq '.content' 2>/dev/null \
84+
| base64 -d 2>/dev/null | jq -r '.common_name // empty' 2>/dev/null || true)
85+
86+
if [[ -z "$common_name" ]]; then
87+
common_name=$(basename "$plugin_path" | sed -E 's/[-_]+/ /g' | sed -E 's/(^|[ ])([a-z])/\1\u\2/g')
88+
echo "::warning::Could not read common_name from plugin.json for $sub_repo@$submodule_sha; falling back to '$common_name'."
89+
fi
90+
91+
new_title="$verb $common_name"
92+
current_title=$(gh pr view "$PR_NUMBER" --json title --jq '.title')
93+
94+
if [[ "$current_title" != "$new_title" ]]; then
95+
gh pr edit "$PR_NUMBER" --title "$new_title"
96+
fi
97+
98+
gh pr edit "$PR_NUMBER" --add-label "$label" --remove-label "$other_label"

0 commit comments

Comments
 (0)