commit

package
v0.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package commit lands rendered files in GitOps repositories as the person: a branch, one commit per repository, the pull request carrying the caller's text, and the merge once the caller says approved and the checks are green.

The module holds no token. A Remote is built from the token the caller supplies (for the managers: the person's user token of the manager's App), and a token GitHub refuses surfaces as ErrAuth carrying the HTTP status; the callers turn it into their sign-in answer. Nothing is retried with another token, nothing is logged, and no error carries file content.

Index

Constants

View Source
const (
	ReviewNone             ReviewState = "none"
	ReviewApproved         ReviewState = "approved"
	ReviewChangesRequested ReviewState = "changes_requested"

	// ChecksNone: the head carries no statuses and no check runs; nothing to wait for.
	ChecksNone    CheckState = "none"
	ChecksPending CheckState = "pending"
	ChecksSuccess CheckState = "success"
	ChecksFailure CheckState = "failure"
)
View Source
const (
	OpCreateBranch    = "create branch"
	OpCommit          = "commit"
	OpOpenPullRequest = "open pull request"
	OpStatus          = "pull request status"
	OpMerge           = "merge"
	OpFindPullRequest = "find pull request"
	OpEnableAutoMerge = "enable auto-merge"
	OpClose           = "close pull request"
	OpRevert          = "revert pull request"
)

Operation names of the remote calls, carried by AuthError and by Fake.Fail.

Variables

View Source
var (
	// ErrAuth: the remote refused the caller's token (401 or 403). The callers
	// answer with their sign-in flow; the module neither retries nor substitutes.
	ErrAuth = errors.New("token refused")
	// ErrInvalidRequest: the request lacks a branch or a title.
	ErrInvalidRequest = errors.New("request needs a branch and a title")
	// ErrNoFiles: a change carries no files.
	ErrNoFiles = errors.New("no files to commit")
	// ErrConflictingBase: two changes for one repository name different branches.
	ErrConflictingBase = errors.New("one repository, two base branches")
	// ErrDuplicatePath: two changes for one repository write the same path.
	ErrDuplicatePath = errors.New("one path in two changes")
	// ErrNotApproved: the caller has not said approved.
	ErrNotApproved = errors.New("merge refused: not approved")
	// ErrChecksPending: a status or check run on the head has not finished.
	ErrChecksPending = errors.New("merge refused: checks pending")
	// ErrChecksFailed: a status or check run on the head failed.
	ErrChecksFailed = errors.New("merge refused: checks failed")
	// ErrHeadMoved: the head is no longer the commit the caller saw.
	ErrHeadMoved = errors.New("merge refused: the head moved since the pull request was seen")
	// ErrNotMerged: only a merged pull request can be reverted.
	ErrNotMerged = errors.New("revert refused: the pull request is not merged")
	// ErrNothingToRevert: the merged pull request changed no files.
	ErrNothingToRevert = errors.New("revert refused: the pull request changed no files")
)

Functions

func Merge

func Merge(ctx context.Context, remote Remote, pr PullRequest, approved bool) error

Merge merges the pull request as the person. It is refused before the caller says approved (ErrNotApproved, no remote call), before every check on the head is green (ErrChecksPending, ErrChecksFailed; a head without checks has nothing to wait for) and when the head is not the commit the caller saw (ErrHeadMoved). A merged pull request is left as it is. GitHub's own rules — the approving review that satisfies enforce_admins and rulesets — apply at the merge call; no administrative path exists.

Types

type AuthError

type AuthError struct {
	Op     string
	Status int
}

AuthError is ErrAuth with the status the remote answered and the operation it refused. errors.Is(err, ErrAuth) matches it.

func (*AuthError) Error

func (e *AuthError) Error() string

func (*AuthError) Unwrap

func (e *AuthError) Unwrap() error

Unwrap makes errors.Is(err, ErrAuth) true.

type Change

type Change struct {
	Location provenance.Location
	Files    map[string][]byte
}

Change is the set of files for one location: the repository, the base branch and the repository-relative paths the files land at (the keys of what sopsenc.Encrypt returns). Changes for one repository become one commit.

type CheckState

type CheckState string

CheckState is the rollup of the commit statuses and check runs on the head.

type Fake

type Fake struct {
	// Fail maps an operation name (OpCreateBranch, OpCommit, ...) to the error
	// that operation returns instead of acting.
	Fail map[string]error
	// contains filtered or unexported fields
}

Fake is an in-process Remote for tests — the module's own and its callers': branches with commits, pull requests with review and check state, and a way to make any operation fail. It never touches the network.

func NewFake

func NewFake() *Fake

NewFake returns an empty Fake; seed base branches with AddBranch.

func (*Fake) AddBranch

func (f *Fake) AddBranch(repo Repository, branch string, files map[string][]byte)

AddBranch seeds branch in repo with one commit holding files (nil for an empty tree).

func (*Fake) Close added in v0.4.0

func (f *Fake) Close(_ context.Context, pr PullRequest, deleteBranch bool) error

Close implements Remote.

func (*Fake) Commit

func (f *Fake) Commit(_ context.Context, repo Repository, branch, message string, files map[string][]byte) error

Commit implements Remote.

func (*Fake) Commits

func (f *Fake) Commits(repo Repository, branch string) []FakeCommit

Commits returns the commits made on branch after its seed, oldest first.

func (*Fake) CreateBranch

func (f *Fake) CreateBranch(_ context.Context, repo Repository, branch, base string) error

CreateBranch implements Remote.

func (*Fake) EnableAutoMerge added in v0.4.0

func (f *Fake) EnableAutoMerge(_ context.Context, pr PullRequest) error

EnableAutoMerge implements Remote: the pull request is marked, nothing merges by itself.

func (*Fake) Files

func (f *Fake) Files(repo Repository, branch string) map[string][]byte

Files returns the tree at the head of branch.

func (*Fake) FindPullRequest added in v0.4.0

func (f *Fake) FindPullRequest(_ context.Context, repo Repository, head string) (PullRequest, bool, error)

FindPullRequest implements Remote.

func (*Fake) Merge

func (f *Fake) Merge(_ context.Context, pr PullRequest) error

Merge implements Remote: the base fast-forwards to the head.

func (*Fake) OpenDraftPullRequest added in v0.4.0

func (f *Fake) OpenDraftPullRequest(_ context.Context, repo Repository, head, base, title, body string) (PullRequest, error)

OpenDraftPullRequest implements Remote.

func (*Fake) OpenPullRequest

func (f *Fake) OpenPullRequest(_ context.Context, repo Repository, head, base, title, body string) (PullRequest, error)

OpenPullRequest implements Remote.

func (*Fake) PullRequests

func (f *Fake) PullRequests() []FakePullRequest

PullRequests returns every pull request the Fake holds, oldest first.

func (*Fake) Revert added in v0.4.0

func (f *Fake) Revert(_ context.Context, pr PullRequest, body string, overrides map[string][]byte) (PullRequest, error)

Revert implements Remote: the merged pull request's files, inverted against the base as it was at the merge, in one commit on the base's tip.

func (*Fake) SetChecks

func (f *Fake) SetChecks(pr PullRequest, state CheckState)

SetChecks sets the check rollup the Fake reports for pr.

func (*Fake) SetReview

func (f *Fake) SetReview(pr PullRequest, state ReviewState)

SetReview sets the review rollup the Fake reports for pr.

func (*Fake) Status

func (f *Fake) Status(_ context.Context, pr PullRequest) (Status, error)

Status implements Remote.

type FakeCommit

type FakeCommit struct {
	Repository Repository
	Branch     string
	Message    string
	Parent     string
	SHA        string
	Files      map[string][]byte
}

FakeCommit is one commit the Fake holds; Files is the full tree at that commit.

type FakePullRequest

type FakePullRequest struct {
	PullRequest
	Title     string
	Body      string
	Draft     bool
	Merged    bool
	Closed    bool // closed without a merge
	AutoMerge bool
	Review    ReviewState
	Checks    CheckState
	// contains filtered or unexported fields
}

FakePullRequest is a pull request the Fake holds, with what the remote knows about it.

type GitHub

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

GitHub is the Remote for github.com (or a GitHub Enterprise Server) acting with the token the caller supplies. It talks REST through google/go-github, never a git or sops binary.

func NewGitHub

func NewGitHub(token string, opts ...GitHubOption) (*GitHub, error)

NewGitHub builds the Remote from the caller's token. The token is the person's; the module keeps none of its own.

func NewGitHubWithClient added in v0.4.0

func NewGitHubWithClient(hc *http.Client, opts ...GitHubOption) (*GitHub, error)

NewGitHubWithClient builds the Remote on an HTTP client that already carries the caller's identity — a GitHub App installation transport, a rotated token file — so no token string changes hands. The module adds no credential of its own to it.

func (*GitHub) Close added in v0.4.0

func (g *GitHub) Close(ctx context.Context, pr PullRequest, deleteBranch bool) error

Close closes the pull request and, when asked, deletes its head branch. A pull request that is closed already (merged or not) is left as it is.

func (*GitHub) Commit

func (g *GitHub) Commit(ctx context.Context, repo Repository, branch, message string, files map[string][]byte) error

Commit writes one commit with files on top of branch: blobs, a tree on the head's tree, the commit, and a fast-forward of the branch.

func (*GitHub) CreateBranch

func (g *GitHub) CreateBranch(ctx context.Context, repo Repository, branch, base string) error

CreateBranch creates branch at base's head; an existing branch is kept.

func (*GitHub) EnableAutoMerge added in v0.4.0

func (g *GitHub) EnableAutoMerge(ctx context.Context, pr PullRequest) error

EnableAutoMerge arms GitHub's auto-merge on the pull request with the repository's merge method. Auto-merge is GraphQL-only; the mutation goes through the same client and identity as every other call.

func (*GitHub) FindPullRequest added in v0.4.0

func (g *GitHub) FindPullRequest(ctx context.Context, repo Repository, head string) (PullRequest, bool, error)

FindPullRequest returns the open pull request of head, if there is one.

func (*GitHub) Merge

func (g *GitHub) Merge(ctx context.Context, pr PullRequest) error

Merge merges the pull request with the repository's merge method (squash where allowed, else merge commit, else rebase), only if the head is still pr.HeadSHA. GitHub applies its own protection rules to the call.

func (*GitHub) OpenDraftPullRequest added in v0.4.0

func (g *GitHub) OpenDraftPullRequest(ctx context.Context, repo Repository, head, base, title, body string) (PullRequest, error)

OpenDraftPullRequest is OpenPullRequest as a draft.

func (*GitHub) OpenPullRequest

func (g *GitHub) OpenPullRequest(ctx context.Context, repo Repository, head, base, title, body string) (PullRequest, error)

OpenPullRequest opens head against base with the caller's title and body. When head already has an open pull request, that one is returned.

func (*GitHub) Revert added in v0.4.0

func (g *GitHub) Revert(ctx context.Context, pr PullRequest, body string, overrides map[string][]byte) (PullRequest, error)

Revert opens a pull request undoing the merged pr: the merge commit's diff against its first parent, inverted into one commit on the tip of the repository's default branch, on branch revert-<number>-<head>.

func (*GitHub) Status

func (g *GitHub) Status(ctx context.Context, pr PullRequest) (Status, error)

Status reads the pull request, its reviews, and the statuses and check runs of its head.

type GitHubOption

type GitHubOption = github.ClientOptionsFunc

GitHubOption configures NewGitHub.

func WithBaseURL

func WithBaseURL(baseURL string) GitHubOption

WithBaseURL points the client at another API root: a GitHub Enterprise Server, or a test server.

func WithHTTPClient

func WithHTTPClient(c *http.Client) GitHubOption

WithHTTPClient sets the HTTP client the requests go through.

type PullRequest

type PullRequest struct {
	Repository Repository
	Number     int
	URL        string
	Head       string
	Base       string
	HeadSHA    string
}

PullRequest identifies a pull request the module opened or found open. HeadSHA is the commit the caller saw; Merge refuses when the head has moved.

func Open

func Open(ctx context.Context, remote Remote, req Request, changes []Change) ([]PullRequest, error)

Open lands the changes: for every repository one branch from its base, one commit with all of that repository's files, one pull request with the caller's title and body. Repositories are handled in name order; on an error the pull requests opened so far are returned with it.

type Remote

type Remote interface {
	// CreateBranch creates branch from base; a branch that exists is left as it is.
	CreateBranch(ctx context.Context, repo Repository, branch, base string) error
	// Commit adds one commit with files to branch.
	Commit(ctx context.Context, repo Repository, branch, message string, files map[string][]byte) error
	// OpenPullRequest opens head against base, or returns the open pull request head already has.
	OpenPullRequest(ctx context.Context, repo Repository, head, base, title, body string) (PullRequest, error)
	// Status reads the pull request's head, merged flag, review and check state.
	Status(ctx context.Context, pr PullRequest) (Status, error)
	// Merge merges the pull request as the person, refusing when the head is not pr.HeadSHA.
	Merge(ctx context.Context, pr PullRequest) error
	// FindPullRequest returns the open pull request whose head is head, and whether there is one.
	FindPullRequest(ctx context.Context, repo Repository, head string) (PullRequest, bool, error)
	// OpenDraftPullRequest is OpenPullRequest with the pull request opened as a draft.
	OpenDraftPullRequest(ctx context.Context, repo Repository, head, base, title, body string) (PullRequest, error)
	// EnableAutoMerge arms the remote's auto-merge on the pull request with the
	// repository's merge method, so it lands once its reviews and checks pass.
	// The caller's choice, never the module's default.
	EnableAutoMerge(ctx context.Context, pr PullRequest) error
	// Close closes the pull request without merging and, when asked, deletes
	// its head branch; a closed pull request is left as it is.
	Close(ctx context.Context, pr PullRequest, deleteBranch bool) error
	// Revert opens a pull request undoing a merged one: the merged change's
	// files are inverted in one commit on the current tip of the base — added
	// files removed, changed and removed files restored — except the paths in
	// overrides, which take the given content. History is never rewritten.
	Revert(ctx context.Context, pr PullRequest, body string, overrides map[string][]byte) (PullRequest, error)
}

Remote is the git hosting the package talks to: GitHub in production, Fake in tests. Every operation acts with the token the Remote was built from.

type Repository

type Repository = provenance.Repository

Repository is the GitHub repository a change lands in.

type Request

type Request struct {
	Branch string
	Title  string
	Body   string
}

Request names one run: its head branch, its commit message and pull request title, and the pull request body — the caller's text, carried verbatim.

type ReviewState

type ReviewState string

ReviewState is the pull request's review rollup: the latest stance of every reviewer, approved when at least one approves and none requests changes.

type Status

type Status struct {
	HeadSHA string
	Merged  bool
	Review  ReviewState
	Checks  CheckState
}

Status is the pull request's state as the remote reports it.

Jump to

Keyboard shortcuts

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