Documentation
¶
Overview ¶
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).
D-I, binding: uses.provider/uses.module resolves ONLY to already compiled, self-registered providers. This is a deliberate security decision — reusing internal/plugins/loader.go's plugin.Open for manifest-declared providers was rejected specifically because it would let a manifest a pipeline author or PR contributor controls run arbitrary native code in-process (supply-chain / arbitrary-code- execution risk). There is no fetch, no download, no cache, no `.so` load, and no registry service anywhere in this package — see security_test.go for the static proof that "plugin" is unreachable from this package's import graph, and register_test.go's TestRegisterDefaults_UnregisteredModuleFailsClosed for the fail-closed behavior that boundary produces at resolution time.
Index ¶
- func RegisterDefaults(r *Registry, client *dagger.Client)
- type ChangelogRunner
- type Ref
- type Registry
- func (r *Registry) RegisterArtifactor(ref Ref, schema WithSchema, f func(Values) shipwright.Artifactor)
- func (r *Registry) RegisterBuilder(ref Ref, schema WithSchema, f func(Values) shipwright.Builder)
- func (r *Registry) RegisterDeployer(ref Ref, schema WithSchema, f func(Values) shipwright.Deployer)
- func (r *Registry) RegisterRunner(ref Ref, schema WithSchema, f func(Values) shipwright.Runner)
- func (r *Registry) RegisterRuntimeInspector(ref Ref, schema WithSchema, f func(Values) shipwright.RuntimeInspector)
- func (r *Registry) RegisterRuntimeUpgrader(ref Ref, schema WithSchema, f func(Values) shipwright.RuntimeUpgrader)
- func (r *Registry) RegisterTester(ref Ref, schema WithSchema, f func(Values) shipwright.Tester)
- func (r *Registry) ResolveArtifactor(ref Ref, v Values) (shipwright.Artifactor, error)
- func (r *Registry) ResolveBuilder(ref Ref, v Values) (shipwright.Builder, error)
- func (r *Registry) ResolveDeployer(ref Ref, v Values) (shipwright.Deployer, error)
- func (r *Registry) ResolveRunner(ref Ref, v Values) (shipwright.Runner, error)
- func (r *Registry) ResolveRuntimeInspector(ref Ref, v Values) (shipwright.RuntimeInspector, error)
- func (r *Registry) ResolveRuntimeUpgrader(ref Ref, v Values) (shipwright.RuntimeUpgrader, error)
- func (r *Registry) ResolveTester(ref Ref, v Values) (shipwright.Tester, error)
- type UnregisteredProviderError
- type UnsupportedVersionError
- type Values
- type WithSchema
- type WithSchemaMismatchError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RegisterDefaults ¶
RegisterDefaults registers Shipwright's five in-repo capability implementations (providers/go, extracted from the former internal/capabilities, WU3) into r under the provider names design.md's own example manifest uses ("go", "go-test", "golangci-lint", "govulncheck", "container"), all pinned to version "1". This is the ONLY place in the tree that wires a manifest-facing provider name to a concrete Go type — the Registry itself has no knowledge of any provider's identity, and no provider registered here (or anywhere else, see security_test.go) is loaded from a path, fetched, or dynamically opened via plugin.Open (design.md D-I).
client is threaded through to every capability's Client field; it MAY be nil in a test that only exercises resolution (never actually calling a capability's method against a real Dagger engine) — every WU3 capability's own method already guards against a nil Client (providers/go/gobuilder.go etc.) and returns an error rather than panicking, so registration itself never needs a live client.
Types ¶
type ChangelogRunner ¶
type ChangelogRunner struct {
// Client is the Dagger client used to construct the git/changelog
// container.
Client daggerkit.DaggerClient
}
ChangelogRunner generates a Keep a Changelog "Unreleased" summary from git history since the last tag and prepends it into build's CHANGELOG.md, returning the resulting Container. It is Shipwright's live-system replacement for the now-deleted internal/app.ChangelogStepHandler, which shelled out to git on the host and wrote directly to the host filesystem — behavior with no place in a capability contract whose only inputs/outputs are Dagger core types (mirroring providers/go/containerpublisher.go's own "Behavioral judgment calls" note about host filesystem side effects). Every text-processing helper below (classification, section building, prepend) is ported unchanged from that handler; only the git access and file I/O move inside a Dagger container.
build is expected to contain a `.git` history — typically a checkout step's source Directory, not a Builder's compiled-output Directory (the Runner interface's build parameter name, pkg/shipwright/capabilities.go, describes the common case, not a hard requirement: any Directory-producing step can feed a Runner via `${{ steps.<id>.output }}` wiring, and this Runner's own contract is "a Directory with git history in it", whatever step produced it).
func (*ChangelogRunner) Run ¶
func (r *ChangelogRunner) Run(ctx context.Context, build *dagger.Directory) (*dagger.Container, error)
Run reads build's git history, classifies commits since the last tag (or the full history when there is none) into Added/Changed/Fixed entries, and prepends the result into build's CHANGELOG.md under its "## [Unreleased]" heading (creating both the heading and the file when absent). When there are no classifiable commits, the changelog is left untouched.
type Ref ¶
Ref identifies one registered provider implementation for a capability (design.md D-I's type sketch, exactly). Module == "" means an in-repo provider — one registered directly by this binary's own provider-registration file (register.go). A non-empty Module names the external module path a manifest's uses.module field references; it is resolved through the identical Register*/Resolve* mechanism as an in-repo provider — there is no separate, more permissive path for "external" providers (workflow-execution spec, "External module: Providers Satisfy The Same Dagger Contract As In-Repo Providers").
Ref is keyed by BOTH Name and Module (never Name alone): a manifest requesting uses.provider: go and a manifest requesting uses.module: go must never resolve to the same registered entry, because they are declaring different trust boundaries (in-repo vs. external) even if they happen to share a literal name.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is the typed, per-capability provider table (design.md D-I). Its zero value is not usable — construct with NewRegistry.
func NewRegistry ¶
func NewRegistry() *Registry
NewRegistry constructs an empty Registry. Register the in-repo WU3 capabilities into it via RegisterDefaults (register.go).
func (*Registry) RegisterArtifactor ¶
func (r *Registry) RegisterArtifactor(ref Ref, schema WithSchema, f func(Values) shipwright.Artifactor)
RegisterArtifactor registers an Artifactor provider factory under ref.
func (*Registry) RegisterBuilder ¶
func (r *Registry) RegisterBuilder(ref Ref, schema WithSchema, f func(Values) shipwright.Builder)
RegisterBuilder registers a Builder provider factory under ref, declaring its accepted `with` fields via schema.
func (*Registry) RegisterDeployer ¶
func (r *Registry) RegisterDeployer(ref Ref, schema WithSchema, f func(Values) shipwright.Deployer)
RegisterDeployer registers a Deployer provider factory under ref. No in-repo Deployer implementation exists yet (pkg/shipwright.DeployConfig is deliberately empty — concrete deploy adapters are deferred to a follow-up change, design.md D-D); this method exists so the Registry's public surface has the same five typed pairs for every capability, ready for a future provider to register into.
func (*Registry) RegisterRunner ¶
func (r *Registry) RegisterRunner(ref Ref, schema WithSchema, f func(Values) shipwright.Runner)
RegisterRunner registers a Runner provider factory under ref. See RegisterDeployer's doc comment — no in-repo Runner implementation exists yet either (pkg/shipwright.RunConfig is likewise empty).
func (*Registry) RegisterRuntimeInspector ¶
func (r *Registry) RegisterRuntimeInspector(ref Ref, schema WithSchema, f func(Values) shipwright.RuntimeInspector)
RegisterRuntimeInspector registers a RuntimeInspector provider factory under ref (runtime-toolchain-upgrade, design.md D-4b). Sixth typed pair, same shape as the original five above.
func (*Registry) RegisterRuntimeUpgrader ¶
func (r *Registry) RegisterRuntimeUpgrader(ref Ref, schema WithSchema, f func(Values) shipwright.RuntimeUpgrader)
RegisterRuntimeUpgrader registers a RuntimeUpgrader provider factory under ref (runtime-toolchain-upgrade, design.md D-9). Seventh typed pair, same shape as RegisterRuntimeInspector above.
func (*Registry) RegisterTester ¶
func (r *Registry) RegisterTester(ref Ref, schema WithSchema, f func(Values) shipwright.Tester)
RegisterTester registers a Tester provider factory under ref. Multiple independent Tester providers MAY register (design.md D-F's orthogonality win: GoUnitTester, GoLinter, GoVulnScanner each register separately for capability: test) — none is privileged over another.
func (*Registry) ResolveArtifactor ¶
func (r *Registry) ResolveArtifactor(ref Ref, v Values) (shipwright.Artifactor, error)
ResolveArtifactor resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.Artifactor.
func (*Registry) ResolveBuilder ¶
ResolveBuilder resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.Builder.
func (*Registry) ResolveDeployer ¶
ResolveDeployer resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.Deployer.
func (*Registry) ResolveRunner ¶
ResolveRunner resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.Runner.
func (*Registry) ResolveRuntimeInspector ¶
func (r *Registry) ResolveRuntimeInspector(ref Ref, v Values) (shipwright.RuntimeInspector, error)
ResolveRuntimeInspector resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.RuntimeInspector.
func (*Registry) ResolveRuntimeUpgrader ¶
func (r *Registry) ResolveRuntimeUpgrader(ref Ref, v Values) (shipwright.RuntimeUpgrader, error)
ResolveRuntimeUpgrader resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.RuntimeUpgrader.
func (*Registry) ResolveTester ¶
ResolveTester resolves ref (and validates v against its declared WithSchema) to a concrete shipwright.Tester.
type UnregisteredProviderError ¶
UnregisteredProviderError reports a uses.provider/uses.module reference naming no provider registered at build time for the requested capability (design.md D-I, tasks.md 7.3). This is the exact fail-closed boundary that makes plugin.Open unreachable from provider resolution: there is no fetch/download/cache/dynamic-load fallback here, only this error.
func (*UnregisteredProviderError) Error ¶
func (e *UnregisteredProviderError) Error() string
type UnsupportedVersionError ¶
type UnsupportedVersionError struct {
Capability string
Name string
Module string
RequestedVersion string
SupportedVersions []string
}
UnsupportedVersionError reports a registered provider Name/Module that exists, but not at the requested Version (tasks.md 7.2). Deliberately a distinct type from UnregisteredProviderError: "you asked for a version we don't ship" is a different failure mode from "you asked for a provider that doesn't exist at all", and a caller/operator needs to be able to tell them apart with errors.As, not string matching.
func (*UnsupportedVersionError) Error ¶
func (e *UnsupportedVersionError) Error() string
type Values ¶
Values carries a step's resolved `with` values, keyed by field name, already interpolated into typed interp.Value carriers — never a raw Go string that might hide a secret (interp.Value's own structural guarantee that a secret cannot be represented as a plain string).
type WithSchema ¶
WithSchema is a provider's declaration of its accepted `with` field names and their expected interp.Kind (design.md D-I). It is what makes stage 7 checkable and what keeps providers receiving typed Values, never an interpolated shell string (the security skill's `sh -c` rule, and design.md's Threat Matrix row 4, "Provider argument construction").
type WithSchemaMismatchError ¶
type WithSchemaMismatchError struct {
Capability string
Field string
Want interp.Kind
Got interp.Kind
}
WithSchemaMismatchError reports a `with` field value whose resolved Kind does not match the resolved provider's declared WithSchema entry for that field name (tasks.md 7.5, stage 7's forbidPlaintext and general with-value type mismatch).
This is the check WU5's task 5.3 and WU6's task 6.9 both explicitly deferred here: WU5's interp.Reference.StaticKind() reports ok=false for steps.<id>.output because that Kind is fixed by whichever provider resolves the step, and WU6's graph package could not compare a with-field's kind against anything because no provider schema existed in that package. Both boundaries close HERE, because this is the first point in the pipeline where a provider's declared WithSchema actually exists to compare against.
func (*WithSchemaMismatchError) Error ¶
func (e *WithSchemaMismatchError) Error() string