gh-infra
gh-infra is a declarative GitHub infrastructure tool for repository settings and managed files.
Use this skill to choose the right resource kind, command flow, and operating pattern. Use the related skills for schema details.
Key characteristics:
- No state file. GitHub is the source of truth.
- Selective management. Omitted fields are left untouched.
- Four resource kinds:
Repository,RepositorySet,File,FileSet. - Supports both bootstrap import and reverse import into existing manifests.
Use This Skill For
- Choosing between
Repository/RepositorySet/File/FileSet - Running
import,validate,plan, andapply - Picking a central-management vs self-managed repo layout
- Finding the right manifest skill for a concrete edit
- Routing
import --intowork to the dedicated skill
Related Skills
| Task | Skill |
|---|---|
Write/edit Repository or RepositorySet YAML | repository-manifest |
Write/edit File or FileSet YAML | file-manifest |
| Set up CI workflows and auth | ci-cd |
| Pull live GitHub state back into existing manifests | import-into |
Resource Selection
Use:
Repositoryfor one repository's settings in one fileRepositorySetfor many repositories with shared defaultsFilefor files in one repositoryFileSetfor distributing shared files to many repositories
Every manifest starts with apiVersion and kind.
Single-repo resources:
apiVersion: gh-infra/v1
kind: Repository
metadata:
owner: <github-owner>
name: <repo-name>
spec:
# ...Set resources:
apiVersion: gh-infra/v1
kind: RepositorySet
metadata:
owner: <github-owner> # no "name" field
defaults: # RepositorySet: shared defaults
spec: { ... }
repositories: # RepositorySet: per-repo entries
- name: <repo-name>
spec: { ... }apiVersion: gh-infra/v1
kind: FileSet
metadata:
owner: <github-owner> # no "name" field
spec:
repositories: [...] # FileSet: target repos
files: [...] # FileSet: files to distributeA single YAML file can contain multiple ----separated documents. Anchors do not cross document boundaries.
Command Workflow
Default workflow:
import -> edit YAML -> validate -> plan -> applyimport
Bootstrap a manifest from live GitHub state:
gh infra import <owner/repo>validate
Validate syntax and schema without contacting GitHub:
gh infra validate [path...]plan
Show diff against live GitHub state:
gh infra plan [path...]Use --ci for drift-detection workflows.
apply
Apply changes to GitHub:
gh infra apply [path...]Use --auto-approve in CI. --force-secrets re-sends all declared secrets.
Path Behavior
For validate, plan, and apply:
- No argument or
.: read*.yamland*.ymlin the current directory - File path: read that file only
- Directory path: read top-level
*.yamland*.ymlonly - Multiple paths:
gh infra plan./repos/./files/— manifests from all paths are combined - Overlapping paths (e.g.,
.and./repos/) are rejected - Subdirectories are not scanned
- Unknown YAML kinds are skipped unless
--fail-on-unknownis set
Common Patterns
- Central management repo: keep org-wide manifests in
repos/andfiles/ - Self-managed repo: keep one manifest inside the managed repository and auto-apply on merge
Read references/patterns.md for layout guidance.
Read Next
- Command details: references/commands.md
- Operating patterns: references/patterns.md
Example Multi-Doc File
apiVersion: gh-infra/v1
kind: Repository
metadata:
owner: my-org
name: my-repo
spec:
visibility: public
---
apiVersion: gh-infra/v1
kind: File
metadata:
owner: my-org
name: my-repo
spec:
files:
- path: .github/CODEOWNERS
content: |
* @username
via: push