forge

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package forge is ynf's port to where code lives (ADR-003, ADR-007): pull requests, their checks and reviews, branches and files, and the writes only ynf makes. GitHub is the first provider. Where work items live is the tracker port; a forge that also tracks issues, as GitHub does, serves it through IssueTracker.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoFix = errors.New("forge: no merged pull request closed it")

ErrNoFix means a closed ticket was not closed by a merged pull request: it was closed by hand, by a commit with no pull request, or by a pull request that was not merged.

View Source
var ErrNotFound = errors.New("forge: not found")

ErrNotFound means the forge has no such object.

View Source
var ErrRebased = errors.New("forge: rebase-merged; base unknown")

ErrRebased means a merged pull request was rebase merged, so its merge commit is only the last of its commits and the commit before the change cannot be taken from it.

Functions

func IssueKey

func IssueKey(repo string, number int) string

IssueKey is an issue's tracker key: owner/name#number.

func IssueTracker

func IssueTracker(i Issues) tracker.Tracker

IssueTracker serves a forge's issues through the tracker port. Keys are owner/name#number; a pull request is an issue here too, so an adopted pull request is its own ticket.

func ParseIssueKey

func ParseIssueKey(key string) (repo string, number int, err error)

ParseIssueKey is the inverse of IssueKey.

Types

type Fix

type Fix struct {
	PR       int
	MergeSHA string // the commit the merge made on the base branch
}

Fix is the merged pull request that closed a ticket (shadow mode).

type Fixes

type Fixes interface {
	FixFor(ctx context.Context, repo string, number int) (Fix, error)
}

Fixes is what a forge that records what closed an issue offers: the merged pull request whose merge closed it, or ErrNoFix. Shadow mode reads it to find the answer a ticket's history holds.

type Forge

type Forge interface {
	Search(ctx context.Context, query string) ([]Hit, error)
	PullRequest(ctx context.Context, repo string, number int) (*facts.PR, error)
	// FindPR returns the open pull request whose head is branch, or 0.
	FindPR(ctx context.Context, repo, branch string) (int, error)
	OpenPR(ctx context.Context, repo string, pr NewPR) (int, error)
	// Comment posts body on a pull request unless a comment containing marker exists: side
	// effects are idempotent per step (ADR-005).
	Comment(ctx context.Context, repo string, number int, marker, body string) error
	DefaultBranch(ctx context.Context, repo string) (string, error)
	// Head is the commit a branch points at, so policy is read at a resolved commit (ADR-006).
	Head(ctx context.Context, repo, branch string) (string, error)
	// File reads a file at ref; ErrNotFound if it does not exist.
	File(ctx context.Context, repo, ref, path string) ([]byte, error)
}

Forge is the port the engine uses.

type GitHub

type GitHub struct {

	// Log receives the warning that a repository's required checks could not be read; the default
	// logger when nil.
	Log *slog.Logger
	// contains filtered or unexported fields
}

GitHub is the GitHub provider.

func NewGitHub

func NewGitHub(token, baseURL string) (*GitHub, error)

NewGitHub returns a GitHub forge authenticated with token. baseURL is for tests; "" is api.github.com.

func (*GitHub) Comment

func (g *GitHub) Comment(ctx context.Context, repo string, number int, marker, body string) error

Comment implements Forge and Issues.

func (*GitHub) DefaultBranch

func (g *GitHub) DefaultBranch(ctx context.Context, repo string) (string, error)

DefaultBranch implements Forge.

func (*GitHub) File

func (g *GitHub) File(ctx context.Context, repo, ref, path string) ([]byte, error)

File implements Forge.

func (*GitHub) FindPR

func (g *GitHub) FindPR(ctx context.Context, repo, branch string) (int, error)

FindPR implements Forge.

func (*GitHub) FixFor

func (g *GitHub) FixFor(ctx context.Context, repo string, number int) (Fix, error)

FixFor implements Fixes. GitHub's GraphQL ClosedEvent names what closed the issue, which the REST timeline does not: a merged pull request gives the fix with its merge commit; a commit is looked up for the merged pull request that made it; an issue closed by hand, or by a pull request that was not merged, is ErrNoFix. A pull request that was rebase merged has no merge commit to take a base from, and is ErrRebased.

func (*GitHub) GraphQLURL

func (g *GitHub) GraphQLURL() string

GraphQLURL is the GraphQL endpoint beside the REST base: <base>graphql on api.github.com (and a test server), <host>/api/graphql on GitHub Enterprise Server, whose REST base ends /api/v3/.

func (*GitHub) Head

func (g *GitHub) Head(ctx context.Context, repo, branch string) (string, error)

Head implements Forge.

func (*GitHub) Host

func (g *GitHub) Host() string

Host is the forge instance's host, as item keys name it: github.com for the public service.

func (*GitHub) OpenPR

func (g *GitHub) OpenPR(ctx context.Context, repo string, n NewPR) (int, error)

OpenPR implements Forge.

func (*GitHub) PullRequest

func (g *GitHub) PullRequest(ctx context.Context, repo string, number int) (*facts.PR, error)

PullRequest implements Forge: state, checks on the head (check runs and commit statuses, every page of each), the base branch's required checks marked, and the latest review per reviewer. A required check that has not reported is listed too, with status "expected", so the pull request cannot read as green while it is missing.

func (*GitHub) RequiredChecks

func (g *GitHub) RequiredChecks(ctx context.Context, repo, branch string) Required

RequiredChecks reads the checks branch requires: the union of classic branch protection and the rulesets that apply to it. An unprotected branch is known to require none. Only when both sources fail to be read is the answer unknown.

func (*GitHub) Search

func (g *GitHub) Search(ctx context.Context, query string) ([]Hit, error)

Search implements Forge.

func (*GitHub) SetLabels

func (g *GitHub) SetLabels(ctx context.Context, repo string, number int, add, remove []string) error

SetLabels implements Issues: labels already present or already absent are left alone.

func (*GitHub) Ticket

func (g *GitHub) Ticket(ctx context.Context, repo string, number int) (facts.Ticket, Text, error)

Ticket implements Issues.

func (*GitHub) Workflows

func (g *GitHub) Workflows(ctx context.Context, repo, ref string) (int, error)

Workflows implements WorkflowReader: the .yml and .yaml files in .github/workflows at ref.

type Hit

type Hit struct {
	Repo   string
	Number int
	IsPR   bool
}

Hit is one search result.

type Issues

type Issues interface {
	Ticket(ctx context.Context, repo string, number int) (facts.Ticket, Text, error)
	Comment(ctx context.Context, repo string, number int, marker, body string) error
	SetLabels(ctx context.Context, repo string, number int, add, remove []string) error
}

Issues is what a forge that also tracks issues offers, keyed by repository and number.

type NewPR

type NewPR struct {
	Head, Base, Title, Body string
	Draft                   bool
}

NewPR is a pull request to open.

type Required

type Required struct {
	Checks []RequiredCheck
	// Known is false when neither source could be read. Checks is then empty, which says nothing
	// about what the branch requires.
	Known bool
	// Detail says how it was read, or why it could not be.
	Detail string
}

Required is what a branch requires before it merges, from classic branch protection and from the repository rulesets that apply to it, together.

type RequiredCheck

type RequiredCheck struct {
	Context string
	AppID   int64
}

RequiredCheck is a check a branch requires: its name, and the GitHub App it must come from, or 0 for any source.

type RequiredReader

type RequiredReader interface {
	RequiredChecks(ctx context.Context, repo, branch string) Required
}

RequiredReader is what a forge offers that can say which checks a branch requires.

type Text

type Text = tracker.Text

Text is a ticket's free text (tracker.Text).

type WorkflowReader

type WorkflowReader interface {
	// Workflows counts the workflow files at ref; a repository with none has zero, not an error.
	Workflows(ctx context.Context, repo, ref string) (int, error)
}

WorkflowReader is what a forge offers that can say whether a branch has CI workflow files.

Jump to

Keyboard shortcuts

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