Documentation
¶
Index ¶
Constants ¶
const ( DefaultAppCatalog = "giantswarm-catalog" DefaultAppCatalogTest = "giantswarm-test-catalog" )
DefaultAppCatalog and DefaultAppCatalogTest are the catalogs the chart pipeline publishes to when a repo does not override them. They match the long-standing template hardcodes, so repos that do not set a catalog get the identical config they had before the override existed.
const ( PackageManagerNPM = "npm" PackageManagerYarn = "yarn" PackageManagerYarnClassic = "yarn-classic" PackageManagerPNPM = "pnpm" )
Package-manager values detected from the lockfile. Yarn Berry and Yarn Classic are distinguished because their install commands and cache directories differ (Berry: `--immutable` + .yarn/cache; Classic: `--frozen-lockfile` + ~/.cache/yarn), and the two cannot be told apart from the lockfile name alone.
const ( DefaultBuildConcurrency = "auto" DefaultResourceClass = "large" )
DefaultBuildConcurrency and DefaultResourceClass are the go-build knobs the cli flavour applies when a repo does not override them. They match the long-standing template hardcodes, so cli repos that set neither render the identical config they had before the overrides existed. Only the cli flavour (ReleaseBinaries) emits these; a non-cli go-build job stays on the orb/CircleCI defaults.
const ATSKindConfigPath = ".ats/kind-config.yaml"
ATSKindConfigPath is the repo-owned kind Cluster configuration the chart-test jobs hand to `kind create cluster --config` (run-tests-with-ats `kind_config`) when the repository carries it. It is a content signal like the Dockerfile and .nvmrc probes, not a gen.ci key: the cluster's shape is test content that changes with .ats/main.yaml and the tests, all repo-owned, so it lives next to them and one repository edits one place. Feature gates and runtime config are fixed at `kind create`, and app-test-suite 1.x provisions no cluster, so this file is the only way a chart's tests get them (first use: Agent Substrate's ClusterTrustBundle, ClusterTrustBundleProjection and PodCertificateRequest gates for the kagent API v2 chart smokes). The job keeps naming the cluster and choosing the node image, so the file carries only what the job does not decide. Absent, the jobs render exactly as before.
const ContinuationOrbVersion = "2.0.1"
ContinuationOrbVersion pins the circleci/continuation orb used by the generated setup config (.circleci/config.yml) to merge the optional repo-owned .circleci/custom.yml into .circleci/workflows.yml at pipeline runtime. Baked in for the same reason as OrbVersion: a bump ships with a devctl release and reaches repos via align-files.
renovate: datasource=orb depName=circleci/continuation
const DefaultATSVersion = "1.0.3"
DefaultATSVersion is the app-test-suite container tag the generated chart-test jobs run when a repo pins none (`gen circleci --ats-version`). app-test-suite 1.x is the default for every generated-CI chart repo: the job creates the kind cluster, the tests live in a uv project and the chart is installed with Helm. A repo that has not migrated its .ats/main.yaml and tests yet pins a 0.x tag (e.g. "0.15.0") to stay on the legacy dats.sh path until it has.
const DefaultImagePlatforms = "linux/amd64,linux/arm64"
DefaultImagePlatforms is the platform list a native per-architecture image build covers when the repo does not override it. It matches the orb's own default for the single-job build, so opting in does not change the set.
const DefaultNodeImageVersion = "24.20.0"
DefaultNodeImageVersion is the cimg/node Docker tag the generated Node job runs on when a repo does not pin its own. Baked in and Renovate-managed, for the same reason as the orb pins: a toolchain bump ships with a devctl release and reaches repos via align-files rather than drifting per repo.
A repo that needs to own its Node version -- because the version is also baked into artifacts devctl does not generate (a Dockerfile FROM, a setup-node step) and must not diverge from CI -- overrides this by committing a .nvmrc, which the runner probes. That keeps the version in ONE place per repo instead of trading a central default for N copies: Renovate's built-in nvm manager owns .nvmrc natively (datasource node-version, depName "node"), so it groups with the repo's other node deps and is LTS-gated, neither of which a rendered cimg/node tag can express.
That trade has one cost worth knowing. This constant is tracked against the docker datasource, so "a cimg/node tag with this name exists" is a precondition of any bump. A .nvmrc is tracked against node-version -- Node releases, which CircleCI trails by hours to days. A repo whose .nvmrc is bumped inside that window renders an image that cannot be pulled yet, and every job fails at container spin-up with a manifest error until CircleCI catches up. It is self-healing and confined to that one repo, but the cause is not obvious from the error; a consuming repo that wants the guarantee back can hold .nvmrc on the docker datasource in its own renovate config.
renovate: datasource=docker depName=cimg/node
const DefaultNodeResourceClass = "large"
DefaultNodeResourceClass is the CircleCI resource_class the Node job runs on when a repo does not override it. The Node verify chain (tsc + lint + test + build over a whole monorepo) is memory-hungry -- backstage's ci:verify pins NODE_OPTIONS max-old-space-size to 6 GiB -- so "large" (4 vCPU / 8 GiB) is the floor. A bigger monorepo raises it via gen.ci.resourceClass, the same knob the cli go-build job uses.
const DefaultNodeTestTarget = "test"
DefaultNodeTestTarget is the package.json script the Node job runs for the verify phase when a repo does not override it. The repo composes typecheck/lint/format/test into its own ci:verify script -- the make-target interface (the Node analogue of `make test`), so CI and local runs share one command.
`test` is only a FLOOR, not the convention: a bare `test` script yields a green job but gates tests alone, silently skipping typecheck/lint/format. The convention is an explicit composed ci:verify (tsc --noEmit + lint + prettier --check + tests, in one process; backstage is the reference), set via gen.ci.node.testTarget. ci:verify owns lint/format CI-wide (verify-canonical: the CI pre-commit job carries no JS/TS hook), and the companion ci:build (NodeBuildTarget) is bundle/emit-only so nothing runs twice -- the single-pass contract recorded in the node-ci-verify-build-single-pass ADR.
const OrbVersion = "10.5.0"
OrbVersion is the aligned giantswarm/architect orb version every generated CircleCI config pins. It is baked in next to the template -- not a flag and not passed in by callers -- so that an orb bump (which can change the template's required job/param shape, i.e. a cross-major compatibility contract) forces a new devctl release rather than silently combining a stale template with a newer orb at generation time.
Renovate keeps this current; a major bump lands as a devctl PR, gets released, and only then reaches repos via the align-files devctl pin.
Tracked via github-tags on the architect-orb source repo rather than the `orb` datasource: the generated renovate.json5 disables `orb` updates for giantswarm/architect (so they stop fighting align-files in .circleci/config.yml), and that root packageRule would otherwise also block this constant. The custom manager that reads this annotation lives in renovate-custom.json5.
renovate: datasource=github-tags depName=giantswarm/architect-orb
Variables ¶
This section is empty.
Functions ¶
func IsInvalidConfig ¶
IsInvalidConfig asserts invalidConfigError.
Types ¶
type CircleCI ¶
type CircleCI struct {
// contains filtered or unexported fields
}
func (*CircleCI) ATSInputs ¶ added in v8.27.0
ATSInputs returns the canonical app-test-suite (ATS) Pipfile input for chart/app (.HasApp) repos, and nil otherwise. ATS chart tests run only for .HasApp -- the same signal that gates the run-tests-with-ats jobs -- so the Pipfile is emitted under exactly that condition and from the same generator call site (devctl gen circleci, the only generator invoked inside align's `if (ci && ci.generate)` guard). That makes "ATS Pipfile only when CI is generated, and only for chart/app repos" structurally guaranteed rather than dependent on a separate, differently-scoped invocation. A repo that opts out of ATS (SkipATS) gets no Pipfile either, matching the suppressed jobs. The default branch-only shape keeps the file (the branch job runs the tests); ATSOnRelease only adds the tag-time job.
func (*CircleCI) SetupConfig ¶ added in v8.11.0
SetupConfig is the static dynamic-config setup workflow written to .circleci/config.yml. It merges the optional repo-owned custom.yml into workflows.yml at pipeline runtime.
type Config ¶
type Config struct {
// RepoName is the repository name, used for the binary, chart, and job
// names.
RepoName string
// Language is the repo language. "go" selects the go-build job.
Language gen.Language
// Flavours are the devctl gen flavours. The "app" flavour selects the
// chart pipeline.
Flavours gen.FlavourSlice
// SkipATS opts the chart pipeline out of app-test-suite (ATS) chart tests.
// When set, the run-tests-with-ats jobs and the canonical tests/ats/Pipfile
// are not generated, and the chart push jobs gate directly on build-chart.
// Only applies to a chart/app repo (the "app" flavour).
SkipATS bool
// ATSOnRelease also runs the app-test-suite (ATS) chart tests on the
// release tag. By default the chart pipeline runs them once, as
// execute-chart-tests on every branch build, and the tag only builds and
// pushes the chart (push-chart-release gates on build-chart): the tag is
// cut from the merge commit of a PR whose branch run already tested that
// tree. When set, the pre-v8.45.0 shape is generated: an additional
// execute-chart-tests-release job on the tag (after the release image when
// there is one) that push-chart-release gates on. For repos whose custom.yml
// jobs require execute-chart-tests-release, or whose branch protection does
// not make the CircleCI statuses required checks so the tag-time run is the
// only enforced one. Mutually exclusive with SkipATS. Only applies to a
// chart/app repo.
ATSOnRelease bool
// ATSVersion pins the app-test-suite container tag the chart-test jobs run
// (run-tests-with-ats `app-test-suite_container_tag`). Empty selects
// DefaultATSVersion. A tag of major 1 or
// higher selects app-test-suite 1.x, which no longer provisions clusters:
// both jobs get `create_kind_cluster: true` (the job creates the kind
// cluster and hands over its kubeconfig) and the generated test dependency
// file switches from tests/ats/Pipfile (pipenv) to tests/ats/pyproject.toml
// + uv.lock (uv), with the Pipfile deleted. A 0.x tag keeps the legacy
// dats.sh path and the Pipfile. Must be a semantic version. Ignored with
// SkipATS. Only applies to a chart/app repo.
ATSVersion string
// HasATSKindConfig is true when the repo carries a kind Cluster
// configuration at ATSKindConfigPath. The runner derives it from the file's
// presence, the way HasDockerfile is derived; both run-tests-with-ats jobs
// then get `kind_config: <that path>`. Ignored when no chart-test job is
// rendered.
HasATSKindConfig bool
// ATSResourceClass overrides the CircleCI resource_class of both
// run-tests-with-ats jobs: one of medium, large, xlarge, 2xlarge (the orb's
// enum; its default is medium). Empty renders nothing. For chart tests that
// run a real workload on the job's kind cluster beside the chart under
// test. Deliberately separate from ResourceClass, which sizes the cli
// go-build and the Node job. Requires the chart-test jobs (app flavour
// without SkipATS); rejected otherwise, since the value would silently
// render nothing.
ATSResourceClass string
// HasDockerfile selects the image pipeline. The runner derives this from
// the presence of a Dockerfile in the repo.
HasDockerfile bool
// AppCatalog overrides the catalog the chart pipeline publishes to. Empty
// defaults to "giantswarm-catalog". Set it for repos that ship to a
// different catalog (e.g. the internal "giantswarm-operations-platform")
// so generation does not migrate their chart to the public catalog.
AppCatalog string
// AppCatalogTest overrides the test catalog. Empty defaults to
// "giantswarm-test-catalog". Kept paired with AppCatalog.
AppCatalogTest string
// ChartName overrides the chart name (the push-to-app-catalog `chart`
// param and the helm/<chart> directory). Empty defaults to RepoName. Set it
// for repos whose chart directory does not match the repo name (e.g.
// docs-proxy ships helm/docs-proxy-app).
ChartName string
// OverrideChartAppVersion decides whether app-build-suite stamps the
// computed build version into the chart's appVersion. nil derives it from
// the repo's shape: a repo that builds its own image ships the app it
// packages, so its appVersion is its own version and is stamped; a
// chart-only repo packages an app built elsewhere, so the appVersion
// declared in Chart.yaml is kept. A non-nil value overrules that in either
// direction. The append-only custom.yml merge cannot add a param to a
// generated job, so the generator carries it.
OverrideChartAppVersion *bool
// ForcePublic pushes the image and chart as public artifacts even though
// the repo is private (architect force-public: true). Set it for private
// repos that publish public artifacts (e.g. web-assets). Mutually exclusive
// with ImagePrivateOnly.
ForcePublic bool
// BranchPublish opts the repo into publishing a dev image and chart on
// branch builds. By default branches build + test only (no push). When
// set, the branch path additionally pushes an amd64 dev image and the
// dev chart, coupled (both or neither).
BranchPublish bool
// ImagePreBuildJob names a repo-owned custom.yml job the image build must
// wait on (adds a `requires` entry to push-to-registries-release and the
// branch build-image / push-to-registries job). Used for workspace-handoff
// pre-steps the append-only custom.yml merge cannot inject into a generated
// job. Empty for the common case.
ImagePreBuildJob string
// ImageDockerfile overrides the Dockerfile path on the image jobs (the
// architect push-to-registries `dockerfile` param). A non-empty value also
// forces the image pipeline on, so a repo whose Dockerfile is not at the
// repo root (e.g. backstage -> packages/backend/Dockerfile) still generates
// image jobs. Empty keeps the orb default ("Dockerfile") and leaves the
// root-Dockerfile derivation untouched.
ImageDockerfile string
// ImagePrivateOnly ships the image to the private registry only
// (gsociprivate), replacing split-china-push and omitting sync-china-registry.
// Set it for private repos whose image must not land in the public catalog.
ImagePrivateOnly bool
// ImageName overrides the `giantswarm/<repo>` default image name on the
// image jobs. Set it for repos whose published image differs from the repo
// name (e.g. kserve -> giantswarm/kserve-controller). Empty keeps the orb
// default.
ImageName string
// ImagePlatforms overrides the buildx platform list on the image jobs.
// Empty lets the orb default apply. Set it for single-architecture images
// (e.g. vllm -> linux/arm64).
ImagePlatforms string
// ImageNativeBuilds builds the image one architecture per job on a native
// resource class (architect build-image, one per platform) and switches
// the push-to-registries jobs to `merge-digests: true`, which joins the
// per-architecture digests into the tagged index instead of building.
// False (default) keeps the single multi-platform buildx job. Set it for
// Dockerfiles with real work in RUN steps (apt, pip, yarn, native
// modules), where the emulated architecture is the whole critical path; a
// COPY of a cross-compiled binary gains nothing. Requires architect-orb
// 10.2.0. Every platform in ImagePlatforms must have a native class.
ImageNativeBuilds bool
// ImageResourceClasses overrides the CircleCI resource_class of the native
// build-image jobs per platform (both the branch and the release leg of that
// platform), e.g. {"linux/arm64": "arm.large"}. Empty keeps the defaults
// (linux/amd64 on small, linux/arm64 on arm.medium). Raise it for images
// whose export, compression or SBOM scan of a very large result is what the
// leg spends its time on (vllm: 22 GB on the 2-vCPU arm.medium). A class
// must belong to the platform's architecture -- the orb has no emulated
// fallback, so a mismatch is rejected here rather than failing the build.
// Only applies with ImageNativeBuilds.
ImageResourceClasses map[string]string
// BuildConcurrency overrides how many architectures the cli-flavour
// go-build job compiles concurrently (the architect go-build
// `build_concurrency` param). Empty defaults to "auto" (nproc). Lower it
// (e.g. "2") for repos whose binary is large enough that a cold full-matrix
// cross-compile OOMs the runner at `auto` -- memory, not CPU, is the binding
// constraint, and a killed build never stores the build cache, so the repo
// stays permanently cold. Only applies to the cli flavour (ReleaseBinaries).
BuildConcurrency string
// ResourceClass overrides the CircleCI resource_class on the cli-flavour
// go-build job. Empty defaults to "large". Raise it (e.g. "xlarge") for
// repos that need more RAM/CPU headroom for the cold cross-compile. Only
// applies to the cli flavour (ReleaseBinaries).
ResourceClass string
// GoBuildPath overrides the package the go-build job compiles (the
// architect go-build `path` param). Empty keeps the orb default ".", the
// module root.
GoBuildPath string
// GoTestArtifacts names a directory under the checkout that `make test`
// writes and that the go-build job keeps as a CircleCI build artifact when
// it fails: the job gains post-steps that stage the directory when: on_fail
// and upload the staging directory with store_artifacts, so a green run
// stores nothing. Empty renders no post-steps. Cleaned with path.Clean; must
// stay a relative path under the checkout made of [A-Za-z0-9._/-], because
// the template splices it into a shell command and into the artifact
// destination verbatim. Requires Language go.
GoTestArtifacts string
// PackageManager selects the Node package manager the build/test job uses
// (one of "npm", "yarn", "yarn-classic", "pnpm"). The runner detects it
// from the lockfile; empty defaults to Yarn Berry. Only applies to a Node
// repo (Language == "node").
PackageManager string
// NodeImageVersion pins the cimg/node tag the build/test job runs on, and
// with it the node-build cache-key salt. The runner detects it from the
// repo's .nvmrc; empty falls back to DefaultNodeImageVersion. Only applies
// to a Node repo (Language == "node").
NodeImageVersion string
// NodeTestTarget overrides the package.json script the Node job runs for
// the verify phase (ci:verify). Empty defaults to "test". The repo composes
// its entire correctness gate -- tsc --noEmit + lint + prettier --check +
// unit tests, in one process -- into this one script (the make-target
// interface). The default "test" is only a floor; the convention is an
// explicit composed ci:verify. Only applies to a Node repo.
NodeTestTarget string
// NodeBuildTarget is the package.json script the Node job runs to build
// (ci:build). Empty omits the build step (a library that only verifies).
// It must be bundle/emit-only -- it must redo nothing NodeTestTarget already
// did (no second typecheck/lint/test) and must not re-install. Only applies
// to a Node repo.
NodeBuildTarget string
// NodeBuildOutput is the workspace path the Node job persists for an image
// handoff (e.g. backstage's "packages/*/dist/*"). Non-empty names the job
// "node-build" and emits persist_to_workspace; empty names it "node-test".
// Only applies to a Node repo.
NodeBuildOutput string
}