From 8b9b75eedf6effac74e4b3f91a6e3544ef69b856 Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Tue, 28 Apr 2026 14:59:04 -0400 Subject: [PATCH 1/4] Update labelling code --- .github/workflows/issue_bot.yml | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/.github/workflows/issue_bot.yml b/.github/workflows/issue_bot.yml index 3e5b2a4dcfa7..15a1a1b477bf 100644 --- a/.github/workflows/issue_bot.yml +++ b/.github/workflows/issue_bot.yml @@ -51,6 +51,32 @@ jobs: `Thanks for your report! The ${component} implementation has moved to https://github.com/apache/${repo}.\n\n` + `This issue has been closed automatically - please open a new issue there.`; + let component_to_prefix = (component) => { + const prefix_overrides = { + "Continuous Integration": "CI", + "Developer Tools": "Dev", + "Documentation": "Docs", + }; + return prefix_overrides[component] || component; + }; + + let strip_component_prefixes = (title, prefixes) => { + let stripped_title = title.trimStart(); + let prefix_removed = true; + while (prefix_removed) { + prefix_removed = false; + for (let prefix of prefixes) { + let title_prefix = `[${prefix}]`; + if (stripped_title.startsWith(title_prefix)) { + stripped_title = stripped_title.substring(title_prefix.length).trimStart(); + prefix_removed = true; + break; + } + } + } + return stripped_title; + }; + let split_body = context.payload.issue.body.split('### Component(s)'); if (split_body.length != 2) throw new Error('No components found!'); @@ -104,6 +130,29 @@ jobs: if (component_labels.length == 0) throw new Error('No components found!'); + let component_prefixes = component_labels.map( + label => component_to_prefix(label.substring("Component: ".length)) + ); + let repo_component_prefixes = repo_labels.data + .map(label => label.name) + .filter(label => label.startsWith("Component: ")) + .map(label => component_to_prefix(label.substring("Component: ".length))); + let stripped_title = strip_component_prefixes( + context.payload.issue.title, + repo_component_prefixes + ); + let prefixed_title = component_prefixes + .map(prefix => `[${prefix}]`) + .join("") + " " + stripped_title; + if (prefixed_title != context.payload.issue.title) { + await github.rest.issues.update({ + "owner": context.repo.owner, + "repo": context.repo.repo, + "issue_number": context.payload.issue.number, + "title": prefixed_title, + }); + } + await github.rest.issues.setLabels({ "owner": context.repo.owner, "repo": context.repo.repo, From 9f51e94220a97702679c288a4c541b08b1803d31 Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Tue, 28 Apr 2026 15:14:38 -0400 Subject: [PATCH 2/4] fix aggressive stripping of labels --- .github/workflows/issue_bot.yml | 35 +++++++++------------------------ 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/.github/workflows/issue_bot.yml b/.github/workflows/issue_bot.yml index 15a1a1b477bf..bca428021e19 100644 --- a/.github/workflows/issue_bot.yml +++ b/.github/workflows/issue_bot.yml @@ -60,21 +60,8 @@ jobs: return prefix_overrides[component] || component; }; - let strip_component_prefixes = (title, prefixes) => { - let stripped_title = title.trimStart(); - let prefix_removed = true; - while (prefix_removed) { - prefix_removed = false; - for (let prefix of prefixes) { - let title_prefix = `[${prefix}]`; - if (stripped_title.startsWith(title_prefix)) { - stripped_title = stripped_title.substring(title_prefix.length).trimStart(); - prefix_removed = true; - break; - } - } - } - return stripped_title; + let title_has_prefix = (title, prefix) => { + return title.includes(`[${prefix}]`); }; let split_body = context.payload.issue.body.split('### Component(s)'); @@ -133,23 +120,19 @@ jobs: let component_prefixes = component_labels.map( label => component_to_prefix(label.substring("Component: ".length)) ); - let repo_component_prefixes = repo_labels.data - .map(label => label.name) - .filter(label => label.startsWith("Component: ")) - .map(label => component_to_prefix(label.substring("Component: ".length))); - let stripped_title = strip_component_prefixes( - context.payload.issue.title, - repo_component_prefixes + let issue_title = context.payload.issue.title.trimStart(); + let missing_prefixes = component_prefixes.filter( + prefix => !title_has_prefix(issue_title, prefix) ); - let prefixed_title = component_prefixes + let missing_title_prefix = missing_prefixes .map(prefix => `[${prefix}]`) - .join("") + " " + stripped_title; - if (prefixed_title != context.payload.issue.title) { + .join(""); + if (missing_title_prefix) { await github.rest.issues.update({ "owner": context.repo.owner, "repo": context.repo.repo, "issue_number": context.payload.issue.number, - "title": prefixed_title, + "title": missing_title_prefix + " " + issue_title, }); } From 1b2ad08740b50fbbffd9dc19a163934eddfca0c2 Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Tue, 28 Apr 2026 15:19:05 -0400 Subject: [PATCH 3/4] Fix spacing --- .github/workflows/issue_bot.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/issue_bot.yml b/.github/workflows/issue_bot.yml index bca428021e19..75789fe53cef 100644 --- a/.github/workflows/issue_bot.yml +++ b/.github/workflows/issue_bot.yml @@ -128,11 +128,12 @@ jobs: .map(prefix => `[${prefix}]`) .join(""); if (missing_title_prefix) { + let title_separator = issue_title.startsWith("[") ? "" : " "; await github.rest.issues.update({ "owner": context.repo.owner, "repo": context.repo.repo, "issue_number": context.payload.issue.number, - "title": missing_title_prefix + " " + issue_title, + "title": missing_title_prefix + title_separator + issue_title, }); } From 5ea06b57b370c873e78812e42e80409cda64185a Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Wed, 29 Apr 2026 13:01:55 -0400 Subject: [PATCH 4/4] Fix spacing --- .github/workflows/issue_bot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/issue_bot.yml b/.github/workflows/issue_bot.yml index 75789fe53cef..32e5effab34b 100644 --- a/.github/workflows/issue_bot.yml +++ b/.github/workflows/issue_bot.yml @@ -120,13 +120,17 @@ jobs: let component_prefixes = component_labels.map( label => component_to_prefix(label.substring("Component: ".length)) ); + let issue_title = context.payload.issue.title.trimStart(); + let missing_prefixes = component_prefixes.filter( prefix => !title_has_prefix(issue_title, prefix) ); + let missing_title_prefix = missing_prefixes .map(prefix => `[${prefix}]`) .join(""); + if (missing_title_prefix) { let title_separator = issue_title.startsWith("[") ? "" : " "; await github.rest.issues.update({