Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels - #8859

Merged
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field
Jun 5, 2026
Merged

Use native GitHub Issue Type field for Bug/Feature/Task instead of type/* labels#8859
Amaury Levé (Evangelink) merged 4 commits into
mainfrom
dev/amauryleve/use-issue-type-field

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Problem

Newly created issues are almost always tagged with the legacy type/feature label (and sometimes type/bug) while the native GitHub Issue Type field stays empty. Example: #8828 has type/feature but issueType: null. The native types (Bug, Feature, Task) were enabled on the microsoft org but never wired in.

Changes

  • .github/copilot-instructions.md - new section "GitHub issue creation guidelines":
    • Use the native Issue Type field (Bug / Feature / Task) instead of type/bug / type/feature labels.
    • Other type/* labels (type/tech-debt, type/test-gap, type/automation, type/regression, type/flaky-test, ...) stay because they have no native equivalent.
    • How to set the Issue Type from issue templates (frontmatter), the web UI, gh issue create, the GraphQL updateIssueIssueType mutation, and gh-awsafe-outputs.create-issue.type.
  • eng/migrate-labels.ps1:
    • Removed type/bug and type/feature from the target taxonomy.
    • Mapped the legacy bug, enhancement, feature-request, type/bug, type/feature labels to deletion in $Migration.
    • Added $IssueTypeReplacement and helper functions (Get-IssueTypeId, Get-IssuesWithLabel, Set-IssueType, Convert-LabelToIssueType).
    • Added Phase 3.5 that converts every issue carrying one of those labels to the matching native Issue Type before Phase 4 deletes the empty label, so we do not lose categorization.

Verification

Dry-run (pwsh -NoProfile -File .\eng\migrate-labels.ps1 -DryRun -Force) shows Phase 3.5 picks up the 5 open type/feature issues (#8793, #8825, #8826, #8827, #8828) and would set them to native Feature, then Phase 4 deletes the now-empty type/bug and type/feature labels. PRs lose the label without any Issue Type change (PRs do not have one).

After this PR merges, run the script once without -DryRun to perform the actual conversion + deletion.

The 'type/bug' and 'type/feature' labels still account for almost all
categorization on new issues even though the microsoft org enabled native
GitHub Issue Types (Bug, Feature, Task). This change:
* Adds a 'GitHub issue creation guidelines' section to
.github/copilot-instructions.md telling humans and agentic workflows to
set the native Issue Type (Bug/Feature/Task) instead of the deprecated
'type/bug' / 'type/feature' labels. Other 'type/*' labels stay because
they have no native equivalent.
* Removes 'type/bug' and 'type/feature' from the target taxonomy in
eng/migrate-labels.ps1 and marks them (plus the legacy 'bug',
'enhancement', 'feature-request' aliases) for deletion.
* Adds a Phase 3.5 to migrate-labels.ps1 that converts every issue still
carrying one of those labels to the matching native Issue Type before
Phase 4 deletes the labels, so we do not lose categorization.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 13:53

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates repository guidance and tooling to use GitHub’s native Issue Type field (Bug / Feature / Task) for primary categorization, instead of the legacy type/bug / type/feature labels, and adds a migration step to preserve that categorization during label cleanup.

Changes:

  • Document new issue-creation policy in .github/copilot-instructions.md (prefer native Issue Type; deprecate type/bug + type/feature; keep other type/* labels).
  • Update eng/migrate-labels.ps1 taxonomy/mapping to remove type/bug + type/feature and delete legacy aliases (bug, enhancement, feature-request, etc.).
  • Add Phase 3.5 to convert legacy labels into native Issue Types via GitHub GraphQL before label deletion.
Show a summary per file
FileDescription
eng/migrate-labels.ps1Removes type/bug/type/feature from target taxonomy, maps legacy labels to deletion, and adds Phase 3.5 to set native Issue Types before deleting labels.
.github/copilot-instructions.mdAdds “GitHub issue creation guidelines” documenting how to set Issue Type across templates/UI/CLI/workflows and deprecating type/bug/type/feature.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment threadeng/migrate-labels.ps1 Outdated
…lint
* eng/migrate-labels.ps1: route the issue 'remove-label' call in
Convert-LabelToIssueType through Invoke-Gh, matching the surrounding
PR-edit path and the rest of the script (centralized dry-run logging
and exit-code handling).
* .github/copilot-instructions.md: surround the bash fenced code block
with blank lines so markdownlint MD031 passes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Algorithmic Correctness — ISSUE (1 BLOCKING)

One bug found; everything else (dry-run guards, pagination, $existing lifetime) is correct.

SeverityBLOCKING
Fileeng/migrate-labels.ps1
Lines457–473

$name variable shadows the $Name parameter in Get-IssueTypeId

PowerShell variable names are case-insensitive: $name and $Name refer to the same variable. On the first call (cache is $null), line 457 executes:

$owner,$name=$Repo-split'/',2# silently overwrites $Name

This replaces the caller-supplied type name (e.g. "Bug") with the repository's short name (e.g. "testfx"). Lines 470–473 then consult $Name for the cache lookup — using "testfx" instead of "Bug" — and always throw:

Issue type 'testfx' is not configured on microsoft/testfx. Available: Bug, Feature, Task

Subsequent calls (warm cache, if block skipped) are fine, but the script never reaches them.

Fix: use a non-clashing local name, e.g.:

$repoOwner,$repoName=$Repo-split'/',2$json=& gh api graphql -f query=$query-F owner=$repoOwner-F name=$repoName

Apply the same rename at line 481 in Get-IssuesWithLabel for consistency (no parameter clash there, but it avoids confusion).

Generated by Expert Code Review (on open) for issue #8859 · sonnet46 6.8M

Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
Comment threadeng/migrate-labels.ps1 Outdated
… prefix
- Get-IssueTypeId: rename $owner/$name to $repoOwner/$repoName so the destructure no longer clobbers the $Name parameter (case-insensitive PowerShell vars made every first call throw).
- Get-IssuesWithLabel: same rename for consistency; consolidate the two gh graphql call sites into a single $ghArgs splat; accumulate paged results in a List[object] to avoid O(n^2) array concatenation.
- Phase-3 log line: replace the ad-hoc 'c ' prefix with '> ' to match the symbol-based legend used elsewhere in the script.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings June 5, 2026 14:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment threadeng/migrate-labels.ps1
Comment threadeng/migrate-labels.ps1
…00-limit truncation
- Convert-LabelToIssueType now wraps each issue and each PR edit in try/catch, collects failures into a per-call list, keeps processing the remaining items, and throws a single aggregated summary at the end (mirrors Merge-LabelInto's failure-collection pattern). Phase 3 still aborts overall on any failure, so Phase 4 deletions never run against a half-migrated state.
- Added the same >=5000 truncation guard as Merge-LabelInto on the PR-list call, so the script refuses to silently drop the tail instead of deleting the label with leftover PRs still carrying it.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not proficient with powershell scripts by any means, but I reviewed the logic anyways and it seems correct to me. Also, dry run output exactly what it should based on the verification steps, so I approve.

@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) June 5, 2026 15:11
@Evangelink
Amaury Levé (Evangelink) merged commit 1308813 into mainJun 5, 2026
48 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/use-issue-type-field branch June 5, 2026 15:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Evangelink@azat-msft