Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 48 additions & 11 deletions .github/workflows/pr-size-label-apply.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,56 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}

- name: Read PR number and size label
id: read
run: |
PR_NUMBER=$(cat pr-size/pr-number.txt)
SIZE_LABEL=$(cat pr-size/label.txt | tr -d '"')
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "size_label=$SIZE_LABEL" >> $GITHUB_OUTPUT
echo "PR #$PR_NUMBER should get label: $SIZE_LABEL"
# The artifact is produced by a `pull_request` workflow, so its contents
# come from the pull request author — including authors from forks. This
# job runs in the base repository with `pull-requests: write`, so the
# artifact is treated as untrusted input: the label must be one we
# recognise, and the pull request number is derived from this job's own
# trigger event rather than read from the artifact.
- name: Resolve pull request and validate label
id: resolve
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const fs = require('fs');
const run = context.payload.workflow_run;

const ALLOWED = ['size/XS', 'size/S', 'size/M', 'size/L', 'size/XL'];
const label = fs.readFileSync('pr-size/label.txt', 'utf8').trim().replace(/^"|"$/g, '');
if (!ALLOWED.includes(label)) {
core.setFailed(`Refusing to apply unrecognised label ${JSON.stringify(label)}`);
return;
}

// workflow_run.pull_requests is empty for pull requests from forks,
// and frequently empty for same-repository ones too, so treat it as
// a fast path and fall back to looking the head commit up.
let number = run.pull_requests?.[0]?.number;
if (!number) {
const { data: associated } =
await github.rest.repos.listPullRequestsAssociatedWithCommit({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: run.head_sha,
});
const open = associated.filter((pr) => pr.state === 'open');
if (open.length !== 1) {
core.setFailed(
`Expected exactly one open pull request for ${run.head_sha}, found ${open.length}`
);
return;
}
number = open[0].number;
}

console.log(`PR #${number} should get label: ${label}`);
core.setOutput('pr_number', String(number));
core.setOutput('size_label', label);

- name: Remove old size labels
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
PR_NUMBER: ${{ steps.read.outputs.pr_number }}
PR_NUMBER: ${{ steps.resolve.outputs.pr_number }}
with:
script: |
const prNumber = parseInt(process.env.PR_NUMBER);
Expand All @@ -62,8 +99,8 @@ jobs:
- name: Add new size label
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
PR_NUMBER: ${{ steps.read.outputs.pr_number }}
SIZE_LABEL: ${{ steps.read.outputs.size_label }}
PR_NUMBER: ${{ steps.resolve.outputs.pr_number }}
SIZE_LABEL: ${{ steps.resolve.outputs.size_label }}
with:
script: |
const prNumber = parseInt(process.env.PR_NUMBER);
Expand Down
17 changes: 15 additions & 2 deletions .github/workflows/pr-size-labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,24 @@ jobs:
console.log(`PR size: ${total} lines -> ${sizeLabel}`);
return sizeLabel;

# This workflow runs on `pull_request`, so a pull request — including one
# from a fork — supplies the definition that produces these files.
# Nothing in them can be trusted to say which pull request to act on, so
# the consumer derives the number from its own trigger event instead.
#
# pr-number.txt is still written even though the new consumer ignores it.
# `workflow_run` consumers always execute the copy on the default branch,
# so until this change merges the consumer reading it is the old one, and
# dropping the file here would break labelling for every open pull
# request. Removing the write is a follow-up once this has landed.
- name: Save size label to artifact
env:
SIZE_LABEL: ${{ steps.size.outputs.result }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
mkdir -p pr-size
echo "${{ steps.size.outputs.result }}" > pr-size/label.txt
echo "${{ github.event.pull_request.number }}" > pr-size/pr-number.txt
echo "$SIZE_LABEL" > pr-size/label.txt
echo "$PR_NUMBER" > pr-size/pr-number.txt

- name: Upload artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
Expand Down
Loading