Coverage for src / gh_secrets_and_vars_async / status.py: 93%
55 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-16 17:56 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-16 17:56 +0000
1"""Informational status dump for a GitHub repository.
3``ai-gh status`` is intentionally opinion-free: it reports current
4auto-merge state, any non-default repo configuration, all current
5rulesets (including org-inherited ones), and whether a pipeline file
6exists on disk. It no longer compares anything to an in-tool template.
7"""
9from pathlib import Path
11import click
12from rich import print
13from rich.table import Table
15from .common import get_github_repo, load_env_config
16from .config import get_auto_merge_status, has_dev_branch
17from .rulesets import display_rulesets, get_rulesets
19# GitHub repo default values. A setting is reported in the "non-default"
20# section only if its current value differs from what's listed here.
21REPO_SETTING_DEFAULTS: dict[str, object] = {
22 "allow_merge_commit": True,
23 "allow_squash_merge": True,
24 "allow_rebase_merge": True,
25 "allow_auto_merge": False,
26 "delete_branch_on_merge": False,
27 "allow_update_branch": False,
28 "web_commit_signoff_required": False,
29 "has_issues": True,
30 "has_projects": True,
31 "has_wiki": True,
32 "merge_commit_title": "MERGE_MESSAGE",
33 "merge_commit_message": "PR_TITLE",
34 "squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
35 "squash_merge_commit_message": "COMMIT_MESSAGES",
36}
39def _get_repo_attr(repo: object, name: str) -> object | None:
40 """Read an attribute from a PyGithub Repository, returning None on failure."""
41 try:
42 value: object = getattr(repo, name)
43 except Exception:
44 return None
45 return value
48def check_auto_merge(repo) -> str:
49 """Return a human-readable line describing the auto-merge state."""
50 if get_auto_merge_status(repo):
51 return "[green]enabled[/green]"
52 return "[red]disabled[/red]"
55def check_repo_settings(repo) -> list[tuple[str, str]]:
56 """Return (setting, current_value) rows for any non-default repo setting.
58 Skips settings that match GitHub's defaults. ``allow_auto_merge`` is
59 intentionally reported here too even though it's also shown above, so
60 users see the full merge policy in one table.
61 """
62 rows: list[tuple[str, str]] = []
63 for name, default in REPO_SETTING_DEFAULTS.items():
64 value = _get_repo_attr(repo, name)
65 if value is None:
66 continue
67 if value != default:
68 rows.append((name, str(value)))
70 if has_dev_branch(repo):
71 rows.append(("dev branch", "present"))
73 return rows
76def check_pipeline_file() -> str:
77 """Return a human-readable line describing the pipeline file state."""
78 if Path(".github/workflows/pipeline.yaml").exists():
79 return "[green].github/workflows/pipeline.yaml exists[/green]"
80 return (
81 "[yellow].github/workflows/pipeline.yaml not found "
82 "(run /ai-standardize-pipeline in augint-shell)[/yellow]"
83 )
86@click.command("status")
87@click.option("--verbose", "-v", is_flag=True, help="Show additional detail.")
88def status_command(verbose: bool) -> None:
89 """Show repository configuration: auto-merge, non-default settings, rulesets, pipeline file."""
90 gh_repo, gh_account, _ = load_env_config()
91 if not gh_repo or not gh_account:
92 raise click.ClickException("GH_REPO and GH_ACCOUNT must be set in .env or environment.")
94 repo = get_github_repo(gh_account, gh_repo)
96 print(f"\n[bold]Status: {gh_account}/{gh_repo}[/bold]\n")
98 # 1. Auto-merge
99 print(f"[bold]Auto-merge:[/bold] {check_auto_merge(repo)}")
101 # 2. Non-default repo configuration
102 non_default = check_repo_settings(repo)
103 if non_default:
104 table = Table(show_header=True, header_style="bold", title="Non-default settings")
105 table.add_column("Setting")
106 table.add_column("Value")
107 for name, value in non_default:
108 table.add_row(name, value)
109 print(table)
110 else:
111 print("[dim]All repo settings are at GitHub defaults.[/dim]")
113 # 3. Rulesets
114 print("\n[bold]Rulesets[/bold]")
115 rulesets = get_rulesets(repo)
116 display_rulesets(rulesets)
118 # 4. Pipeline file
119 print(f"\n[bold]Pipeline:[/bold] {check_pipeline_file()}")