ship

package
v0.65.0 Latest Latest
Warning

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

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package ship — hook.go provides the pre-push hook content and installation.

Package ship implements the deterministic agent pipeline guardrail. It wraps pre-flight checks, git push, PR creation, and synchronous CI polling into a single blocking operation so AI agents cannot skip post-merge verification.

Index

Constants

View Source
const (
	ExitOK            = 0
	ExitPreFlightFail = 50
	ExitPushFail      = 51
	ExitPRFail        = 52
	ExitCIFail        = 53
	ExitCITimeout     = 54
	ExitDocCheckFail  = 55
	ExitNothingToShip = 56
)

ExitCodes for deterministic agent error handling.

View Source
const PreCommitHookContent = `` /* 2167-byte string literal not displayed */

PreCommitHookContent is the shell script installed into .git/hooks/pre-commit. It prevents direct commits to protected trunk branches and forces developers to work on feature branches. Humans can bypass with: git commit --no-verify

View Source
const PrePushHookContent = `` /* 2577-byte string literal not displayed */

PrePushHookContent is the shell script installed into .git/hooks/pre-push. It runs devx audit (secrets + vulnerability scanning) first, then blocks all git push attempts and directs agents to use devx agent ship. Humans can bypass with: git push --no-verify

Variables

View Source
var ErrNoStack = errors.New("no recognized stack detected (go.mod, package.json, Cargo.toml, pyproject.toml, pom.xml, build.gradle, *.csproj) and no pipeline: block in devx.yaml — pre-flight checks were skipped")

ErrNoStack is returned when no stack is detected and no explicit pipeline exists. Callers should surface this as a warning to the developer.

Functions

func CreatePR added in v0.34.0

func CreatePR(dir, commitMsg, baseBranch string) (string, error)

CreatePR creates a GitHub PR from a commit-message-style string. The first line of commitMsg becomes the PR title; the remainder (if any) becomes the PR body. Splitting is required because GitHub's API rejects titles that contain newlines or exceed ~256 chars, so passing the full multi-line `-m` payload as the title returns a 422 and surfaces as `gh pr create: exit 1`. Returns the PR URL.

func CurrentBranch

func CurrentBranch(dir string) string

CurrentBranch returns the current git branch name.

func DetectAllStacks added in v0.44.0

func DetectAllStacks(dir string) []*stackInfo

DetectAllStacks returns all matching stacks for the given directory. This enables multi-stack monorepo support.

func DetectStack

func DetectStack(dir string) *stackInfo

DetectStack profiles the repository by looking for marker files. Returns the first matching stack (highest precedence).

func GitPush

func GitPush(dir, commitMsg, branch string) error

GitPush commits any working-tree changes (no-op if already committed) and pushes to a feature branch using --no-verify to bypass our own pre-push hook.

func HasStagedChanges

func HasStagedChanges(dir string) bool

HasStagedChanges checks if there are any uncommitted changes.

func HasUnpushedCommits added in v0.58.0

func HasUnpushedCommits(dir, baseRef string) bool

HasUnpushedCommits reports whether the current branch has commits that are not present on baseRef (e.g. "origin/main"). This lets review/ship recognize already-committed work that still needs pushing even when the working tree is clean. Returns false if the comparison can't be made (e.g. baseRef missing).

func InstallPreCommitHook added in v0.45.0

func InstallPreCommitHook(repoDir string) error

InstallPreCommitHook writes the pre-commit hook into .git/hooks/. If any devx-managed hook already exists, it will be safely overwritten. If a non-devx hook exists, it returns an error to avoid clobbering.

func InstallPrePushHook

func InstallPrePushHook(repoDir string) error

InstallPrePushHook writes the pre-push hook into .git/hooks/. If any devx-managed hook already exists, it will be safely overwritten. If a non-devx hook exists, it returns an error to avoid clobbering.

func IsPreCommitHookInstalled added in v0.45.0

func IsPreCommitHookInstalled(repoDir string) bool

IsPreCommitHookInstalled checks if a devx pre-commit hook is present.

func IsPrePushHookInstalled

func IsPrePushHookInstalled(repoDir string) bool

IsPrePushHookInstalled checks if a devx pre-push hook is present.

func LatestCommitMessage added in v0.58.0

func LatestCommitMessage(dir string) (string, error)

LatestCommitMessage returns the full message (subject + body) of HEAD's most recent commit, trimmed. Used to derive a PR title/body for an already-committed branch where there's no working-tree diff to summarize.

func MergePR added in v0.34.0

func MergePR(dir, prURL string) error

MergePR merges the given PR using admin privileges. Captures stderr so transient failures (mergeability race, branch-protection edge cases) surface a real error message instead of an opaque exit code.

func SplitCommitMessage added in v0.45.0

func SplitCommitMessage(msg string) (title, body string)

SplitCommitMessage splits a commit-style string into (title, body) using the first newline as the separator. Surrounding whitespace is trimmed from both halves. The body preserves its internal blank lines.

func WatchPRChecks added in v0.34.0

func WatchPRChecks(dir, prURL, branch string, timeout time.Duration) (runID, conclusion string, failureLogs []string, err error)

WatchPRChecks waits for the PR checks to complete using gh pr checks --watch. It blocks until the pipeline finishes or the timeout expires. Returns the run conclusion and any failure logs.

Types

type Options

type Options struct {
	CommitMsg      string
	Branch         string // target branch (default: current)
	BaseBranch     string // base branch for PR (default: main)
	Verbose        bool
	JSON           bool
	NonInteractive bool
	SkipPreFlight  bool
	CITimeout      time.Duration
}

Options configures a ship run.

type PipelineConfig added in v0.30.0

type PipelineConfig struct {
	Test   *PipelineStage
	Lint   *PipelineStage
	Build  *PipelineStage
	Verify *PipelineStage
}

PipelineConfig holds explicit pipeline stage overrides from devx.yaml. When non-nil, auto-detection via DetectStack is bypassed entirely ("Explicit Wins").

type PipelineStage added in v0.30.0

type PipelineStage struct {
	Cmds   [][]string // Resolved commands to run sequentially
	Before [][]string // Pre-stage hooks (run before Cmds)
	After  [][]string // Post-stage hooks (run after Cmds)
}

PipelineStage defines a single pipeline step with support for multi-command and lifecycle hooks (before/after).

type PreFlightResult

type PreFlightResult struct {
	Stack        string `json:"stack"`
	TestPass     bool   `json:"test_pass"`
	LintPass     bool   `json:"lint_pass"`
	BuildPass    bool   `json:"build_pass"`
	TestSkipped  bool   `json:"test_skipped,omitempty"`
	LintSkipped  bool   `json:"lint_skipped,omitempty"`
	BuildSkipped bool   `json:"build_skipped,omitempty"`
}

PreFlightResult holds the outcome of each local pre-flight step.

func RunPreFlight

func RunPreFlight(dir string, verbose bool, pipeline *PipelineConfig) (*PreFlightResult, error)

RunPreFlight executes local tests, linter, and build. If an explicit pipeline is provided, it takes precedence over auto-detection.

type Result

type Result struct {
	Success     bool             `json:"success"`
	ExitCode    int              `json:"exit_code"`
	Phase       string           `json:"phase"`
	Message     string           `json:"message"`
	PRURL       string           `json:"pr_url,omitempty"`
	CIRunID     string           `json:"ci_run_id,omitempty"`
	CIStatus    string           `json:"ci_status,omitempty"`
	FailureLogs []string         `json:"failure_logs,omitempty"`
	PreFlight   *PreFlightResult `json:"pre_flight,omitempty"`
}

Result is the machine-readable output of a ship operation.

Jump to

Keyboard shortcuts

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