Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
72bc9e8
Update README based on tags.yaml changes (#2109)
cncf-automation-bot Apr 7, 2026
94a9c7e
Add contribution agreement labels to labels.yaml (#2112)
riaankleinhans Apr 9, 2026
a2f66c9
Enhance project name extraction in tech review workflow (#2115)
riaankleinhans Apr 16, 2026
9e9be1c
Implement checks for existing tech review issues in workflow (#2119)
riaankleinhans Apr 16, 2026
bdcd13a
Update label logic (#2126)
riaankleinhans Apr 21, 2026
020d01f
Update labeler action version in workflows to a specific commit hash …
riaankleinhans Apr 21, 2026
817000c
Enhance checkout steps in workflows (#2128)
riaankleinhans Apr 21, 2026
f656a80
Refactor PR file retrieval in labeler workflow to use GitHub API (#2130)
riaankleinhans Apr 21, 2026
c81d5da
Refactor PR file retrieval in labeler workflow to use GitHub API (#21…
riaankleinhans Apr 21, 2026
6e5df6a
Temp labeler for open issues and PRs (#2131)
riaankleinhans Apr 21, 2026
df90f7a
Meeting notes: add README
stackedsax May 22, 2026
b0bb499
Meeting notes: 2026-04-21
stackedsax May 22, 2026
e947c9e
Meeting notes: 2026-05-05
stackedsax May 22, 2026
d353ae1
Meeting notes: 2026-05-19
stackedsax May 22, 2026
5e8f3b8
Meeting notes: export 2026-06-02 from Google Doc
stackedsax May 22, 2026
8626968
Meeting notes: export 2026-05-19 from Google Doc
stackedsax May 22, 2026
26ae482
Meeting notes: export 2026-05-05 from Google Doc
stackedsax May 22, 2026
fffb540
Meeting notes: export 2026-04-21 from Google Doc
stackedsax May 22, 2026
82255f5
Meeting notes: export 2026-04-07 from Google Doc
stackedsax May 22, 2026
352f010
Meeting notes: export 2026-03-10 from Google Doc
stackedsax May 22, 2026
3527521
Meeting notes: export 2026-02-24 from Google Doc
stackedsax May 22, 2026
9a95b04
Meeting notes: export 2026-02-10 from Google Doc
stackedsax May 22, 2026
3e6f073
Meeting notes: export 2026-01-27 from Google Doc
stackedsax May 22, 2026
d3f0b60
Meeting notes: export 2023-05-22 from Google Doc
stackedsax May 22, 2026
f1b2d7c
Meeting notes: export 2023-05-08 from Google Doc
stackedsax May 22, 2026
ad6dbe6
Meeting notes: export 2023-04-24 from Google Doc
stackedsax May 22, 2026
f9623d5
Meeting notes: export 2023-04-10 from Google Doc
stackedsax May 22, 2026
cd9cde5
Meeting notes: export 2023-03-27 from Google Doc
stackedsax May 22, 2026
62ebbd2
Meeting notes: export 2023-03-13 from Google Doc
stackedsax May 22, 2026
0aed050
Meeting notes: export 2023-02-27 from Google Doc
stackedsax May 22, 2026
00ddac5
Meeting notes: export 2023-02-13 from Google Doc
stackedsax May 22, 2026
01ec48a
Meeting notes: export 2023-01-30 from Google Doc
stackedsax May 22, 2026
10b031b
Meeting notes: export 2022-12-19 from Google Doc
stackedsax May 22, 2026
6d836ba
Meeting notes: export 2022-11-21 from Google Doc
stackedsax May 22, 2026
86b25de
Meeting notes: export 2022-11-07 from Google Doc
stackedsax May 22, 2026
8ee1bf1
Meeting notes: export 2022-10-10 from Google Doc
stackedsax May 22, 2026
a6d417d
Meeting notes: export 2022-09-26 from Google Doc
stackedsax May 22, 2026
e9dc2e9
Meeting notes: export 2022-08-15 from Google Doc
stackedsax May 22, 2026
4623537
Meeting notes: export 2022-08-01 from Google Doc
stackedsax May 22, 2026
dc8477d
Meeting notes: export 2022-07-18 from Google Doc
stackedsax May 22, 2026
2b48d21
Meeting notes: export 2022-06-20 from Google Doc
stackedsax May 22, 2026
51313b7
Meeting notes: export 2026-06-02 from Google Doc
stackedsax May 23, 2026
618e99e
Meeting notes: export 2026-05-19 from Google Doc
stackedsax May 23, 2026
87cfa4a
Meeting notes: export 2026-05-05 from Google Doc
stackedsax May 23, 2026
55f14cd
Meeting notes: export 2026-04-21 from Google Doc
stackedsax May 23, 2026
02e583c
Meeting notes: export 2026-04-07 from Google Doc
stackedsax May 23, 2026
d164fc1
Meeting notes: export 2026-03-10 from Google Doc
stackedsax May 23, 2026
db962c4
Meeting notes: export 2026-02-24 from Google Doc
stackedsax May 23, 2026
92a39f8
Meeting notes: export 2026-02-10 from Google Doc
stackedsax May 23, 2026
bb0956c
Meeting notes: export 2026-01-27 from Google Doc
stackedsax May 23, 2026
29d4f38
Meeting notes: export 2023-05-22 from Google Doc
stackedsax May 23, 2026
e6363ab
Meeting notes: export 2023-05-08 from Google Doc
stackedsax May 23, 2026
f384042
Meeting notes: export 2023-04-24 from Google Doc
stackedsax May 23, 2026
80b517d
Meeting notes: export 2023-04-10 from Google Doc
stackedsax May 23, 2026
eefceb3
Meeting notes: export 2023-03-27 from Google Doc
stackedsax May 23, 2026
c353e43
Meeting notes: export 2023-03-13 from Google Doc
stackedsax May 23, 2026
fc0e642
Meeting notes: export 2023-02-27 from Google Doc
stackedsax May 23, 2026
905ef71
Meeting notes: export 2023-02-13 from Google Doc
stackedsax May 23, 2026
70344e2
Meeting notes: export 2023-01-30 from Google Doc
stackedsax May 23, 2026
d5cc35d
Meeting notes: export 2022-12-19 from Google Doc
stackedsax May 23, 2026
e4902e5
Meeting notes: export 2022-11-21 from Google Doc
stackedsax May 23, 2026
edd5565
Meeting notes: export 2022-11-07 from Google Doc
stackedsax May 23, 2026
26ff6b8
Meeting notes: export 2022-10-10 from Google Doc
stackedsax May 23, 2026
e2ca04e
Meeting notes: export 2022-09-26 from Google Doc
stackedsax May 23, 2026
1c9c7e6
Meeting notes: export 2022-08-15 from Google Doc
stackedsax May 23, 2026
3f29573
Meeting notes: export 2022-08-01 from Google Doc
stackedsax May 23, 2026
424c06b
Meeting notes: export 2022-07-18 from Google Doc
stackedsax May 23, 2026
2a3ed88
Meeting notes: export 2022-06-20 from Google Doc
stackedsax May 23, 2026
ca8b526
Meeting notes: export 2026-06-02 from Google Doc
stackedsax May 23, 2026
cda9dcf
Meeting notes: export 2026-05-19 from Google Doc
stackedsax May 23, 2026
763299d
Meeting notes: export 2026-05-05 from Google Doc
stackedsax May 23, 2026
da5f005
Meeting notes: export 2026-04-21 from Google Doc
stackedsax May 23, 2026
ad70479
Meeting notes: export 2026-04-07 from Google Doc
stackedsax May 23, 2026
e4c977f
Meeting notes: export 2026-03-10 from Google Doc
stackedsax May 23, 2026
10692b2
Meeting notes: export 2026-02-24 from Google Doc
stackedsax May 23, 2026
625e1f2
Meeting notes: export 2026-02-10 from Google Doc
stackedsax May 23, 2026
1ba5c8b
Meeting notes: export 2026-01-27 from Google Doc
stackedsax May 23, 2026
e225d0c
Meeting notes: export 2023-05-22 from Google Doc
stackedsax May 23, 2026
5f425f3
Meeting notes: export 2023-05-08 from Google Doc
stackedsax May 23, 2026
902efbf
Meeting notes: export 2023-04-24 from Google Doc
stackedsax May 23, 2026
8207797
Meeting notes: export 2023-04-10 from Google Doc
stackedsax May 23, 2026
4169c7d
Meeting notes: export 2023-03-27 from Google Doc
stackedsax May 23, 2026
3c2c5a3
Meeting notes: export 2023-03-13 from Google Doc
stackedsax May 23, 2026
007052f
Meeting notes: export 2023-02-27 from Google Doc
stackedsax May 23, 2026
1000300
Meeting notes: export 2023-02-13 from Google Doc
stackedsax May 23, 2026
38e8dc6
Meeting notes: export 2023-01-30 from Google Doc
stackedsax May 23, 2026
72f7832
Meeting notes: export 2022-12-19 from Google Doc
stackedsax May 23, 2026
c3defb0
Meeting notes: export 2022-11-21 from Google Doc
stackedsax May 23, 2026
f7e0013
Meeting notes: export 2022-11-07 from Google Doc
stackedsax May 23, 2026
0d52c57
Meeting notes: export 2022-10-10 from Google Doc
stackedsax May 23, 2026
0dc8f22
Meeting notes: export 2022-09-26 from Google Doc
stackedsax May 23, 2026
3e03b45
Meeting notes: export 2022-08-15 from Google Doc
stackedsax May 23, 2026
6f1f71d
Meeting notes: export 2022-08-01 from Google Doc
stackedsax May 23, 2026
3129ee1
Meeting notes: export 2022-07-18 from Google Doc
stackedsax May 23, 2026
9296219
Meeting notes: export 2022-06-20 from Google Doc
stackedsax May 23, 2026
e76a77f
Meeting notes: export 2026-06-02 from Google Doc
stackedsax May 24, 2026
f853909
Meeting notes: export 2026-05-19 from Google Doc
stackedsax May 24, 2026
76eb376
Meeting notes: export 2026-05-05 from Google Doc
stackedsax May 24, 2026
3db2d4e
Meeting notes: export 2026-04-21 from Google Doc
stackedsax May 24, 2026
641d2ff
Meeting notes: export 2026-04-07 from Google Doc
stackedsax May 24, 2026
80cdd25
Meeting notes: export 2026-03-10 from Google Doc
stackedsax May 24, 2026
057cfe0
Meeting notes: export 2026-02-24 from Google Doc
stackedsax May 24, 2026
cd6eed5
Meeting notes: export 2026-02-10 from Google Doc
stackedsax May 24, 2026
fa230f2
Meeting notes: export 2026-01-27 from Google Doc
stackedsax May 24, 2026
d5adcb3
Meeting notes: export 2026-01-13 from Google Doc
stackedsax May 24, 2026
7adb61d
Meeting notes: export 2025-12-02 from Google Doc
stackedsax May 24, 2026
d4936ad
Meeting notes: export 2025-11-18 from Google Doc
stackedsax May 24, 2026
75f0bc7
Meeting notes: export 2025-10-21 from Google Doc
stackedsax May 24, 2026
bcedfb2
Meeting notes: export 2025-10-07 from Google Doc
stackedsax May 24, 2026
13b1bcd
Meeting notes: export 2025-09-23 from Google Doc
stackedsax May 24, 2026
1d3eaa3
Meeting notes: export 2025-09-09 from Google Doc
stackedsax May 24, 2026
f7bd381
Meeting notes: export 2025-08-26 from Google Doc
stackedsax May 24, 2026
f4825c5
Meeting notes: export 2025-08-12 from Google Doc
stackedsax May 24, 2026
5a94fd1
Meeting notes: export 2025-07-29 from Google Doc
stackedsax May 24, 2026
1ac2ce2
Meeting notes: export 2025-07-15 from Google Doc
stackedsax May 24, 2026
1e72d9f
Meeting notes: export 2025-07-01 from Google Doc
stackedsax May 24, 2026
35877d1
Meeting notes: export 2025-06-17 from Google Doc
stackedsax May 24, 2026
4402155
Meeting notes: export 2025-06-03 from Google Doc
stackedsax May 24, 2026
67ffcbf
Meeting notes: export 2025-05-20 from Google Doc
stackedsax May 24, 2026
744c6fd
Meeting notes: export 2025-05-06 from Google Doc
stackedsax May 24, 2026
ad84023
Meeting notes: export 2025-04-22 from Google Doc
stackedsax May 24, 2026
086dec6
Meeting notes: export 2025-04-08 from Google Doc
stackedsax May 24, 2026
23f2865
Meeting notes: export 2025-03-25 from Google Doc
stackedsax May 24, 2026
65c87d2
Meeting notes: export 2025-03-11 from Google Doc
stackedsax May 24, 2026
0d06fe9
Meeting notes: export 2025-02-25 from Google Doc
stackedsax May 24, 2026
41b6f42
Meeting notes: export 2025-02-11 from Google Doc
stackedsax May 24, 2026
f7b9190
Meeting notes: export 2025-01-27 from Google Doc
stackedsax May 24, 2026
bb23139
Meeting notes: export 2025-01-13 from Google Doc
stackedsax May 24, 2026
559c5ce
Meeting notes: export 2024-12-16 from Google Doc
stackedsax May 24, 2026
cc6eb1a
Meeting notes: export 2024-12-02 from Google Doc
stackedsax May 24, 2026
7a7d92a
Meeting notes: export 2024-11-18 from Google Doc
stackedsax May 24, 2026
1f2cb50
Meeting notes: export 2024-07-01 from Google Doc
stackedsax May 24, 2026
4253bda
Meeting notes: export 2023-10-09 from Google Doc
stackedsax May 24, 2026
2bff59c
Meeting notes: export 2023-09-11 from Google Doc
stackedsax May 24, 2026
2abfb94
Meeting notes: export 2023-05-22 from Google Doc
stackedsax May 24, 2026
b9daf43
Meeting notes: export 2023-05-08 from Google Doc
stackedsax May 24, 2026
11823b2
Meeting notes: export 2023-04-24 from Google Doc
stackedsax May 24, 2026
3fb2faa
Meeting notes: export 2023-04-10 from Google Doc
stackedsax May 24, 2026
8daaa69
Meeting notes: export 2023-03-27 from Google Doc
stackedsax May 24, 2026
851b8e7
Meeting notes: export 2023-03-13 from Google Doc
stackedsax May 24, 2026
6312fef
Meeting notes: export 2023-02-27 from Google Doc
stackedsax May 24, 2026
66cfe75
Meeting notes: export 2023-02-13 from Google Doc
stackedsax May 24, 2026
f774ff2
Meeting notes: export 2023-01-30 from Google Doc
stackedsax May 24, 2026
75f39cd
Meeting notes: export 2022-12-19 from Google Doc
stackedsax May 24, 2026
015afd4
Meeting notes: export 2022-11-21 from Google Doc
stackedsax May 24, 2026
dce7d19
Meeting notes: export 2022-11-07 from Google Doc
stackedsax May 24, 2026
1c5096a
Meeting notes: export 2022-10-10 from Google Doc
stackedsax May 24, 2026
81b5ec8
Meeting notes: export 2022-09-26 from Google Doc
stackedsax May 24, 2026
52009c4
Meeting notes: export 2022-08-15 from Google Doc
stackedsax May 24, 2026
47e0339
Meeting notes: export 2022-08-01 from Google Doc
stackedsax May 24, 2026
6281e94
Meeting notes: export 2022-07-18 from Google Doc
stackedsax May 24, 2026
2ae24a5
Meeting notes: export 2022-06-20 from Google Doc
stackedsax May 24, 2026
c6d5b67
Meeting notes: export 2022-06-06 from Google Doc
stackedsax May 24, 2026
396a52e
Meeting notes: update README
stackedsax May 24, 2026
13d93cd
Batch subproject: replace charter placeholder with real content
stackedsax May 24, 2026
7ad1a52
Batch subproject: add initiative_benchmarking directory
stackedsax May 24, 2026
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
81 changes: 81 additions & 0 deletions .github/README_Labelling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# TOC Labeling Guide

This repository has two labeling paths:

1. **Slash commands in comments** (manual, explicit)
2. **Automatic labeling** (event and file-path based)

## 1) Slash Commands in Comments

Use slash commands in a normal issue/PR comment to apply or remove labels.

- Command must be on the **first line** of the comment.
- Format is usually `/command value` (or `/command` for commands with no argument).
- Commands are processed for issue comments and PR conversation comments.

### Valid commands

#### Core triage/grouping

- `/kind <value>`
- values: `dd`, `docs`, `enhancement`, `initiative`, `meeting`, `review`, `subproject`
- `/triage <value>`
- values: `valid`, `needs-information`, `duplicate`, `not-planned`
- `/tag <value>`
- values: `developer-experience`, `infrastructure`, `operational-resilience`, `security-and-compliance`, `workloads-foundation`
- `/sub <value>`
- values: `contributor-strategy-and-advocacy`, `mentoring`, `project-reviews`
- `/toc`

#### DD lifecycle

- `/dd/triage <value>`
- values: `needs-triage`, `needs-adopters`, `needs-more-information`, `needs-security-assessment`
- `/dd/status <value>`
- values: `ready-for-assignment`, `in-progress`, `in-comment-period`, `in-voting`, `complete`, `waiting`
- `/dd/adopters <value>`
- values: `not-started`, `in-progress`, `complete`
- `/dd/gov-review <value>`
- values: `not-started`, `in-progress`, `complete`
- `/dd/tech-review <value>`
- values: `not-started`, `in-progress`, `complete`
- `/dd/sec-review <value>`
- values: `not-started`, `in-progress`, `complete`

#### Initiatives and votes

- `/toc/initiative <value>`
- values: `AI`
- `/init <value>`
- values: `not-started`, `in-progress`, `complete`, `stale`
- `/vote <value>`
- values: `open`, `closed`, `nomination`
- `/help`

#### Remove commands

- `/remove-kind <value>`
- `/remove-triage <value>`
- `/remove-tag <value>`
- `/remove-sub <value>`
- `/remove-toc`
- `/remove-toc/initiative <value>`
- `/remove-init <value>`
- `/remove-vote`
- `/remove-dd/triage <value>`
- `/remove-review <value>`
- `/remove-level <value>`
- `/remove-help`

## 2) Automatic Labeling (Overview)

Automatic labeling runs from GitHub Actions and handles broad classification without requiring manual `/` commands.

At a high level it does the following:

- Applies labels when issues/PRs are opened or edited.
- Uses changed file paths in PRs to infer group labels (for example, TOC/TAG/subproject areas).
- Maintains helper labels like `needs-kind`, `needs-triage`, and `needs-group` when required categories are missing.
- Keeps label state clean by removing/replacing mutually exclusive labels in command-driven flows.

In short: use `/` commands when you want explicit control, and rely on automatic labeling for baseline triage and path-based routing.
11 changes: 10 additions & 1 deletion .github/labels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ definitionRequired: true


labels:
- name: contribution-agreement/signed
description: Contributor has signed the required contribution agreement
color: 0e8a16
- name: contribution-agreement/unsigned
description: Contributor has not yet signed the required contribution agreement
color: b60205
- name: dd/adopters/complete
description: DD Adopter Interviews have been completed
color: 41cd40
Expand Down Expand Up @@ -68,6 +74,9 @@ labels:
- name: dd/triage/needs-adopters
description: Additional adopters needed for DD application to be marked ready
color: b60205
- name: dd/triage/needs-security-assessment
description: Security assessment must be completed before DD can proceed
color: b60205
- name: gitvote
description: ''
color: ededed
Expand Down Expand Up @@ -427,7 +436,7 @@ ruleset:
- tag/developer-experience
- tag/infrastructure
- tag/operational-resilience
- tag/security-compliance
- tag/security-and-compliance
- tag/workloads-foundation
actions:
- kind: remove-label
Expand Down
106 changes: 91 additions & 15 deletions .github/workflows/create-tech-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ jobs:
}
}

async function commentExistingTechReview(issueNumber, existingIssue) {
await commentOnce(
issueNumber,
COMMENT_MARKERS.techReviewExists,
`Tech review issue: [#${existingIssue.number} - ${existingIssue.title}](${existingIssue.html_url})`
);
}

function extractFormField(body, fieldKey) {
if (!body) return null;
const labels = FIELD_LABELS[fieldKey] || [fieldKey];
Expand Down Expand Up @@ -116,20 +124,56 @@ jobs:
return null;
}

function extractProjectNameFallback(issueTitle, issueBody) {
// Handle DD app titles like:
// [Graduation] KubeVirt Graduation Application
// [Incubation] HAMi Incubation Application
if (issueTitle) {
const titlePattern = /^\s*\[(?:Tech\s*Review|Graduation|Incubation|Sandbox)\]\s*(.+?)\s*(?:Tech\s*Review|Graduation\s*Application|Incubation\s*Application|Sandbox\s*Application)?\s*$/i;
const titleMatch = issueTitle.match(titlePattern);
if (titleMatch && titleMatch[1] && titleMatch[1].trim().length > 0) {
return titleMatch[1].trim();
}
}

// Handle markdown heading bodies like:
// # KubeVirt Graduation Application
if (issueBody) {
const headingPattern = /^#\s+(.+?)\s+(?:Graduation|Incubation|Sandbox)\s+Application\s*$/im;
const headingMatch = issueBody.match(headingPattern);
if (headingMatch && headingMatch[1] && headingMatch[1].trim().length > 0) {
return headingMatch[1].trim();
}
}

return null;
}

function normalize(str) {
return (str || '').trim().toLowerCase();
}

function extractTechReviewProjectNameFromTitle(title) {
if (!title) return null;
const match = title.match(/^\s*\[Tech\s*Review\]:\s*(.+?)\s*$/i);
return match && match[1] ? match[1].trim() : null;
}

function escapeForSearchQuery(value) {
return (value || '').replace(/"/g, '\\"').trim();
}

// --- Main Logic ---
const issue = context.payload.issue;
const issueNumber = issue.number;
const issueTitle = issue.title;
const issueBody = issue.body;

console.log(`🔍 Processing issue #${issueNumber}`);
console.log(`📄 Issue body length: ${issueBody ? issueBody.length : 0}`);

// Extract fields
const projectName = extractFormField(issueBody, 'name');
const projectName = extractFormField(issueBody, 'name') || extractProjectNameFallback(issueTitle, issueBody);
const projectLink = extractFormField(issueBody, 'projectLink');
const ddLink = extractFormField(issueBody, 'ddLink');
const projectContact = extractFormField(issueBody, 'projectContact');
Expand Down Expand Up @@ -168,32 +212,64 @@ jobs:
return;
}

// Check for existing tech review issues for this project
// Safety check #1: GitHub search for existing OPEN tech review issue by project
let existingIssue = null;
try {
const allIssues = await github.paginate(github.rest.issues.listForRepo, {
const searchQuery = [
`repo:${context.repo.owner}/${context.repo.repo}`,
'is:issue',
'is:open',
'in:title',
'"[Tech Review]:"',
`"${escapeForSearchQuery(normalizedProjectName)}"`
].join(' ');

const searchResults = await github.paginate(github.rest.search.issuesAndPullRequests, {
q: searchQuery,
per_page: 100
});

existingIssue = searchResults.find(item => {
if (item.number === issueNumber) return false;
if (item.pull_request) return false;
const projectNameFromTechReviewTitle = extractTechReviewProjectNameFromTitle(item.title);
return normalize(projectNameFromTechReviewTitle) === projectNameLower;
});

if (existingIssue) {
console.log(`ℹ️ Found existing tech review issue via search #${existingIssue.number} - commenting and exiting`);
await commentExistingTechReview(issueNumber, existingIssue);
return;
}
} catch (error) {
console.log('⚠️ Error checking for existing issues via search:', error.message);
}

// Safety check #2: scan open issues as fallback
try {
const openIssues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'all',
labels: 'review/tech',
state: 'open',
per_page: 100
});

existingIssue = allIssues.find(item => {
existingIssue = openIssues.find(item => {
if (item.number === issueNumber) return false;
if (!item.title.includes('[Tech Review]:')) return false;
const existingProjectName = extractFormField(item.body, 'name');
if (normalize(existingProjectName) === projectNameLower) return true;
// Fallback: check title for exact word match
const titleLower = item.title.toLowerCase();
const projectNameRegex = new RegExp(`\\b${projectNameLower.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i');
return projectNameRegex.test(titleLower);
if (item.pull_request) return false;

const projectNameFromTechReviewTitle = extractTechReviewProjectNameFromTitle(item.title);
if (!projectNameFromTechReviewTitle) return false;

if (normalize(projectNameFromTechReviewTitle) === projectNameLower) return true;

const existingProjectNameFromBody = extractFormField(item.body, 'name');
return normalize(existingProjectNameFromBody) === projectNameLower;
});

if (existingIssue) {
console.log(`ℹ️ Found existing tech review issue #${existingIssue.number} - commenting and exiting`);
await commentOnce(issueNumber, COMMENT_MARKERS.techReviewExists,
`A tech review issue already exists for this project: [#${existingIssue.number} - ${existingIssue.title}](${existingIssue.html_url})`);
await commentExistingTechReview(issueNumber, existingIssue);
return;
} else {
console.log('✅ No existing tech review issue found - proceeding to create');
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/labeler-backfill.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Labeler Backfill (manual)

# TEMPORARY: one-shot workflow to re-run the auto-labeler across every open
# PR and issue in the base repo. Added to recover labels for items whose
# original labeler run failed (e.g. fork PRs whose "Re-run jobs" is pinned
# to an old workflow file). Revert this file (and scripts/labeler-backfill.sh)
# once the backfill has been applied.
#
# Run from the Actions tab -> "Labeler Backfill (manual)" -> Run workflow.
# Leave dry_run=true for the first run to preview; re-run with dry_run=false
# to apply labels.

on:
workflow_dispatch:
inputs:
scope:
description: What to relabel
type: choice
options:
- all
- prs
- issues
default: all
dry_run:
description: Dry run (log only, no API writes)
type: boolean
default: true

permissions:
contents: read
issues: write
pull-requests: write

jobs:
backfill:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
persist-credentials: false

- name: Run labeler backfill
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
SCOPE: ${{ inputs.scope }}
DRY_RUN: ${{ inputs.dry_run && '1' || '0' }}
run: ./scripts/labeler-backfill.sh
44 changes: 35 additions & 9 deletions .github/workflows/labeler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: Auto Label Issues and PRs
on:
issues:
types: [opened, edited, reopened, transferred]
issue_comment:
types: [created, edited]
pull_request_target:
types: [opened, edited, reopened]

Expand All @@ -16,19 +14,47 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout code
- name: Checkout PR head for changed-files
if: ${{ github.event.pull_request }}
uses: actions/checkout@v5
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false

- name: Checkout repository for issue events
if: ${{ !github.event.pull_request }}
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Debug event context (temporary)
run: |
echo "event_name=${{ github.event_name }}"
echo "action=${{ github.event.action }}"
echo "has_pull_request=${{ github.event.pull_request != null }}"
echo "issue_number=${{ github.event.issue.number }}"
echo "pr_number=${{ github.event.pull_request.number }}"

- name: Get changed files
- name: Get changed files from PR API
if: ${{ github.event.pull_request }}
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
uses: actions/github-script@v8
with:
separator: ","
script: |
const prNumber = context.payload.pull_request.number;
const files = await github.paginate(github.rest.pulls.listFiles, {
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
per_page: 100
});
core.setOutput("all_changed_files", files.map(f => f.filename).join(","));

- name: Run labeler action for PR
if: ${{ github.event.pull_request }}
uses: cncf/automation/.github/actions/labeler-action@main
uses: cncf/automation/.github/actions/labeler-action@66a552b17f013289688a4e238f7a64b0d8e334a6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand All @@ -41,12 +67,12 @@ jobs:

- name: Run labeler action for Issue
if: ${{ !github.event.pull_request }}
uses: cncf/automation/.github/actions/labeler-action@main
uses: cncf/automation/.github/actions/labeler-action@66a552b17f013289688a4e238f7a64b0d8e334a6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
labels: https://raw.githubusercontent.com/cncf/toc/refs/heads/main/.github/labels.yaml
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
issue_number: ${{ github.event.issue.number }}
comment_body: ${{ github.event.comment.body }}
comment_body: ${{ github.event.issue.body }}
Loading
Loading