The Alpiq BESS org keeps its GitLab CI in a shared component repo, not in each project’s .gitlab-ci.yml. Consumer pipelines (e.g. bess-optimization) are ~40 lines of include: component: + inputs:; every job body lives in the component library. Discovered 2026-08-05 by inspecting GitLab directly.
For Agents
Repo path: alpiq_cicd/sales-and-origination/flexible-assets/bess/poc/bess-os-ci-components
Tags: v1.0.0 .. v1.4.0 (semantic-release via .releaserc.json)
Components live at templates/<name>/template.yml; consumed as component: $CI_SERVER_FQDN/<path>/<name>@v1.x.0
This is the Python/data-science side of BESS CI. The Rust mando pipeline does NOT use it — mando hand-rolls its jobs.
Component inventory
Component
Role
mr-jira-check
MR gate: Jira key present/valid
python-setup
”Dynamic Env Variable Setup” — derives all version/ECR/release vars, exports via dotenv
python-test
pytest job (junit XML, no docker services)
python-docker-publish
build + push image to ECR
release-notes
release metadata / changelog
simulator-pipeline
simulator child pipeline
Each takes a spec: inputs: block, so consumers pass parameters instead of overriding YAML. python-test inputs seen in the wild: stage, pre_test_script, extra_apt_packages, timeout.
How the data-driven test CI actually works
This is the machinery behind the cheap 7.4-min/54-case and 13.8-min/68-case suites.
python-setup — the dotenv broadcast pattern
One job derives everything version-shaped from the branch name + pyproject.toml, then hands it to every downstream job:
PROJECT_VERSION derivation by ref:
main / release/* → BASE_VERSION+<pipelineIID>.<shortsha>
when: always is load-bearing: a failing suite still uploads its report, so GitLab renders per-case failures in the MR widget instead of just “job failed”.
Consumers pin @v1.0.0-style refs, so a component bump is an explicit consumer commit. The repo itself is released by semantic-release (.releaserc.json), which is where the v1.0.0..v1.4.0 tag range comes from.
consume a prebuilt artifact rather than compiling; artifacts: when: always + reports: junit: so failures are readable in the MR
mando’s .integration-test-linux
services: sidecars — the e2e harness needs wiremock + postgres, which the pure data-driven Python suites deliberately have none of
The component library cannot be copied wholesale for e2e
python-test is explicitly service-less. The e2e harness’s whole point is a live stack (mando up → migrate → seed → flow run --bundle → verify), so the sidecar half must come from mando’s own integration job. Only the artifact-consumption and junit-always halves transfer.
Long-term option: package the e2e job as a new bess-os-ci-components component (e.g. mando-e2e) with spec: inputs: for suite path, image tag, and timeout — so other BESS repos can run mando e2e suites without copy-pasting job YAML. Not decided.
Related
Mando CI-CD — the Rust-side pipeline, which does NOT consume these components