-
Notifications
You must be signed in to change notification settings - Fork 1.9k
148 lines (131 loc) · 5.77 KB
/
Copy pathclose-invalid-pr-writer.yml
File metadata and controls
148 lines (131 loc) · 5.77 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
name: Close invalid PR writer
on:
workflow_run:
workflows: [Close issue/PR on adding invalid label]
types: [completed]
# pull_request does not run for conflicted PRs, so reconcile from the trusted default branch.
schedule:
- cron: '*/5 * * * *'
workflow_dispatch:
permissions: {}
jobs:
close-invalid-pr-from-workflow-run:
if: >
github.repository == 'github/copilot-cli' &&
github.event_name == 'workflow_run' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.repository.full_name == github.repository
runs-on: ubuntu-latest
permissions:
actions: read
pull-requests: write
concurrency:
group: close-invalid-pr-${{ github.event.workflow_run.pull_requests[0].number || github.run_id }}
cancel-in-progress: false
steps:
- name: Close invalid PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
run: |
set -euo pipefail
trusted_workflow_id="$(gh api "repos/$GH_REPO/actions/workflows/close-invalid.yml" --jq .id)"
workflow_run="$(gh api "repos/$GH_REPO/actions/runs/$WORKFLOW_RUN_ID")"
if [ "$(jq -r .workflow_id <<<"$workflow_run")" != "$trusted_workflow_id" ] ||
[ "$(jq -r .event <<<"$workflow_run")" != "pull_request" ] ||
[ "$(jq -r .repository.full_name <<<"$workflow_run")" != "$GH_REPO" ]; then
echo "Workflow run is not a trusted pull_request run from $GH_REPO; skipping."
exit 0
fi
run_head_sha="$(jq -r .head_sha <<<"$workflow_run")"
run_head_repo="$(jq -r '.head_repository.full_name // empty' <<<"$workflow_run")"
run_head_branch="$(jq -r '.head_branch // empty' <<<"$workflow_run")"
if [ -z "$run_head_repo" ] ||
[ -z "$run_head_branch" ] ||
[[ ! "$run_head_sha" =~ ^[0-9a-f]{40}$ ]] ||
[ "${run_head_repo#*/}" = "$run_head_repo" ] ||
[ -z "${run_head_repo%%/*}" ] ||
[ -z "${run_head_repo#*/}" ]; then
echo "Workflow run is missing valid head repository, branch, or SHA metadata; skipping."
exit 0
fi
pull_request_count="$(jq '.pull_requests | length' <<<"$workflow_run")"
if [ "$pull_request_count" -eq 1 ]; then
pr_number="$(jq -r .pull_requests[0].number <<<"$workflow_run")"
elif [ "$pull_request_count" -eq 0 ]; then
run_head_owner="${run_head_repo%%/*}"
matching_prs="$(
gh api --method GET --paginate "repos/$GH_REPO/pulls" \
-f state=open \
-f head="$run_head_owner:$run_head_branch" \
-f per_page=100 |
jq -cs \
--arg repo "$GH_REPO" \
--arg head_repo "$run_head_repo" \
--arg head_branch "$run_head_branch" \
--arg head_sha "$run_head_sha" \
'add | [
.[] |
select(
.state == "open" and
.base.repo.full_name == $repo and
.head.repo.full_name == $head_repo and
.head.ref == $head_branch and
.head.sha == $head_sha
)
]'
)"
if [ "$(jq 'length' <<<"$matching_prs")" -ne 1 ]; then
echo "Workflow run could not be uniquely associated with an open PR; skipping."
exit 0
fi
pr_number="$(jq -r '.[0].number' <<<"$matching_prs")"
else
echo "Workflow run is associated with multiple PRs; skipping."
exit 0
fi
if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]]; then
echo "Workflow run produced an invalid PR number; skipping."
exit 0
fi
pr="$(gh api "repos/$GH_REPO/pulls/$pr_number")"
if [ "$(jq -r .base.repo.full_name <<<"$pr")" != "$GH_REPO" ] ||
[ "$(jq -r '.head.repo.full_name // empty' <<<"$pr")" != "$run_head_repo" ] ||
[ "$(jq -r .head.ref <<<"$pr")" != "$run_head_branch" ] ||
[ "$(jq -r .head.sha <<<"$pr")" != "$run_head_sha" ]; then
echo "PR #$pr_number no longer matches the workflow run head; skipping."
exit 0
fi
if [ "$(jq -r .state <<<"$pr")" != "open" ] ||
! jq -e 'any(.labels[]?; .name == "invalid")' >/dev/null <<<"$pr"; then
echo "PR #$pr_number is not open with the invalid label; skipping."
exit 0
fi
gh api -X PATCH "repos/$GH_REPO/pulls/$pr_number" -f state=closed
reconcile-invalid-prs:
if: >
github.repository == 'github/copilot-cli' &&
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-latest
permissions:
pull-requests: write
concurrency:
group: close-invalid-pr-reconciliation
cancel-in-progress: false
steps:
- name: Close open PRs with the invalid label
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
gh api --paginate "repos/$GH_REPO/pulls?state=open&per_page=100" \
--jq '.[] | select(any(.labels[]?; .name == "invalid")) | .number' |
while read -r pr_number; do
pr="$(gh api "repos/$GH_REPO/pulls/$pr_number")"
if [ "$(jq -r .state <<<"$pr")" = "open" ] &&
jq -e 'any(.labels[]?; .name == "invalid")' >/dev/null <<<"$pr"; then
gh api -X PATCH "repos/$GH_REPO/pulls/$pr_number" -f state=closed
fi
done