@@ -13,16 +13,13 @@ name: companion-pr-check
1313# surfaces the declared link but reports "couldn't verify".
1414
1515on :
16+ # PR-driven only: runs on the one PR being opened/edited/synced — no periodic
17+ # bulk scan. We assume companions are declared on BOTH sides, so the per-PR
18+ # trigger keeps each side's status fresh; to refresh after a companion merges,
19+ # re-edit the PR (or run this workflow manually via the Actions tab).
1620 pull_request :
1721 types : [opened, edited, reopened, synchronize]
1822 branches : [staging, main]
19- schedule :
20- # Refresh open staging/main PRs in case the companion merges AFTER this PR was
21- # opened. CAVEAT: GitHub runs scheduled workflows ONLY from the DEFAULT branch's
22- # copy of this file — so this auto-refresh activates once the workflow lands on
23- # the default branch (via the normal promotion), not before. The pull_request
24- # triggers below always work; re-editing the PR re-runs the check meanwhile.
25- - cron : ' */30 * * * *'
2623 workflow_dispatch : {}
2724
2825permissions :
@@ -114,16 +111,16 @@ jobs:
114111 const ex = await findSticky(prNumber);
115112 if (ex) await github.rest.issues.deleteComment({ owner, repo, comment_id: ex.id });
116113 // Drop the label too, so a PR edited to remove all companions doesn't
117- // keep a stale badge. 404 if not present → ignore.
118- try { await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: LABEL }); } catch {}
114+ // keep a stale badge. 404 (not present) is expected; surface anything else.
115+ try { await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: LABEL }); }
116+ catch (e) { if (e.status !== 404) core.warning(`companion: removeLabel ${LABEL} on #${prNumber} failed (${e.status || e.message})`); }
119117 }
120118 async function ensureLabel() {
121- try { await github.rest.issues.getLabel({ owner, repo, name: LABEL }); }
122- catch {
123- try {
124- await github.rest.issues.createLabel({ owner, repo, name: LABEL, color: 'd93f0b', description: LABEL_DESC });
125- } catch {}
126- }
119+ try { await github.rest.issues.getLabel({ owner, repo, name: LABEL }); return; }
120+ catch (e) { if (e.status && e.status !== 404) { core.warning(`companion: getLabel ${LABEL} failed (${e.status})`); return; } }
121+ // 404 → label doesn't exist yet, create it. 422 = another run beat us (fine).
122+ try { await github.rest.issues.createLabel({ owner, repo, name: LABEL, color: 'd93f0b', description: LABEL_DESC }); }
123+ catch (e) { if (e.status !== 422) core.warning(`companion: createLabel ${LABEL} failed (${e.status || e.message})`); }
127124 }
128125
129126 // staging PRs are a single feature → just this PR's body ("the one").
@@ -165,7 +162,8 @@ jobs:
165162 const companions = await collectCompanions(pr);
166163 if (companions.length === 0) { await clear(pr.number); return; }
167164 await ensureLabel();
168- try { await github.rest.issues.addLabels({ owner, repo, issue_number: pr.number, labels: [LABEL] }); } catch {}
165+ try { await github.rest.issues.addLabels({ owner, repo, issue_number: pr.number, labels: [LABEL] }); }
166+ catch (e) { core.warning(`companion: addLabels ${LABEL} on #${pr.number} failed (${e.status || e.message})`); }
169167
170168 const base = pr.base.ref;
171169 const lines = [];
@@ -203,6 +201,7 @@ jobs:
203201 if (context.eventName === 'pull_request') {
204202 await checkPR(context.payload.pull_request);
205203 } else {
204+ // workflow_dispatch only: manual full re-scan of open staging/main PRs.
206205 for (const b of ['staging', 'main']) {
207206 const prs = await github.paginate(github.rest.pulls.list, { owner, repo, base: b, state: 'open', per_page: 100 });
208207 for (const pr of prs) await checkPR(pr);
0 commit comments