Skip to content

Commit 119534b

Browse files
committed
refactor: use github-script for external labels
1 parent fbf4dd4 commit 119534b

1 file changed

Lines changed: 79 additions & 84 deletions

File tree

‎.github/workflows/label-external-contributions.yml‎

Lines changed: 79 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -30,98 +30,93 @@ jobs:
3030
permission-members: read
3131

3232
- name: Label external contributions
33+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
3334
env:
34-
API_URL: ${{ github.api_url }}
35-
GH_TOKEN: ${{ github.token }}
3635
MEMBERS_TOKEN: ${{ steps.membership-token.outputs.token }}
37-
ORG: ${{ github.repository_owner }}
38-
REPO: ${{ github.repository }}
39-
run: |
40-
set -euo pipefail
36+
with:
37+
github-token: ${{ github.token }}
38+
retries: 3
39+
script: |
40+
const label = "external-contribution";
41+
const { owner, repo } = context.repo;
42+
const fullRepo = `${owner}/${repo}`;
43+
const since = new Date(Date.now() - 60 * 60 * 1000).toISOString();
44+
const membershipGithub = getOctokit(process.env.MEMBERS_TOKEN);
45+
let membershipCheckFailed = false;
4146
42-
label="external-contribution"
43-
membership_check_failed=false
44-
updated_cutoff=$(date -u -d "1 hour ago" "+%Y-%m-%dT%H:%M:%SZ")
47+
const issues = await github.paginate("GET /repos/{owner}/{repo}/issues", {
48+
owner,
49+
repo,
50+
state: "open",
51+
since,
52+
sort: "updated",
53+
direction: "desc",
54+
per_page: 100,
55+
});
4556
46-
while IFS= read -r pr_number; do
47-
if [[ ! "$pr_number" =~ ^[1-9][0-9]*$ ]]; then
48-
echo "Skipping malformed pull request number."
49-
continue
50-
fi
57+
for (const issue of issues) {
58+
if (!issue.pull_request) {
59+
continue;
60+
}
5161
52-
pr_json=$(gh api "repos/$REPO/pulls/$pr_number")
53-
if ! jq -e \
54-
--arg repo "$REPO" \
55-
--arg label "$label" \
56-
'.state == "open" and
57-
.draft == false and
58-
.base.repo.full_name == $repo and
59-
(.head.repo.full_name | type == "string") and
60-
.head.repo.full_name != $repo and
61-
.user.type == "User" and
62-
(.user.login | type == "string" and length > 0) and
63-
(any(.labels[]?; .name == $label) | not)' \
64-
>/dev/null <<<"$pr_json"; then
65-
continue
66-
fi
62+
const { data: pull } = await github.request(
63+
"GET /repos/{owner}/{repo}/pulls/{pull_number}",
64+
{ owner, repo, pull_number: issue.number },
65+
);
6766
68-
author=$(jq -r '.user.login' <<<"$pr_json")
69-
events=$(gh api --paginate \
70-
"repos/$REPO/issues/$pr_number/events?per_page=100" |
71-
jq -cs 'add')
67+
if (
68+
pull.state !== "open" ||
69+
pull.draft ||
70+
pull.base.repo.full_name !== fullRepo ||
71+
!pull.head.repo?.full_name ||
72+
pull.head.repo.full_name === fullRepo ||
73+
pull.user?.type !== "User" ||
74+
!pull.user.login ||
75+
pull.labels.some(({ name }) => name === label)
76+
) {
77+
continue;
78+
}
7279
73-
if jq -e --arg label "$label" \
74-
'any(.[]; .event == "labeled" and .label.name == $label)' \
75-
>/dev/null <<<"$events"; then
76-
continue
77-
fi
80+
const events = await github.paginate(
81+
"GET /repos/{owner}/{repo}/issues/{issue_number}/events",
82+
{ owner, repo, issue_number: issue.number, per_page: 100 },
83+
);
7884
79-
if ! membership_status=$(curl \
80-
--silent \
81-
--show-error \
82-
--output /dev/null \
83-
--write-out '%{http_code}' \
84-
--connect-timeout 10 \
85-
--max-time 30 \
86-
--header "Accept: application/vnd.github+json" \
87-
--header "Authorization: Bearer $MEMBERS_TOKEN" \
88-
--header "X-GitHub-Api-Version: 2022-11-28" \
89-
"$API_URL/orgs/$ORG/members/$author"); then
90-
echo "::error::Membership check failed for pull request #$pr_number; skipping."
91-
membership_check_failed=true
92-
continue
93-
fi
85+
if (
86+
events.some(
87+
(event) =>
88+
event.event === "labeled" && event.label?.name === label,
89+
)
90+
) {
91+
continue;
92+
}
9493
95-
case "$membership_status" in
96-
204)
97-
echo "Pull request #$pr_number was opened by an organization member; skipping."
98-
continue
99-
;;
100-
404)
101-
;;
102-
*)
103-
echo "::error::Membership check for pull request #$pr_number returned HTTP $membership_status; skipping."
104-
membership_check_failed=true
105-
continue
106-
;;
107-
esac
94+
try {
95+
await membershipGithub.request(
96+
"GET /orgs/{org}/members/{username}",
97+
{ org: owner, username: pull.user.login },
98+
);
99+
core.info(
100+
`Pull request #${issue.number} was opened by an organization member; skipping.`,
101+
);
102+
continue;
103+
} catch (error) {
104+
if (error.status !== 404) {
105+
core.error(
106+
`Membership check failed for pull request #${issue.number}: ${error.message}`,
107+
);
108+
membershipCheckFailed = true;
109+
continue;
110+
}
111+
}
108112
109-
jq -n --arg label "$label" '{labels: [$label]}' |
110-
gh api --method POST \
111-
"repos/$REPO/issues/$pr_number/labels" \
112-
--input - \
113-
>/dev/null
114-
echo "Labelled pull request #$pr_number."
115-
done < <(
116-
gh api --method GET --paginate "repos/$REPO/issues" \
117-
-f state=open \
118-
-f since="$updated_cutoff" \
119-
-f sort=updated \
120-
-f direction=desc \
121-
-f per_page=100 |
122-
jq -r '.[] | select(.pull_request != null) | .number'
123-
)
113+
await github.request(
114+
"POST /repos/{owner}/{repo}/issues/{issue_number}/labels",
115+
{ owner, repo, issue_number: issue.number, labels: [label] },
116+
);
117+
core.info(`Labelled pull request #${issue.number}.`);
118+
}
124119
125-
if [ "$membership_check_failed" = true ]; then
126-
exit 1
127-
fi
120+
if (membershipCheckFailed) {
121+
core.setFailed("One or more organization membership checks failed.");
122+
}

0 commit comments

Comments
 (0)