mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 01:59:34 +02:00
## Summary - skip AI issue triage when the latest issue state is closed and recheck state before publishing - restrict duplicate searches and digest canonical candidates to live open issues - add deterministic, additive `Product-*` labels from changed paths for draft and non-draft PRs - map Window Hopper, Cursor Wrap, and all Mouse Jump project paths to their specific product labels before generic fallbacks - preserve manually applied product labels while managing only intake lifecycle labels and trusted comments - collect the PowerToys version and release channel in one required bug/localization field - add Window Hopper to the bug report area dropdown and preserve parsing of both old and combined version headings This consolidates and supersedes #49961 and #49804. ## Validation - `node --test .github\scripts\pr-intake\tests\pr-intake.test.mjs` - 39 passing - `python -m unittest discover .github\scripts\issue-triage\tests -v` - 55 passing - parsed all modified issue-form and workflow YAML files with PyYAML - verified every current `src/modules/*` root maps to a product label - verified the Window Hopper path maps to `Product-Window Hopper` - `git diff --check` --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b313a270-e6e8-4c4a-89b2-880c1d79027c Copilot-Session: 498721d4-1098-4298-ac8a-147066fbfea3
74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
import unittest
|
|
from pathlib import Path
|
|
|
|
|
|
GITHUB_DIR = Path(__file__).resolve().parents[3]
|
|
WORKFLOW_SOURCE = GITHUB_DIR / "workflows" / "issue-triage.md"
|
|
WORKFLOW_LOCK = GITHUB_DIR / "workflows" / "issue-triage.lock.yml"
|
|
|
|
|
|
class WorkflowContractTests(unittest.TestCase):
|
|
def test_agent_evidence_uses_shared_runtime_directory(self):
|
|
source = WORKFLOW_SOURCE.read_text(encoding="utf-8")
|
|
generated = WORKFLOW_LOCK.read_text(encoding="utf-8")
|
|
|
|
for filename in (
|
|
"issue-context.md",
|
|
"triage-event.json",
|
|
"bug-report-context.md",
|
|
):
|
|
expected_path = f"/tmp/gh-aw/{filename}"
|
|
self.assertIn(expected_path, source)
|
|
self.assertIn(expected_path, generated)
|
|
|
|
def test_copilot_can_publish_without_general_write_or_shell_access(self):
|
|
generated = WORKFLOW_LOCK.read_text(encoding="utf-8")
|
|
|
|
self.assertIn("shell(safeoutputs:*)", generated)
|
|
self.assertIn("--deny-tool write", generated)
|
|
for command in (
|
|
"cat",
|
|
"date",
|
|
"echo",
|
|
"grep",
|
|
"head",
|
|
"ls",
|
|
"printf",
|
|
"pwd",
|
|
"sort",
|
|
"tail",
|
|
"uniq",
|
|
"wc",
|
|
"yq",
|
|
):
|
|
self.assertIn(f"--deny-tool '\\''shell({command})'\\''", generated)
|
|
|
|
def test_workflow_never_manages_version_labels(self):
|
|
source = WORKFLOW_SOURCE.read_text(encoding="utf-8")
|
|
generated = WORKFLOW_LOCK.read_text(encoding="utf-8")
|
|
|
|
for workflow in (source, generated):
|
|
self.assertNotIn("versionLabels", workflow)
|
|
self.assertNotIn("desiredVersionLabel", workflow)
|
|
self.assertRegex(source, r"never adds or removes\s+version labels")
|
|
|
|
def test_closed_issues_are_gated_before_publication(self):
|
|
source = WORKFLOW_SOURCE.read_text(encoding="utf-8")
|
|
generated = WORKFLOW_LOCK.read_text(encoding="utf-8")
|
|
|
|
self.assertIn("id: refresh", source)
|
|
self.assertEqual(
|
|
source.count("if: steps.refresh.outputs.should_process == 'true'"),
|
|
3,
|
|
)
|
|
for workflow in (source, generated):
|
|
self.assertIn("Issue is closed; ${action} was skipped.", workflow)
|
|
self.assertIn(
|
|
"currentIssue.closed_by?.login === 'github-actions[bot]'",
|
|
workflow,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|