How ariesq/gh-safe-repo works
1. Project shape
- gh-safe-repo is a Python CLI tool, not a web service.
- The runtime is the Python standard library only; there are no runtime third-party dependencies.
- The main external boundaries are GitHub’s API, local git, and optional secret-scanning tooling.
2. Top-level control flow
- The CLI exposes three entry points: create, fix, and scan.
- create and fix both build a “plan” from desired vs current state, print that plan, then optionally apply it.
- scan is standalone and local-only; it never talks to GitHub.
3. Command layer
- gh_safe_repo/cli.py dispatches to subcommand handlers in gh_safe_repo/commands/.
- _common.py holds shared CLI context, formatting, confirmation, and plan rendering logic.
- create.py, fix.py, and scan.py orchestrate workflows but do not directly own the per-setting logic.
4. Configuration boundary
- Configuration is loaded before command execution and merged with CLI overrides.
- The precedence is explicit config path, local ./gh-safe-repo.ini, then user-level XDG config, with built-in defaults as the fallback.
- Configuration drives repository defaults, branch/tag protection behavior, security settings, scanner behavior, and git transport mode.
5. Settings-as-plugins architecture
- Repository settings are split into plugins under gh_safe_repo/plugins/.
- Each plugin owns one concern area: repository basics, Actions, branch protection, security, tag protection.
- The plugins share the same lifecycle: fetch current state, diff against desired state, return plan changes, then apply only real deltas.
6. Plan / diff model
- The tool’s central abstraction is a plan made of changes such as add, update, delete, or skip.
- create usually compares against GitHub defaults; fix compares against an existing repository’s live state.
- Dry-run and JSON output are both derived from this same plan model, so preview and execution stay consistent.
7. GitHub API integration
- All GitHub API calls are executed through gh api in subprocesses, rather than through a native GitHub SDK.
- Authentication is inherited from GITHUB_TOKEN or gh auth token, and the token is passed to child processes as GH_TOKEN.
- This keeps credential handling outside the application code and makes GitHub the main remote system boundary.
8. Repository creation and post-create mutation flow
- create first creates the repository, then applies repository settings, Actions policy, security settings, and protection rules.
- Branch protection and tag protection are applied after code push when needed so the target refs exist.
- In public repos or paid-plan private repos, protection and security features are enabled; on free private repos, unsupported items are surfaced as skipped in the plan.
9. Local git transport path
- The --local and --from workflows introduce a separate git transport boundary via gh_safe_repo/git_transport.py.
- These flows verify credentials up front, then use local clone/push operations to move code, not the GitHub API.
- The tool supports both mirror-style repo transfer and push-all-tags style local publication, with the original repo’s upstream configured after push for convenience.
10. Pre-flight security scanner
- gh_safe_repo/security_scanner.py is a local scanning subsystem used by scan and automatically before risky publish flows.
- It prefers native truffleHog, can fall back to containerized truffleHog via Docker/Podman, and finally a regex-based fallback.
- It detects secrets, banned strings, AI context files, emails, large files, and TODO/FIXME markers, with interactive approval before code ever reaches GitHub.
11. User-visible safety model
- The architecture is intentionally conservative: it previews changes, skips unsupported features instead of failing silently, and avoids no-op API calls.
- fix is audit-first; it can show drift without changing anything.
- create is safety-first; when code import is involved, it scans locally before pushing.
12. Supporting assets
- tests/ mirrors the architecture with unit tests for config, diffing, transport, GitHub client behavior, plugins, and scanner logic, plus end-to-end CLI coverage.
- docs/ captures the design rationale, API discoveries, manual test cases, and security research that shaped the current behavior.
Main entry points: github_client.py GH client · tests Tests · create.py Create · base.py Plugin base
Components 18
CLI flow
Command dispatch and user-facing orchestration
- CLI · Dispatches subcommands and argument handling
gh_safe_repo/cli.py - Shared cmd · Shared formatting, confirmation, and plan rendering
gh_safe_repo/commands/_common.py - Create · Creates a repo plan, prints it, then applies it optionally
gh_safe_repo/commands/create.py - Fix · Diffs live state against desired state and can apply drift fixes
gh_safe_repo/commands/fix.py - Scan · Runs local-only preflight scanning
gh_safe_repo/commands/scan.py
Core engine
Config, planning, and shared runtime logic
Settings plugins
Repository setting subsystems with shared lifecycle
- Plugin base · Shared lifecycle for fetch, diff, plan, and apply
gh_safe_repo/plugins/base.py - Repository · Repository basics and default settings
gh_safe_repo/plugins/repository.py - Actions · GitHub Actions policy and repository automation settings
gh_safe_repo/plugins/actions.py - Branch prot. · Branch protection rules and related ref policy
gh_safe_repo/plugins/branch_protection.py - Security · Advanced security and repo security settings
gh_safe_repo/plugins/security.py - Tag prot. · Tag protection rules
gh_safe_repo/plugins/tag_protection.py
External boundaries
GitHub, git, and local security scanning
- GH client · Executes GitHub API calls through gh subprocesses
gh_safe_repo/github_client.py - Git transport · Handles local clone, push, mirror, and tag publication flows
gh_safe_repo/git_transport.py - Scanner · Local secret and policy scanning with fallback strategies
gh_safe_repo/security_scanner.py
Connections 34
- CLI → Create: dispatch · Routes create subcommand
- CLI → Fix: dispatch · Routes fix subcommand
- CLI → Scan: dispatch · Routes scan subcommand
- Create → Shared cmd: uses · Shares plan rendering and confirmation
- Fix → Shared cmd: uses · Shares plan rendering and confirmation
- Scan → Scanner: runs · Invokes local scanning workflow
- Create → Config: loads · Builds runtime config before execution
- Fix → Config: loads · Builds runtime config before execution
- Scan → Config: loads · Reads scanner and CLI settings
- Create → Plan diff: builds · Constructs desired-versus-current plan
- Fix → Plan diff: builds · Constructs drift-remediation plan
- Plan diff → Plugin base: drives · Shared plan lifecycle across plugins
- Plugin base → Repository: implements · Repository settings plugin
- Plugin base → Actions: implements · Actions settings plugin
- Plugin base → Branch prot.: implements · Branch protection plugin
- Plugin base → Security: implements · Security settings plugin
- Plugin base → Tag prot.: implements · Tag protection plugin
- Repository → GH client: queries · Reads and mutates GitHub repository state
- Actions → GH client: queries · Reads and mutates GitHub repository state
- Branch prot. → GH client: queries · Reads and mutates GitHub repository state
- Security → GH client: queries · Reads and mutates GitHub repository state
- Tag prot. → GH client: queries · Reads and mutates GitHub repository state
- Create → Git transport: optional · Uses local publish and mirror flows when requested
- Create → Scanner: preflight · Scans local code before risky publish flows
- GH client → Git transport: token flow · Shares inherited GitHub auth with subprocesses
- Tests → CLI: covers · CLI behavior and command wiring
- Tests → Config: covers · Configuration precedence and merging
- Tests → Plan diff: covers · Plan and diff behavior
- Tests → Git transport: covers · Local transport flows
- Tests → GH client: covers · GitHub subprocess integration
- Tests → Scanner: covers · Security scanning behavior
- Docs → Config: documents · Captures configuration and defaults rationale
- Docs → GH client: documents · Captures API discovery and auth architecture
- Docs → Scanner: documents · Captures security research and manual testing