sync

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Apply

func Apply(ctx context.Context, c *gh.Client, plan util.Plan) error

func ApplyWithOptions added in v0.2.6

func ApplyWithOptions(ctx context.Context, c *gh.Client, plan util.Plan, opts ApplyOptions) error

ApplyWithOptions applies the plan's changes using the given options.

func BuildPlan

func BuildPlan(ctx context.Context, c *gh.Client, cfg *config.Root) (util.Plan, error)

func ExplainFileRoutes added in v0.4.2

func ExplainFileRoutes(ctx context.Context, c *gh.Client, cfg *config.Root) []string

ExplainFileRoutes reports the route gomgr would take for each managed repository's file writes, and why. It exists so the decision can be inspected without applying anything.

func LogTeamImportWarnings added in v0.4.0

func LogTeamImportWarnings(result *TeamImportResult)

LogTeamImportWarnings emits the caveats a team import cannot encode in the files it writes.

Types

type ApplyOptions added in v0.2.6

type ApplyOptions struct {
	// ContinueOnError keeps applying remaining changes after a handler fails,
	// then returns an aggregated error at the end. When false (the default),
	// the first handler error aborts the run.
	ContinueOnError bool
}

ApplyOptions tunes how Apply processes the change set.

type Handler added in v0.2.4

type Handler interface {
	Apply(ctx context.Context, c *gh.Client, ch util.Change) error
}

Handler applies a single planned change against GitHub.

Implementations should be idempotent where possible; the planner already filters out no-op changes, but partial failures mid-apply are possible.

type HandlerFunc added in v0.2.4

type HandlerFunc func(ctx context.Context, c *gh.Client, ch util.Change) error

HandlerFunc adapts an ordinary function to the Handler interface.

func (HandlerFunc) Apply added in v0.2.4

func (f HandlerFunc) Apply(ctx context.Context, c *gh.Client, ch util.Change) error

Apply implements Handler.

type HandlerRegistry added in v0.2.4

type HandlerRegistry struct {
	// contains filtered or unexported fields
}

HandlerRegistry resolves change kinds (scope:action) to handlers and orders them.

func NewHandlerRegistry added in v0.2.4

func NewHandlerRegistry() *HandlerRegistry

NewHandlerRegistry returns an empty registry.

func (*HandlerRegistry) Lookup added in v0.2.4

func (r *HandlerRegistry) Lookup(scope, action string) (Handler, bool)

Lookup returns the Handler registered for scope:action, if any.

func (*HandlerRegistry) Precedence added in v0.2.4

func (r *HandlerRegistry) Precedence(scope, action string) int

Precedence returns the ordering weight for scope:action. Unregistered keys sort last so unknown change kinds don't silently jump the queue.

func (*HandlerRegistry) Register added in v0.2.4

func (r *HandlerRegistry) Register(scope, action string, precedence int, h Handler)

Register binds a Handler to scope:action with the given precedence. Lower precedence runs first. Duplicate registrations panic so misconfigured registries fail fast at startup rather than during an apply.

type ImportOptions added in v0.4.0

type ImportOptions struct {
	// Only restricts the repository scan to names matching these path.Match
	// globs. Empty scans every repository in the organization.
	Only []string
}

ImportOptions tunes what ImportRulesets looks at.

type ImportResult added in v0.4.0

type ImportResult struct {
	// Org holds organization rulesets the configuration does not declare.
	Org []ImportedRuleset
	// Repos maps a repository name to the rulesets on it that the
	// configuration does not declare, sorted by repository name.
	Repos map[string][]ImportedRuleset
	// Unmanaged lists repositories that hold adoptable rulesets but appear in
	// no team file. There is nowhere in the configuration to write their
	// rulesets until the repository itself is adopted into a team.
	Unmanaged []string
	// Skipped lists rulesets that exist but could not be represented as
	// configuration, with the reason.
	Skipped []SkippedRuleset
	// AlreadyDeclared counts rulesets skipped because the configuration
	// already declares a ruleset of that name at that scope.
	AlreadyDeclared int
	// Scanned counts the repositories inspected.
	Scanned int
}

ImportResult is what a scan found.

func ImportRulesets added in v0.4.0

func ImportRulesets(ctx context.Context, c *gh.Client, cfg *config.Root, opts ImportOptions) (*ImportResult, error)

ImportRulesets discovers the rulesets that already exist on GitHub — the ones somebody created in the web UI, or that predate gomgr managing the org — and converts them back into configuration.

It only reports rulesets the configuration does not already declare. A declared ruleset is gomgr's to define, and re-importing it would overwrite the YAML with whatever the live state happens to be, which is backwards.

Unlike planning, this scans every repository rather than only the managed ones: a ruleset on a repository nobody has adopted yet is exactly the kind of thing this command exists to surface.

func (*ImportResult) RepoNames added in v0.4.0

func (r *ImportResult) RepoNames() []string

RepoNames returns the repositories in Repos, sorted.

func (*ImportResult) Total added in v0.4.0

func (r *ImportResult) Total() int

Total returns how many rulesets are available to adopt.

type ImportedRuleset added in v0.4.0

type ImportedRuleset struct {
	// Repo is the repository the ruleset belongs to, or "" for an
	// organization-level one.
	Repo string
	// Spec is the ruleset as configuration, ready to be written to YAML.
	Spec config.RulesetConfig
}

ImportedRuleset is a ruleset that exists on GitHub, rendered back into the shape gomgr's configuration uses.

type ImportedTeam added in v0.4.0

type ImportedTeam struct {
	Config config.TeamConfig
	// Parent is the slug of the team this one is nested under, if any. It is
	// written into Config.Parents once the whole scan is in, because a parent
	// is only expressible when the file that defines it is also being written
	// — an import that adopts a child whose parent is already declared, or is
	// not being imported, has nowhere to point.
	Parent string
	// ParentUnwritable is set when Parent names a team this import will not
	// produce a file for, so the nesting is reported instead of recorded.
	ParentUnwritable bool
}

ImportedTeam is a team that exists on GitHub, rendered as configuration.

type SkippedRuleset added in v0.4.0

type SkippedRuleset struct {
	Repo   string // "" for an organization ruleset
	Name   string
	Reason string
}

SkippedRuleset is a ruleset the import could not turn into configuration.

GitHub's ruleset schema is wider than gomgr's, and grows: a rule or bypass actor type that postdates this build has to land somewhere. One such ruleset must not abort a scan of fifty, so it is reported and passed over — the ruleset itself is left exactly as it is on GitHub.

type SkippedTeam added in v0.4.0

type SkippedTeam struct {
	Slug   string
	Reason string
}

SkippedTeam is a team that could not be turned into configuration.

type State

type State struct {
	Org          string
	ManagedRepos map[string]bool

	// Cached API results to avoid duplicate calls
	ActualTeams []*github.Team
	ActualRepos []*github.Repository

	// Current state from GitHub
	CurrentTeams       int
	CurrentTeamMembers int
	CurrentRepos       int
	CurrentRepoPerms   int
	CurrentCustomRoles int
	CurrentRulesets    int
	CurrentOwners      int

	// Desired state from config
	DesiredTeams       int
	DesiredTeamMembers int
	DesiredRepos       int
	DesiredRepoPerms   int
	DesiredCustomRoles int
	DesiredRulesets    int
	DesiredOwners      int

	// RepoWarnings are advisories raised while planning repository settings.
	RepoWarnings []string
	// contains filtered or unexported fields
}

type TeamImportResult added in v0.4.0

type TeamImportResult struct {
	// Teams holds teams the configuration does not declare, sorted by slug.
	Teams []ImportedTeam
	// Skipped lists teams that exist but could not be represented.
	Skipped []SkippedTeam
	// AlreadyDeclared counts teams skipped because a team file declares them.
	AlreadyDeclared int
	// Ungranted lists repositories in the organization that no team — declared
	// or imported — grants access to. They have no home in the configuration.
	Ungranted []string
	// WouldDelete is the subset of Ungranted the next sync would actually
	// delete: not named by repos.yaml, and not already archived. Both of those
	// are spared by planRepoCleanups, so naming them here would be a threat
	// gomgr does not carry out.
	WouldDelete []string
	// DeletionRisk is true when WouldDelete is non-empty and the configuration
	// would act on it — delete_unmanaged_repos set, and archive_unmanaged_repos
	// not, since archiving wins over deleting.
	DeletionRisk bool
}

TeamImportResult is what a team scan found.

func ImportTeams added in v0.4.0

func ImportTeams(ctx context.Context, c *gh.Client, cfg *config.Root) (*TeamImportResult, error)

ImportTeams discovers the teams that exist on GitHub and renders them as configuration: name, privacy, description, maintainers, members, and the repositories each team can reach with the permission it holds.

This is the command for bringing an organization under management that was never under management before. Teams the configuration already declares are left alone, on the same reasoning as the ruleset import: a declared team is gomgr's to define, and overwriting it from the live state is backwards.

func (*TeamImportResult) Total added in v0.4.0

func (r *TeamImportResult) Total() int

Total returns how many teams are available to adopt.

Jump to

Keyboard shortcuts

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