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; optional label for FileSet
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 | optional | All repos listed in repositories |
A FileSet’s metadata.name does not select repositories. It names the FileSet in plan output and in the defaults for its commit message, pull request branch (gh-infra/sync-<owner>-<name>), and pull request body. Without it, the FileSet is named <owner>/<repo-a>+<repo-b> after its sorted repository names (see Delivery Method).
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.