Skip to content

Overview

gh-infra manages GitHub infrastructure through four resource kinds, organized in two pairs:

1 repoN repos
Repository settingsRepositoryRepositorySet
File managementFileFileSet

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.

All resources share the same top-level structure:

apiVersion: gh-infra/v1
kind: <Repository | RepositorySet | File | FileSet>
metadata:
owner: <github-owner>
name: <repo-name> # single-repo resources only
spec:
# Resource-specific fields
Resourcemetadata.ownermetadata.nameIdentifies
RepositoryrequiredrequiredA single repo (owner/name)
FilerequiredrequiredA single repo (owner/name)
RepositorySetrequiredAll repos listed in repositories
FileSetrequiredAll repos listed in repositories

You can organize YAML files however you like. gh-infra accepts a file or directory path:

Terminal window
gh infra plan ./repos/ # All YAML files in the directory
gh infra plan ./repos/my-cli.yaml # A single file

Multiple resource kinds can coexist in the same directory. gh-infra processes each file based on its kind.

A single YAML file can contain multiple documents separated by ---. This lets you group related resources together without creating separate files:

apiVersion: gh-infra/v1
kind: Repository
metadata:
name: my-app
owner: my-org
spec:
description: "Application repository"
visibility: public
---
apiVersion: gh-infra/v1
kind: File
metadata:
name: my-app
owner: my-org
spec:
files:
- path: .github/CODEOWNERS
content: |
* @my-org/platform
via: push

You can mix any resource kinds within a single file. Each document is parsed independently, so they do not share YAML anchors or other state.