Documentation
¶
Overview ¶
Package ciconfig extracts candidate validation commands from a repository's checked-in CircleCI configuration.
It is a reducer, not an interpreter. A real config can run to thousands of lines; this narrows it to the handful of `run` steps belonging to jobs that run on a developer's working branch, so a caller can classify that short list into test/lint/format roles instead of guessing from root filenames.
Constructs it cannot resolve are reported rather than guessed at: orb steps hide their contents behind a name, and a `setup: true` config generates the real one at run time. In both cases an empty candidate list means "could not tell", not "nothing to run" — callers must check Dynamic and SkippedOrbs before treating a miss as a clean negative.
Index ¶
Constants ¶
const ( // MaxDepth is exported so a caller reporting what went unexpanded can say // how deep the walk goes rather than repeat the number. MaxDepth = maxDepth )
Variables ¶
var ErrNotFound = errors.New("no CircleCI config found")
ErrNotFound reports that workDir has no CircleCI config.
Functions ¶
This section is empty.
Types ¶
type Candidate ¶
type Candidate struct {
Job string // job definition name
Step string // step name, empty if the step was unnamed
Command string // shell command, with parameters substituted
// WorkingDir is the step's own working_directory, empty when unset. Only
// a step-level directory narrows where a command runs: a job-level
// working_directory is where checkout places the repo, so it is the
// repo root and every step in the job already runs relative to it.
WorkingDir string
}
Candidate is one `run` step from a job that gates the default branch.
type ConfigError ¶
ConfigError reports a config that exists but could not be used — unreadable or unparseable. It carries Path so a caller can tell it apart from ErrNotFound: there is nothing to explain when a repo has no config, but a config that was found and rejected has to be said out loud rather than silently falling back to guessing from filenames.
func (*ConfigError) Error ¶
func (e *ConfigError) Error() string
func (*ConfigError) Unwrap ¶
func (e *ConfigError) Unwrap() error
type Result ¶
type Result struct {
Path string // config file the result came from
Candidates []Candidate // run steps from working-branch jobs, in config order
// Dynamic reports a `setup: true` config. The checked-in file only
// generates the real config at run time, so Candidates is not meaningful.
Dynamic bool
// SkippedOrbs lists orb-provided steps whose commands are not in this
// file, e.g. "node/install-packages".
SkippedOrbs []string
// Truncated counts candidates dropped at maxCandidates.
Truncated int
// Unresolved counts run steps skipped because they still carried an
// interpolation we could not substitute — an unbound parameter, or a
// pipeline-time reference such as << pipeline.parameters.x >>.
Unresolved int
// TooDeep counts custom-command invocations left unexpanded at maxDepth.
// Separate from Unresolved because the reason differs and so does the
// remedy: nothing here failed to resolve, the nesting simply ran deeper
// than this package follows. Counting it at all is the point — dropping
// the subtree silently let a config with legitimate deep nesting report
// full coverage while missing every check underneath.
TooDeep int
// GateJobs counts the workflow entries that qualified as gates. Zero from a
// non-dynamic config means every job in it is pinned to branches a
// developer does not work on — a different miss from "the jobs ran but
// nothing in them classified".
GateJobs int
}
Result is what Extract could and could not determine from a config.
func Extract ¶
Extract reads workDir's CircleCI config and returns the run steps belonging to jobs that run on a developer's working branch. It returns ErrNotFound if no config exists, so callers can fall back to filename-based detection, and a *ConfigError if one exists but cannot be read or parsed.