mirror of
https://github.com/lunchcat/sif.git
synced 2026-07-03 19:34:53 -07:00
78a2ec364f
fork PRs get a read-only token on pull_request, so the label, size and ci-summary jobs 403 and the summary check shows red on every external PR. run on pull_request_target (write token, base-repo context), key the concurrency group on the PR number so runs don't collide, and drop the size job's unused checkout. none of these jobs check out or run PR code, they only call the github API with the event payload, so this is the safe labeler pattern. supersedes #146 (same fix by @TBX3D, which conflicted after the checkout bump in #143).
139 lines
4.7 KiB
YAML
139 lines
4.7 KiB
YAML
name: pr bot
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, synchronize, reopened, edited]
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-pr-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
label:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/labeler@v6
|
|
with:
|
|
configuration-path: .github/labeler.yml
|
|
|
|
size:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: label pr size
|
|
uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
const { data: files } = await github.rest.pulls.listFiles({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number,
|
|
per_page: 100,
|
|
});
|
|
|
|
const changes = files.reduce((sum, f) => sum + f.additions + f.deletions, 0);
|
|
|
|
let size;
|
|
if (changes < 10) size = "size/xs";
|
|
else if (changes < 50) size = "size/s";
|
|
else if (changes < 200) size = "size/m";
|
|
else if (changes < 500) size = "size/l";
|
|
else size = "size/xl";
|
|
|
|
const sizeLabels = ["size/xs", "size/s", "size/m", "size/l", "size/xl"];
|
|
const currentLabels = context.payload.pull_request.labels.map(l => l.name);
|
|
const toRemove = currentLabels.filter(l => sizeLabels.includes(l) && l !== size);
|
|
|
|
for (const label of toRemove) {
|
|
await github.rest.issues.removeLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.payload.pull_request.number,
|
|
name: label,
|
|
}).catch(() => {});
|
|
}
|
|
|
|
await github.rest.issues.addLabels({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.payload.pull_request.number,
|
|
labels: [size],
|
|
});
|
|
|
|
ci-summary:
|
|
runs-on: ubuntu-latest
|
|
needs: [label, size]
|
|
if: always()
|
|
steps:
|
|
- uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
const pr = context.payload.pull_request;
|
|
const { data: checks } = await github.rest.checks.listForRef({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
ref: pr.head.sha,
|
|
per_page: 100,
|
|
});
|
|
|
|
const { data: files } = await github.rest.pulls.listFiles({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: pr.number,
|
|
per_page: 100,
|
|
});
|
|
|
|
const additions = files.reduce((sum, f) => sum + f.additions, 0);
|
|
const deletions = files.reduce((sum, f) => sum + f.deletions, 0);
|
|
const fileCount = files.length;
|
|
|
|
let body = `### pr summary\n\n`;
|
|
body += `**${fileCount}** files changed (+${additions} -${deletions})\n\n`;
|
|
|
|
const goFiles = files.filter(f => f.filename.endsWith('.go')).length;
|
|
const testFiles = files.filter(f => f.filename.endsWith('_test.go')).length;
|
|
const ciFiles = files.filter(f => f.filename.startsWith('.github/')).length;
|
|
const modFiles = files.filter(f => f.filename === 'go.mod' || f.filename === 'go.sum').length;
|
|
|
|
if (goFiles > 0 || testFiles > 0 || ciFiles > 0 || modFiles > 0) {
|
|
body += `| category | files |\n|----------|-------|\n`;
|
|
if (goFiles > 0) body += `| go source | ${goFiles} |\n`;
|
|
if (testFiles > 0) body += `| tests | ${testFiles} |\n`;
|
|
if (ciFiles > 0) body += `| ci/workflows | ${ciFiles} |\n`;
|
|
if (modFiles > 0) body += `| deps | ${modFiles} |\n`;
|
|
body += `\n`;
|
|
}
|
|
|
|
// find existing bot comment
|
|
const { data: comments } = await github.rest.issues.listComments({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: pr.number,
|
|
});
|
|
|
|
const marker = '<!-- sif-pr-bot -->';
|
|
body = marker + '\n' + body;
|
|
|
|
const existing = comments.find(c =>
|
|
c.user.type === 'Bot' && c.body.includes(marker)
|
|
);
|
|
|
|
if (existing) {
|
|
await github.rest.issues.updateComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
comment_id: existing.id,
|
|
body,
|
|
});
|
|
} else {
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: pr.number,
|
|
body,
|
|
});
|
|
}
|