#!/usr/bin/env python3 """Generate .github/copilot-instructions.md from AGENTS.md and the PR template.""" from pathlib import Path import sys GENERATED_MESSAGE = ( f"\n\n" ) AGENTS_FILE = Path("AGENTS.md") OUTPUT_FILE = Path(".github/copilot-instructions.md") PR_TEMPLATE_FILE = Path(".github/PULL_REQUEST_TEMPLATE.md") COPILOT_SPECIFIC_INSTRUCTIONS = """ # Copilot code review instructions - Start review comments with a short, one-sentence summary of the suggested fix. - Do not comment on code style, formatting or linting issues. - When reviewing changes under `homeassistant/components/` or `tests/components/`, use the `ha-integration-knowledge` skill as the primary reference. - Flag comments that over-explain straightforward code, narrate the obvious, or read like AI commentary (multi-sentence justifications for a single line). - A Pull Request with a dependency version bump should only contain changes required for the version bump. If the PR includes other changes, request that they are removed from the PR. - Check that the PR description is complete and filled in according to the PR template included below. Every section and checklist item from the template must be present, except the `## Breaking change` section which is optional. No content from the template should be missing, except for HTML comments and Markdown link reference definitions (lines of the form `[name]: url`), which do not render and cannot be verified from the description. Even unchecked checkboxes or empty sections must be present. This is a hard requirement. ## Pull Request template The PR description must follow this template (from `.github/PULL_REQUEST_TEMPLATE.md`): ```markdown {pr_template} ``` """ def generate_output() -> str: """Generate the copilot-instructions.md content.""" if not AGENTS_FILE.exists(): print(f"Error: {AGENTS_FILE} not found") sys.exit(1) if not PR_TEMPLATE_FILE.exists(): print(f"Error: {PR_TEMPLATE_FILE} not found") sys.exit(1) copilot_instructions = COPILOT_SPECIFIC_INSTRUCTIONS.replace( "{pr_template}", PR_TEMPLATE_FILE.read_text().strip() ) output_parts: list[str] = [GENERATED_MESSAGE, copilot_instructions] # Add AGENTS.md content agents_content = AGENTS_FILE.read_text() output_parts.append(agents_content.strip()) output_parts.append("") return "\n".join(output_parts) def check_file(path: Path, expected_content: str): """Check if the file exists and has the expected content.""" if not path.exists(): print(f"Error: {path} does not exist") sys.exit(1) existing = path.read_text() if existing != expected_content: print(f"Error: {path} is out of date") print("Please run: python -m script.gen_copilot_instructions") sys.exit(1) print(f"{path} is up to date") def main(validate: bool = False) -> int: """Run the script.""" if not Path("homeassistant").is_dir(): print("Run this from HA root dir") return 1 main_content = generate_output() if validate: check_file(OUTPUT_FILE, main_content) return 0 OUTPUT_FILE.write_text(main_content) print(f"Generated {OUTPUT_FILE}") return 0 if __name__ == "__main__": _validate = len(sys.argv) > 1 and sys.argv[1] == "validate" sys.exit(main(_validate))