@@ -142,3 +142,65 @@ jobs:
142142 with :
143143 repo-token : " ${{ github.token }}"
144144 pr-number : ${{ steps.validate.outputs.pr_numbers }}
145+
146+ - name : Label external contributions
147+ if : steps.validate.outputs.has_prs == 'true'
148+ env :
149+ GH_TOKEN : ${{ github.token }}
150+ REPO : ${{ github.repository }}
151+ PR_NUMBERS : ${{ steps.validate.outputs.pr_numbers }}
152+ run : |
153+ set -euo pipefail
154+
155+ label="external-contribution"
156+ cutoff=$(date -u -d "24 hours ago" "+%Y-%m-%dT%H:%M:%SZ")
157+ while IFS= read -r pr_number; do
158+ if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]]; then
159+ echo "Skipping malformed pull request number."
160+ continue
161+ fi
162+
163+ pr_json=$(gh api "repos/$REPO/pulls/$pr_number")
164+ if ! jq -e \
165+ --arg repo "$REPO" \
166+ --arg label "$label" \
167+ '.state == "open" and
168+ .draft == false and
169+ .base.repo.full_name == $repo and
170+ .head.repo.full_name != $repo and
171+ .user.type == "User" and
172+ .author_association != "MEMBER" and
173+ .author_association != "OWNER" and
174+ (any(.labels[]?; .name == $label) | not)' \
175+ >/dev/null <<<"$pr_json"; then
176+ continue
177+ fi
178+
179+ events=$(gh api --paginate \
180+ "repos/$REPO/issues/$pr_number/events?per_page=100" |
181+ jq -cs 'add')
182+
183+ if ! jq -e -s --arg cutoff "$cutoff" \
184+ '.[0].created_at >= $cutoff or
185+ any(.[1][];
186+ (.event == "reopened" or .event == "ready_for_review") and
187+ .created_at >= $cutoff)' \
188+ <(printf '%s\n' "$pr_json") \
189+ <(printf '%s\n' "$events") \
190+ >/dev/null; then
191+ continue
192+ fi
193+
194+ if jq -e --arg label "$label" \
195+ 'any(.[]; .event == "unlabeled" and .label.name == $label)' \
196+ >/dev/null <<<"$events"; then
197+ continue
198+ fi
199+
200+ jq -n --arg label "$label" '{labels: [$label]}' |
201+ gh api --method POST \
202+ "repos/$REPO/issues/$pr_number/labels" \
203+ --input - \
204+ >/dev/null
205+ echo "Labelled pull request #$pr_number."
206+ done <<<"$PR_NUMBERS"
0 commit comments