release

package
v0.1.0-rc2 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package release holds the pure, table-driven-testable logic that the release CI workflows depend on: the release-PR title grammar, the git-tag grammar, the typed release-kind derivation, and the final-release guard decision.

Everything here is deliberately side-effect-free so the negative paths (a malformed title, a non-release tag, a final release with no proven rc) are unit-testable BEFORE they run in a workflow. The thin CLI in cmd/release-guard wires these functions to real git/gh queries; the workflows shell out to that CLI.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckFinal

func CheckFinal(final Version, rcs []RCStatus) error

CheckFinal decides whether a FINAL release may proceed.

A final release is permitted only if at least one same-base-version release candidate exists that is BOTH (a) green — its release.yml run succeeded — AND (b) an ancestor of the final commit. This enforces the "final ⇒ proven rc on the same commit lineage" invariant inside the pipeline rather than by convention. rc-to-final tree identity is impossible (they are different merge commits by construction), so ancestry is the strongest cheap invariant.

CheckFinal is pure: the caller supplies the observed rc statuses. It returns nil to proceed, or an actionable error naming exactly which condition failed for every candidate considered.

func CheckReleaseWorkflow

func CheckReleaseWorkflow(path string, data []byte) error

CheckReleaseWorkflow validates release.yml from parsed YAML bytes.

func CheckReleaseWorkflowFile

func CheckReleaseWorkflowFile(path string) error

CheckReleaseWorkflowFile validates the release workflow's publication gates. It is intentionally narrow: the workflow may evolve, but the GitHub-Release publish job must stay behind the guard, the Nix vendorHash gate, and the contract gates.

func IsMaintainer

func IsMaintainer(perm CollaboratorPermission) bool

IsMaintainer reports whether a collaborator permission grants release- maintainer authority (may open OR approve a release PR).

This is the SINGLE source of the maintainer predicate. Both release-pr.yml gates — the PR-author check and the approver check — consume it via `release-guard check-maintainer`, so the {admin, maintain} set is defined exactly once (no duplicated `admin|maintain` shell case across jobs).

func LatestApprovers

func LatestApprovers(reviews []Review) []string

LatestApprovers returns logins whose latest non-COMMENTED review is APPROVED. Plain comments do not withdraw or shadow a standing approval.

The "latest" review is determined by input slice order: the loop below is intentionally last-write-wins per reviewer. The release-guard caller feeds this from GitHub's pull-request reviews API, which returns reviews in ascending chronological/id order, and that order is preserved through `gh api --paginate --slurp` and parseReviews flattening. This id/input order is preferred over sorting by submitted_at because GitHub IDs are stable and order-preserving even when multiple reviews have same-second submitted_at timestamps.

func ParseReleaseTitle

func ParseReleaseTitle(title string) (Version, ReleaseKind, error)

ParseReleaseTitle parses a release-PR title of the form "release(vX.Y.Z): subject" or "release(vX.Y.Z-rcN): subject" and returns the validated version and its kind.

On any grammar violation it returns (KindInvalid, error) with an actionable message describing the expected shape and a concrete example. This is the single implementation of the title grammar; the workflows must NOT re-encode it inline.

func ParseTag

func ParseTag(tag string) (Version, ReleaseKind, error)

ParseTag parses a git tag as a schema release reference. It accepts ONLY bare "vX.Y.Z[-rcN]" tags; namespaced tags such as the legacy "pkg/schema/v1.2.3" (retained from when this module was nested in peasant) are rejected because they are not releases of THIS module and must never trigger the release pipeline. (The release.yml trigger filter `v*` already excludes pkg/schema/v* by name; this parse is the defense-in-depth guard inside the workflow.)

Types

type CollaboratorPermission

type CollaboratorPermission string

CollaboratorPermission is a GitHub repository collaborator permission level — the `.permission` field returned by the collaborators API. Typed per the repo's no-stringly-typed rule so the maintainer predicate compares against named constants, not bare strings.

const (
	PermAdmin    CollaboratorPermission = "admin"
	PermMaintain CollaboratorPermission = "maintain"
	PermWrite    CollaboratorPermission = "write"
	PermTriage   CollaboratorPermission = "triage"
	PermRead     CollaboratorPermission = "read"
	PermNone     CollaboratorPermission = "none"
)

func (CollaboratorPermission) String

func (p CollaboratorPermission) String() string

String renders the permission for CLI output and error messages.

type RCStatus

type RCStatus struct {
	// Tag is the release-candidate tag, e.g. v0.1.0-rc1.
	Tag Version
	// RunGreen is true when the rc tag's release.yml run completed successfully.
	RunGreen bool
	// IsAncestor is true when the rc tag's commit is an ancestor of the final
	// release commit (the final was tagged on a descendant of the proven rc).
	IsAncestor bool
}

RCStatus is the observed state of one release-candidate tag relative to a pending final release: whether its release.yml run was green, and whether the rc tag is an ancestor of the final release commit (git merge-base --is-ancestor). The CLI populates these from real git/gh queries; CheckFinal consumes them as pure data.

type ReleaseKind

type ReleaseKind string

ReleaseKind classifies a release reference (a PR title or a git tag) as a release candidate, a final release, or an invalid/unrecognized reference.

It is a strongly-typed enum (per the repo's no-stringly-typed-API rule) so that workflow steps and Go callers compare against named constants rather than bare strings.

const (
	// KindInvalid is returned together with an error whenever a reference does
	// not parse as a release.
	KindInvalid ReleaseKind = "invalid"
	// KindRC is a release candidate: a version carrying an -rcN prerelease
	// suffix (e.g. v0.1.0-rc1). RCs never publish to external package repos.
	KindRC ReleaseKind = "rc"
	// KindFinal is a final, non-prerelease version (e.g. v0.1.0).
	KindFinal ReleaseKind = "final"
)

func (ReleaseKind) String

func (k ReleaseKind) String() string

String renders the kind for CLI output and workflow consumption.

type Review

type Review struct {
	User  *ReviewUser `json:"user"`
	State ReviewState `json:"state"`
}

Review is the subset of a GitHub pull-request review needed by the release approval gate.

type ReviewState

type ReviewState string

ReviewState is the `.state` field returned by the GitHub pull-request reviews API for a submitted review.

const (
	ReviewStateApproved         ReviewState = "APPROVED"
	ReviewStateCommented        ReviewState = "COMMENTED"
	ReviewStateChangesRequested ReviewState = "CHANGES_REQUESTED"
	ReviewStateDismissed        ReviewState = "DISMISSED"
)

func (ReviewState) String

func (s ReviewState) String() string

String renders the review state for CLI output and error messages.

type ReviewUser

type ReviewUser struct {
	Login string `json:"login"`
}

ReviewUser is the GitHub user shape embedded in a pull-request review.

type Version

type Version string

Version is a validated schema release version, always including the leading "v" (e.g. "v0.1.0" or "v0.1.0-rc1"). Construct only via NewVersion so the invariant (matches the frozen grammar) holds everywhere a Version is seen.

func NewVersion

func NewVersion(raw string) (Version, error)

NewVersion validates raw against the frozen release-version grammar and returns a typed Version. On failure it returns an actionable error naming the expected shape and a concrete example.

func (Version) Base

func (v Version) Base() Version

Base returns the version with any -rcN suffix stripped: the final version a release candidate is a candidate FOR. For a final version Base is the identity (v0.1.0 -> v0.1.0); for an rc it strips the suffix (v0.1.0-rc3 -> v0.1.0).

func (Version) IsRC

func (v Version) IsRC() bool

IsRC reports whether the version carries an -rcN prerelease suffix.

func (Version) Kind

func (v Version) Kind() ReleaseKind

Kind returns KindRC for prerelease (-rcN) versions and KindFinal otherwise. A Version is, by construction, never KindInvalid.

func (Version) String

func (v Version) String() string

String renders the version (with its leading "v").

Jump to

Keyboard shortcuts

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