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
- func ParseRepositories(content, owner, path string) ([]string, map[string]Exception, error)
- func RepositoriesFile(team string) string
- func TeamFile(team string) string
- type BudgetDocument
- type ConcurrencyDocument
- type Document
- type Exception
- type File
- type GitHubSource
- type Loader
- type RescueDocument
- type Scope
- type Set
- type Source
Constants ¶
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.
const PolicyDir = "bot-prs-sweep"
PolicyDir holds the company defaults and every team's policy file.
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 ¶
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 ¶
RepositoriesFile returns the path of a team's repository list.
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 ¶
ConcurrencyDocument is the concurrency section of a policy file.
type Document ¶
type Document struct {
UpdateTypes map[string][]string `yaml:"updateTypes"`
Schedule *string `yaml:"schedule"`
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 ¶
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 ¶
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 ¶
GitHubSource reads the files from the default branch of one repository, giantswarm/github in every real run.
func (GitHubSource) List ¶ added in v0.19.0
List returns the paths of the files in dir on the repository's default branch. A directory that is not there, like a repository the token cannot read, answers 404 and is reported as not found.
func (GitHubSource) Read ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
Base returns the policy of a repository without an exception. The sweep reads its concurrency and its Slack channel from it.
type Source ¶
type Source interface {
fmt.Stringer
Read(ctx context.Context, path string) (content string, found bool, err error)
// List returns the paths of the files directly under dir, and reports
// found false for a directory the source does not hold.
List(ctx context.Context, dir string) (paths []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.