releasepromote

package
v8.103.2 Latest Latest
Warning

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

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

Documentation

Overview

Package releasepromote promotes the latest release candidate of auto-release repositories to a stable release: what `devctl release promote` does. The auto-release workflow cuts a candidate vX.Y.Z-rc.N, a GitHub pre-release, on every releasable push; a stable release is cut only by running that workflow by hand with release-type stable, which promotes the latest candidate since the last stable release. The package checks that the workflow on the default branch is one that promotes, picks that candidate from the repository's releases reachable from the default branch, checks that its commit is built (the rule the workflow applies) and dispatches the workflow on the default branch. The workflow does the promotion and its own checks; nothing here waits for its run.

Index

Constants

View Source
const (
	// StateDispatched: the workflow was dispatched with release-type stable.
	StateDispatched = "dispatched"
	// StateWouldDispatch: with --dry-run, the workflow would be dispatched.
	StateWouldDispatch = "would_dispatch"
	// StateNothingToPromote: no candidate pre-release newer than the latest
	// stable release.
	StateNothingToPromote = "nothing_to_promote"
	// StateNotBuilt: a commit status of the candidate's commit is not
	// success; statusState names the combined state.
	StateNotBuilt = "not_built"
	// StateNotAutoRelease: the repository has no auto-release workflow.
	StateNotAutoRelease = "not_auto_release"
	// StateOutdatedWorkflow: the auto-release workflow on the default branch
	// has no promotion step: its release-type stable tags the branch head.
	StateOutdatedWorkflow = "outdated_workflow"
	// StateFailed: a read or the dispatch failed; the message has GitHub's
	// answer.
	StateFailed = "failed"
)

The states of one repository.

View Source
const Command = "release promote"

Command is the envelope's command name.

View Source
const Workflow = "zz_generated.auto_release.yaml"

Workflow is the file name of the generated auto-release workflow.

Variables

View Source
var ErrNotPrerelease = errors.New("not a GitHub pre-release")

ErrNotPrerelease is the highest candidate being a full GitHub release, not a pre-release: the workflow stops on it rather than promote a lower one.

Functions

func DispatchBlockedReason

func DispatchBlockedReason(token authstore.Token) string

DispatchBlockedReason is why the App login cannot dispatch a workflow: it needs Actions write, which the App does not carry, and the variables that override the login. Empty for a token from the environment.

func Promote

func Promote(ctx context.Context, config Config, repositories []string, result *Result) error

Promote runs the promotion of every repository, owner/repo each, in order, and fills result.Repositories. A repository that is not dispatched is reported in its entry and does not stop the others; the error is then an agentcli.ExitRed outcome naming them. Nil when every repository was dispatched, would be, or has nothing to promote.

func SelectCandidate

func SelectCandidate(releases []githubclient.Release, reachable func(tag string) (bool, error)) (stable, candidate string, err error)

SelectCandidate returns the tag of the highest stable release reachable from the default branch and of the highest reachable candidate newer than it, "" for either when there is none: the tags the workflow's `--merged HEAD` lets it see. reachable says whether a tag is on the default branch; it is asked from the highest tag down and only until the first reachable one, so a higher stable release or candidate of another branch (a backport line) is skipped without hiding the default branch's. Drafts are no releases. The highest candidate must be a GitHub pre-release, the form the workflow promotes: a full release there is ErrNotPrerelease with its tag, never a lower candidate, as the workflow refuses it too. Versions are compared as semver, so rc.10 follows rc.9 and a candidate for a higher version follows one it replaced.

func SplitRepository

func SplitRepository(s string) (owner, repo string, ok bool)

SplitRepository reads owner/repo.

func TeamRepositories

func TeamRepositories(ctx context.Context, gh *github.Client, team string) ([]string, error)

TeamRepositories lists owner/repo of every entry of a team's file in giantswarm/github whose release model is auto-release (releaseWorkflow, defaulting from gen.ci.generate), in file order. The repositories are in the organisation the team files describe. A team without a file is a usage error.

Types

type Config

type Config struct {
	// GitHub is required.
	GitHub GitHub
	// DryRun checks every repository and dispatches nothing.
	DryRun bool
	// NotFoundHint is added to GitHub's 404 for a repository: what the
	// token reaches. Empty adds nothing.
	NotFoundHint string
	// Progress receives one line per repository; nil is silent.
	Progress *agentcli.Progress
}

Config configures a promotion.

type Document

type Document struct {
	agentcli.Envelope
	Result
}

Document is the command's JSON: the envelope and the result.

type GitHub

type GitHub interface {
	DefaultBranch(ctx context.Context, owner, repo string) (string, error)
	ReadFile(ctx context.Context, owner, repo, path, ref string) ([]byte, bool, error)
	ListReleases(ctx context.Context, owner, repo string) ([]githubclient.Release, error)
	Reachable(ctx context.Context, owner, repo, ref, branch string) (bool, error)
	GetCombinedStatus(ctx context.Context, owner, repo, ref string) (githubclient.CombinedStatus, error)
	DispatchWorkflow(ctx context.Context, owner, repo, file, ref string, inputs map[string]any) error
}

GitHub is what a promotion reads from and writes to GitHub; *githubclient.Client is one.

type Repository

type Repository struct {
	// Repository is owner/repo.
	Repository string `json:"repository"`
	// Stable is the tag of the latest stable release; empty when there is
	// none.
	Stable string `json:"stable"`
	// Candidate is the tag of the candidate to promote; empty when there is
	// none.
	Candidate string `json:"candidate"`
	// StatusState is the combined commit status of the candidate: success,
	// pending, failure or error; empty until read.
	StatusState string `json:"statusState"`
	// State is one of the State constants.
	State string `json:"state"`
	// Message says what was done or why not.
	Message string `json:"message"`
}

Repository is one repository's promotion as the document reports it.

func (Repository) OK

func (r Repository) OK() bool

OK says whether the repository is dispatched, would be, or has nothing to promote.

type Result

type Result struct {
	// Team is the team whose repositories were promoted; empty for named
	// repositories.
	Team string `json:"team"`
	// DryRun is set with --dry-run: nothing was dispatched.
	DryRun bool `json:"dryRun"`
	// Repositories are the repositories in the order they were given or
	// the team file lists them.
	Repositories []Repository `json:"repositories"`
}

Result is the command's document below the envelope.

func NewResult

func NewResult(team string) Result

NewResult is the result before anything is known: no repositories.

type Sources

type Sources struct {
	GitHub GitHub
	// Team lists the auto-release repositories of a team.
	Team func(ctx context.Context, team string) ([]string, error)
	// NotFoundHint is [Config]'s.
	NotFoundHint string
	// DispatchBlocked is set when the token cannot dispatch a workflow (the
	// App login, which carries no Actions write): the reason a run that
	// dispatches stops with before any repository is read. Empty when the
	// token may.
	DispatchBlocked string
}

Sources are what one promotion reads and writes, opened after the version gate.

func OpenSources

func OpenSources(ctx context.Context, endpoints agentcli.Endpoints, transport http.RoundTripper, warn func(string)) (*Sources, error)

OpenSources is the production wiring: the GitHub token of authstore.ResolveGitHub (the App login, or a token in the environment that overrides it; its warning goes to warn), conditional requests below it, and the team files of the organisation. The requests go through transport.

Jump to

Keyboard shortcuts

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