From 1f1196b7309a7aaf11b3e311504a71c80aec21bf Mon Sep 17 00:00:00 2001 From: Aditya Pujara <59631311+a0x1ab@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:06:04 +0930 Subject: [PATCH 1/6] Move Azure CLI skills into repository policy Copilot-Session: da851f42-f383-454b-83ea-398b7c4c972a --- .x/coordinator.md | 9 ++- .x/fixer.md | 9 ++- .x/reviewer.md | 6 +- .x/skills/README.md | 11 ++- .x/skills/changed_test_files.py | 23 ++++++ .../find_aaz_fork_prs_ready_for_promotion.py | 8 ++ .x/skills/find_promoted_aaz_source_pr.py | 9 +++ .../get_pr_regression_coverage_summary.py | 66 +++++++++++++++ .x/skills/infer_target_for_repo.py | 80 +++++++++++++++++++ .x/skills/promote_aaz_fork_pr.py | 11 +++ .x/skills/start_aaz_source_task.py | 12 +++ .x/skills/start_extension_tracker_task.py | 22 +++++ .x/tester.md | 11 ++- .x/x.yml | 24 +++--- 14 files changed, 276 insertions(+), 25 deletions(-) create mode 100644 .x/skills/changed_test_files.py create mode 100644 .x/skills/find_aaz_fork_prs_ready_for_promotion.py create mode 100644 .x/skills/find_promoted_aaz_source_pr.py create mode 100644 .x/skills/get_pr_regression_coverage_summary.py create mode 100644 .x/skills/infer_target_for_repo.py create mode 100644 .x/skills/promote_aaz_fork_pr.py create mode 100644 .x/skills/start_aaz_source_task.py create mode 100644 .x/skills/start_extension_tracker_task.py diff --git a/.x/coordinator.md b/.x/coordinator.md index fbf5a5489ea..c69869e48d7 100644 --- a/.x/coordinator.md +++ b/.x/coordinator.md @@ -16,8 +16,13 @@ For this repository, apply the generic loop priorities as follows: `Azure/azure-cli` before normal work. Never act on a dispute from another repository. 2. Handle explicit, deduplicated human feedback on an Agent-managed PR. -3. Promote completed Copilot fork work and complete any required AAZ source - promotion before downstream readiness. +3. Promote completed Copilot fork work. After a downstream CLI PR exists, use + the repository-owned `start_aaz_source_task` custom skill when generated + AAZ output requires a durable source change. Discover completed source work + with `find_aaz_fork_prs_ready_for_promotion`, promote it with + `promote_aaz_fork_pr`, and confirm the live source PR with + `find_promoted_aaz_source_pr` before downstream readiness. Do not invoke the + neutral generation-source bridge primitives directly. 4. Trigger missing CI for a ready fork PR. 5. Send an actionable in-flight PR to Tester, then Reviewer after required live tests and CI complete. diff --git a/.x/fixer.md b/.x/fixer.md index 48edaf607be..819b09e8bd0 100644 --- a/.x/fixer.md +++ b/.x/fixer.md @@ -19,15 +19,18 @@ for a due single follow-up. Stop after either write. ## Target and implementation routing -For sufficient reports, call `infer_target_for_repo` with the sanitized text. -Verify the returned target against current repository structure. +For sufficient reports, call the repository-owned `infer_target_for_repo` +custom skill with `repo_full_name="Azure/azure-cli"`, the sanitized text, and +an empty `pr_files` list. It resolves only against the configured live module +and extension roots. Verify the returned target against current repository +structure. - A core module remains in `Azure/azure-cli`. Build the exact `[Component] Fix #N: \`az ...\`: Summary` title with `pr_title_for`, include `pr_format_guidance`, post the evidence-based bug analysis, then start the configured Copilot fork task. - An extension is routed with the idempotent - `start_extension_tracker_task` workflow to + repository-owned `start_extension_tracker_task` custom skill to `Azure/azure-cli-extensions`. It creates or resumes the tracker, records a pending source marker, starts Copilot in the extension fork, and finalizes the source backlink only after dispatch succeeds. Include the complete diff --git a/.x/reviewer.md b/.x/reviewer.md index 6e7ab513efd..528aaee3468 100644 --- a/.x/reviewer.md +++ b/.x/reviewer.md @@ -10,9 +10,9 @@ human reviews, and live-test state once. Pending required CI or live tests are waiting, not failure. If the current decisive human review requests changes, preserve that state and do not post an Agent pass. -Run `get_pr_regression_coverage_summary` and `get_pr_review_skill_summary` -against -the current diff. Deterministic findings are requirements. Semantic candidates +Run the repository-owned `get_pr_regression_coverage_summary` custom skill +with the PR number, then run `get_pr_review_skill_summary` against the current +diff. Deterministic findings are requirements. Semantic candidates become findings only when changed-line evidence confirms them. Diagnose each failed check as PR-related, unrelated, or uncertain and include the exact evidence, practical correction, and focused verification. diff --git a/.x/skills/README.md b/.x/skills/README.md index e2327c98c91..a95f43076a9 100644 --- a/.x/skills/README.md +++ b/.x/skills/README.md @@ -1,6 +1,9 @@ # Custom skills -This repository currently uses the approved X Engineering Agent base skill -library. A repository-owned custom skill must be one Python file containing -one public top-level function and must be mapped in `.x/x.yml`. Markdown files -in this directory are documentation and are never executable. +Each Python file contains one repository-owned public function mapped by +`.x/x.yml`. Custom skills own Azure CLI target inference, regression policy, +AAZ source routing, and the CLI-to-Extensions handoff. Authentication, +sensitive-data checks, repository scoping, and narrow GitHub mutations remain +in the approved base primitives. Repository directory discovery resolves roots +and branches from central trusted configuration rather than repository-supplied +arguments. Markdown files are never executable. diff --git a/.x/skills/changed_test_files.py b/.x/skills/changed_test_files.py new file mode 100644 index 00000000000..a7052b2eceb --- /dev/null +++ b/.x/skills/changed_test_files.py @@ -0,0 +1,23 @@ +"""Select changed Azure CLI pytest modules.""" + + +def changed_test_files(pr_files): + """Return unique changed test filename stems outside azure-cli-core.""" + stems = [] + seen = set() + for path in pr_files or []: + normalized = str(path).replace("\\", "/") + lowered = normalized.casefold() + name = normalized.rsplit("/", 1)[-1] + if ( + "/tests/" not in f"/{lowered}" + or not name.casefold().startswith("test_") + or not name.casefold().endswith(".py") + or "azure-cli-core" in lowered.split("/") + ): + continue + stem = name[:-3] + if stem not in seen: + seen.add(stem) + stems.append(stem) + return stems diff --git a/.x/skills/find_aaz_fork_prs_ready_for_promotion.py b/.x/skills/find_aaz_fork_prs_ready_for_promotion.py new file mode 100644 index 00000000000..437a5ac80cd --- /dev/null +++ b/.x/skills/find_aaz_fork_prs_ready_for_promotion.py @@ -0,0 +1,8 @@ +"""Bind generation-source candidate discovery to Azure CLI.""" + + +def find_aaz_fork_prs_ready_for_promotion(): + """Find completed AAZ fork pull requests ready for promotion.""" + return find_generation_source_fork_prs_ready_for_promotion( + repository=None, + ) diff --git a/.x/skills/find_promoted_aaz_source_pr.py b/.x/skills/find_promoted_aaz_source_pr.py new file mode 100644 index 00000000000..d65254d03c4 --- /dev/null +++ b/.x/skills/find_promoted_aaz_source_pr.py @@ -0,0 +1,9 @@ +"""Bind promoted generation-source lookup to Azure CLI.""" + + +def find_promoted_aaz_source_pr(issue_number): + """Find the promoted AAZ source pull request for an Agent issue.""" + return find_promoted_generation_source_pr( + repository=None, + issue_number=issue_number, + ) diff --git a/.x/skills/get_pr_regression_coverage_summary.py b/.x/skills/get_pr_regression_coverage_summary.py new file mode 100644 index 00000000000..6598f96fb30 --- /dev/null +++ b/.x/skills/get_pr_regression_coverage_summary.py @@ -0,0 +1,66 @@ +"""Evaluate Azure CLI command-module regression coverage.""" + + +def get_pr_regression_coverage_summary(pr_number): + """Find changed command modules without focused tests or recordings.""" + changes = get_pr_file_changes( + owner=None, + repo=None, + pr_number=pr_number, + ) + files = [ + item.get("filename") + for item in changes + if isinstance(item, dict) and item.get("filename") + ] + root = "src/azure-cli/azure/cli/command_modules/" + production_files = [] + modules = set() + for path in files: + normalized = str(path).replace("\\", "/") + name = normalized.rsplit("/", 1)[-1] + if ( + normalized.startswith(root) + and normalized.endswith(".py") + and "/tests/" not in normalized + and name not in {"__init__.py", "_help.py"} + ): + production_files.append(normalized) + remainder = normalized[len(root):] + module = remainder.split("/", 1)[0].split(".", 1)[0].casefold() + if module: + modules.add(module) + + test_files = [] + recording_files = [] + covered = set() + for path in files: + normalized = str(path).replace("\\", "/") + if not normalized.startswith(root) or "/tests/" not in normalized: + continue + module = ( + normalized[len(root):] + .split("/", 1)[0] + .split(".", 1)[0] + .casefold() + ) + if module not in modules: + continue + name = normalized.rsplit("/", 1)[-1] + if name.casefold().startswith("test_") and name.casefold().endswith(".py"): + test_files.append(normalized) + covered.add(module) + if "/recordings/" in normalized: + recording_files.append(normalized) + covered.add(module) + + uncovered = sorted(modules - covered) + return { + "applicable": bool(production_files), + "gap": bool(uncovered), + "modules": sorted(modules), + "uncovered_modules": uncovered, + "production_files": production_files, + "test_files": test_files, + "recording_files": recording_files, + } diff --git a/.x/skills/infer_target_for_repo.py b/.x/skills/infer_target_for_repo.py new file mode 100644 index 00000000000..66aa11ea13d --- /dev/null +++ b/.x/skills/infer_target_for_repo.py @@ -0,0 +1,80 @@ +"""Infer an Azure CLI module or extension from trusted repository structure.""" + + +def infer_target_for_repo(repo_full_name, text, pr_files): + """Resolve a sanitized issue or PR diff to a live CLI target.""" + if repo_full_name != "Azure/azure-cli": + raise ValueError("infer_target_for_repo is restricted to Azure/azure-cli") + + modules = list_repository_directories( + source_repository="Azure/azure-cli", + ) + extensions = list_repository_directories( + source_repository="Azure/azure-cli-extensions", + ) + + def normalize(value): + return "".join( + character + for character in str(value or "").casefold() + if character.isalnum() + ) + + def resolve(candidate): + candidate_normalized = normalize(candidate) + for extension in extensions: + if normalize(extension) == candidate_normalized: + return { + "kind": "extension", + "name": extension, + "repo": "Azure/azure-cli-extensions", + } + for module in modules: + if normalize(module) == candidate_normalized: + return { + "kind": "module", + "name": module, + "repo": "Azure/azure-cli", + } + return None + + scores = {} + for path in pr_files or []: + parts = str(path).replace("\\", "/").split("/") + if "command_modules" in parts: + index = parts.index("command_modules") + if index + 1 < len(parts): + candidate = parts[index + 1] + scores[candidate] = scores.get(candidate, 0) + 10 + elif len(parts) > 1 and parts[0].casefold() == "src": + candidate = parts[1] + scores[candidate] = scores.get(candidate, 0) + 10 + if pr_files: + for candidate in sorted(scores, key=lambda item: (-scores[item], item)): + target = resolve(candidate) + if target is not None: + return target + return {"kind": "none", "name": None, "repo": None} + + cleaned = "".join( + character if character.isalnum() or character in "-_./" else " " + for character in str(text or "").casefold() + ) + words = cleaned.split() + for index, word in enumerate(words): + if word == "az" and index + 1 < len(words): + candidate = words[index + 1] + scores[candidate] = scores.get(candidate, 0) + 5 + if word.startswith("src/"): + parts = word.split("/") + if len(parts) > 1: + candidate = parts[1] + scores[candidate] = scores.get(candidate, 0) + 3 + if "command_modules/" in word: + candidate = word.split("command_modules/", 1)[1].split("/", 1)[0] + scores[candidate] = scores.get(candidate, 0) + 3 + for candidate in sorted(scores, key=lambda item: (-scores[item], item)): + target = resolve(candidate) + if target is not None: + return target + return {"kind": "unknown", "name": None, "repo": None} diff --git a/.x/skills/promote_aaz_fork_pr.py b/.x/skills/promote_aaz_fork_pr.py new file mode 100644 index 00000000000..e959a464f36 --- /dev/null +++ b/.x/skills/promote_aaz_fork_pr.py @@ -0,0 +1,11 @@ +"""Bind generation-source promotion to Azure CLI.""" + + +def promote_aaz_fork_pr(fork_pr_number, title, body): + """Promote one validated AAZ fork pull request.""" + return promote_generation_source_fork_pr( + repository=None, + fork_pr_number=fork_pr_number, + title=title, + body=body, + ) diff --git a/.x/skills/start_aaz_source_task.py b/.x/skills/start_aaz_source_task.py new file mode 100644 index 00000000000..f23edff1cb6 --- /dev/null +++ b/.x/skills/start_aaz_source_task.py @@ -0,0 +1,12 @@ +"""Bind durable generation-source task creation to Azure CLI.""" + + +def start_aaz_source_task(issue_number, downstream_pr_url, changed_files, prompt_context): + """Start the configured AAZ source task for an Azure CLI pull request.""" + return start_generation_source_task( + repository=None, + issue_number=issue_number, + downstream_pr_url=downstream_pr_url, + changed_files=changed_files, + prompt_context=prompt_context, + ) diff --git a/.x/skills/start_extension_tracker_task.py b/.x/skills/start_extension_tracker_task.py new file mode 100644 index 00000000000..e8a6e27c8b7 --- /dev/null +++ b/.x/skills/start_extension_tracker_task.py @@ -0,0 +1,22 @@ +"""Own the Azure CLI to CLI Extensions implementation handoff.""" + + +def start_extension_tracker_task(issue_number, view, target, prompt, command, summary): + """Create or resume the scoped extension tracker and Copilot task.""" + if ( + not isinstance(target, dict) + or target.get("repo") != "Azure/azure-cli-extensions" + or not target.get("name") + ): + raise ValueError( + "start_extension_tracker_task requires a CLI Extensions target" + ) + return start_repository_handoff_task( + repository=None, + issue_number=issue_number, + view=view, + target=target, + prompt=prompt, + command=command, + summary=summary, + ) diff --git a/.x/tester.md b/.x/tester.md index dff21ffe389..b4745900669 100644 --- a/.x/tester.md +++ b/.x/tester.md @@ -5,10 +5,13 @@ Coordinator whose current head either has a completed Copilot task marker or is a verified human-requested review candidate, and has no completed live-test run for that head. -Use `dispatch_live_test_workflow` with the PR number and -`pr_repo="Azure/azure-cli"`. Do not provide a guessed module; the dispatcher -resolves changed files against the live module list and the workflow validates -the target. +Read the PR and `get_pr_file_changes` once. Pass the filenames to the +repository-owned `changed_test_files` custom skill and call +`infer_target_for_repo` with the PR title/body and those filenames. Use +`dispatch_live_test_workflow` with the PR number, +`pr_repo="Azure/azure-cli"`, and the resolved module and target kind. Never +guess a module; the custom skill resolves only against configured live roots +and the workflow validates the target. Before dispatch, reuse any queued, in-progress, or completed run for the same head SHA. A new dispatch counts as one action; a reused run is a read. Call diff --git a/.x/x.yml b/.x/x.yml index b9eb8e4d5f4..afc0a60f9b1 100644 --- a/.x/x.yml +++ b/.x/x.yml @@ -6,18 +6,17 @@ agents: skills: - auto_trigger_pr_validation - build_promoted_pr_body - - changed_test_files - codegen_execution_guidance - compare_issue_similarity - copilot_iteration_cap_reached - copilot_iteration_state - daily_pr_cap_reached - dispatch_live_test_workflow - - find_aaz_fork_prs_ready_for_promotion - find_copilot_fork_prs_ready_for_promotion - find_fork_prs_needing_ci + - find_generation_source_fork_prs_ready_for_promotion - find_in_flight_prs - - find_promoted_aaz_source_pr + - find_promoted_generation_source_pr - find_sensitive_redaction_dispute - find_stale_prs - follow_up_requirements @@ -30,13 +29,12 @@ skills: - get_pr_check_runs - get_pr_check_summary - get_pr_file_changes - - get_pr_regression_coverage_summary - get_pr_review_skill_summary - get_profile - get_workflow_run - handle_sensitive_redaction_dispute - has_agent_reviewed_head - - infer_target_for_repo + - list_repository_directories - mark_pr_ready_for_review - post_bug_analysis - post_comment @@ -44,7 +42,7 @@ skills: - post_pr_review - pr_format_guidance - pr_title_for - - promote_aaz_fork_pr + - promote_generation_source_fork_pr - promote_copilot_fork_pr - recall_repository_memory - remediate_sensitive_issue @@ -60,10 +58,18 @@ skills: - safe_issue_view - select_triagable_issues_for_repo - similar_issue_candidates - - start_aaz_source_task - start_copilot_fork_task - - start_extension_tracker_task + - start_generation_source_task + - start_repository_handoff_task - synchronize_pull_request_feedback - synchronize_repository_feedback - update_pr_branch -custom_skills: {} +custom_skills: + changed_test_files: changed_test_files + find_aaz_fork_prs_ready_for_promotion: find_aaz_fork_prs_ready_for_promotion + find_promoted_aaz_source_pr: find_promoted_aaz_source_pr + get_pr_regression_coverage_summary: get_pr_regression_coverage_summary + infer_target_for_repo: infer_target_for_repo + promote_aaz_fork_pr: promote_aaz_fork_pr + start_aaz_source_task: start_aaz_source_task + start_extension_tracker_task: start_extension_tracker_task From ff35dd6a3d119b43e6930ac07ec786900b14ea0d Mon Sep 17 00:00:00 2001 From: Aditya Pujara <59631311+a0x1ab@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:24:43 +0930 Subject: [PATCH 2/6] Remove custom skills README Copilot-Session: da851f42-f383-454b-83ea-398b7c4c972a --- .x/skills/README.md | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .x/skills/README.md diff --git a/.x/skills/README.md b/.x/skills/README.md deleted file mode 100644 index a95f43076a9..00000000000 --- a/.x/skills/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Custom skills - -Each Python file contains one repository-owned public function mapped by -`.x/x.yml`. Custom skills own Azure CLI target inference, regression policy, -AAZ source routing, and the CLI-to-Extensions handoff. Authentication, -sensitive-data checks, repository scoping, and narrow GitHub mutations remain -in the approved base primitives. Repository directory discovery resolves roots -and branches from central trusted configuration rather than repository-supplied -arguments. Markdown files are never executable. From 29fe438a5346fab0774f7f7b56ec986478a50c32 Mon Sep 17 00:00:00 2001 From: Aditya Pujara <59631311+a0x1ab@users.noreply.github.com> Date: Fri, 4 Sep 2026 16:26:04 +0930 Subject: [PATCH 3/6] Fix tester target inference arguments Copilot-Session: da851f42-f383-454b-83ea-398b7c4c972a --- .x/tester.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.x/tester.md b/.x/tester.md index b4745900669..9860d8370b6 100644 --- a/.x/tester.md +++ b/.x/tester.md @@ -7,7 +7,8 @@ run for that head. Read the PR and `get_pr_file_changes` once. Pass the filenames to the repository-owned `changed_test_files` custom skill and call -`infer_target_for_repo` with the PR title/body and those filenames. Use +`infer_target_for_repo` with `repo_full_name="Azure/azure-cli"`, `text` set to +the PR title/body, and `pr_files` set to those filenames. Use `dispatch_live_test_workflow` with the PR number, `pr_repo="Azure/azure-cli"`, and the resolved module and target kind. Never guess a module; the custom skill resolves only against configured live roots From e940fab97597bd783b27517626b11d0f7396f770 Mon Sep 17 00:00:00 2001 From: Aditya Pujara <59631311+a0x1ab@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:05:46 +0930 Subject: [PATCH 4/6] Complete repository-owned agent workflows --- .x/reviewer.md | 9 ++++++--- .x/skills/changed_test_files.py | 15 +++++++-------- .x/tester.md | 7 ++++--- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.x/reviewer.md b/.x/reviewer.md index 528aaee3468..6f6e9022d1a 100644 --- a/.x/reviewer.md +++ b/.x/reviewer.md @@ -28,9 +28,12 @@ Require: - owning-team review for high-risk auth, security, core runtime, generated surface, or broad behavior changes. -Use `repair_pr_title_check` only for a confirmed metadata-gate failure, -then read the rerun in a later round. Combine CI, live-test, regression, risk, -and review-skill evidence in one review. +Use `repair_pr_title_check` only for a confirmed metadata-gate failure. Resolve +the component first with repository-owned `infer_target_for_repo` using the +current PR title, body, and changed filenames, then pass its name as +`component`; central title repair must not infer repository policy. Read the +rerun in a later round. Combine CI, live-test, regression, risk, and +review-skill evidence in one review. For a human-requested PR, post one `COMMENT`. For a Copilot-authored PR with relevant failures, use `request_copilot_changes`; after the iteration cap, diff --git a/.x/skills/changed_test_files.py b/.x/skills/changed_test_files.py index a7052b2eceb..006d1900ff9 100644 --- a/.x/skills/changed_test_files.py +++ b/.x/skills/changed_test_files.py @@ -1,9 +1,9 @@ -"""Select changed Azure CLI pytest modules.""" +"""Select changed Azure CLI live-test files.""" def changed_test_files(pr_files): - """Return unique changed test filename stems outside azure-cli-core.""" - stems = [] + """Return unique changed pytest paths outside azure-cli-core.""" + selected = [] seen = set() for path in pr_files or []: normalized = str(path).replace("\\", "/") @@ -16,8 +16,7 @@ def changed_test_files(pr_files): or "azure-cli-core" in lowered.split("/") ): continue - stem = name[:-3] - if stem not in seen: - seen.add(stem) - stems.append(stem) - return stems + if normalized not in seen: + seen.add(normalized) + selected.append(normalized) + return selected diff --git a/.x/tester.md b/.x/tester.md index 9860d8370b6..fc6afa226eb 100644 --- a/.x/tester.md +++ b/.x/tester.md @@ -10,9 +10,10 @@ repository-owned `changed_test_files` custom skill and call `infer_target_for_repo` with `repo_full_name="Azure/azure-cli"`, `text` set to the PR title/body, and `pr_files` set to those filenames. Use `dispatch_live_test_workflow` with the PR number, -`pr_repo="Azure/azure-cli"`, and the resolved module and target kind. Never -guess a module; the custom skill resolves only against configured live roots -and the workflow validates the target. +`pr_repo="Azure/azure-cli"`, the resolved module and target kind, and +`test_files` set to the paths returned by `changed_test_files`. Never guess a +module or test path; repository custom skills own both decisions and the +workflow validates them against the current PR. Before dispatch, reuse any queued, in-progress, or completed run for the same head SHA. A new dispatch counts as one action; a reused run is a read. Call From 6a09333cef32336e0884e6485710074b8548a63c Mon Sep 17 00:00:00 2001 From: Aditya Pujara <59631311+a0x1ab@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:30:06 +0930 Subject: [PATCH 5/6] Address custom skill review feedback --- .x/skills/find_aaz_fork_prs_ready_for_promotion.py | 2 +- .x/skills/find_promoted_aaz_source_pr.py | 2 +- .x/skills/get_pr_regression_coverage_summary.py | 4 ++-- .x/skills/promote_aaz_fork_pr.py | 2 +- .x/skills/start_aaz_source_task.py | 2 +- .x/skills/start_extension_tracker_task.py | 2 +- .x/tester.md | 5 +++++ 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.x/skills/find_aaz_fork_prs_ready_for_promotion.py b/.x/skills/find_aaz_fork_prs_ready_for_promotion.py index 437a5ac80cd..0902b1849fc 100644 --- a/.x/skills/find_aaz_fork_prs_ready_for_promotion.py +++ b/.x/skills/find_aaz_fork_prs_ready_for_promotion.py @@ -4,5 +4,5 @@ def find_aaz_fork_prs_ready_for_promotion(): """Find completed AAZ fork pull requests ready for promotion.""" return find_generation_source_fork_prs_ready_for_promotion( - repository=None, + repository="Azure/azure-cli", ) diff --git a/.x/skills/find_promoted_aaz_source_pr.py b/.x/skills/find_promoted_aaz_source_pr.py index d65254d03c4..4fc2784d8f2 100644 --- a/.x/skills/find_promoted_aaz_source_pr.py +++ b/.x/skills/find_promoted_aaz_source_pr.py @@ -4,6 +4,6 @@ def find_promoted_aaz_source_pr(issue_number): """Find the promoted AAZ source pull request for an Agent issue.""" return find_promoted_generation_source_pr( - repository=None, + repository="Azure/azure-cli", issue_number=issue_number, ) diff --git a/.x/skills/get_pr_regression_coverage_summary.py b/.x/skills/get_pr_regression_coverage_summary.py index 6598f96fb30..ef77a9cbb29 100644 --- a/.x/skills/get_pr_regression_coverage_summary.py +++ b/.x/skills/get_pr_regression_coverage_summary.py @@ -4,8 +4,8 @@ def get_pr_regression_coverage_summary(pr_number): """Find changed command modules without focused tests or recordings.""" changes = get_pr_file_changes( - owner=None, - repo=None, + owner="Azure", + repo="azure-cli", pr_number=pr_number, ) files = [ diff --git a/.x/skills/promote_aaz_fork_pr.py b/.x/skills/promote_aaz_fork_pr.py index e959a464f36..d587ee03af7 100644 --- a/.x/skills/promote_aaz_fork_pr.py +++ b/.x/skills/promote_aaz_fork_pr.py @@ -4,7 +4,7 @@ def promote_aaz_fork_pr(fork_pr_number, title, body): """Promote one validated AAZ fork pull request.""" return promote_generation_source_fork_pr( - repository=None, + repository="Azure/azure-cli", fork_pr_number=fork_pr_number, title=title, body=body, diff --git a/.x/skills/start_aaz_source_task.py b/.x/skills/start_aaz_source_task.py index f23edff1cb6..ae94157fb64 100644 --- a/.x/skills/start_aaz_source_task.py +++ b/.x/skills/start_aaz_source_task.py @@ -4,7 +4,7 @@ def start_aaz_source_task(issue_number, downstream_pr_url, changed_files, prompt_context): """Start the configured AAZ source task for an Azure CLI pull request.""" return start_generation_source_task( - repository=None, + repository="Azure/azure-cli", issue_number=issue_number, downstream_pr_url=downstream_pr_url, changed_files=changed_files, diff --git a/.x/skills/start_extension_tracker_task.py b/.x/skills/start_extension_tracker_task.py index e8a6e27c8b7..d51a3db0513 100644 --- a/.x/skills/start_extension_tracker_task.py +++ b/.x/skills/start_extension_tracker_task.py @@ -12,7 +12,7 @@ def start_extension_tracker_task(issue_number, view, target, prompt, command, su "start_extension_tracker_task requires a CLI Extensions target" ) return start_repository_handoff_task( - repository=None, + repository="Azure/azure-cli", issue_number=issue_number, view=view, target=target, diff --git a/.x/tester.md b/.x/tester.md index fc6afa226eb..2344b69d8d8 100644 --- a/.x/tester.md +++ b/.x/tester.md @@ -15,6 +15,11 @@ the PR title/body, and `pr_files` set to those filenames. Use module or test path; repository custom skills own both decisions and the workflow validates them against the current PR. +If no test path is selected, call the dispatcher with the empty list so it +records a neutral skip for the current revision. If tests are selected but +target inference does not return a named `module` or `extension`, stop with a +pending result and do not dispatch. + Before dispatch, reuse any queued, in-progress, or completed run for the same head SHA. A new dispatch counts as one action; a reused run is a read. Call `get_workflow_run` once. If it is not complete, return pending and let a later From 7f6b74b46bfea6c1caa80cab7ee26448273d0e06 Mon Sep 17 00:00:00 2001 From: Aditya Pujara <59631311+a0x1ab@users.noreply.github.com> Date: Fri, 4 Sep 2026 20:46:19 +0930 Subject: [PATCH 6/6] Add license headers to repository skills Copilot-Session: da851f42-f383-454b-83ea-398b7c4c972a --- .x/skills/changed_test_files.py | 5 +++++ .x/skills/find_aaz_fork_prs_ready_for_promotion.py | 5 +++++ .x/skills/find_promoted_aaz_source_pr.py | 5 +++++ .x/skills/get_pr_regression_coverage_summary.py | 5 +++++ .x/skills/infer_target_for_repo.py | 5 +++++ .x/skills/promote_aaz_fork_pr.py | 5 +++++ .x/skills/start_aaz_source_task.py | 5 +++++ .x/skills/start_extension_tracker_task.py | 5 +++++ 8 files changed, 40 insertions(+) diff --git a/.x/skills/changed_test_files.py b/.x/skills/changed_test_files.py index 006d1900ff9..658beecea10 100644 --- a/.x/skills/changed_test_files.py +++ b/.x/skills/changed_test_files.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Select changed Azure CLI live-test files.""" diff --git a/.x/skills/find_aaz_fork_prs_ready_for_promotion.py b/.x/skills/find_aaz_fork_prs_ready_for_promotion.py index 0902b1849fc..14775a85685 100644 --- a/.x/skills/find_aaz_fork_prs_ready_for_promotion.py +++ b/.x/skills/find_aaz_fork_prs_ready_for_promotion.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Bind generation-source candidate discovery to Azure CLI.""" diff --git a/.x/skills/find_promoted_aaz_source_pr.py b/.x/skills/find_promoted_aaz_source_pr.py index 4fc2784d8f2..5fbe0c22296 100644 --- a/.x/skills/find_promoted_aaz_source_pr.py +++ b/.x/skills/find_promoted_aaz_source_pr.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Bind promoted generation-source lookup to Azure CLI.""" diff --git a/.x/skills/get_pr_regression_coverage_summary.py b/.x/skills/get_pr_regression_coverage_summary.py index ef77a9cbb29..6f2827bab5d 100644 --- a/.x/skills/get_pr_regression_coverage_summary.py +++ b/.x/skills/get_pr_regression_coverage_summary.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Evaluate Azure CLI command-module regression coverage.""" diff --git a/.x/skills/infer_target_for_repo.py b/.x/skills/infer_target_for_repo.py index 66aa11ea13d..50287c81c58 100644 --- a/.x/skills/infer_target_for_repo.py +++ b/.x/skills/infer_target_for_repo.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Infer an Azure CLI module or extension from trusted repository structure.""" diff --git a/.x/skills/promote_aaz_fork_pr.py b/.x/skills/promote_aaz_fork_pr.py index d587ee03af7..d1ecbc94a10 100644 --- a/.x/skills/promote_aaz_fork_pr.py +++ b/.x/skills/promote_aaz_fork_pr.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Bind generation-source promotion to Azure CLI.""" diff --git a/.x/skills/start_aaz_source_task.py b/.x/skills/start_aaz_source_task.py index ae94157fb64..daf321c2759 100644 --- a/.x/skills/start_aaz_source_task.py +++ b/.x/skills/start_aaz_source_task.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Bind durable generation-source task creation to Azure CLI.""" diff --git a/.x/skills/start_extension_tracker_task.py b/.x/skills/start_extension_tracker_task.py index d51a3db0513..8b942c2e992 100644 --- a/.x/skills/start_extension_tracker_task.py +++ b/.x/skills/start_extension_tracker_task.py @@ -1,3 +1,8 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + """Own the Azure CLI to CLI Extensions implementation handoff."""