Documentation
¶
Overview ¶
Package ci detects the CI/CD platform the CLI is currently running under and exposes the base/head commit refs it needs to compute changed dependencies.
Implementations are registered in priority order in registry.go. Detect() returns the first provider whose env-var signature matches; the Local fallback is last so an unrecognised CI still works off `git rev-parse` defaults.
Each provider reports a Platform value from the locally-defined set of constants below. When adding a provider, define its constant here and return it from Platform().
Index ¶
- Variables
- type AWSCodeBuild
- func (a *AWSCodeBuild) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (a *AWSCodeBuild) Detect() bool
- func (a *AWSCodeBuild) EnrichHeader(h http.Header)
- func (a *AWSCodeBuild) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (a *AWSCodeBuild) PRNumber() (int, bool)
- func (a *AWSCodeBuild) Platform() Platform
- func (a *AWSCodeBuild) RepoSlug() (string, string, bool)
- type AzureDevOps
- func (a *AzureDevOps) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (a *AzureDevOps) Detect() bool
- func (a *AzureDevOps) EnrichHeader(h http.Header)
- func (a *AzureDevOps) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (a *AzureDevOps) PRNumber() (int, bool)
- func (a *AzureDevOps) Platform() Platform
- func (a *AzureDevOps) RepoSlug() (string, string, bool)
- type BitbucketPipelines
- func (b *BitbucketPipelines) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (b *BitbucketPipelines) Detect() bool
- func (b *BitbucketPipelines) EnrichHeader(h http.Header)
- func (b *BitbucketPipelines) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (b *BitbucketPipelines) PRNumber() (int, bool)
- func (b *BitbucketPipelines) Platform() Platform
- func (b *BitbucketPipelines) RepoSlug() (string, string, bool)
- type CircleCI
- func (c *CircleCI) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (c *CircleCI) Detect() bool
- func (c *CircleCI) EnrichHeader(h http.Header)
- func (c *CircleCI) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (c *CircleCI) PRNumber() (int, bool)
- func (c *CircleCI) Platform() Platform
- func (c *CircleCI) RepoSlug() (string, string, bool)
- type GitHubActions
- func (g *GitHubActions) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (g *GitHubActions) Detect() bool
- func (g *GitHubActions) EnrichHeader(h http.Header)
- func (g *GitHubActions) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (g *GitHubActions) PRNumber() (int, bool)
- func (g *GitHubActions) Platform() Platform
- func (g *GitHubActions) RepoSlug() (string, string, bool)
- type GitLabCI
- func (g *GitLabCI) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (g *GitLabCI) Detect() bool
- func (g *GitLabCI) EnrichHeader(h http.Header)
- func (g *GitLabCI) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (g *GitLabCI) PRNumber() (int, bool)
- func (g *GitLabCI) Platform() Platform
- func (g *GitLabCI) RepoSlug() (string, string, bool)
- type GoogleCloudBuild
- func (g *GoogleCloudBuild) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (g *GoogleCloudBuild) Detect() bool
- func (g *GoogleCloudBuild) EnrichHeader(h http.Header)
- func (g *GoogleCloudBuild) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (g *GoogleCloudBuild) PRNumber() (int, bool)
- func (g *GoogleCloudBuild) Platform() Platform
- func (g *GoogleCloudBuild) RepoSlug() (string, string, bool)
- type Jenkins
- func (j *Jenkins) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (j *Jenkins) Detect() bool
- func (j *Jenkins) EnrichHeader(h http.Header)
- func (j *Jenkins) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (j *Jenkins) PRNumber() (int, bool)
- func (j *Jenkins) Platform() Platform
- func (j *Jenkins) RepoSlug() (string, string, bool)
- type Local
- func (l *Local) BaseRef(ctx context.Context, repoPath string) (string, error)
- func (l *Local) Detect() bool
- func (l *Local) EnrichHeader(h http.Header)
- func (l *Local) HeadRef(ctx context.Context, repoPath string) (string, error)
- func (l *Local) PRNumber() (int, bool)
- func (l *Local) Platform() Platform
- func (l *Local) RepoSlug() (string, string, bool)
- type Platform
- type Provider
- func Default() []Provider
- func Detect(providers []Provider) (Provider, error)
- func NewAWSCodeBuild() Provider
- func NewAzureDevOps() Provider
- func NewBitbucketPipelines() Provider
- func NewCircleCI() Provider
- func NewGitHubActions() Provider
- func NewGitLabCI() Provider
- func NewGoogleCloudBuild() Provider
- func NewJenkins() Provider
- func NewLocal() Provider
Constants ¶
This section is empty.
Variables ¶
var ErrNoProvider = errors.New("no CI provider detected")
ErrNoProvider is returned by Detect when no registered provider matches — shouldn't happen in practice because the Local fallback always returns true, but declared so callers can assert on it.
Functions ¶
This section is empty.
Types ¶
type AWSCodeBuild ¶
type AWSCodeBuild struct{}
AWSCodeBuild — https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
Key envs:
CODEBUILD_BUILD_ID signature CODEBUILD_RESOLVED_SOURCE_VERSION head CODEBUILD_WEBHOOK_BASE_REF base (webhook-triggered PRs) CODEBUILD_SOURCE_REPO_URL https://github.com/org/repo.git
func (*AWSCodeBuild) Detect ¶
func (a *AWSCodeBuild) Detect() bool
func (*AWSCodeBuild) EnrichHeader ¶
func (a *AWSCodeBuild) EnrichHeader(h http.Header)
func (*AWSCodeBuild) PRNumber ¶
func (a *AWSCodeBuild) PRNumber() (int, bool)
func (*AWSCodeBuild) Platform ¶
func (a *AWSCodeBuild) Platform() Platform
type AzureDevOps ¶
type AzureDevOps struct{}
AzureDevOps — https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables
Key envs:
TF_BUILD=True signature BUILD_SOURCEVERSION head commit SYSTEM_PULLREQUEST_TARGETBRANCHNAME target branch (PR builds) SYSTEM_PULLREQUEST_PULLREQUESTNUMBER PR number BUILD_REPOSITORY_NAME repo name (no owner) BUILD_BUILDID run id
func (*AzureDevOps) Detect ¶
func (a *AzureDevOps) Detect() bool
func (*AzureDevOps) EnrichHeader ¶
func (a *AzureDevOps) EnrichHeader(h http.Header)
func (*AzureDevOps) PRNumber ¶
func (a *AzureDevOps) PRNumber() (int, bool)
func (*AzureDevOps) Platform ¶
func (a *AzureDevOps) Platform() Platform
type BitbucketPipelines ¶
type BitbucketPipelines struct{}
BitbucketPipelines — https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/
Key envs:
BITBUCKET_BUILD_NUMBER signature BITBUCKET_COMMIT head BITBUCKET_PR_DESTINATION_BRANCH target branch (PR builds) BITBUCKET_PR_ID PR number BITBUCKET_REPO_OWNER / REPO_SLUG
func (*BitbucketPipelines) Detect ¶
func (b *BitbucketPipelines) Detect() bool
func (*BitbucketPipelines) EnrichHeader ¶
func (b *BitbucketPipelines) EnrichHeader(h http.Header)
func (*BitbucketPipelines) PRNumber ¶
func (b *BitbucketPipelines) PRNumber() (int, bool)
func (*BitbucketPipelines) Platform ¶
func (b *BitbucketPipelines) Platform() Platform
type CircleCI ¶
type CircleCI struct{}
CircleCI — https://circleci.com/docs/variables/
Key envs:
CIRCLECI=true
CIRCLE_SHA1 head
CIRCLE_PR_NUMBER PR number (only when triggered from a
forked-PR webhook)
CIRCLE_PULL_REQUEST "https://github.com/org/repo/pull/N"
— parse to recover the PR number
for non-forked PRs too
CIRCLE_PROJECT_USERNAME/REPONAME
CIRCLE_WORKFLOW_ID run id
func (*CircleCI) EnrichHeader ¶
type GitHubActions ¶
type GitHubActions struct{}
GitHubActions — https://docs.github.com/en/actions/learn-github-actions/variables
Key envs we rely on:
GITHUB_ACTIONS=true signature GITHUB_SHA head commit GITHUB_EVENT_NAME=pull_request + GITHUB_BASE_REF (target branch name) GITHUB_REPOSITORY owner/name GITHUB_RUN_ID + GITHUB_RUN_ATTEMPT
PR base is tricky: GITHUB_BASE_REF is just the target branch NAME, not a commit. BaseRef() resolves it by running `git rev-parse origin/<base>` which assumes the runner fetched origin (the standard actions/checkout@v4 does).
func (*GitHubActions) Detect ¶
func (g *GitHubActions) Detect() bool
func (*GitHubActions) EnrichHeader ¶
func (g *GitHubActions) EnrichHeader(h http.Header)
func (*GitHubActions) PRNumber ¶
func (g *GitHubActions) PRNumber() (int, bool)
func (*GitHubActions) Platform ¶
func (g *GitHubActions) Platform() Platform
type GitLabCI ¶
type GitLabCI struct{}
GitLabCI — https://docs.gitlab.com/ci/variables/predefined_variables.html
Key envs:
GITLAB_CI=true CI_COMMIT_SHA head CI_MERGE_REQUEST_TARGET_BRANCH_SHA base (MR builds) CI_COMMIT_BEFORE_SHA base (push builds) CI_MERGE_REQUEST_IID PR number CI_PROJECT_PATH owner/name CI_PIPELINE_ID run id
func (*GitLabCI) EnrichHeader ¶
type GoogleCloudBuild ¶
type GoogleCloudBuild struct{}
GoogleCloudBuild — https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values
GCB's predefined substitutions are prefixed COMMIT_SHA, BUILD_ID, PROJECT_ID, REPO_NAME. When triggered via the GitHub mirror integration we also get _PR_NUMBER. No standard "target branch" variable — rely on NULLIFY_BASE_REF when running against PR diffs.
func (*GoogleCloudBuild) Detect ¶
func (g *GoogleCloudBuild) Detect() bool
Detect: Google Cloud Build doesn't expose a single CI=true-style flag; BUILD_ID + PROJECT_ID together are a reasonable signature.
func (*GoogleCloudBuild) EnrichHeader ¶
func (g *GoogleCloudBuild) EnrichHeader(h http.Header)
func (*GoogleCloudBuild) PRNumber ¶
func (g *GoogleCloudBuild) PRNumber() (int, bool)
func (*GoogleCloudBuild) Platform ¶
func (g *GoogleCloudBuild) Platform() Platform
type Jenkins ¶
type Jenkins struct{}
Jenkins — https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
Jenkins has no canonical "target branch" variable — different pipeline setups expose different things. We read the common Multibranch / GitHub-branch-source envs + fall back to NULLIFY_BASE_REF for anything the operator prefers to set by hand.
Key envs:
JENKINS_URL signature GIT_COMMIT head CHANGE_ID PR number (Multibranch) CHANGE_TARGET PR target branch BUILD_NUMBER run id
func (*Jenkins) EnrichHeader ¶
type Local ¶
type Local struct{}
Local is the fallback when no CI env vars match — useful when developers run `nullify deps analyze` on their laptop before pushing. Always returns true from Detect(), so it MUST be the last entry in the registry list.
Defaults:
BaseRef = origin/HEAD (the remote's default-branch tip) HeadRef = HEAD
Operators can override either via NULLIFY_BASE_REF / NULLIFY_HEAD_REF env vars if their local-dev workflow needs something specific.
func (*Local) EnrichHeader ¶
type Platform ¶
type Platform string
Platform is the canonical identifier for a CI/CD platform. Values are stamped onto the X-Nullify-CI-Provider header so scpm's audit log can attribute a CLI run to its CI environment.
const ( PlatformGitHubActions Platform = "GITHUB_ACTIONS" PlatformGitLabCI Platform = "GITLAB_CI" PlatformCircleCI Platform = "CIRCLECI" PlatformBitbucketPipelines Platform = "BITBUCKET_PIPELINES" PlatformJenkins Platform = "JENKINS" PlatformAzureDevOps Platform = "AZURE_DEVOPS" PlatformGoogleCloudBuild Platform = "GOOGLE_CLOUD_BUILD" PlatformAWSCodeBuild Platform = "AWS_CODEBUILD" PlatformOther Platform = "OTHER" )
type Provider ¶
type Provider interface {
// Platform returns this provider's Platform constant.
Platform() Platform
// Detect returns true when the current process env matches this
// provider's signature. Detect MUST NOT touch the network or
// filesystem — env var inspection only.
Detect() bool
// BaseRef returns the commit or ref (short sha, full sha, or
// branch name) the CI declared as the base of the current build,
// resolved against the git repository at repoPath. For PR builds,
// this is the PR target branch's HEAD at PR open time; for push
// builds, it's the previous HEAD of the pushed branch. Fall back to
// "origin/<default-branch>" when CI doesn't expose a specific base.
BaseRef(ctx context.Context, repoPath string) (string, error)
// HeadRef returns the commit the current build is running against,
// resolved against the git repository at repoPath. For PR builds,
// this is the PR's head commit; for push builds, the pushed commit.
HeadRef(ctx context.Context, repoPath string) (string, error)
// PRNumber returns the pull-request number if the current build is
// a PR, and (0, false) otherwise. Used for diagnostic logging + as
// the idempotency-key prefix in scpm calls.
PRNumber() (int, bool)
// RepoSlug returns (owner, name) for GitHub/GitLab/Bitbucket-style
// coordinates. Returns (_, _, false) when the provider doesn't
// expose it (eg. Jenkins, self-hosted CI).
RepoSlug() (owner, name string, ok bool)
// EnrichHeader adds CI-specific headers to outbound HTTP requests
// (commit SHA, PR number, run ID) so scpm's audit log can tie a
// specific CLI run back to a CI invocation. Called once per HTTP
// request built by the workflow.
EnrichHeader(h http.Header)
}
Provider identifies one CI/CD platform and exposes the information the CLI's deps-analyze + containers-analyze workflows need. All methods are expected to be cheap — provider detection happens on every CLI invocation.
func Default ¶
func Default() []Provider
Default returns the full list of providers in detection priority. Exposed as a constructor (not a package-level var) so tests can build a truncated list without touching shared state.
func Detect ¶
Detect walks providers in order and returns the first one whose Detect() matches. Returns ErrNoProvider only if the caller passed a custom list without Local.
func NewAWSCodeBuild ¶
func NewAWSCodeBuild() Provider
func NewAzureDevOps ¶
func NewAzureDevOps() Provider
func NewBitbucketPipelines ¶
func NewBitbucketPipelines() Provider
func NewCircleCI ¶
func NewCircleCI() Provider
func NewGitHubActions ¶
func NewGitHubActions() Provider
func NewGitLabCI ¶
func NewGitLabCI() Provider
func NewGoogleCloudBuild ¶
func NewGoogleCloudBuild() Provider
func NewJenkins ¶
func NewJenkins() Provider