shipwright

package
v0.12.0 Latest Latest
Warning

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

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

Documentation

Overview

Package shipwright defines Shipwright's public, versioned capability contract (Layer 1). Every capability interface here is a plain exported Go interface — no generic type parameters, no module-defined Object types in method signatures — so it can be projected onto Dagger's module type system (see .dagger/, Layer 2) and consumed through generated cross-language SDK bindings. Signature rule (design.md D-A, binding per the proposal's Dagger type-system constraint): every method uses only Dagger core types (*dagger.Directory, *dagger.File, *dagger.Container, *dagger.Secret), Go scalars, context.Context, and error.

Index

Constants

View Source
const ContractVersion = "1.0.0"

ContractVersion is the source of truth for the public capability contract's SemVer-style compatibility guarantee (design.md D-E). It resolves independently of the CLI binary's release SemVer (.dagger/release_package.go + CHANGELOG.md, main.go's `Version` var) and of the `dagger.json` engineVersion pin — three separate version axes that are never conflated.

A breaking change to the guaranteed surface (the five capability interfaces, the Shipwright/composition-type surface, and the pkg/shipwright config structs) MUST bump the major segment here and ship a written migration note. Internal, non-exported packages carry no compatibility guarantee and never require a bump.

Variables

This section is empty.

Functions

This section is empty.

Types

type ArtifactConfig

type ArtifactConfig struct {
	// Registry is the target Docker registry (e.g.
	// registry.gitlab.com/my-org/my-project/service).
	Registry string
	// RegistryURL is the Docker registry URL used for authentication.
	RegistryURL string
	// RegistryUser is the registry username (e.g. gitlab-ci-token in CI).
	RegistryUser string
	// RegistryPass is the registry password/personal access token,
	// carried as a Dagger secret so it never surfaces as plaintext.
	RegistryPass *dagger.Secret
	// RegistryToken is the registry authentication token, carried as a
	// Dagger secret so it never surfaces as plaintext.
	RegistryToken *dagger.Secret
	// ImageName is the published image name.
	ImageName string
	// BinaryName is the name of the compiled binary file inside the
	// published image, used to compute the container entrypoint
	// ("/app/"+BinaryName). Left empty, an Artifactor falls back to its own
	// default binary name (mirroring BuildConfig.BinaryName's own
	// empty-falls-back-to-default convention) — set it explicitly whenever
	// the paired Builder was configured with a non-default BuildConfig.
	// BinaryName, so the two agree on where the binary actually lives.
	BinaryName string
	// ImageTag is the published image tag (e.g. latest, sha, v1.2.3).
	ImageTag string
	// BuildTag is the build tag associated with the artifact.
	BuildTag string
	// CommitSHA is the commit SHA the artifact was built from.
	CommitSHA string
	// BranchName is the Git branch the artifact was built from.
	BranchName string
	// Version is the artifact version.
	Version string
	// Token is a generic authentication token, carried as a Dagger secret
	// so it never surfaces as plaintext.
	Token *dagger.Secret
}

ArtifactConfig configures an Artifactor implementation.

Security-relevant: RegistryPass, RegistryToken, and Token are *dagger.Secret, never a plaintext string — credentials MUST cross the public contract as *dagger.Secret only (design.md D-D, Threat Matrix).

type Artifactor

type Artifactor interface {
	Publish(ctx context.Context, build *dagger.Directory, ref string, creds *dagger.Secret) (string, error)
}

Artifactor publishes a build-output Directory as a versioned artifact and returns its resolved reference (for example an image reference).

type BuildConfig

type BuildConfig struct {
	// GoVersion is the Go toolchain version to use (e.g. "1.26.1").
	GoVersion string
	// JavaVersion is the Java toolchain version to use (e.g. "17").
	JavaVersion string
	// BuildMode selects how the Builder produces its output (e.g.
	// "binary", "docker", "both"). Left as a plain string here; a
	// concrete Builder implementation owns its own enum.
	BuildMode string
	// BinaryName is the name of the output binary file, when applicable.
	BinaryName string
}

BuildConfig configures a Builder implementation.

type Builder

type Builder interface {
	Build(ctx context.Context, source *dagger.Directory) (*dagger.Directory, error)
}

Builder builds a source Directory into a build-output Directory. It has no knowledge of Test, Artifact, Deploy, or Run — capabilities compose, they do not depend on siblings.

Name collision (temporary, by design): internal/pipelines/pipeline.go also declares a "Builder" — an unused, incompatible single-method interface (`Build(ctx) error`, no Directory in/out) predating this capability contract. That legacy type, along with the rest of internal/pipelines/pipeline.go, is deleted in a later work unit of this change (design.md's Migration Sequence) once nothing references it. Until then the two coexist in sibling packages; do not rename this one to work around it — this exported name is what design.md/spec fix as the public Builder capability.

type ConflictState

type ConflictState struct {
	// Ambiguous is true when two or more declarative locations disagree
	// with no resolvable precedence.
	Ambiguous bool `json:"ambiguous"`
	// Code is the ambiguity rule that fired (design.md D-5: A1-A6), empty
	// when Ambiguous is false.
	Code string `json:"code,omitempty"`
	// Sites names every conflicting source and the version it declares,
	// empty when Ambiguous is false.
	Sites []string `json:"sites,omitempty"`
}

ConflictState is DriftReport's explicit ambiguity marker. Ambiguous is false and Code/Sites are empty whenever every present tier-1 source agrees; no single "winning" version is ever inferred when they do not (spec: "Ambiguous sources are reported, never guessed").

type DeployConfig

type DeployConfig struct{}

DeployConfig configures a Deployer implementation. Empty at this change — concrete deploy adapters (Kubernetes, Nomad, SSH, ...) are deferred to a follow-up change (design.md D-D).

type Deployer

type Deployer interface {
	Deploy(ctx context.Context, artifactRef, environment string, creds *dagger.Secret) (string, error)
}

Deployer deploys a previously published artifact reference into a named environment and returns a deployment result reference.

type DriftReport

type DriftReport struct {
	// WorkspaceRoot is the inspected workspace-relative root ("." by
	// default).
	WorkspaceRoot string `json:"workspaceRoot"`
	// ExpectedVersion echoes the caller-configured expected version, if
	// any ("" when not configured). It is informational only: Inspect
	// does not compare it against the discovered sources itself, leaving
	// that judgment to the report's consumer.
	ExpectedVersion string `json:"expectedVersion,omitempty"`
	// Sources maps each present tier-1 declarative location's fixed name
	// ("go.work", ".go-version") to the version it declares. A location
	// that does not exist in the workspace has no entry here.
	Sources map[string]string `json:"sources"`
	// Modules lists every discovered module's own go.mod version
	// directives. A single-module workspace (no go.work) has exactly one
	// entry with Path ".".
	Modules []ModuleVersion `json:"modules,omitempty"`
	// Conflict is the explicit ambiguity state (spec: "the report marks
	// the conflict state explicitly, naming both sources and versions").
	Conflict ConflictState `json:"conflict"`
}

DriftReport is the JSON payload RuntimeInspector.Inspect returns as a plain string (design.md D-1: report structs may never appear directly in a capability interface signature — only context.Context, error, string, and the four Dagger core types may). It is the JSON contract, not a method parameter.

Spec requirement "Read-Only Drift Inspection" (runtime-toolchain): contains the version(s) discovered at each declarative location, the configured target/expected version (if any), and an explicit conflict/ambiguity state. A declarative location that is absent from the inspected workspace is omitted from Sources entirely — never fabricated with a default or assumed value.

type ModuleDrift

type ModuleDrift struct {
	// Path is the module's directory relative to the workspace root ("."
	// for a single go.mod at the workspace root itself).
	Path string `json:"path"`
	// PreviousGo is the module's go directive value before mutation ("" if
	// absent).
	PreviousGo string `json:"previousGo,omitempty"`
	// UpdatedGo is the module's go directive value after mutation.
	UpdatedGo string `json:"updatedGo,omitempty"`
	// PreviousToolchain is the module's toolchain directive value before
	// mutation ("" if it had none — a toolchain directive is never added
	// where none existed before).
	PreviousToolchain string `json:"previousToolchain,omitempty"`
	// UpdatedToolchain is the module's toolchain directive value after
	// mutation ("" if it had none before, and therefore was left absent).
	UpdatedToolchain string `json:"updatedToolchain,omitempty"`
	// GoSumChanged is true when this module's go.sum content actually
	// changed as a result of post-mutation `go mod tidy` (design.md D-7),
	// determined by a literal byte comparison of go.sum before and after
	// tidy ran — never inferred from the go.mod require-list delta, which
	// misses `go mod tidy` bumping an already-required dependency's
	// version (the require path stays the same; only its pinned version
	// and go.sum's hash entries change). It never carries the raw go.sum
	// diff itself, which can run to thousands of unreviewable lines.
	GoSumChanged bool `json:"goSumChanged"`
	// AddedModules lists every require module path `go mod tidy` added
	// that was not present before validation ran.
	AddedModules []string `json:"addedModules,omitempty"`
	// RemovedModules lists every require module path `go mod tidy`
	// dropped that was present before validation ran.
	RemovedModules []string `json:"removedModules,omitempty"`
}

ModuleDrift is one module's before/after toolchain-version directives, as reported by RuntimeUpgrader.Upgrade. A directive absent both before and after is omitted (discovery-driven: never fabricate a directive that wasn't there).

type ModuleVersion

type ModuleVersion struct {
	// Path is the module's directory relative to the workspace root ("."
	// for a single go.mod at the workspace root itself).
	Path string `json:"path"`
	// Go is the module's go directive value ("" if absent).
	Go string `json:"go,omitempty"`
	// Toolchain is the module's toolchain directive value ("" if absent).
	Toolchain string `json:"toolchain,omitempty"`
}

ModuleVersion is one workspace module's go.mod version directives, as reported by RuntimeInspector.Inspect.

type RunConfig

type RunConfig struct{}

RunConfig configures a Runner implementation. Empty at this change — concrete run adapters are deferred to a follow-up change (design.md D-D).

type Runner

type Runner interface {
	Run(ctx context.Context, build *dagger.Directory) (*dagger.Container, error)
}

Runner runs a build-output Directory as a live Container, for example to execute it locally or expose it for interactive inspection.

type RuntimeInspector

type RuntimeInspector interface {
	Inspect(ctx context.Context, source *dagger.Directory) (string, error)
}

RuntimeInspector reports drift across a workspace's declarative toolchain-version sources (e.g. Go's go.mod/go.work/.go-version) without mutating anything, returning a JSON-encoded report (see DriftReport). It never returns a DriftReport directly (design.md D-1): a report struct may never appear in a capability interface signature, only context.Context, error, string, and the four Dagger core types may.

type RuntimeUpgrader

type RuntimeUpgrader interface {
	Upgrade(ctx context.Context, source *dagger.Directory, targetVersion string) (*dagger.Directory, error)
}

RuntimeUpgrader mutates a workspace's declarative toolchain-version sources (go.mod's go/toolchain directives, .go-version) to targetVersion and returns the mutated Directory. Discovery-driven: it only mutates locations that actually exist in source, never fabricating one that wasn't there (design.md's Discovery-Driven Upgrade requirement). Because *dagger.Directory is an immutable value, a failed run (ambiguity detected, malformed input) returns (nil, err) — never a partially mutated directory (no-partial-mutation guarantee).

type SourceConfig

type SourceConfig struct {
	// GitRepo is the Git repository URL.
	GitRepo string
	// GitRef is the Git reference (branch or tag) to check out.
	GitRef string
	// GitProtocol is the Git transport protocol ("ssh" or "https").
	GitProtocol string
	// GitUserEmail is the Git user email used for any commits made during
	// the pipeline.
	GitUserEmail string
	// GitUserName is the Git user name used for any commits made during
	// the pipeline.
	GitUserName string
	// SSHPrivateKey is the SSH private key used for Git authentication,
	// carried as a Dagger secret so it never surfaces as plaintext.
	SSHPrivateKey *dagger.Secret
}

SourceConfig configures how a Builder obtains its source input (git checkout, credentials). It carries no Build/Test/Artifact/Deploy/Run field — decomposed per design.md D-D so orthogonality is compiler-enforced rather than documented.

Security-relevant: SSHPrivateKey is a *dagger.Secret, never a plaintext string — credentials MUST cross the public contract as *dagger.Secret only (design.md D-D, Threat Matrix), the same invariant already enforced for ArtifactConfig's credential fields.

type TestConfig

type TestConfig struct {
	// Coverage is the minimum required test coverage percentage.
	Coverage float64
}

TestConfig configures a Tester implementation.

type Tester

type Tester interface {
	Test(ctx context.Context, source *dagger.Directory) (*dagger.File, error)
}

Tester runs tests against a build-output Directory and returns a report File. Multiple independent Tester implementations MAY exist for the same input (unit, lint, vulnerability scan, ...); none is privileged.

Same temporary name collision as Builder, with internal/pipelines's unused legacy Tester interface — see the Builder doc comment above.

type UpgradeReport

type UpgradeReport struct {
	// WorkspaceRoot is the upgraded workspace-relative root ("." by
	// default).
	WorkspaceRoot string `json:"workspaceRoot"`
	// TargetVersion is the version every mutated directive was set to.
	TargetVersion string `json:"targetVersion"`
	// Modules lists every module actually mutated. Phase 2 (single-module
	// only, no go.work traversal) always reports exactly one entry with
	// Path ".".
	Modules []ModuleDrift `json:"modules"`
	// Validation names the post-mutation validation Upgrade actually ran
	// (design.md D-6: always "build" — `go build ./...`, never `go vet`)
	// so no consumer is misled into believing more was proven than a
	// successful compile.
	Validation string `json:"validation"`
}

UpgradeReport is the JSON payload RuntimeUpgrader.Upgrade writes to .shipwright/runtime-upgrade-report.json inside the returned Directory (design.md D-2). Like DriftReport, it never appears directly in a capability interface signature (design.md D-1).

Directories

Path Synopsis
Package invocation carries the identity of the step currently being dispatched through context.Context, so that Layer 1 providers (which only ever see ctx and Values — never manifest.Step) can differentiate per-invocation resources, such as Dagger service graphs that would otherwise be content-addressed to the same node when two steps build an identical container definition concurrently (see providers/rust/dockerdaemon.go).
Package invocation carries the identity of the step currently being dispatched through context.Context, so that Layer 1 providers (which only ever see ctx and Values — never manifest.Step) can differentiate per-invocation resources, such as Dagger service graphs that would otherwise be content-addressed to the same node when two steps build an identical container definition concurrently (see providers/rust/dockerdaemon.go).

Jump to

Keyboard shortcuts

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