repocfg

package
v1.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package repocfg models and applies a repository's GitHub configuration — general settings, security, CodeQL, Pages and the per-repo rulesets — from editable YAML templates under templates/.

The desired state for a repo is composed from three inputs:

  • a CLASS preset (classes/<class>.yaml) — the per-kind toggles,
  • an ORG profile (orgs/<org>.yaml) — bypass actors and signing,
  • semantically DISCOVERED checks (checks.yaml + the detect package),

then overridden by CLI flags / the interactive form. The templates are plain YAML so they can be edited without touching Go; an on-disk copy (under the stack checkout, or $REPO_CONFIG_DIR) wins over the embedded copy so edits don't need a rebuild.

Index

Constants

This section is empty.

Variables

AllClasses is the ordered set of known classes (for the UI picker and flag validation).

Functions

func ReadTemplate

func ReadTemplate(rel string) ([]byte, error)

ReadTemplate returns the bytes of templates/<rel>, preferring an on-disk copy so edits don't need a rebuild, falling back to the embedded copy. On-disk precedence: $REPO_CONFIG_DIR, else <stack>/cli/internal/repocfg/templates.

func RenderCodeQL

func RenderCodeQL(langs []string, querySuite, defaultBranch string) (string, error)

RenderCodeQL fills the CodeQL advanced-setup workflow template.

func SecurityBlock

func SecurityBlock(c *ClassPreset) map[string]any

SecurityBlock is the security_and_analysis sub-object.

func SettingsBody

func SettingsBody(c *ClassPreset) map[string]any

SettingsBody is the PATCH /repos body for general + merge + security.

Types

type APIBypassActor

type APIBypassActor struct {
	ActorID    *int64 `json:"actor_id"`
	ActorType  string `json:"actor_type"`
	BypassMode string `json:"bypass_mode"`
}

APIBypassActor / APIRule / APIRuleset mirror the GitHub rulesets API request body.

type APIRule

type APIRule struct {
	Type       string         `json:"type"`
	Parameters map[string]any `json:"parameters,omitempty"`
}

type APIRuleset

type APIRuleset struct {
	Name         string           `json:"name"`
	Target       string           `json:"target"`
	Enforcement  string           `json:"enforcement"`
	Conditions   map[string]any   `json:"conditions"`
	BypassActors []APIBypassActor `json:"bypass_actors"`
	Rules        []APIRule        `json:"rules"`
}

func BuildRuleset

func BuildRuleset(spec *RulesetSpec, org *OrgProfile, checks []CheckRef) (*APIRuleset, error)

BuildRuleset turns a ruleset template + org + discovered checks into the API body, resolving generic bypass entries and injecting the checks.

type CheckDef

type CheckDef struct {
	Context     string `yaml:"context"`
	Integration string `yaml:"integration"`
}

CheckDef is one required status check (its integration key resolves to an app id via ChecksConfig.Integrations).

type CheckRef

type CheckRef struct {
	Context       string
	IntegrationID int64
}

CheckRef is a required status check resolved to its posting app.

type ChecksConfig

type ChecksConfig struct {
	Integrations map[string]int64       `yaml:"integrations"`
	Always       []CheckDef             `yaml:"always"`
	Languages    map[string]LangRule    `yaml:"languages"`
	Features     map[string]FeatureRule `yaml:"features"`
	Docker       DockerRule             `yaml:"docker"`
	Codecov      CodecovRule            `yaml:"codecov"`
}

ChecksConfig is checks.yaml — the semantic discovery map.

func LoadChecks

func LoadChecks() (*ChecksConfig, error)

LoadChecks reads and parses checks.yaml.

type Class

type Class string

Class is a repository kind; each maps to one classes/<class>.yaml preset.

const (
	ClassService   Class = "service"
	ClassLibrary   Class = "library"
	ClassWorkflows Class = "workflows"
	ClassMeta      Class = "meta"
)

type ClassPreset

type ClassPreset struct {
	Class       Class           `yaml:"class"`
	Features    Features        `yaml:"features"`
	Merge       Merge           `yaml:"merge"`
	Security    SecurityToggles `yaml:"security"`
	CodeQL      CodeQLPreset    `yaml:"codeql"`
	Pages       bool            `yaml:"pages"`
	Codecov     CodecovMode     `yaml:"codecov"`
	CodeQuality bool            `yaml:"code_quality"`
	Rulesets    ClassRulesets   `yaml:"rulesets"`
}

ClassPreset is one classes/<class>.yaml file.

func LoadClass

func LoadClass(c Class) (*ClassPreset, error)

LoadClass reads and parses classes/<class>.yaml.

func LoadRepoOverride

func LoadRepoOverride(org, repo string) (*ClassPreset, bool, error)

LoadRepoOverride reads repos/<org>_<repo>.yaml if it exists. The bool is false (nil error) when the repo has no override and should use its class.

type ClassRulesets

type ClassRulesets struct {
	Master          bool `yaml:"master"`
	RequireApproval bool `yaml:"require_approval"`
}

ClassRulesets says which named rulesets the class applies. codecov is driven separately by ClassPreset.Codecov.

type CodeQLPreset

type CodeQLPreset struct {
	Enabled    bool   `yaml:"enabled"`
	QuerySuite string `yaml:"query_suite"`
}

CodeQLPreset configures CodeQL advanced setup. Languages are discovered, not declared here.

type CodeQualityParams

type CodeQualityParams struct {
	Severity string `yaml:"severity"`
}

CodeQualityParams is the code_quality rule's parameters.

type CodecovMode

type CodecovMode string

CodecovMode is auto | enabled | disabled (auto = on when the repo has tests). Kept a string, not a bool, to avoid the yaml off/on pitfall.

const (
	CodecovAuto     CodecovMode = "auto"
	CodecovEnabled  CodecovMode = "enabled"
	CodecovDisabled CodecovMode = "disabled"
)

type CodecovRule

type CodecovRule struct {
	EnableWhenTests bool       `yaml:"enable_when_tests"`
	Checks          []CheckDef `yaml:"checks"`
}

CodecovRule controls the codecov ruleset's auto-enable + its checks.

type Discovered

type Discovered struct {
	Checks      []CheckRef
	CodeQLLangs []string
	HasTests    bool
}

Discovered is what probing a repo tells us: the required checks, the CodeQL languages, and whether the repo has tests (informational; the codecov ruleset is gated on actual Codecov reporting, not this).

func Discover

func Discover(repoPath string, cc *ChecksConfig) (*Discovered, error)

Discover walks repoPath and applies the checks.yaml map to produce the required-check set + CodeQL languages. Detection is by file presence plus the detect package for docker build targets.

type DockerRule

type DockerRule struct {
	ContextFormat string `yaml:"context_format"`
	Integration   string `yaml:"integration"`
}

DockerRule formats a build-<target> check per detected docker target.

type FeatureRule

type FeatureRule struct {
	Detect []string   `yaml:"detect"`
	Checks []CheckDef `yaml:"checks"`
}

FeatureRule maps a sub-feature (e.g. pkg/js) to extra checks.

type Features

type Features struct {
	Issues      bool `yaml:"issues"`
	Wiki        bool `yaml:"wiki"`
	Projects    bool `yaml:"projects"`
	Discussions bool `yaml:"discussions"`
}

Features mirrors the repo "Features" toggles.

type LangRule

type LangRule struct {
	Detect []string   `yaml:"detect"`
	Checks []CheckDef `yaml:"checks"`
	CodeQL []string   `yaml:"codeql"`
}

LangRule maps a detected language to its checks + CodeQL languages.

type Merge

type Merge struct {
	Squash              bool `yaml:"squash"`
	MergeCommit         bool `yaml:"merge_commit"`
	Rebase              bool `yaml:"rebase"`
	AutoMerge           bool `yaml:"auto_merge"`
	DeleteBranchOnMerge bool `yaml:"delete_branch_on_merge"`
	AllowUpdateBranch   bool `yaml:"allow_update_branch"`
	SignoffRequired     bool `yaml:"signoff_required"`
}

Merge mirrors the merge-button + PR settings.

type Op

type Op struct {
	Method      string `json:"method,omitempty"`
	Path        string `json:"path,omitempty"`
	Body        any    `json:"body,omitempty"`
	Content     string `json:"content,omitempty"`
	RulesetName string `json:"ruleset,omitempty"`
}

Op is one API operation the plan would perform.

  • settings/pages: Method + Path + Body.
  • contents (codeql/dependabot): Method PUT + Path + Content (file text).
  • ruleset: RulesetName set; reconciled by name at apply time (POST when absent, PUT .../{id} when present), Body is the ruleset payload.

func (Op) Title

func (o Op) Title() string

Title is a one-line human label for the op.

type OrgProfile

type OrgProfile struct {
	Org             string           `yaml:"org"`
	SigningRequired bool             `yaml:"signing_required"`
	Bots            map[string]int64 `yaml:"bots"`
}

OrgProfile is orgs/<org>.yaml — per-org bot ids and signing policy. A ruleset's generic bot name (bots key) resolves to the app id here.

func LoadOrg

func LoadOrg(org string) (*OrgProfile, error)

LoadOrg reads and parses orgs/<org>.yaml.

type Plan

type Plan struct {
	Ops []Op
}

Plan is the ordered set of operations to bring a repo to desired state.

func BuildPlan

func BuildPlan(t *RepoTarget) (*Plan, error)

BuildPlan assembles the desired-state operations for a repo.

func (*Plan) Render

func (p *Plan) Render(w io.Writer) error

Render writes the plan as labelled raw JSON (and verbatim file content for content writes) — close to what GitHub receives, no extra formatting.

func (*Plan) RenderJSON

func (p *Plan) RenderJSON(w io.Writer) error

RenderJSON writes the plan as a JSON array of ops — machine-readable, so the exact operations can be inspected or applied verbatim.

type RSCParams

type RSCParams struct {
	Strict               bool `yaml:"strict"`
	DoNotEnforceOnCreate bool `yaml:"do_not_enforce_on_create"`
}

RSCParams is the static part of a required_status_checks rule; the checks list is injected from discovery.

type RepoTarget

type RepoTarget struct {
	Org, Repo, DefaultBranch string
	Class                    *ClassPreset
	OrgProfile               *OrgProfile
	Checks                   *ChecksConfig
	Discovered               *Discovered

	// MasterChecks, when non-nil, is the authoritative required-check set
	// for the master ruleset — used by `update` to PRESERVE the live
	// ruleset's checks rather than overwrite them with discovery (which can
	// only approximate names). Nil (e.g. on `create`) falls back to the
	// discovered set.
	MasterChecks []CheckRef
	// CodecovReports is whether Codecov posts a status on this repo. It
	// gates `codecov: auto` — a coverage ruleset is only enforced where
	// Codecov actually reports, so it never blocks PRs on a repo that has
	// no coverage upload.
	CodecovReports bool
}

RepoTarget is everything needed to compute a repo's desired config.

type RulesetConditions

type RulesetConditions struct {
	RefName struct {
		Include []string `yaml:"include"`
		Exclude []string `yaml:"exclude"`
	} `yaml:"ref_name"`
}

RulesetConditions is the ref-name match for a branch ruleset.

type RulesetRules

type RulesetRules struct {
	Deletion             bool               `yaml:"deletion"`
	NonFastForward       bool               `yaml:"non_fast_forward"`
	RequiredSignatures   bool               `yaml:"required_signatures"`
	RequiredStatusChecks *RSCParams         `yaml:"required_status_checks"`
	MergeQueue           map[string]any     `yaml:"merge_queue"`
	CodeQuality          *CodeQualityParams `yaml:"code_quality"`
	PullRequest          map[string]any     `yaml:"pull_request"`
	CopilotCodeReview    map[string]any     `yaml:"copilot_code_review"`
}

RulesetRules holds every rule a template may set; absent ones stay nil/ false. Param blobs that pass straight through to the API (merge_queue, pull_request, copilot_code_review) are kept as maps so the template owns their shape.

type RulesetSpec

type RulesetSpec struct {
	Name        string            `yaml:"name"`
	Target      string            `yaml:"target"`
	Enforcement string            `yaml:"enforcement"`
	Conditions  RulesetConditions `yaml:"conditions"`
	Bypass      []string          `yaml:"bypass"`
	Rules       RulesetRules      `yaml:"rules"`
}

RulesetSpec is one rulesets/<name>.yaml base. The required-status-checks list and concrete bypass actors are injected by the builder, not stored here.

func LoadRuleset

func LoadRuleset(name string) (*RulesetSpec, error)

LoadRuleset reads rulesets/<name>.yaml.

type SecurityToggles

type SecurityToggles struct {
	SecretScanning bool `yaml:"secret_scanning"`
	PushProtection bool `yaml:"push_protection"`
	Dependabot     bool `yaml:"dependabot"`
}

SecurityToggles mirrors the security_and_analysis block we manage.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL