mirror of
https://github.com/VibedByKaKi/t3-code-android-nightly.git
synced 2026-10-09 20:01:15 +02:00
199 lines
6.3 KiB
YAML
199 lines
6.3 KiB
YAML
name: PR Vouch
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, reopened, synchronize, ready_for_review, converted_to_draft]
|
|
issue_comment:
|
|
types: [created]
|
|
push:
|
|
branches:
|
|
- main
|
|
paths:
|
|
- .github/VOUCHED.td
|
|
- .github/workflows/pr-vouch.yml
|
|
|
|
permissions:
|
|
contents: read
|
|
issues: write
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
collect-targets:
|
|
name: Collect PR targets
|
|
runs-on: ubuntu-24.04
|
|
outputs:
|
|
targets: ${{ steps.collect.outputs.targets }}
|
|
steps:
|
|
- id: collect
|
|
uses: actions/github-script@v8
|
|
with:
|
|
script: |
|
|
if (context.eventName === "pull_request_target") {
|
|
const pr = context.payload.pull_request;
|
|
core.setOutput("targets", JSON.stringify([{ number: pr.number, user: pr.user.login }]));
|
|
return;
|
|
}
|
|
|
|
if (context.eventName === "issue_comment") {
|
|
const issue = context.payload.issue;
|
|
const body = context.payload.comment?.body ?? "";
|
|
if (!issue?.pull_request || !body.includes("/recheck-vouch")) {
|
|
core.setOutput("targets", "[]");
|
|
return;
|
|
}
|
|
|
|
core.setOutput(
|
|
"targets",
|
|
JSON.stringify([{ number: issue.number, user: issue.user.login }]),
|
|
);
|
|
return;
|
|
}
|
|
|
|
const pulls = await github.paginate(github.rest.pulls.list, {
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
state: "open",
|
|
per_page: 100,
|
|
});
|
|
|
|
const targets = pulls.map((pull) => ({
|
|
number: pull.number,
|
|
user: pull.user.login,
|
|
}));
|
|
core.setOutput("targets", JSON.stringify(targets));
|
|
|
|
label:
|
|
name: Label PR ${{ matrix.target.number }}
|
|
needs: collect-targets
|
|
if: ${{ needs.collect-targets.outputs.targets != '[]' }}
|
|
runs-on: ubuntu-24.04
|
|
concurrency:
|
|
group: pr-vouch-${{ matrix.target.number }}
|
|
cancel-in-progress: true
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
target: ${{ fromJson(needs.collect-targets.outputs.targets) }}
|
|
steps:
|
|
- id: vouch
|
|
name: Check PR author trust
|
|
uses: mitchellh/vouch/action/check-user@v1
|
|
with:
|
|
user: ${{ matrix.target.user }}
|
|
allow-fail: true
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Sync PR labels
|
|
uses: actions/github-script@v8
|
|
env:
|
|
PR_NUMBER: ${{ matrix.target.number }}
|
|
VOUCH_STATUS: ${{ steps.vouch.outputs.status }}
|
|
with:
|
|
script: |
|
|
const issueNumber = Number(process.env.PR_NUMBER);
|
|
const status = process.env.VOUCH_STATUS;
|
|
const managedLabels = [
|
|
{
|
|
name: "vouch:trusted",
|
|
color: "1f883d",
|
|
description: "PR author is trusted by repo permissions or the VOUCHED list.",
|
|
},
|
|
{
|
|
name: "vouch:unvouched",
|
|
color: "fbca04",
|
|
description: "PR author is not yet trusted in the VOUCHED list.",
|
|
},
|
|
{
|
|
name: "vouch:denounced",
|
|
color: "d1242f",
|
|
description: "PR author is explicitly blocked by the VOUCHED list.",
|
|
},
|
|
];
|
|
|
|
const managedLabelNames = new Set(managedLabels.map((label) => label.name));
|
|
|
|
for (const label of managedLabels) {
|
|
try {
|
|
const { data: existing } = await github.rest.issues.getLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
name: label.name,
|
|
});
|
|
|
|
if (
|
|
existing.color !== label.color ||
|
|
(existing.description ?? "") !== label.description
|
|
) {
|
|
await github.rest.issues.updateLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
name: label.name,
|
|
color: label.color,
|
|
description: label.description,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
if (error.status !== 404) {
|
|
throw error;
|
|
}
|
|
|
|
try {
|
|
await github.rest.issues.createLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
name: label.name,
|
|
color: label.color,
|
|
description: label.description,
|
|
});
|
|
} catch (createError) {
|
|
if (createError.status !== 422) {
|
|
throw createError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const nextLabelName =
|
|
status === "denounced"
|
|
? "vouch:denounced"
|
|
: ["bot", "collaborator", "vouched"].includes(status)
|
|
? "vouch:trusted"
|
|
: "vouch:unvouched";
|
|
|
|
const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: issueNumber,
|
|
per_page: 100,
|
|
});
|
|
|
|
for (const label of currentLabels) {
|
|
if (!managedLabelNames.has(label.name) || label.name === nextLabelName) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
await github.rest.issues.removeLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: issueNumber,
|
|
name: label.name,
|
|
});
|
|
} catch (removeError) {
|
|
if (removeError.status !== 404) {
|
|
throw removeError;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!currentLabels.some((label) => label.name === nextLabelName)) {
|
|
await github.rest.issues.addLabels({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: issueNumber,
|
|
labels: [nextLabelName],
|
|
});
|
|
}
|
|
|
|
core.info(`PR #${issueNumber}: ${status} -> ${nextLabelName}`);
|