Documentation
¶
Index ¶
- Constants
- func ApplyOnFailure(ctx *ExecContext, runErr error) error
- func BuildAtmosEnv(ctx *ExecContext, outputFile, outputDir string) map[string]string
- func ClearKinds()
- func ListKinds() []string
- func RegisterFormatHandler(format string, handler ResultHandler) error
- func RegisterKind(k *Kind) error
- func RunCIHooks(opts *RunCIHooksOptions) error
- type Artifact
- type Command
- type CommandEngine
- type Engine
- type ExecContext
- type Finding
- type GitCommitSpec
- type Hook
- type HookEvent
- type Hooks
- type Kind
- type Outcome
- type Output
- type ResultHandler
- type RunCIHooksOptions
- type RunStatus
- type StoreCommand
- type Summary
- type SummaryStatus
- type TerraformOutputGetter
Constants ¶
const ( OnFailureWarn = "warn" OnFailureFail = "fail" OnFailureIgnore = "ignore" )
On-failure modes for the command engine.
const ( WhenSuccess = "success" WhenFailure = "failure" WhenAlways = "always" )
When values for Hook.When.
const (
FormatMarkdown = "markdown"
)
Format constants understood by the engine for inline rendering.
const ( // FormatSARIF parses the command's output as a SARIF document, giving a // custom hook the same findings summary / CI annotations / SARIF upload as // the built-in scanner kinds. FormatSARIF = "sarif" )
Inline output formats a generic `kind: command` hook can declare via the hook's `format:` field.
Variables ¶
This section is empty.
Functions ¶
func ApplyOnFailure ¶ added in v1.222.0
func ApplyOnFailure(ctx *ExecContext, runErr error) error
ApplyOnFailure applies the hook's effective on_failure mode to runErr: "warn" logs and swallows, "ignore" swallows silently, "fail" propagates. Exported so engines living outside this package (pkg/hooks/kinds/*) enforce the same on_failure semantics as the built-in command engine.
func BuildAtmosEnv ¶ added in v1.222.0
func BuildAtmosEnv(ctx *ExecContext, outputFile, outputDir string) map[string]string
BuildAtmosEnv exposes the ATMOS_* env-var map builder to engines outside the CommandEngine (e.g. the step bridge in step_engine.go) so they expose the same standard variables (ATMOS_STACK, ATMOS_COMPONENT, ATMOS_COMPONENT_PATH, …) to the work they run.
func ClearKinds ¶ added in v1.220.0
func ClearKinds()
ClearKinds removes all registered kinds. For testing only.
func ListKinds ¶ added in v1.220.0
func ListKinds() []string
ListKinds returns all registered kind names, sorted.
func RegisterFormatHandler ¶ added in v1.222.0
func RegisterFormatHandler(format string, handler ResultHandler) error
RegisterFormatHandler registers the ResultHandler used to parse a hook's declared output `format:` when its kind has no built-in ResultHandler (i.e. the generic command kind). Returns an error on empty format, nil handler, or duplicate registration. Parser packages call this from init().
func RegisterKind ¶ added in v1.220.0
RegisterKind registers a hook kind. Kinds self-register from pkg/hooks/kinds/*/kind.go via init() — this is the only registration path (there is no YAML-defined kind registry; reuse uses stack imports).
func RunCIHooks ¶ added in v1.210.0
func RunCIHooks(opts *RunCIHooksOptions) error
RunCIHooks executes CI actions based on provider bindings. This is called automatically during command execution if CI is enabled.
Types ¶
type Artifact ¶ added in v1.220.0
type Artifact struct {
// Name is the filename inside the upload bundle (e.g. "breakdown.json").
Name string
// Body is the artifact content.
Body []byte
// Format is the optional generic-renderer hint ("markdown" or "").
// For named kinds, Pro derives rendering from the kind name, so this
// remains empty.
Format string
// Metadata is arbitrary tags attached to the artifact.
Metadata map[string]string
}
Artifact is the opaque blob produced by a hook. Subsequent commits extend this with backend-routing metadata.
type Command ¶
type Command interface {
GetName() string
RunE(hook *Hook, event HookEvent, cmd *cobra.Command, args []string) error
}
Command is the interface for all commands that can be run by hooks
type CommandEngine ¶ added in v1.220.0
type CommandEngine struct{}
CommandEngine runs a binary (resolved via PATH — set up by the toolchain or any other install mechanism) against the component being orchestrated. It exposes standard ATMOS_* env vars to the subprocess and captures structured output via ATMOS_OUTPUT_FILE.
Tool stdout/stderr stream straight through to the user's terminal so progress and warnings appear in real time (same UX as Terraform output). Structured output goes through the side-channel file, read by the kind's ResultHandler (if any) and packaged as an Artifact.
func (*CommandEngine) Run ¶ added in v1.220.0
func (e *CommandEngine) Run(ctx *ExecContext) (*Output, error)
Run satisfies Engine. It's an orchestrator — the actual work lives in named helpers (validateCtx / prepareSubprocess / runSubprocess / captureOutput / renderTerminal) so each step has a single responsibility and the orchestrator stays a flat linear pipeline.
type Engine ¶ added in v1.220.0
type Engine interface {
// Run executes the hook with the given context.
// Implementations that produce no structured output return (nil, err).
Run(ctx *ExecContext) (*Output, error)
}
Engine runs a hook of a given kind. Different kinds may implement different engines: StoreEngine reads terraform outputs into a store; CommandEngine (added in a later commit) executes a binary and captures its structured output.
type ExecContext ¶ added in v1.220.0
type ExecContext struct {
// Hook is the resolved hook (kind defaults applied; user overrides preserved).
Hook *Hook
// Kind is the registered kind handling this hook.
Kind *Kind
// Event is the lifecycle event triggering the hook.
Event HookEvent
// AtmosConfig is the global Atmos configuration.
AtmosConfig *schema.AtmosConfiguration
// Info carries component and stack information.
Info *schema.ConfigAndStacksInfo
// Cmd is the cobra command currently executing.
Cmd *cobra.Command
// Args are the command-line args passed to Cmd.
Args []string
// Outcome is the lifecycle operation result this hook fires around
// (success/failure, exit code, error). Set by RunAll. Distinct from the
// ExitCode/CommandError fields below, which a command engine sets for its
// own subprocess. Engines expose this to their work (e.g. the step bridge
// sets ATMOS_HOOK_STATUS and injects `.status` into the template context).
Outcome Outcome
// ToolchainPATH is the PATH fragment containing directories for any
// dependencies.tools that were auto-installed for this component's
// hooks. Populated by Hooks.preflight; consumed by CommandEngine
// so the installed pinned versions take precedence over the operator's
// PATH. Empty when the component declares no hook dependencies.
ToolchainPATH string
// OutputFile is the temp file path the tool wrote structured output to.
// Populated by CommandEngine before calling ResultHandler.
OutputFile string
// OutputDir is the temp directory containing OutputFile. Exposed for
// directory-output tools (e.g., KICS writes results.sarif into a dir).
OutputDir string
// ExitCode is the subprocess exit code (0 = success).
ExitCode int
// CommandError is the subprocess error, if any.
CommandError error
}
ExecContext is everything an engine needs at run time. Built per hook invocation by RunAll after kind defaults have been applied. Some fields (OutputFile, OutputDir, ExitCode, CommandError) are populated by the engine before calling a kind's ResultHandler.
type Finding ¶ added in v1.222.0
type Finding struct {
// Path is the file the finding refers to, relative to the scanned root.
Path string
// Line is the 1-based line number; 0 when unknown (anchor at file level).
Line int
// Severity is the normalized bucket: critical | high | medium | low | info.
Severity string
// RuleID is the tool's rule identifier (e.g. "CKV_AWS_21").
RuleID string
// Message is the human-readable finding description.
Message string
}
Finding is one normalized, line-anchored result behind a Summary. It is a provider-neutral, SARIF-agnostic shape (the SARIF parser maps into it) so the engine can translate it to CI annotations without pkg/hooks depending on the sarif subpackage (which would be an import cycle).
type GitCommitSpec ¶ added in v1.222.0
type GitCommitSpec struct {
// Message is the commit message; empty selects the engine default
// ("Update artifacts for <component> in <stack>").
Message string `yaml:"message,omitempty"`
// Paths are repo-relative paths staged for the commit.
Paths []string `yaml:"paths,omitempty"`
}
GitCommitSpec is the `commit` block of a git-kind hook. Message supports the same template rendering as every other hook string (rendered by resolveHookForExecution before the engine runs).
type Hook ¶
type Hook struct {
// Kind selects the engine that runs this hook. Built-in kinds:
// "store" (existing semantics), "command" (generic binary execution),
// plus step-backed kinds like "step" and "steps", and named tool kinds
// like "infracost", "checkov", "trivy", "kics".
//
// For back-compat, the legacy `command:` YAML key is accepted as an
// alias when `kind:` is absent. See UnmarshalYAML.
Kind string `yaml:"kind,omitempty"`
Events []string `yaml:"events,omitempty"`
// When selects whether this hook runs. Empty defaults to success-only,
// preserving the original behavior where after-* hooks fired only when the
// operation succeeded.
When schema.Condition `yaml:"when,omitempty"`
// Generic command-kind fields. Used by the command engine and by named
// tool kinds via their defaults.
//
// Command is the binary to execute (resolved via the toolchain). For
// named kinds it defaults to the kind's binary; users may override.
Command string `yaml:"command,omitempty"`
Args []string `yaml:"args,omitempty"`
Env map[string]string `yaml:"env,omitempty"`
// Format is the inline rendering / parsing hint for generic kinds. Accepts
// "markdown" (render the artifact inline), "sarif" (parse the output as
// SARIF — giving a custom `kind: command` hook the same findings summary,
// CI annotations, and SARIF upload as the built-in scanner kinds), or
// empty (= downloadable artifact, no inline render).
Format string `yaml:"format,omitempty"`
// Results names the file a `format: sarif` command writes its SARIF to,
// relative to $ATMOS_OUTPUT_DIR, for tools that write a fixed filename
// into a directory rather than to $ATMOS_OUTPUT_FILE. When empty, the
// SARIF is read from $ATMOS_OUTPUT_FILE.
Results string `yaml:"results,omitempty"`
// OnFailure is the failure mode. "warn" (default for tool kinds),
// "fail" (propagate non-zero exit), or "ignore" (swallow).
OnFailure string `yaml:"on_failure,omitempty"`
// Store-kind specific (existing, unchanged semantics).
Name string `yaml:"name,omitempty"`
Outputs map[string]string `yaml:"outputs,omitempty"`
// Git-kind specific (kind: git; see pkg/hooks/kinds/git).
//
// Repository names a managed repository under the top-level
// git.repositories config. Empty targets the current repository.
Repository string `yaml:"repository,omitempty"`
// Commit configures the commit the git kind creates.
Commit *GitCommitSpec `yaml:"commit,omitempty"`
// Push pushes the created commit to the remote when true.
Push bool `yaml:"push,omitempty"`
// Step-kind specific (kind: step; see pkg/hooks/step_engine.go).
//
// Type names the step-registry step type to run (e.g. "container",
// "toast", "http"). Required for kind: step.
Type string `yaml:"type,omitempty"`
// With holds the kind-specific payload. For kind: step it is the step's
// parameter map, decoded into one WorkflowStep. For kind: steps it is an
// ordered list of WorkflowStep objects. Rendered (templates + YAML
// functions) by resolveHookForExecution before the engine sees it.
With any `yaml:"with,omitempty"`
// Retry wraps the step execution in retry.Do. Same schema as a
// workflow step's retry block; interpreted by the bridge, not the step.
Retry *schema.RetryConfig `yaml:"retry,omitempty"`
}
Hook is the structure for a hook configured in stack YAML. Each hook has a Kind that determines what engine runs it.
func (Hook) MatchesEvent ¶ added in v1.216.0
MatchesEvent reports whether this hook should run for the given event. It normalises the yaml event format (hyphens, e.g. "after-terraform-apply") to the canonical Go format (dots, e.g. "after.terraform.apply") before comparing, so both styles are accepted in stack configuration.
If the hook has no events configured, it matches all events to preserve backward compatibility with configs written before event filtering existed.
func (*Hook) RunsOnStatus ¶ added in v1.222.0
RunsOnStatus reports whether this hook should run given the lifecycle operation's status. It is retained for tests and callers that do not need CI conditions.
func (*Hook) RunsWhen ¶ added in v1.222.0
RunsWhen reports whether this hook should run given lifecycle status and CI state. An empty When defaults to success-only, preserving the pre-When behavior where after-* hooks fired only on success.
func (*Hook) UnmarshalYAML ¶ added in v1.220.0
UnmarshalYAML decodes a Hook, accepting the legacy `command:` key as an alias for `kind:` when `kind:` is absent. Pre-existing stack manifests with `command: store` continue to parse identically post-rename.
type HookEvent ¶ added in v1.159.0
type HookEvent string
const ( BeforeTerraformInit HookEvent = "before.terraform.init" AfterTerraformInit HookEvent = "after.terraform.init" AfterTerraformApply HookEvent = "after.terraform.apply" AfterTerraformApplyAggregate HookEvent = "after.terraform.apply.aggregate" BeforeTerraformApply HookEvent = "before.terraform.apply" AfterTerraformPlan HookEvent = "after.terraform.plan" AfterTerraformPlanAggregate HookEvent = "after.terraform.plan.aggregate" BeforeTerraformPlan HookEvent = "before.terraform.plan" BeforeTerraformTest HookEvent = "before.terraform.test" AfterTerraformTest HookEvent = "after.terraform.test" BeforeTerraformDeploy HookEvent = "before.terraform.deploy" AfterTerraformDeploy HookEvent = "after.terraform.deploy" AfterTerraformDestroyAggregate HookEvent = "after.terraform.destroy.aggregate" BeforeKubernetesRender HookEvent = "before.kubernetes.render" AfterKubernetesRender HookEvent = "after.kubernetes.render" BeforeKubernetesPlan HookEvent = "before.kubernetes.plan" AfterKubernetesPlan HookEvent = "after.kubernetes.plan" BeforeKubernetesDiff HookEvent = "before.kubernetes.diff" AfterKubernetesDiff HookEvent = "after.kubernetes.diff" BeforeKubernetesApply HookEvent = "before.kubernetes.apply" AfterKubernetesApply HookEvent = "after.kubernetes.apply" BeforeKubernetesDeploy HookEvent = "before.kubernetes.deploy" AfterKubernetesDeploy HookEvent = "after.kubernetes.deploy" BeforeKubernetesDelete HookEvent = "before.kubernetes.delete" AfterKubernetesDelete HookEvent = "after.kubernetes.delete" BeforeKubernetesValidate HookEvent = "before.kubernetes.validate" AfterKubernetesValidate HookEvent = "after.kubernetes.validate" BeforeHelmTemplate HookEvent = "before.helm.template" AfterHelmTemplate HookEvent = "after.helm.template" BeforeHelmDiff HookEvent = "before.helm.diff" AfterHelmDiff HookEvent = "after.helm.diff" BeforeHelmApply HookEvent = "before.helm.apply" AfterHelmApply HookEvent = "after.helm.apply" BeforeHelmDeploy HookEvent = "before.helm.deploy" AfterHelmDeploy HookEvent = "after.helm.deploy" BeforeHelmDelete HookEvent = "before.helm.delete" AfterHelmDelete HookEvent = "after.helm.delete" BeforeHelmfileTemplate HookEvent = "before.helmfile.template" AfterHelmfileTemplate HookEvent = "after.helmfile.template" BeforeHelmfileDiff HookEvent = "before.helmfile.diff" AfterHelmfileDiff HookEvent = "after.helmfile.diff" BeforeHelmfileApply HookEvent = "before.helmfile.apply" AfterHelmfileApply HookEvent = "after.helmfile.apply" BeforeHelmfileSync HookEvent = "before.helmfile.sync" AfterHelmfileSync HookEvent = "after.helmfile.sync" BeforeHelmfileDeploy HookEvent = "before.helmfile.deploy" AfterHelmfileDeploy HookEvent = "after.helmfile.deploy" BeforeHelmfileDestroy HookEvent = "before.helmfile.destroy" AfterHelmfileDestroy HookEvent = "after.helmfile.destroy" )
func (HookEvent) IsPostExecution ¶ added in v1.216.0
IsPostExecution reports whether the event fires after a component command has already run, i.e. any "after.*" event (Terraform, Kubernetes, etc.). For Terraform specifically, store hooks use this to decide whether to skip terraform init when reading outputs: after-events can safely skip init because the workdir is already initialized, while before-events must run init because the workdir may not be initialized yet.
type Hooks ¶
type Hooks struct {
// contains filtered or unexported fields
}
func GetHooks ¶ added in v1.159.0
func GetHooks(atmosConfig *schema.AtmosConfiguration, info *schema.ConfigAndStacksInfo) (*Hooks, error)
func (*Hooks) RunAll ¶ added in v1.159.0
func (h *Hooks) RunAll(event HookEvent, atmosConfig *schema.AtmosConfiguration, info *schema.ConfigAndStacksInfo, cmd *cobra.Command, args []string) error
func (*Hooks) SetOutcome ¶ added in v1.222.0
SetOutcome records the lifecycle operation outcome (success/failure) for the next RunAll. Hooks are filtered by their `when` against this status, and the outcome is exposed to engines (env vars, template context). A zero value (or not calling this) defaults to a successful outcome, preserving the original behavior where after-* hooks fired only on success.
type Kind ¶ added in v1.220.0
type Kind struct {
// Name is the kind discriminator (e.g. "store", "command", "infracost").
Name string
// Defaults for the generic command engine. Named kinds set these;
// user Hook fields override.
Command string
DefaultArgs []string
DefaultEnv map[string]string
// OnFailure is the default failure mode if the hook doesn't override.
OnFailure string
// Engine runs hooks of this kind.
Engine Engine
// ResultHandler parses structured output into a Summary. Optional.
ResultHandler ResultHandler
}
Kind is a registered hook type. Built-ins self-register from pkg/hooks/kinds/*/kind.go via init().
func (*Kind) ResolveDefaults ¶ added in v1.220.0
ResolveDefaults returns a copy of hook with kind defaults filled in for any fields the hook didn't set explicitly. The original hook is not modified.
type Outcome ¶ added in v1.222.0
type Outcome struct {
// Status is the operation outcome: success or failure.
Status RunStatus
// Err is the operation error on failure; nil on success.
Err error
// ExitCode is the operation exit code (0 on success).
ExitCode int
}
Outcome carries the result of the lifecycle operation a hook fires around (e.g. terraform apply). RunAll builds it from the command error and exposes it to engines so hooks can report what happened.
type Output ¶ added in v1.220.0
type Output struct {
// Artifact is the opaque blob produced by the hook (tool output file,
// rendered report, etc.). May be nil.
Artifact *Artifact
// Summary is the typed envelope used for run pages, PR comments, and
// terminal rendering. May be nil.
Summary *Summary
}
Output is what one hook invocation produces. Engines that don't emit structured output (e.g. store) return nil.
type ResultHandler ¶ added in v1.220.0
type ResultHandler func(ctx *ExecContext) (*Summary, error)
ResultHandler parses the kind's structured output and produces a Summary. Returning (nil, nil) is valid for kinds with no structured summary.
type RunCIHooksOptions ¶ added in v1.217.0
type RunCIHooksOptions struct {
// Event is the hook event (e.g., "after.terraform.deploy").
Event HookEvent
// AtmosConfig is the Atmos configuration.
AtmosConfig *schema.AtmosConfiguration
// Info contains component and stack information.
Info *schema.ConfigAndStacksInfo
// Output is the captured command output to process.
Output string
// ForceCIMode forces CI mode even when environment detection fails (--ci flag).
ForceCIMode bool
// CommandError is the error from the command execution, if any (nil on success).
CommandError error
// ExitCode is the exit code from the command execution. This is the
// authoritative signal plugins use to determine success/failure and (for
// `terraform plan` with -detailed-exitcode) change detection. Pass 0 on success.
ExitCode int
// Aggregate carries command-specific aggregate result data for hook events
// that summarize more than one component.
Aggregate any
}
RunCIHooksOptions configures a RunCIHooks invocation.
type RunStatus ¶ added in v1.222.0
type RunStatus string
RunStatus is the outcome of the lifecycle operation a hook fires around.
type StoreCommand ¶ added in v1.159.0
type StoreCommand struct {
Name string
// contains filtered or unexported fields
}
func NewStoreCommand ¶ added in v1.159.0
func NewStoreCommand(atmosConfig *schema.AtmosConfiguration, info *schema.ConfigAndStacksInfo) (*StoreCommand, error)
func (*StoreCommand) GetName ¶ added in v1.159.0
func (c *StoreCommand) GetName() string
func (*StoreCommand) RunE ¶ added in v1.159.0
RunE is the entrypoint for the store command. It selects the appropriate terraform output getter based on the event: after-events (e.g. after-terraform-apply) skip terraform init because the workdir is already initialized; before-events run init normally since the workdir may not exist yet.
type Summary ¶ added in v1.220.0
type Summary struct {
// Kind is the registered kind name (Pro selects its renderer from this).
Kind string
// Status is success | warning | failure.
Status SummaryStatus
// Title is the short headline (e.g. "+$47.20/mo" or "2 HIGH, 5 MED").
Title string
// Counts is an optional grouped breakdown (e.g. {"high": 2, "medium": 5}).
Counts map[string]int
// Body is the single markdown rendering used in every surface that
// renders markdown: terminal, Pro run page, PR comments, step summaries.
Body string
// Findings is the optional structured, line-anchored findings behind the
// summary (populated by SARIF-producing kinds). The engine maps these to
// CI annotations; left nil by kinds that produce no findings (e.g. cost).
Findings []Finding
// SARIF is the optional raw SARIF document the kind produced (passed
// through verbatim for upload to a CI security store). Left nil by
// non-SARIF kinds. Kept separate from Findings so a clean (zero-finding)
// SARIF can still be uploaded to mark previously-open alerts as fixed.
SARIF []byte
}
Summary is the typed envelope every hook kind fills the same way.
type SummaryStatus ¶ added in v1.220.0
type SummaryStatus string
SummaryStatus is the run status reported by a hook for the Pro/PR/terminal summary card.
const ( StatusSuccess SummaryStatus = "success" StatusWarning SummaryStatus = "warning" StatusFailure SummaryStatus = "failure" )
Summary statuses understood by Pro and the terminal renderer.
type TerraformOutputGetter ¶ added in v1.194.0
type TerraformOutputGetter func( atmosConfig *schema.AtmosConfiguration, stack string, component string, output string, skipCache bool, authContext *schema.AuthContext, authManager any, ) (any, bool, error)
TerraformOutputGetter retrieves terraform outputs. This enables dependency injection for testing. Returns:
- value: The output value (may be nil if the output exists but has a null value)
- exists: Whether the output key exists in the terraform outputs
- error: Any error that occurred during retrieval (SDK errors, network issues, etc.)
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
kinds
|
|
|
checkov
Package checkov registers the built-in `checkov` hook kind.
|
Package checkov registers the built-in `checkov` hook kind. |
|
git
Package git registers the built-in `git` hook kind, which publishes component artifacts to a Git repository on Atmos lifecycle events (e.g.
|
Package git registers the built-in `git` hook kind, which publishes component artifacts to a Git repository on Atmos lifecycle events (e.g. |
|
infracost
Package infracost registers the built-in `infracost` hook kind.
|
Package infracost registers the built-in `infracost` hook kind. |
|
kics
Package kics registers the built-in `kics` hook kind.
|
Package kics registers the built-in `kics` hook kind. |
|
trivy
Package trivy registers the built-in `trivy` hook kind.
|
Package trivy registers the built-in `trivy` hook kind. |
|
Package sarif parses SARIF 2.1.0 documents into a normalized Findings representation usable by hook ResultHandlers.
|
Package sarif parses SARIF 2.1.0 documents into a normalized Findings representation usable by hook ResultHandlers. |