Overview
gh-infra manages GitHub infrastructure through four resource kinds, organized in two pairs:
| 1 repo | N repos | |
|---|---|---|
| Repository settings | Repository | RepositorySet |
| File management | File | FileSet |
The single-repo resource (Repository, File) manages one repository in detail. The set resource (RepositorySet, FileSet) applies shared configuration across multiple repositories — each entry can override specific values.
Common Structure
Section titled “Common Structure”All resources share the same top-level structure:
apiVersion: gh-infra/v1kind: <Repository | RepositorySet | File | FileSet>metadata: owner: <github-owner> name: <repo-name> # single-repo resources only
spec: # Resource-specific fieldsMetadata
Section titled “Metadata”| Resource | metadata.owner | metadata.name | Identifies |
|---|---|---|---|
| Repository | required | required | A single repo (owner/name) |
| File | required | required | A single repo (owner/name) |
| RepositorySet | required | — | All repos listed in repositories |
| FileSet | required | — | All repos listed in repositories |
File Organization
Section titled “File Organization”You can organize YAML files however you like. gh-infra accepts a file or directory path:
gh infra plan ./repos/ # All YAML files in the directorygh infra plan ./repos/my-cli.yaml # A single fileMultiple resource kinds can coexist in the same directory. gh-infra processes each file based on its kind.
Multi-Document YAML
Section titled “Multi-Document YAML”A single YAML file can contain multiple documents separated by ---. This lets you group related resources together without creating separate files:
apiVersion: gh-infra/v1kind: Repositorymetadata: name: my-app owner: my-orgspec: description: "Application repository" visibility: public---apiVersion: gh-infra/v1kind: Filemetadata: name: my-app owner: my-orgspec: files: - path: .github/CODEOWNERS content: | * @my-org/platform via: pushYou can mix any resource kinds within a single file. Each document is parsed independently, so they do not share YAML anchors or other state.