mirror of
https://github.com/github/awesome-copilot.git
synced 2026-08-14 21:26:54 +00:00
169 lines
7.5 KiB
YAML
169 lines
7.5 KiB
YAML
name: Label PR Intent Writer
|
|
|
|
on:
|
|
workflow_run:
|
|
workflows: ["Label PR Intent"]
|
|
types: [completed]
|
|
|
|
permissions:
|
|
actions: read
|
|
issues: write
|
|
pull-requests: read
|
|
|
|
concurrency:
|
|
group: lpiw-${{ github.event.workflow_run.head_repository.id || 'unknown-repo' }}-${{ github.event.workflow_run.head_branch || 'unknown-branch' }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
apply-labels:
|
|
runs-on: ubuntu-latest
|
|
if: github.event.workflow_run.event == 'pull_request'
|
|
steps:
|
|
- name: Download desired label artifact
|
|
id: download-result
|
|
continue-on-error: true
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: label-pr-intent-result
|
|
path: ${{ runner.temp }}/label-pr-intent-result
|
|
run-id: ${{ github.event.workflow_run.id }}
|
|
github-token: ${{ github.token }}
|
|
|
|
- name: Apply intent labels
|
|
if: steps.download-result.outcome == 'success'
|
|
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const workflowRun = context.payload.workflow_run;
|
|
const resultPath = path.join(process.env.RUNNER_TEMP, 'label-pr-intent-result', 'result.json');
|
|
const result = JSON.parse(fs.readFileSync(resultPath, 'utf8'));
|
|
const managedLabels = new Set([
|
|
'skills',
|
|
'plugin',
|
|
'agent',
|
|
'instructions',
|
|
'new-submission',
|
|
'website-update',
|
|
'external-plugin',
|
|
'hooks',
|
|
'workflow',
|
|
'canvas-extension',
|
|
]);
|
|
|
|
function fail(message) {
|
|
throw new Error(`Invalid label intent artifact: ${message}`);
|
|
}
|
|
|
|
if (result.schema_version !== 'label-pr-intent-result/v1') fail('unexpected schema_version');
|
|
if (result.event !== 'pull_request') fail('unexpected event');
|
|
if (!Number.isInteger(result.pr_number) || result.pr_number < 1) fail('invalid pr_number');
|
|
if (!/^[0-9a-f]{40}$/i.test(String(result.head_sha || ''))) fail('invalid head_sha');
|
|
if (workflowRun.event !== 'pull_request') fail('unexpected workflow_run event');
|
|
if (String(result.run_id || '') !== String(workflowRun.id)) fail('run_id did not match workflow_run');
|
|
if (result.head_sha !== workflowRun.head_sha) fail('head_sha did not match workflow_run');
|
|
if (!Array.isArray(result.desired_labels) || result.desired_labels.length > managedLabels.size) fail('invalid desired_labels');
|
|
if (!Array.isArray(result.managed_labels)) fail('invalid managed_labels');
|
|
for (const label of result.managed_labels) {
|
|
if (!managedLabels.has(label)) fail(`unexpected managed label ${label}`);
|
|
}
|
|
for (const label of result.desired_labels) {
|
|
if (!managedLabels.has(label)) fail(`unexpected desired label ${label}`);
|
|
}
|
|
|
|
const { data: pr } = await github.rest.pulls.get({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: result.pr_number,
|
|
});
|
|
if (pr.state !== 'open') {
|
|
core.info(`Skipping non-open PR #${result.pr_number}.`);
|
|
return;
|
|
}
|
|
const expectedBaseRepository = `${context.repo.owner}/${context.repo.repo}`.toLowerCase();
|
|
const runHeadRepository = String(workflowRun.head_repository?.full_name || '');
|
|
const runHeadRepositoryParts = runHeadRepository.split('/');
|
|
const runHeadRef = String(workflowRun.head_branch || '');
|
|
if (String(pr.base?.repo?.full_name || '').toLowerCase() !== expectedBaseRepository) {
|
|
fail(`PR #${result.pr_number} does not target this repository`);
|
|
}
|
|
if (pr.head.sha !== workflowRun.head_sha) {
|
|
core.warning(`Skipping stale label intent result for PR #${result.pr_number}: artifact head ${result.head_sha}, current head ${pr.head.sha}`);
|
|
return;
|
|
}
|
|
if (
|
|
runHeadRepositoryParts.length !== 2 ||
|
|
!runHeadRepositoryParts[0] ||
|
|
!runHeadRepositoryParts[1] ||
|
|
!runHeadRef ||
|
|
String(pr.head?.repo?.full_name || '').toLowerCase() !== runHeadRepository.toLowerCase() ||
|
|
String(pr.head?.ref || '') !== runHeadRef
|
|
) {
|
|
fail(`PR #${result.pr_number} head did not match workflow_run`);
|
|
}
|
|
|
|
const workflowRunPullRequests = Array.isArray(workflowRun.pull_requests) ? workflowRun.pull_requests : [];
|
|
if (workflowRunPullRequests.length > 0) {
|
|
if (!workflowRunPullRequests.some((pullRequest) => pullRequest.number === result.pr_number)) {
|
|
fail(`PR #${result.pr_number} was not present in workflow_run.pull_requests`);
|
|
}
|
|
} else {
|
|
const candidatePullRequests = await github.paginate(github.rest.pulls.list, {
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
state: 'open',
|
|
head: `${runHeadRepositoryParts[0]}:${runHeadRef}`,
|
|
per_page: 100,
|
|
});
|
|
const trustedMatches = candidatePullRequests.filter((candidate) =>
|
|
candidate.head?.sha === workflowRun.head_sha &&
|
|
String(candidate.head?.ref || '') === runHeadRef &&
|
|
String(candidate.head?.repo?.full_name || '').toLowerCase() === runHeadRepository.toLowerCase() &&
|
|
String(candidate.base?.repo?.full_name || '').toLowerCase() === expectedBaseRepository
|
|
);
|
|
if (trustedMatches.length !== 1 || trustedMatches[0].number !== result.pr_number) {
|
|
fail(`PR #${result.pr_number} could not be uniquely associated with workflow_run`);
|
|
}
|
|
}
|
|
|
|
const desiredLabels = new Set(result.desired_labels);
|
|
const currentLabels = await github.paginate(github.rest.issues.listLabelsOnIssue, {
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: result.pr_number,
|
|
per_page: 100,
|
|
});
|
|
|
|
const currentManagedLabels = currentLabels
|
|
.map((label) => label.name)
|
|
.filter((name) => managedLabels.has(name));
|
|
|
|
const labelsToAdd = [...desiredLabels].filter((name) => !currentManagedLabels.includes(name));
|
|
const labelsToRemove = currentManagedLabels.filter((name) => !desiredLabels.has(name));
|
|
|
|
if (labelsToAdd.length > 0) {
|
|
await github.rest.issues.addLabels({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: result.pr_number,
|
|
labels: labelsToAdd,
|
|
});
|
|
}
|
|
|
|
for (const name of labelsToRemove) {
|
|
await github.rest.issues.removeLabel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: result.pr_number,
|
|
name,
|
|
});
|
|
}
|
|
|
|
core.info(`Managed labels: ${[...desiredLabels].sort().join(', ') || 'none'}`);
|
|
|
|
- name: Note missing artifact
|
|
if: steps.download-result.outcome != 'success'
|
|
run: echo "No label-pr-intent-result artifact was available; nothing to synchronize."
|