policy

package
v0.26.0 Latest Latest
Warning

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

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

Documentation

Overview

Package policy reads the bot PR sweep policy files and resolves them into the policy one repository is swept under.

Three files take part, applied in this order on top of the company defaults in pr.CompanyDefaults:

bot-prs-sweep/default.yaml        company defaults
bot-prs-sweep/team-<name>.yaml    one team's deviations, owned by the team
repositories/team-<name>.yaml     one repository's exception, on its entry

Every file lives in giantswarm/github and is read from its default branch at the start of a sweep. A file that does not parse, or that names a key, a bot PR kind, an update type or a value the sweep does not know, is an error. A policy a team cannot read back is worse than no policy, so the sweep stops instead of quietly applying defaults.

Index

Constants

View Source
const DefaultFile = "bot-prs-sweep/default.yaml"

DefaultFile holds the company defaults; TeamFile is one team's deviations and RepositoriesFile is the team's repository list, which also carries the per-repository exceptions.

View Source
const PolicyDir = "bot-prs-sweep"

PolicyDir holds the company defaults and every team's policy file.

View Source
const TeamFilePrefix = "bot-prs-sweep/team-"

TeamFilePrefix and teamFileSuffix bracket a team name in the path of its policy file, and are what Teams reads a team name back out of.

Variables

This section is empty.

Functions

func ParseRepositories

func ParseRepositories(content, owner, path string) ([]string, map[string]Exception, error)

ParseRepositories returns the owner/name entries of a team's repository list together with the botPRsSweep exception of every entry that carries one, keyed by the same owner/name. Only the name and that one key are read; every other key of the file belongs to the generators and changes without notice. The repositories live under the list's own owner.

func RepositoriesFile

func RepositoriesFile(team string) string

RepositoriesFile returns the path of a team's repository list.

func TeamFile

func TeamFile(team string) string

TeamFile returns the path of a team's policy file.

Types

type BudgetDocument

type BudgetDocument struct {
	PerRescue *float64 `yaml:"perRescue"`
	Weekly    *float64 `yaml:"weekly"`
}

BudgetDocument is the rescue budget in US dollars. Neither figure is enforced yet; see pr.BudgetEnforced.

type ConcurrencyDocument

type ConcurrencyDocument struct {
	PerTeam *int `yaml:"perTeam"`
	PerRepo *int `yaml:"perRepo"`
}

ConcurrencyDocument is the concurrency section of a policy file.

type Document

type Document struct {
	UpdateTypes  map[string][]string  `yaml:"updateTypes"`
	Rescue       *RescueDocument      `yaml:"rescue"`
	Concurrency  *ConcurrencyDocument `yaml:"concurrency"`
	ModelConfig  *string              `yaml:"modelConfig"`
	SlackChannel *string              `yaml:"slackChannel"`
	// contains filtered or unexported fields
}

Document is one policy file. Every field is optional and an absent field keeps what the file before it said. UpdateTypes replaces the list of the kinds it names and leaves every other kind alone.

The names a file writes are also held in their resolved form, which ParseDocument fills. Only ParseDocument builds a Document, so a Document that exists has been resolved, and applying one needs no second pass over the names and no error a caller has to discard.

func ParseDocument

func ParseDocument(path, content string) (*Document, error)

ParseDocument reads one policy file. An unknown key, a value of the wrong type and an unknown kind, update type or enumerated value are all errors naming path.

type Exception

type Exception struct {
	Enabled     *bool    `yaml:"enabled"`
	UpdateTypes []string `yaml:"updateTypes"`
	Rescue      *bool    `yaml:"rescue"`
}

Exception is one repository's deviation, written under the botPRsSweep key of its entry in repositories/team-<name>.yaml. Three keys are allowed and each one only narrows: switch the sweep off, restrict the update types that merge, switch the rescues off.

type File

type File struct {
	Path string
	Doc  *Document
}

File is one policy file and the path it was read from. The path travels with the document so a resolved policy can name the files that made it.

type GitHubSource

type GitHubSource struct {
	Client *github.Client
	Owner  string
	Repo   string
}

GitHubSource reads the files from the default branch of one repository, giantswarm/github in every real run.

func (GitHubSource) Read

func (g GitHubSource) Read(ctx context.Context, path string) (string, bool, error)

Read returns the content of path on the repository's default branch. GitHub answers 404 both for a file that is not there and for a repository the token cannot read, so neither is reported as an error here.

func (GitHubSource) String

func (g GitHubSource) String() string

type Loader

type Loader struct {
	Source Source
	// Owner is the GitHub organisation the repository lists name their
	// entries under. It is a property of what the files say, not of where
	// they are read from, so it stays on the loader.
	Owner string
}

Loader resolves a sweep's scope and policy from the files of one Source.

func (Loader) QueryScope

func (l Loader) QueryScope(ctx context.Context) (Scope, error)

QueryScope reads the company defaults alone. The query scope has no team, so no team file and no repository exception apply to it.

func (Loader) TeamScope

func (l Loader) TeamScope(ctx context.Context, team string) (Scope, error)

TeamScope reads the team's repository list, the company defaults and the team's policy file, and resolves all three. A missing repository list is an error: without it the sweep has no scope. A missing policy file is not: the company defaults then apply on their own, and pr.Policy.Sources names the files that were read.

The repository list is read first. GitHub answers 404 for a repository the token cannot read, so an absent policy file and an unreadable giantswarm/github look the same. Reading the one file that must exist first turns that case into one error that names the access.

type RescueDocument

type RescueDocument struct {
	Enabled *bool           `yaml:"enabled"`
	Timeout *string         `yaml:"timeout"`
	Weekly  *int            `yaml:"weekly"`
	Budget  *BudgetDocument `yaml:"budget"`
	Confirm *string         `yaml:"confirm"`
	// contains filtered or unexported fields
}

RescueDocument is the rescue section of a policy file.

type Scope

type Scope struct {
	Repos    []string
	Policies *Set
}

Scope is what one sweep resolves before it starts: the repositories it covers and the policy they are swept under. Repos is nil outside the team scope, where the PRs come from a GitHub search instead.

type Set

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

Set is the policy of one sweep: the policy every repository of the scope is swept under, and the repositories whose own exception deviates from it. A Set is read-only once built, so the sweep's goroutines share one.

func NewSet

func NewSet(files []File, exceptions map[string]Exception) (*Set, error)

NewSet resolves the base policy from the files, applies each repository exception on top of it, and returns the result. Exceptions are keyed by "owner/name", matched the way GitHub matches a repository, without case.

func (*Set) Base

func (s *Set) Base() pr.Policy

Base returns the policy of a repository without an exception. The sweep reads its concurrency and its Slack channel from it.

func (*Set) For

func (s *Set) For(owner, name string) pr.Policy

For returns the policy the repository is swept under. The owner is part of the lookup: a sweep can hold repositories of more than one owner, and a team's exception covers its own owner alone. The returned policy is read-only: callers never write to it or to its map.

type Source

type Source interface {
	fmt.Stringer
	Read(ctx context.Context, path string) (content string, found bool, err error)
}

Source holds the policy files. Read returns the content of path, and reports found false for a path the source does not hold, which is not an error: an absent policy file falls back to the company defaults. A Source names where it looked in its String, so an error can say so.

GitHubSource is the only source the sweep ships. Nothing else in the package knows where a file was read from.

Jump to

Keyboard shortcuts

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