Documentation
¶
Overview ¶
Package pipeline is a user-defined CI/CD layer on top of the existing build and deploy primitives. A pipeline is a YAML file describing triggers, jobs, and steps; the Engine drives runs level-triggered from persisted state and never touches the reconciler directly.
Index ¶
- Constants
- Variables
- func ApplyFilters(data []byte, paths, pathsIgnore []string, reportStatus *bool) ([]byte, error)
- func ComboKey(job string, c Combo) string
- func Discover(repoDir, brandedName string) ([]string, error)
- func DiscoverDirs(brandedName string) []string
- func Diverged(p store.Pipeline) bool
- func EvalCondition(expr string, sc Scope) (bool, error)
- func HashYAML(y string) string
- func Interpolate(s string, sc Scope) (string, error)
- func InterpolateScript(s string, sc Scope) (body string, env map[string]string, err error)
- func SchemaJSON() []byte
- func TargetApps(def *Definition, ownApp string) []string
- func Validate(data []byte) (*Definition, []Issue)
- func ValidateCondition(expr string) error
- type Actions
- type BuildRequest
- type CacheSpec
- type Combo
- type Concurrency
- type Config
- type Definition
- type DeployRequest
- type DirFetcher
- type Duration
- type Engine
- func (e *Engine) Cancel(ctx context.Context, runID string) error
- func (e *Engine) Close()
- func (e *Engine) DecideHold(ctx context.Context, runID string, approved bool, by string) (bool, error)
- func (e *Engine) Nudge()
- func (e *Engine) OIDCTokenRequestHandler() http.Handler
- func (e *Engine) Rerun(ctx context.Context, runID, actor string) (store.PipelineRun, error)
- func (e *Engine) Run(ctx context.Context, interval time.Duration) error
- func (e *Engine) Start(ctx context.Context, p store.Pipeline, opt StartOptions) (store.PipelineRun, error)
- func (e *Engine) Tick(ctx context.Context) error
- func (e *Engine) TriggerEvent(ctx context.Context, app string, ev Event, ref, sha, actor string) []store.PipelineRun
- func (e *Engine) Wait()
- type Event
- type FilterView
- type GitFetcher
- type Input
- type Issue
- type Job
- type ManualTrigger
- type Matrix
- type MergeGroupTrigger
- type OIDCIssuer
- type OIDCRequest
- type OIDCTokenRequest
- type PRTrigger
- type RefTrigger
- type RepoFiles
- type ReportReceipt
- type ReportRequest
- type Resources
- type Runtime
- type RuntimeResolver
- type Scheduler
- type Scope
- type SecretResolver
- type Source
- type StartOptions
- type StatusReporter
- type Step
- type Store
- type StringList
- type SyncConfig
- type SyncItem
- type SyncResult
- type SyncStore
- type Syncer
- type TagTrigger
- type Template
- type Triggers
- type VolumeRemover
Constants ¶
const ( KindRun = "run" KindTest = "test" KindBuild = "build" KindDeploy = "deploy" KindPromote = "promote" KindRollback = "rollback" KindNotify = "notify" KindApproval = "approval" KindArtifactUpload = "artifact-upload" KindArtifactDownload = "artifact-download" TemplatePrefix = "template/" )
Step kinds, the values of a step's `uses` field. A step with a `run` script is kind "run".
const ( TriggerPush = "push" TriggerPullRequest = "pull_request" TriggerTag = "tag" TriggerMergeGroup = "merge_group" TriggerManual = "manual" TriggerSchedule = "schedule" TriggerAPI = "api" )
Trigger kinds recorded on a run.
const ( ForksBlock = "block" ForksApprove = "approve" ForksAllow = "allow" )
Fork policies for pull requests whose source is another repository.
const ( ReportPending = "pending" ReportSuccess = "success" ReportFailure = "failure" ReportError = "error" )
Commit status states a run is reported as.
const ( SyncCreated = "created" SyncUpdated = "updated" SyncUnchanged = "unchanged" // SyncDiverged means the stored definition was edited after the last // sync (or was never synced) and repo_is_truth is off, so it was kept. SyncDiverged = "diverged" SyncInvalid = "invalid" SyncRefused = "refused" // SourceRepo marks a pipeline whose definition comes from the repository. SourceRepo = "repo" )
Sync outcomes reported per pipeline file.
const KindSetup = "setup"
KindSetup is the implicit step that prepares the workspace and container.
const MaxMatrixCombinations = 256
MaxMatrixCombinations bounds one job's expansion.
const SchemaVersion = 1
SchemaVersion is the only pipeline file version this package accepts.
Variables ¶
var ErrInvalidInput = errors.New("pipeline: invalid input")
ErrInvalidInput marks a run request the pipeline's declared inputs reject.
var ErrNoPathTrigger = errors.New("pipeline: path filters need an on.push or on.pull_request trigger")
ErrNoPathTrigger is returned by ApplyFilters when the pipeline has neither a push nor a pull_request trigger to attach path filters to.
var ErrNoRepo = errors.New("pipeline: app has no connected repository")
ErrNoRepo is returned by Source when an app has no connected repository.
var ErrNoReportTarget = errors.New("pipeline: no git forge to report to")
ErrNoReportTarget is returned by a StatusReporter when the run's app has no git forge to report to. The engine treats it as "nothing to do".
ErrSHAUnavailable means the requested commit could not be fetched, so the definitions at that commit are unknown.
var PRTypes = []string{prActionOpened, prActionReopened, prActionSynchronize}
PRTypes lists the values on.pull_request.types accepts.
Functions ¶
func ApplyFilters ¶
ApplyFilters rewrites a pipeline's YAML so its push and pull_request triggers carry paths and paths_ignore, and sets report_status. A nil list or flag leaves that setting as it is; an empty non-nil list removes it.
func Discover ¶
Discover returns the pipeline files under repoDir (*.yaml and *.yml in the first candidate directory that exists), sorted by name.
func DiscoverDirs ¶
DiscoverDirs returns the candidate pipeline directories relative to a repository root: a generic name first, then the branded one, so a product rename never strands existing repositories. brandedName is the caller's brand short name; pass "" to skip it.
func EvalCondition ¶
EvalCondition evaluates an `if:` expression. An empty expression is true only when the scope is in a success state.
func Interpolate ¶
Interpolate replaces every ${{ path }} in s. A missing "secrets." path is an error so a typo never silently runs a step without its credential; any other missing path resolves to the empty string.
func InterpolateScript ¶
InterpolateScript is Interpolate for shell script text. Values that could be attacker-controlled are not spliced into the script: each is replaced by a ${PIPELINE_EXPR_*} reference and returned in env, which the caller exports single-quoted, so the shell never parses them as code.
func SchemaJSON ¶
func SchemaJSON() []byte
SchemaJSON returns the JSON Schema pipeline files are validated against.
func TargetApps ¶
func TargetApps(def *Definition, ownApp string) []string
TargetApps returns the literal app or service names the definition's deploy, promote, rollback, and notify steps act on, excluding the pipeline's own app. Validation guarantees these are literals.
func Validate ¶
func Validate(data []byte) (*Definition, []Issue)
Validate parses data, checks it against the JSON Schema, then runs the semantic checks (needs graph, conditions, step arguments, cron expressions). The definition is non-nil only when there are no issues.
func ValidateCondition ¶
ValidateCondition checks that expr parses, without evaluating it.
Types ¶
type Actions ¶
type Actions interface {
Build(ctx context.Context, req BuildRequest, log func(line string)) (image string, err error)
Deploy(ctx context.Context, req DeployRequest, log func(line string)) error
Promote(ctx context.Context, from, to string, log func(line string)) (image string, err error)
Rollback(ctx context.Context, service string, log func(line string)) (image string, err error)
Notify(ctx context.Context, app string, succeeded bool, message string) error
}
Actions are the control-plane primitives non-container steps call. They wrap the existing build and deploy code; the Engine never reconciles.
type BuildRequest ¶
type BuildRequest struct {
App string
Ref string
SHA string
Type string
Context string
Dockerfile string
Image string
Tag string
}
BuildRequest is one image build for the build step.
type CacheSpec ¶
CacheSpec mounts a persistent named volume at Path. Runs sharing a Key share the volume.
type Concurrency ¶
type Concurrency struct {
Group string `yaml:"group" json:"group"`
CancelInProgress bool `yaml:"cancel_in_progress,omitempty" json:"cancel_in_progress,omitempty"`
}
Concurrency serializes runs sharing a group; CancelInProgress cancels the older active runs in the group instead of queueing behind them.
type Config ¶
type Config struct {
Store Store
Runtime RuntimeResolver
Actions Actions
Secrets SecretResolver
Source Source
// RunEnv returns extra environment variables for a run's steps, for
// example the preview environment a pull request run belongs to. Optional.
RunEnv func(ctx context.Context, run store.PipelineRun) map[string]string
// OIDCIssuer mints a job's oidc token; nil means opting a job into
// oidc fails with a clear error rather than silently getting none.
OIDCIssuer OIDCIssuer
// OIDCRequestURL is the base URL for the runtime "request a token
// for this audience" endpoint (Engine.OIDCTokenRequestHandler),
// reachable from inside a job's own container, never externally.
// Empty means a job that lists more than one oidc.audiences entry
// fails with a clear error instead of getting an unreachable URL.
OIDCRequestURL string
Logger *slog.Logger
Now func() time.Time
NewID func() string
// NamePrefix namespaces containers and volumes (the brand short name).
NamePrefix string
// GitImage runs the checkout; it needs a POSIX shell and git.
GitImage string
MaxParallelJobs int
MaxLogLines int
StepTimeout time.Duration
JobTimeout time.Duration
ApprovalTimeout time.Duration
KeepRuns int
// Reporter, when set, posts run state to the git forge as a commit
// status. ReportTimeout bounds each post.
Reporter StatusReporter
ReportTimeout time.Duration
}
Config wires an Engine. Zero limits fall back to the defaults below; cmd wiring overrides them from environment variables.
type Definition ¶
type Definition struct {
Version int `yaml:"version" json:"version"`
Name string `yaml:"name" json:"name"`
On Triggers `yaml:"on" json:"on"`
Stages []string `yaml:"stages,omitempty" json:"stages,omitempty"`
Env map[string]string `yaml:"env,omitempty" json:"env,omitempty"`
Concurrency *Concurrency `yaml:"concurrency,omitempty" json:"concurrency,omitempty"`
// ReportStatus posts run state back to the forge as a commit status.
// Nil means on, when the app has provider credentials.
ReportStatus *bool `yaml:"report_status,omitempty" json:"report_status,omitempty"`
Timeout Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
Templates map[string]Template `yaml:"templates,omitempty" json:"templates,omitempty"`
Jobs map[string]*Job `yaml:"jobs" json:"jobs"`
// JobOrder is the order jobs appear in the file, kept for stable display.
JobOrder []string `yaml:"-" json:"job_order"`
}
Definition is a parsed pipeline file.
func Parse ¶
func Parse(data []byte) (*Definition, error)
Parse decodes YAML into a Definition and expands step templates. It does not validate; call Validate for structural and semantic checks.
func (*Definition) ReportsStatus ¶
func (d *Definition) ReportsStatus() bool
ReportsStatus reports whether run state is posted back to the forge.
type DeployRequest ¶
DeployRequest is one deploy of an existing service to an image.
type DirFetcher ¶
type DirFetcher interface {
FetchFiles(ctx context.Context, url, token, branch, sha string, dirs []string) (RepoFiles, error)
}
DirFetcher reads the first existing pipeline directory of a repository at sha, or at the branch tip when sha is empty.
type Duration ¶
Duration is a time.Duration that unmarshals from a Go duration string.
func (Duration) MarshalYAML ¶
MarshalYAML renders the duration in Go duration syntax.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine drives pipeline runs from persisted state. Every Tick re-derives what to do from the database, so a restart resumes in-flight runs: jobs recorded as running with no live goroutine are picked up again.
func (*Engine) Close ¶
func (e *Engine) Close()
Close interrupts running jobs and waits for them to stop.
func (*Engine) DecideHold ¶
func (e *Engine) DecideHold(ctx context.Context, runID string, approved bool, by string) (bool, error)
DecideHold releases or rejects a run held for approval. It reports false when the run is not pending a decision.
func (*Engine) OIDCTokenRequestHandler ¶
OIDCTokenRequestHandler serves the runtime token request endpoint a job script calls as PIPELINE_OIDC_REQUEST_URL: GET ?audience=X with "Authorization: Bearer <PIPELINE_OIDC_REQUEST_TOKEN>" mints a token for that one audience, only if the job's own `oidc` config allows it. Binding this to a container-reachable, never externally reachable address is the caller's job (see cmd/levelrail's wiring), not this package's: the bearer token is the actual access control either way.
func (*Engine) Rerun ¶
Rerun starts a new run from an earlier one's trigger and inputs, using the pipeline's current definition.
func (*Engine) Run ¶
Run ticks every interval (or sooner after a Nudge) until ctx is done, then interrupts running jobs. Interrupted jobs stay recorded as running and are resumed by the next process.
func (*Engine) Start ¶
func (e *Engine) Start(ctx context.Context, p store.Pipeline, opt StartOptions) (store.PipelineRun, error)
Start queues a run of a saved pipeline. The definition is re-validated and snapshotted onto the run so later edits never change it.
func (*Engine) TriggerEvent ¶
func (e *Engine) TriggerEvent(ctx context.Context, app string, ev Event, ref, sha, actor string) []store.PipelineRun
TriggerEvent starts a run of every enabled pipeline of app that accepts ev and records why each pipeline did or did not start. A pull request from a fork follows the pipeline's forks policy: blocked, held for approval, or allowed. Failures to start one pipeline are logged and never block the rest.
type Event ¶
type Event struct {
Kind string
Branch string
Tag string
// Fork marks a pull request whose source is another repository.
Fork bool
// HeadRepo is that source repository's full name, for the trigger log.
HeadRepo string
// Action is a pull request's normalized action (opened, synchronize).
Action string
// Changed lists the files the event touched. ChangedFn, when set, is
// called at most once to fetch the list when Changed is empty. An
// empty result means the list is unknown, so path filters pass.
Changed []string
ChangedFn func(ctx context.Context) ([]string, error)
}
Event is what a trigger is matched against.
type FilterView ¶
type FilterView struct {
Paths []string `json:"paths"`
PathsIgnore []string `json:"paths_ignore"`
ReportStatus bool `json:"report_status"`
// Split is true when push and pull_request carry different filters. The
// shown Paths and PathsIgnore are the push trigger's, and writing them
// through ApplyFilters would overwrite the pull request ones.
Split bool `json:"split"`
}
FilterView is the path filters and status reporting flag of a definition, as the editor and CLI show them.
func FiltersOf ¶
func FiltersOf(def *Definition) FilterView
FiltersOf reads the filters from the push trigger, falling back to the pull_request trigger when there is no push trigger.
type GitFetcher ¶
type GitFetcher struct{}
GitFetcher reads pipeline files with a shallow, in-memory clone, so nothing is written to disk and no checkout is needed.
func (GitFetcher) FetchFiles ¶
func (GitFetcher) FetchFiles(ctx context.Context, url, token, branch, sha string, dirs []string) (RepoFiles, error)
FetchFiles returns the *.yaml and *.yml files of the first directory in dirs that exists. With sha empty it reads the tip of branch (the remote default when empty); otherwise it reads that exact commit and returns ErrSHAUnavailable when the commit cannot be fetched.
type Input ¶
type Input struct {
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Default string `yaml:"default,omitempty" json:"default,omitempty"`
Required bool `yaml:"required,omitempty" json:"required,omitempty"`
Options []string `yaml:"options,omitempty" json:"options,omitempty"`
}
Input is one manual-run parameter.
type Issue ¶
type Issue struct {
Path string `json:"path"`
Line int `json:"line"`
Message string `json:"message"`
}
Issue is one validation problem, located by dotted path and source line.
type Job ¶
type Job struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Stage string `yaml:"stage,omitempty" json:"stage,omitempty"`
Needs StringList `yaml:"needs,omitempty" json:"needs,omitempty"`
If string `yaml:"if,omitempty" json:"if,omitempty"`
Image string `yaml:"image,omitempty" json:"image,omitempty"`
Node string `yaml:"node,omitempty" json:"node,omitempty"`
Env map[string]string `yaml:"env,omitempty" json:"env,omitempty"`
Matrix *Matrix `yaml:"matrix,omitempty" json:"matrix,omitempty"`
Resources *Resources `yaml:"resources,omitempty" json:"resources,omitempty"`
Timeout Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
Retries int `yaml:"retries,omitempty" json:"retries,omitempty"`
ContinueOnError bool `yaml:"continue_on_error,omitempty" json:"continue_on_error,omitempty"`
Checkout *bool `yaml:"checkout,omitempty" json:"checkout,omitempty"`
Cache []CacheSpec `yaml:"cache,omitempty" json:"cache,omitempty"`
OIDC *OIDCRequest `yaml:"oidc,omitempty" json:"oidc,omitempty"`
Steps []Step `yaml:"steps" json:"steps"`
}
Job is a group of steps run in one container on one node.
type ManualTrigger ¶
type ManualTrigger struct {
Inputs map[string]Input `yaml:"inputs,omitempty" json:"inputs,omitempty"`
}
ManualTrigger declares the inputs a manual run prompts for.
type Matrix ¶
type Matrix struct {
Vars map[string]StringList `yaml:",inline" json:"vars,omitempty"`
Include []map[string]string `yaml:"include,omitempty" json:"include,omitempty"`
Exclude []map[string]string `yaml:"exclude,omitempty" json:"exclude,omitempty"`
}
Matrix expands a job into one instance per combination of Vars.
type MergeGroupTrigger ¶
type MergeGroupTrigger struct {
Branches StringList `yaml:"branches,omitempty" json:"branches,omitempty"`
}
MergeGroupTrigger filters merge queue events by the branch they merge into.
type OIDCIssuer ¶
type OIDCIssuer func(ctx context.Context, req OIDCTokenRequest) (string, error)
OIDCIssuer mints a short-lived signed token for a job that opts in via `oidc: {audience: ...}` (Job.OIDC), for cloud OIDC federation (AWS IAM, GCP workload identity, Vault JWT auth) without a long-lived credential. Optional: nil means a job requesting oidc fails with a clear per-job error rather than silently getting no token. internal/oidc.Manager's IssueToken satisfies this once its request/response types are adapted by the caller (cmd/levelrail/pipelines.go), keeping this package unaware of internal/oidc entirely, the same "translation is the caller's job" shape RunEnv above already establishes.
type OIDCRequest ¶
type OIDCRequest struct {
// Audience is the token's "aud" claim, the value the cloud
// provider's trust policy expects (e.g. "sts.amazonaws.com").
// Pre-minted at job start and injected as PIPELINE_OIDC_TOKEN.
Audience string `yaml:"audience,omitempty" json:"audience,omitempty"`
// Audiences lists every additional audience this job may request a
// token for at runtime, one at a time, via PIPELINE_OIDC_REQUEST_URL
// (Audience is always implicitly allowed too). A job that needs
// tokens for more than one audience in the same run (e.g. one step
// calling AWS, another GCP) uses this instead of pre-minting every
// combination up front.
Audiences []string `yaml:"audiences,omitempty" json:"audiences,omitempty"`
}
OIDCRequest opts a job into minted OIDC tokens for cloud provider federation (AWS IAM, GCP workload identity, Vault JWT auth) without a long-lived credential. See docs/pipelines-oidc.md.
type OIDCTokenRequest ¶
type OIDCTokenRequest struct {
Audience string
Subject string
Repo string
Ref string
PipelineID string
}
OIDCTokenRequest is what a job's `oidc: {audience: ...}` config asks OIDCIssuer to mint a token for.
type PRTrigger ¶
type PRTrigger struct {
Branches StringList `yaml:"branches,omitempty" json:"branches,omitempty"`
// Types limits which pull request actions start a run: opened,
// reopened, synchronize. Empty means all three.
Types StringList `yaml:"types,omitempty" json:"types,omitempty"`
Paths StringList `yaml:"paths,omitempty" json:"paths,omitempty"`
PathsIgnore StringList `yaml:"paths_ignore,omitempty" json:"paths_ignore,omitempty"`
// Forks is block (the default), approve (hold the run until an
// approver releases it), or allow.
Forks string `yaml:"forks,omitempty" json:"forks,omitempty"`
}
PRTrigger filters pull request events by target branch glob and sets what happens to a pull request from a fork.
func (*PRTrigger) ForkPolicy ¶
ForkPolicy returns the effective fork policy, defaulting to block.
type RefTrigger ¶
type RefTrigger struct {
Branches StringList `yaml:"branches,omitempty" json:"branches,omitempty"`
Paths StringList `yaml:"paths,omitempty" json:"paths,omitempty"`
PathsIgnore StringList `yaml:"paths_ignore,omitempty" json:"paths_ignore,omitempty"`
}
RefTrigger filters push events by branch glob and by the paths the commits changed.
type RepoFiles ¶
type RepoFiles struct {
SHA string
Dir string
Files map[string][]byte
// Oversize lists files skipped for exceeding maxSyncFileSize, by size.
Oversize map[string]int64
}
RepoFiles is the pipeline directory of a repository at one commit.
type ReportReceipt ¶
type ReportReceipt struct {
Provider string
// URL is the dashboard page the status links to, empty when the
// control plane has no dashboard URL configured.
URL string
}
ReportReceipt says where a status went.
type ReportRequest ¶
type ReportRequest struct {
App string
Pipeline string
RunID string
RunNumber int
SHA string
Ref string
State string
Description string
// Context labels the status so several pipelines stay distinct.
Context string
}
ReportRequest is one commit status to post for a run.
type Resources ¶
type Resources struct {
Memory string `yaml:"memory,omitempty" json:"memory,omitempty"`
CPU float64 `yaml:"cpu,omitempty" json:"cpu,omitempty"`
}
Resources caps a job container. Memory uses Kubernetes-style suffixes.
type Runtime ¶
type Runtime interface {
Create(ctx context.Context, spec docker.ContainerSpec) (string, error)
Start(ctx context.Context, id string) error
Remove(ctx context.Context, id string, force bool) error
ListByPrefix(ctx context.Context, prefix string) ([]docker.ContainerState, error)
EnsureVolume(ctx context.Context, name string) error
ExecWithInput(ctx context.Context, containerID string, cmd []string, stdin io.Reader) (io.ReadCloser, error)
}
Runtime is the slice of docker.Runtime a job needs, so tests can fake it and remote nodes work through the same interface as the local daemon.
type RuntimeResolver ¶
RuntimeResolver returns the runtime for a node ID ("" means the local node).
type Scheduler ¶
type Scheduler struct {
// contains filtered or unexported fields
}
Scheduler starts pipelines whose `on.schedule` cron expressions come due. It mirrors internal/scheduledtask: a schedule arms on first sight and never catches up runs missed while the control plane was down.
func NewScheduler ¶
NewScheduler builds a Scheduler over engine.
type Scope ¶
Scope is what expressions and ${{ }} references resolve against. Vars holds dotted paths such as "ref", "matrix.go", "needs.build.result".
type SecretResolver ¶
SecretResolver reads an app's secret value. *secrets.Manager satisfies it.
type StartOptions ¶
type StartOptions struct {
Trigger string
Actor string
Ref string
SHA string
Inputs map[string]string
// BaseBranch is a pull request's target branch, which trigger filters
// match against instead of the source branch in Ref.
BaseBranch string
// Hold, when set, creates the run held for approval with this reason:
// no job starts and no secret is read until an approver releases it.
Hold string
}
StartOptions describes one run to start.
type StatusReporter ¶
type StatusReporter interface {
ReportRun(ctx context.Context, req ReportRequest) (ReportReceipt, error)
}
StatusReporter posts a run's state to the git forge that hosts its commit. Implementations return ErrNoReportTarget when there is no forge.
type Step ¶
type Step struct {
ID string `yaml:"id,omitempty" json:"id,omitempty"`
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Run string `yaml:"run,omitempty" json:"run,omitempty"`
Uses string `yaml:"uses,omitempty" json:"uses,omitempty"`
With map[string]string `yaml:"with,omitempty" json:"with,omitempty"`
Env map[string]string `yaml:"env,omitempty" json:"env,omitempty"`
Secrets []string `yaml:"secrets,omitempty" json:"secrets,omitempty"`
If string `yaml:"if,omitempty" json:"if,omitempty"`
Timeout Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`
Retries int `yaml:"retries,omitempty" json:"retries,omitempty"`
ContinueOnError bool `yaml:"continue_on_error,omitempty" json:"continue_on_error,omitempty"`
}
Step is one unit of work. Exactly one of Run or Uses is set.
func (Step) DisplayName ¶
DisplayName is the step's name, falling back to its kind or script.
func (Step) NeedsContainer ¶
NeedsContainer reports whether the step executes inside the job container.
type Store ¶
type Store interface {
GetPipeline(ctx context.Context, id string) (store.Pipeline, error)
ListPipelines(ctx context.Context, app string) ([]store.Pipeline, error)
CreatePipelineRun(ctx context.Context, r store.PipelineRun) (store.PipelineRun, error)
GetPipelineRun(ctx context.Context, id string) (store.PipelineRun, error)
ListActivePipelineRuns(ctx context.Context) ([]store.PipelineRun, error)
ListPipelineRunsInGroup(ctx context.Context, group string) ([]store.PipelineRun, error)
SetPipelineRunStatus(ctx context.Context, id, status, reason string, started, finished *time.Time) error
RequestPipelineRunCancel(ctx context.Context, id string) error
CreatePipelineJobs(ctx context.Context, jobs []store.PipelineJob) error
ListPipelineJobs(ctx context.Context, runID string) ([]store.PipelineJob, error)
SetPipelineJobStatus(ctx context.Context, id, status, reason, nodeID string, attempt int, started, finished *time.Time) error
SetPipelineJobOutputs(ctx context.Context, id, outputsJSON string) error
SetPipelineStepStatus(ctx context.Context, jobID string, idx int, status, reason string, exitCode *int, attempt int, started, finished *time.Time) error
AppendPipelineLogs(ctx context.Context, lines []store.PipelineLogLine) error
CreatePipelineApproval(ctx context.Context, a store.PipelineApproval) error
ListPipelineApprovals(ctx context.Context, runID string) ([]store.PipelineApproval, error)
PrunePipelineRuns(ctx context.Context, keep int) (int64, error)
AddPipelineTriggerLog(ctx context.Context, e store.PipelineTriggerLog) error
DecidePipelineRunHold(ctx context.Context, id string, approved bool, by string, now time.Time) (bool, error)
}
Store is the persistence surface the Engine needs. *store.DB satisfies it.
type StringList ¶
type StringList []string
StringList unmarshals either a single string or a list of strings.
func (*StringList) UnmarshalYAML ¶
func (l *StringList) UnmarshalYAML(n *yaml.Node) error
UnmarshalYAML accepts a scalar or a sequence.
type SyncConfig ¶
type SyncConfig struct {
Store SyncStore
Source Source
Fetcher DirFetcher
// BrandName is the brand short name for the branded pipeline directory.
BrandName string
Logger *slog.Logger
Now func() time.Time
NewID func() string
}
SyncConfig wires a Syncer.
type SyncItem ¶
type SyncItem struct {
File string `json:"file"`
Name string `json:"name"`
Outcome string `json:"outcome"`
Message string `json:"message,omitempty"`
}
SyncItem is the outcome for one pipeline file.
type SyncResult ¶
type SyncResult struct {
SHA string `json:"sha"`
Dir string `json:"dir,omitempty"`
Items []SyncItem `json:"items"`
}
SyncResult is the outcome of one repository sync.
type SyncStore ¶
type SyncStore interface {
ListPipelines(ctx context.Context, app string) ([]store.Pipeline, error)
SavePipeline(ctx context.Context, p store.Pipeline) (store.Pipeline, error)
GetPipelineSync(ctx context.Context, app string) (store.PipelineSync, error)
SavePipelineSync(ctx context.Context, s store.PipelineSync) error
GetGitSource(ctx context.Context, serviceName string) (*store.GitSource, error)
}
SyncStore is the persistence surface a Syncer needs. *store.DB satisfies it.
type Syncer ¶
type Syncer struct {
// contains filtered or unexported fields
}
Syncer copies an app's repository pipeline directory into its saved pipeline definitions.
func NewSyncer ¶
func NewSyncer(cfg SyncConfig) *Syncer
NewSyncer builds a Syncer, defaulting the logger, clock, and ID source.
func (*Syncer) Sync ¶
Sync reads the repository at the app's tracked branch and upserts the definitions it finds. The outcome, or the error, is recorded so the dashboard can show it.
func (*Syncer) SyncOnPush ¶
func (s *Syncer) SyncOnPush(ctx context.Context, app, ref, sha string) (res SyncResult, ran bool, err error)
SyncOnPush syncs the definitions at the pushed commit sha when ref is a push to the app's tracked branch. ran is false for any other ref or an app with no repository.
type TagTrigger ¶
type TagTrigger struct {
Patterns StringList `yaml:"patterns,omitempty" json:"patterns,omitempty"`
}
TagTrigger filters tag pushes by glob.
type Template ¶
type Template struct {
Params []string `yaml:"params,omitempty" json:"params,omitempty"`
Steps []Step `yaml:"steps" json:"steps"`
}
Template is a reusable list of steps invoked with `uses: template/<name>`. Parameters are referenced as ${{ inputs.<param> }} inside the steps.
type Triggers ¶
type Triggers struct {
Push *RefTrigger `yaml:"push,omitempty" json:"push,omitempty"`
PullRequest *PRTrigger `yaml:"pull_request,omitempty" json:"pull_request,omitempty"`
Tag *TagTrigger `yaml:"tag,omitempty" json:"tag,omitempty"`
MergeGroup *MergeGroupTrigger `yaml:"merge_group,omitempty" json:"merge_group,omitempty"`
Manual *ManualTrigger `yaml:"manual,omitempty" json:"manual,omitempty"`
Schedule []string `yaml:"schedule,omitempty" json:"schedule,omitempty"`
API bool `yaml:"api,omitempty" json:"api,omitempty"`
}
Triggers lists what starts a run. A nil field means that trigger is off.