8686
8787 const TYPE_LABELS = [
8888 { name: 'type:feature', color: 'DDD1F2', description: 'New capability' },
89+ { name: 'type:enhancement', color: 'A2EEEF', description: 'Improvement to existing functionality' },
8990 { name: 'type:bug', color: 'FF0422', description: 'Something broken' },
9091 { name: 'type:question', color: 'D876E3', description: 'Questions about usage or behavior' },
9192 { name: 'type:documentation', color: '0075CA', description: 'Documentation issues or requests' },
9596 { name: 'type:epic', color: 'CC4455', description: 'Parent issue that decomposes into sub-issues' }
9697 ];
9798
99+ const CLOSE_LABELS = [
100+ { name: 'close:fixed', color: '0E8A16', description: 'Fixed by a previous PR or release' },
101+ { name: 'close:wont-fix', color: 'FFFFFF', description: 'Will not be addressed' },
102+ { name: 'close:duplicate', color: 'CFD3D7', description: 'Duplicate of another issue' },
103+ { name: 'close:question-answered', color: 'D876E3', description: 'Question has been answered' }
104+ ];
105+
98106 const EFFORT_LABELS = [
99107 { name: 'effort:S', color: '0E8A16', description: 'Small effort (< 1 day)' },
100108 { name: 'effort:M', color: 'FBCA04', description: 'Medium effort (1-3 days)' },
@@ -104,7 +112,6 @@ jobs:
104112
105113 // High-signal labels — these MUST visually dominate all others
106114 const SIGNAL_LABELS = [
107- { name: 'bug', color: 'FF0422', description: 'Something isn\'t working' },
108115 { name: 'feedback', color: '00E5FF', description: 'User feedback — high signal, needs attention' }
109116 ];
110117
@@ -144,15 +151,47 @@ jobs:
144151 });
145152 }
146153
147- // Add go:, release:, type:, effort:, priority:, high-signal, and lifecycle labels
154+ // Add go:, release:, type:, close:, effort:, priority:, high-signal, and lifecycle labels
148155 labels.push(...GO_LABELS);
149156 labels.push(...RELEASE_LABELS);
150157 labels.push(...TYPE_LABELS);
158+ labels.push(...CLOSE_LABELS);
151159 labels.push(...EFFORT_LABELS);
152160 labels.push(...PRIORITY_LABELS);
153161 labels.push(...SIGNAL_LABELS);
154162 labels.push(...LIFECYCLE_LABELS);
155163
164+ // Migrate legacy labels → type: equivalents (rename preserves issue associations)
165+ const MIGRATIONS = [
166+ { from: 'bug', to: 'type:bug' },
167+ { from: 'question', to: 'type:question' },
168+ { from: 'enhancement', to: 'type:enhancement' }
169+ ];
170+
171+ for (const { from, to } of MIGRATIONS) {
172+ try {
173+ await github.rest.issues.getLabel({
174+ owner: context.repo.owner,
175+ repo: context.repo.repo,
176+ name: from
177+ });
178+ // Old label exists — rename it (this moves all issues to the new name)
179+ await github.rest.issues.updateLabel({
180+ owner: context.repo.owner,
181+ repo: context.repo.repo,
182+ name: from,
183+ new_name: to
184+ });
185+ core.info(`Migrated label: ${from} → ${to}`);
186+ } catch (err) {
187+ if (err.status === 404) {
188+ core.info(`Legacy label "${from}" not found — no migration needed`);
189+ } else {
190+ core.warning(`Failed to migrate ${from}: ${err.message}`);
191+ }
192+ }
193+ }
194+
156195 // Sync labels (create or update)
157196 for (const label of labels) {
158197 try {
0 commit comments