From adaeb324ccc5035627cd8a0711274fa406babaaf Mon Sep 17 00:00:00 2001 From: Jarred Stelfox Date: Sat, 10 Oct 2026 21:47:55 -0700 Subject: [PATCH] Repair script: skip deleted issues and shared new names The dry run on dev stopped at ifixit#34336: GitHub answers 410 for a deleted issue, not 404, so the guard let it through and the script crashed. It also mapped both FoF and squad-carpenter to carpenter in ifixit: their PRs carry both old labels, so carpenter is new on every one of them for either label. Two old labels with one new name are now listed and left alone. Co-Authored-By: Claude Opus 5.5 --- bin/repair-renamed-labels | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/bin/repair-renamed-labels b/bin/repair-renamed-labels index 3430b7d9..8e2f6ed0 100755 --- a/bin/repair-renamed-labels +++ b/bin/repair-renamed-labels @@ -46,7 +46,7 @@ try { const byRepo = new Map(); for (const row of stored) byRepo.set(row.repo, [...(byRepo.get(row.repo) ?? []), row.title]); - const renames = []; + let renames = []; for (const [repo, titles] of byRepo) { let live; try { @@ -70,8 +70,9 @@ try { const data = await git.github.issues .listLabelsOnIssue({ ...split(repo), issue_number: number }) .then(res => res.data) - // deleted or moved away: it says nothing about the new name - .catch(err => (err.status === 404 ? null : Promise.reject(err))); + // deleted (410) or moved away (404): it says nothing about + // the new name + .catch(err => ([404, 410].includes(err.status) ? null : Promise.reject(err))); if (!data) continue; const mine = (await dbManager.getLabels(repo, number)).map(l => l.data.title); const fresh = data.map(l => l.name).filter(name => !mine.includes(name)); @@ -92,6 +93,21 @@ try { } } + // two old labels pointing at one new name: an item carrying both (FoF + // and squad-carpenter, now carpenter) can't say which was renamed + const key = r => `${r.repo}#${r.to.toLowerCase()}`; + const counts = new Map(); + for (const r of renames) counts.set(key(r), (counts.get(key(r)) ?? 0) + 1); + for (const r of renames.filter(r => counts.get(key(r)) > 1)) { + console.log( + '%s: "%s" -> "%s" shares its new name with another, left alone', + r.repo, + r.from, + r.to + ); + } + renames = renames.filter(r => counts.get(key(r)) === 1); + if (apply) { for (const { repo, from, to } of renames) await dbManager.renameLabel(repo, from, to); const slug = name =>