shipwright

command module
v0.0.0-...-c4e71b8 Latest Latest
Warning

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

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

README

Shipwright

Release Pipeline

Shipwright is a Dagger-powered software delivery engine: it defines CI/CD pipelines as code, once, so they can run the same way on your laptop and in any CI provider.

Why Shipwright?

CI/CD logic tends to spread out and drift: provider YAML (GitHub Actions, GitLab CI, Jenkins) accumulates business delivery logic, local scripts reimplement a looser version of the same thing for developer convenience, and every repository re-derives its own version of "lint, test, build, scan, package, publish." Shipwright's premise is that this logic should live in one place, as code, executed consistently — with CI providers reduced to thin triggers instead of the source of truth for delivery behavior.

Status

Shipwright is under active architectural evolution. It started as a Go-specific pipeline library and is moving toward a provider-neutral, polyglot delivery engine built on Dagger. Some of what follows already works today; some of it is the direction the project is heading. They are marked accordingly — do not assume a "planned" item is already usable.

Available today

  • A compiled Go CLI/binary (shipwright) whose sole entrypoint is a declarative workflow manifest engine (--workflow, shipwright.dev/v1 schema) that composes registered providers per step. Providers registered today include five Go providers (setup/test, lint, vulnerability scan, build, container publish) plus a full Rust equivalent set (rust, rust-test, rust-integration-test, clippy, cargo-audit, rust-container) and toolchain-drift runtime-inspect/runtime-upgrade capabilities.
  • A Docker/Dagger-based execution path for workflow steps.
  • Rust provider support (providers/rust): a Go-implemented provider package — builder, unit/integration testers, linter, vulnerability scanner, container publisher — mirroring providers/go's shape and consumed through the workflow manifest engine above. Proven standalone (GOWORK=off, no workspace, no replace directive) on every push via make provider-rust-standalone, and via a dedicated git-tag release workflow.
  • A public, versionable Dagger Module API at the repository root (dagger call; see .dagger/capabilities.go and COMPATIBILITY.md). The five core capabilities (Builder/Tester/Artifactor/Deployer/Runner) are wired into a chainable Plan/Execute composition today, versioned via ContractVersion (currently 1.0.0). Two further capabilities, RuntimeInspector/RuntimeUpgrader, are also declared as Dagger Interfaces but not yet wired into Plan's composition chain.
  • A GitHub Actions composite action that wraps the CLI.
  • A plugin/hook registration system at the infrastructure level.

Planned / evolving

  • One unified pipeline/step abstraction (two structurally similar Pipeline interfaces exist internally today, bridged by an adapter).
  • Typed artifacts between steps (today steps communicate through struct fields and host paths).
  • Reusable step composition — configuring, disabling, replacing, or inserting steps without forking Shipwright.
  • An additional language toolchain (Java) — not implemented today (Rust ships today, see above).
  • Wiring RuntimeInspector/RuntimeUpgrader into the Dagger Module API's Plan/Execute composition chain.
  • Build-once/promote artifact handling and an explicit Git-lifecycle (feature/develop/release/main/hotfix) model.
  • GitLab CI and Jenkins integration with parity to the GitHub Actions path.

See docs/PRD.md for the full product vision, current-state detail, and roadmap.

How it works today

Shipwright ships as a single binary whose only entrypoint is a declarative workflow manifest (shipwright.dev/v1 schema). It executes steps against a Dagger-provisioned environment.

# Build from source
git clone https://github.com/pablogore/shipwright.git
cd shipwright
make build

# Run every step in a workflow manifest
./shipwright --workflow path/to/workflow.yaml

# Run a single step (and its needs-transitive dependencies)
./shipwright --workflow path/to/workflow.yaml --step test

# List the steps declared in a manifest instead of executing them
./shipwright --workflow path/to/workflow.yaml --list-steps

# Select which branch predicate conditional steps evaluate against
./shipwright --workflow path/to/workflow.yaml --branch main

A missing or invalid manifest fails closed with an explicit error — there is no fallback pipeline to run instead. --workflow, --step, --list-steps, and --branch are the flags that actually affect a workflow run; see shipwright --help for the full flag set, but note that several flags in that list (--executor, --local, --env, --coverage, --git-ref, --git-auth, --config/.shipwright.yml) are parsed but currently have no effect on --workflow execution — everything a workflow needs (source, secrets, variables, per-step options) is declared in the manifest itself.

Building from source
git clone https://github.com/pablogore/shipwright.git
cd shipwright
go mod download
make build   # builds ./shipwright
make test    # go test -race ./...
make lint    # golangci-lint

Requires Go 1.26 (see go.mod / .go-version) and Docker, since workflow steps run via Dagger.

Compiled release binaries for Linux/macOS/Windows (amd64/arm64) are published on the GitHub Releases page.

GitHub Actions

A composite action wraps the CLI so provider YAML stays a thin trigger:

- uses: actions/checkout@v4
- uses: ./.github/actions/shipwright
  with:
    workflow: .shipwright/workflow.yaml
    step: test
    branch: develop

See examples/github-actions for complete workflow examples.

Architecture direction

GitHub Actions / GitLab CI / Jenkins / Local
                    |
                    v
                Shipwright
                    |
        +-----------+-----------+
        |           |           |
    Lifecycle*  Pipeline    Toolchain*
        |           |           |
        +-----------+-----------+
                    |
                  Dagger
                    |
                    v
          reproducible execution

* marks target components that do not exist as standalone abstractions yet — Lifecycle and Toolchain are goals of the ongoing architectural evolution, not shipped concepts. Pipeline exists today but as two overlapping internal interfaces rather than one unified model. Dagger is already the real execution substrate for the workflow manifest engine's container-based steps.

Current capabilities

Verified against the repository:

  • Declarative workflow manifests (--workflow, shipwright.dev/v1 schema) composing registered Go and Rust providers per step: test with coverage threshold, golangci-lint/clippy linting, govulncheck/cargo-audit vulnerability scanning, binary and/or container image build, and toolchain-drift runtime-inspect/runtime-upgrade.
  • A public, versionable Dagger Module API at the repository root (dagger call, .dagger/capabilities.go) exposing Builder/Tester/ Artifactor/Deployer/Runner as chainable Dagger Interfaces via Plan/Execute — see COMPATIBILITY.md for the exact guaranteed surface.
  • Dagger-provisioned execution for workflow steps.
  • Plugin registry/loader and a hook manager at the infrastructure layer (one built-in plugin, nomad-deploy); pipelines do not yet invoke before/after hooks.
  • GitHub Actions composite action and example workflows.
  • GoReleaser-based multi-platform release builds.

Legacy / internal historical implementation

internal/pipelines/ still contains the original go-service and infra pipeline implementations (setup/test/lint/scan/build/package/tag/push logic predating the workflow manifest engine). They are not invocable from the current CLI — the --pipeline flag and preset registry that used to dispatch to them were removed, and main.go's only entrypoint is --workflow. The code remains in the tree as history/reference, not as a supported delivery path.

Roadmap

High-level themes (see docs/PRD.md §22 for detail):

  • Wire RuntimeInspector/RuntimeUpgrader into the Dagger Module API's Plan/Execute composition chain (both capabilities exist today but are not yet chained)
  • Unified pipeline/step model (retire the duplicate Pipeline interfaces)
  • Typed artifacts between steps
  • Pipeline composition: configure, disable, add, replace, insert steps
  • Additional polyglot toolchain: Java (Rust ships today via providers/rust)
  • Explicit Git-lifecycle engine (feature/develop/release/main/hotfix)
  • Build-once, promote: immutable release artifacts
  • Provider-neutral integrations (GitLab CI, Jenkins) with GitHub Actions parity
  • Reproducibility: eliminate mutable latest dependencies, pin toolchain versions
  • Structured, queryable execution observability

Development

make build     # build the shipwright binary
make test      # go test -race ./...
make lint      # golangci-lint
make coverage  # coverage report with threshold validation

Project layout:

shipwright/
├── main.go                 # CLI entry point
├── internal/
│   ├── app/                # DI container, executors, plugin/hook wiring
│   ├── config/             # configuration loading and validation
│   ├── executors/          # native and Docker/Dagger execution
│   ├── interfaces/         # shared interfaces
│   ├── pipelines/          # legacy pipeline implementations (go-service, infra) -- not invocable from the CLI
│   └── plugins/            # plugin/hook system
├── examples/                # usage examples (GitHub Actions, Jenkins, local)
└── docs/                    # documentation

Documentation

Support

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
app
config
Package config contiene la configuración de la aplicación Shipwright.
Package config contiene la configuración de la aplicación Shipwright.
daggerkit
Package daggerkit provides adapters to convert real Dagger types to interfaces, mirroring internal/pipelines/dagger_adapter.go.
Package daggerkit provides adapters to convert real Dagger types to interfaces, mirroring internal/pipelines/dagger_adapter.go.
pipelines
Package pipelines provides adapters to convert real Dagger types to interfaces.
Package pipelines provides adapters to convert real Dagger types to interfaces.
pipelines/shared
Package shared contiene utilidades y helpers para operaciones comunes en los pipelines.
Package shared contiene utilidades y helpers para operaciones comunes en los pipelines.
pipelines/test
Package test provides testing utilities and implementations for pipelines.
Package test provides testing utilities and implementations for pipelines.
releaseguard
Package releaseguard guards design.md D6's release-automation decision.
Package releaseguard guards design.md D6's release-automation decision.
workflow/engine
Package engine implements the wave-scheduling execution engine for Shipwright's declarative workflow layer (design.md D-K, workflow-execution spec).
Package engine implements the wave-scheduling execution engine for Shipwright's declarative workflow layer (design.md D-K, workflow-execution spec).
workflow/graph
Package graph implements stage 5 of the manifest's fixed seven-stage validation pipeline (design.md D-H): dependency-graph construction from each step's needs[], cycle detection via Kahn's algorithm (design.md D-J), rejection of an undeclared data reference (a steps.<id>.output interpolation reference to a step not present in the consuming step's own needs[]), and the output-kind/input-kind checks that are statically knowable without a resolved provider.
Package graph implements stage 5 of the manifest's fixed seven-stage validation pipeline (design.md D-H): dependency-graph construction from each step's needs[], cycle detection via Kahn's algorithm (design.md D-J), rejection of an undeclared data reference (a steps.<id>.output interpolation reference to a step not present in the consuming step's own needs[]), and the output-kind/input-kind checks that are statically knowable without a resolved provider.
workflow/interp
Package interp implements stage 4 (references) of the manifest's fixed seven-stage validation pipeline (design.md D-H): a hand-written scanner over a CLOSED interpolation grammar (design.md D-L), plus the typed Value carrier that makes secrecy a structural property rather than a runtime discipline.
Package interp implements stage 4 (references) of the manifest's fixed seven-stage validation pipeline (design.md D-H): a hand-written scanner over a CLOSED interpolation grammar (design.md D-L), plus the typed Value carrier that makes secrecy a structural property rather than a runtime discipline.
workflow/manifest
Package manifest defines Shipwright's declarative workflow manifest schema (design.md D-H, the workflow-manifest spec): the typed Go structs a YAML workflow document decodes into, plus stages 1-3 of the fixed seven-stage validation pipeline — size-capped read + decode (stage 1), document identity (stage 2), and structure (stage 3).
Package manifest defines Shipwright's declarative workflow manifest schema (design.md D-H, the workflow-manifest spec): the typed Go structs a YAML workflow document decodes into, plus stages 1-3 of the fixed seven-stage validation pipeline — size-capped read + decode (stage 1), document identity (stage 2), and structure (stage 3).
workflow/providers
Package providers implements stage 6 (provider resolution) of the manifest's fixed seven-stage validation pipeline (design.md D-H) and, via WithSchema-checked resolution, the general-with-value-kind-mismatch portion of stage 7 (design.md D-H's "type mismatch in with") — see registry.go's checkWithSchema and this package's doc comment on WithSchemaMismatchError for the exact boundary this closes from WU5 (internal/workflow/interp, Reference.StaticKind) and WU6 (internal/workflow/graph, build.go's package doc comment).
Package providers implements stage 6 (provider resolution) of the manifest's fixed seven-stage validation pipeline (design.md D-H) and, via WithSchema-checked resolution, the general-with-value-kind-mismatch portion of stage 7 (design.md D-H's "type mismatch in with") — see registry.go's checkWithSchema and this package's doc comment on WithSchemaMismatchError for the exact boundary this closes from WU5 (internal/workflow/interp, Reference.StaticKind) and WU6 (internal/workflow/graph, build.go's package doc comment).
workspaceguard
Package workspaceguard guards design.md D1's go.work isolation decision: go.work declares which modules participate in the workspace and how dependency resolution works, but it does NOT make `go build ./...` or `go test -race ./...` from root traverse nested modules — each module must be tested/built explicitly (e.g., `cd providers/go && go test ./...`).
Package workspaceguard guards design.md D1's go.work isolation decision: go.work declares which modules participate in the workspace and how dependency resolution works, but it does NOT make `go build ./...` or `go test -race ./...` from root traverse nested modules — each module must be tested/built explicitly (e.g., `cd providers/go && go test ./...`).
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
pkg
containerutil
Package containerutil holds small, source-language-agnostic helpers shared by the container-publishing Artifactor providers (providers/go, providers/rust).
Package containerutil holds small, source-language-agnostic helpers shared by the container-publishing Artifactor providers (providers/go, providers/rust).
shipwright
Package shipwright defines Shipwright's public, versioned capability contract (Layer 1).
Package shipwright defines Shipwright's public, versioned capability contract (Layer 1).
providers
go module
rust module
tests
mocks
Package mocks provides mock implementations for testing.
Package mocks provides mock implementations for testing.

Jump to

Keyboard shortcuts

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