Skip to content

Commit 5837aa3

Browse files
Create pr-inbound-check.yml
1 parent 23bc8ad commit 5837aa3

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
on:
2+
pull_request_target:
3+
types: [opened, reopened, edited, synchronize]
4+
5+
jobs:
6+
validate-issue:
7+
runs-on: ubuntu-latest
8+
permissions:
9+
pull-requests: write
10+
issues: read
11+
12+
steps:
13+
- name: Scan PR description for Issue URL(s)
14+
id: scan
15+
env:
16+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17+
PR_NUMBER: ${{ github.event.pull_request.number }}
18+
REPO_FULL: ${{ github.repository }}
19+
run: |
20+
# Fetch PR body safely (handles null -> empty string)
21+
BODY=$(gh api repos/$REPO_FULL/pulls/$PR_NUMBER --jq '.body // ""')
22+
23+
# Look for direct GitHub Issue links (any org/repo)
24+
URLS=$(printf '%s\n' "$BODY" \
25+
| grep -Eo 'https://github\.com/airbnb/viaduct/issues/[0-9]+' \
26+
| sort -u)
27+
28+
if [ -z "$URLS" ]; then
29+
echo "none=true" >> "$GITHUB_OUTPUT"
30+
else
31+
echo "none=false" >> "$GITHUB_OUTPUT"
32+
{
33+
echo "list<<EOF"
34+
echo "$URLS"
35+
echo "EOF"
36+
} >> "$GITHUB_OUTPUT"
37+
fi
38+
39+
- name: Status — PR has Issue URL(s)
40+
if: steps.scan.outputs.none == 'false'
41+
run: |
42+
echo "✅ PR description contains Issue URL(s):"
43+
echo "${{ steps.scan.outputs.list }}"
44+
45+
- name: Status — PR has no Issue URL
46+
if: steps.scan.outputs.none == 'true'
47+
run: |
48+
echo "⚠️ PR description contains no direct Issue URL."
49+
50+
- name: Comment on PR if missing Issue URL
51+
if: steps.scan.outputs.none == 'true'
52+
env:
53+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
PR_NUMBER: ${{ github.event.pull_request.number }}
55+
REPO_FULL: ${{ github.repository }}
56+
run: |
57+
gh api repos/$REPO_FULL/issues/$PR_NUMBER/comments \
58+
-f body=$'⚠️ This Pull Request does not include a direct Issue link in its description.\n\nPlease add a URL to a GitHub Issue, for example:\nhttps://github.com/owner/repo/issues/123\n\n(Optional) You can also use keywords like **Closes #123**, but this check only looks for direct links.'
59+
60+
- name: Manage labels (issue-linked/review me/create patch + synchronize behavior)
61+
env:
62+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
PR_NUMBER: ${{ github.event.pull_request.number }}
64+
REPO_FULL: ${{ github.repository }}
65+
ACTION: ${{ github.event.action }}
66+
LABEL_MISSING: "needs-issue ❗"
67+
LABEL_REVIEW: "ready-to-go"
68+
LABEL_CREATE: "create-patch"
69+
LABEL_INREVIEW: "in-review"
70+
run: |
71+
set -e
72+
73+
# URL-encode for DELETE endpoints
74+
uri() { jq -rn --arg s "$1" '$s|@uri'; }
75+
76+
# Ensure labels exist (best-effort)
77+
ensure_label() {
78+
local name="$1" color="$2"
79+
if ! gh api repos/$REPO_FULL/labels --paginate --jq '.[].name' | grep -Fxq "$name"; then
80+
gh api -X POST "repos/$REPO_FULL/labels" -f name="$name" -f color="$color" >/dev/null 2>&1 || true
81+
fi
82+
}
83+
ensure_label "$LABEL_MISSING" "d73a4a" # red
84+
ensure_label "$LABEL_REVIEW" "0366d6" # blue
85+
ensure_label "$LABEL_CREATE" "6f42c1" # purple
86+
87+
# Helpers
88+
refresh() { CURRENT=$(gh api "repos/$REPO_FULL/issues/$PR_NUMBER/labels" --jq '.[].name'); }
89+
has() { grep -Fxq "$1" <<< "$CURRENT"; }
90+
add() { gh api "repos/$REPO_FULL/issues/$PR_NUMBER/labels" -f labels[]="$1" >/dev/null; }
91+
del() { gh api -X DELETE "repos/$REPO_FULL/issues/$PR_NUMBER/labels/$(uri "$1")" >/dev/null 2>&1 || true; }
92+
93+
refresh
94+
95+
# 1) Base rule according to the presence of a link
96+
if [ "${{ steps.scan.outputs.none }}" = "false" ]; then
97+
# Link present → remove needs-issue
98+
99+
if has "$LABEL_MISSING"; then del "$LABEL_MISSING"; fi
100+
refresh
101+
102+
# Exclusion with create patch: if create patch exists → do not put review me (and remove if it was there)
103+
if has "$LABEL_CREATE"; then
104+
if has "$LABEL_REVIEW"; then del "$LABEL_REVIEW"; fi
105+
else
106+
# create patch does not exist
107+
if ! has "$LABEL_REVIEW"; then add "$LABEL_REVIEW"; fi
108+
fi
109+
else
110+
# No link → needs-issue; remove review me / create patch
111+
has "$LABEL_MISSING" || add "$LABEL_MISSING"
112+
if has "$LABEL_REVIEW"; then del "$LABEL_REVIEW"; fi
113+
if has "$LABEL_CREATE"; then del "$LABEL_CREATE"; fi
114+
fi
115+
116+
refresh
117+
118+
# 2) Extra behavior in synchronize: in review -> create patch, and remove in review
119+
if [ "$ACTION" = "synchronize" ] && has "$LABEL_INREVIEW"; then
120+
has "$LABEL_CREATE" || add "$LABEL_CREATE"
121+
del "$LABEL_INREVIEW"
122+
refresh
123+
if has "$LABEL_CREATE" && has "$LABEL_REVIEW"; then del "$LABEL_REVIEW"; fi
124+
fi

0 commit comments

Comments
 (0)