Files
SpacetimeDB/.github/workflows/pr_approval_check.yml
T
Zeke Foppa 4d7db102fc CI - PR approval check skips for external PRs (properly this time) (#4611)
# Description of Changes

https://github.com/clockworklabs/SpacetimeDB/pull/4604 skipped the check
run for external PRs, but because it needs to post a separate commit
status (see https://github.com/clockworklabs/SpacetimeDB/pull/4578),
this was not the right solution. We need to _run_ the check but
trivially post a success on external PRs. Sigh.

# API and ABI breaking changes

None.

# Expected complexity level and risk

1

# Testing

I don't know how to test github workflows.

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-11 17:08:19 +00:00

110 lines
3.8 KiB
YAML

name: Review Checks
on:
pull_request:
types: [opened, synchronize, reopened]
pull_request_review:
types: [submitted, dismissed]
merge_group:
permissions:
contents: read
pull-requests: read
statuses: write
concurrency:
group: pr-approval-check-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
publish-approval-status:
name: Set approval status
runs-on: ubuntu-latest
steps:
- name: Evaluate and publish approval status
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const contextName = "PR approval check";
let targetSha;
let state;
let description;
if (context.eventName === "merge_group") {
targetSha = process.env.GITHUB_SHA;
state = "success";
description = "Merge group entry; approvals already satisfied";
} else {
const pr = context.payload.pull_request;
targetSha = pr.head.sha;
if (pr.head.repo.fork) {
state = "success";
description = "Skipped for external PR";
} else if (pr.user.login !== "clockwork-labs-bot") {
state = "success";
description = "PR author is not clockwork-labs-bot";
} else {
const result = await github.graphql(
`
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $number) {
latestOpinionatedReviews(first: 100, writersOnly: true) {
nodes {
state
author {
login
}
}
}
}
}
}
`,
{
owner: context.repo.owner,
repo: context.repo.repo,
number: pr.number,
}
);
const effectiveApprovers =
result.repository.pullRequest.latestOpinionatedReviews.nodes
.filter((review) => review.state === "APPROVED")
.map((review) => review.author?.login)
.filter(Boolean);
core.info(
`Latest effective approvers (${effectiveApprovers.length}): ${effectiveApprovers.join(", ")}`
);
if (effectiveApprovers.length < 2) {
state = "failure";
description = "PRs from clockwork-labs-bot require at least 2 approvals";
} else {
state = "success";
description = "PR has the required number of approvals";
}
}
}
core.info(`Publishing status ${state} for ${targetSha}: ${description}`);
// We need to set a separate commit status for this, because it runs on both
// pull_request and pull_request_review events. If we don't set an explicit context,
// what happens is that there are sometimes two separate statuses on the same commit -
// one from each event type. This leads to weird cases where one copy of the check is failed,
// and the other is successful, and the failed one blocks the PR from merging.
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: targetSha,
state,
context: contextName,
description,
});