gh-infra
Declarative GitHub infrastructure management via YAML. Like Terraform, but for GitHub — no state file required.
gh infra plan # Show what would change
gh infra apply # Apply the changes
📖 babarot.github.io/gh-infra — Full YAML reference, usage patterns, and guides.
Why
The Terraform GitHub Provider covers most GitHub-as-Code use cases, but it's overkill for personal or small-team use — provider installation, HCL, state files, and state locking add real overhead before you can change a single setting.
gh-infra takes a different approach:
- YAML instead of HCL. Declare what your repos should look like in plain YAML.
- No state file. GitHub itself is the source of truth. Every
planfetches the live state and diffs directly — there's nothing to store, lock, or lose. planbeforeapply. See exactly what will change before it happens. Most alternatives (Probot Settings, GHaC) apply immediately with no preview.- One file, many repos. A single
RepositorySetcan enforce consistent settings across dozens of repositories. No more clicking through the UI one repo at a time. - Just
ghand a token. No GitHub App, no server, no extra infrastructure. If you can rungh, you can rungh infra.
Install
gh extension install babarot/gh-infra
Agent Skills (optional)
Install gh-infra skills for your coding agent (Claude Code, Copilot, Codex, Cursor, etc.):
# via GitHub CLI (v2.90.0+)
gh skill install babarot/gh-infra
via npx
npx skills add babarot/gh-infra
This gives your agent knowledge of gh-infra commands, YAML schema, and CI/CD patterns so it can write and manage manifests for you.
Quick Start
1. Import an existing repository
gh infra import babarot/my-project > my-project.yaml
2. Edit the YAML to your desired state
apiVersion: gh-infra/v1
kind: Repository
metadata:
name: my-project
owner: babarot
spec:
description: "My awesome project"
visibility: public
topics:
- go
- cli
features:
issues: true
- projects: false
+ projects: true
wiki: false
discussions: true
3. Plan and apply
gh infra plan
gh infra apply
4. Run it in CI
Plan each pull request and post the plan as a comment, apply on merge, and check for drift on a schedule. With --changed-since, only the repositories a change affects are planned and applied. See CI/CD Integration for the workflows.
Commands
| Command | Description |
|---------|-------------|
| plan [path] | Show diff between YAML and current GitHub state |
| apply [path] | Apply changes (with confirmation prompt) |
| import | Export existing repo settings as YAML |
| validate [path] | Check YAML syntax and schema |
Path Resolution
plan, apply, and validate accept an optional [path] argument:
| Argument | Example | Behavior |
|----------|---------|----------|
| (none) or . | gh infra plan | All .yaml / .yml in the current directory |
| File | gh infra plan repos/my-cli.yaml | That file only |
| Directory | gh infra plan repos/ | All .yaml / .yml directly under it (subdirectories are ignored) |
YAML files that are not gh-infra manifests (e.g., GitHub Actions workflows, docker-compose) are silently skipped. Use --fail-on-unknown to treat them as errors instead.
Documentation
For full documentation — YAML reference, usage patterns, and guides — visit babarot.github.io/gh-infra.
License
MIT