CI/CD Tiered Pipeline¶
The GE CI/CD pipeline uses a 3-tier execution model to balance speed on every push against thoroughness on merge requests and nightly runs. Each tier is a superset of the previous: STANDARD includes all FAST jobs, FULL includes all STANDARD jobs.
Tier Overview¶
| Tier | Trigger | Approx. Duration | Job Count | Purpose |
|---|---|---|---|---|
| FAST | Every push to any branch | ~2 minutes | 10 | Immediate feedback. Blocks obvious failures fast. |
| STANDARD | MR open/update + push to main |
~5 minutes | 25 | Full gate before merge. Includes build, sign, and staging deploy. |
| FULL | Nightly at 02:00 CEST + manual trigger | ~20 minutes | 31 | Complete validation including mutation, E2E, DAST, and property tests. |
FAST Tier — Every Push (~2 min, 10 jobs)¶
These jobs run on every push to any branch. They are fast, deterministic, and provide immediate signal.
| Job | What it does |
|---|---|
lint:python |
ruff zero-tolerance linting |
lint:secrets |
gitleaks secret detection (445-finding baseline; blocks NEW secrets only) |
build:backend |
Verifies 4 core Python modules import without error |
test:unit |
553 unit tests via pytest |
tdd:oracle-check |
Verifies TDD test files do not import from src/ (oracle independence) |
security:bandit |
Python SAST — CRITICAL/HIGH severity blocks |
security:semgrep |
TypeScript SAST + 8 custom LLM anti-pattern rules |
security:dependency-scan |
Python dependency vulnerability audit via safety |
test:integration |
Real PostgreSQL 15 + Redis 6381 service containers |
types:typescript |
tsc --noEmit --strict across all TypeScript |
All 10 jobs are blocking. A failure on any FAST job blocks further CI execution on that commit.
STANDARD Tier — MR + main (~5 min, 25 jobs)¶
Runs on merge request open/update and on every push to main. Includes all FAST jobs plus:
| Job | What it does |
|---|---|
types:python |
pyright --strict type checking across all Python modules |
lint:deadcode |
knip (TypeScript) + vulture (Python) dead code detection |
iac:checkov |
Checkov scan of k8s manifests and Dockerfiles |
iac:kubesec |
Kubesec security scoring across all k8s YAML |
test:e2e |
Playwright E2E suite — 4 parallel workers in CI |
test:adversarial |
AST forbidden-call scan + 100-input fuzz test |
test:reconciliation |
Jasper: TDD-phase suite vs post-implementation comparison |
test:contract |
OpenAPI contract verification |
build:image |
kaniko container build → push to GitLab Container Registry |
sign:image |
cosign signing with SLSA Level 3 attestation |
sbom:generate |
Syft CycloneDX SBOM — attached to container image |
deploy:staging |
ArgoCD API-triggered sync to staging namespace |
verify:health |
HTTP health checks, SSL verification, error rate < 0.1% |
merge:gate |
Reads JUnit/SARIF artifacts; computes release readiness score (threshold: 70/100) |
deps:node |
npm audit + Trivy filesystem scan |
All 25 jobs are blocking. The following jobs were previously soft-failures (allow_failure: true) and have been hardened as of 2026-04-02:
types:pythonlint:deadcodeiac:checkoviac:kubesectest:e2everify:health
FULL Tier — Nightly + Manual (~20 min, 31 jobs)¶
Runs nightly at 02:00 CEST via GitLab scheduled pipeline and on manual trigger. Includes all STANDARD jobs plus:
| Job | What it does |
|---|---|
mutation:typescript |
Full Stryker mutation run across all TypeScript — blocking |
mutation:python |
Full mutmut mutation run across all Python |
test:property:python |
Hypothesis property-based tests (max_examples=1000) |
test:property:typescript |
fast-check property-based tests (numRuns=1000) |
dast:zap |
OWASP ZAP baseline scan against staging |
dast:nuclei |
Nuclei template scan against staging |
The FULL tier also includes the manual production deployment gate:
| Job | What it does |
|---|---|
deploy:production |
Manual trigger required — human-in-the-loop gate before production promote |
Note on mutation testing: On STANDARD tier runs, test:mutation runs in Stryker incremental mode — only files changed in the MR are mutated. The mutation:typescript job in the FULL tier runs the complete Stryker suite against all TypeScript. This distinction keeps STANDARD tier fast while ensuring full mutation coverage nightly.
How to Trigger a Full Run Manually¶
Via GitLab UI¶
- Navigate to your project in GitLab (
gitlab.ge.internal). - Go to Build → Pipelines.
- Click Run pipeline.
- Set the variable
CI_TIERtofull. - Click Run pipeline.
The pipeline will execute all 31 jobs including mutation testing, property-based testing, DAST, and the production deploy gate.
Via GitLab API¶
curl --request POST \
--form "token=$CI_JOB_TOKEN" \
--form "ref=main" \
--form "variables[CI_TIER]=full" \
"https://gitlab.ge.internal/api/v4/projects/$PROJECT_ID/trigger/pipeline"
Replace $PROJECT_ID with your numeric project ID (visible in the GitLab project settings page).
Via git push with CI variable¶
This works from any branch and forces the FULL tier for that specific push only.
Nightly Schedule¶
The FULL tier runs automatically at 02:00 CEST every night via a GitLab scheduled pipeline. This ensures:
- Full mutation testing runs on all code, not just changed files.
- DAST scans run against the current staging environment.
- Property-based tests run with high iteration counts (1000 examples/runs).
- Any regressions introduced during the day are caught before business hours.
Results from the nightly FULL run are visible in Build → Pipelines with the scheduled source label.
Tier Selection Logic¶
The pipeline determines the tier from the following precedence:
- If
CI_TIER=fullvariable is set → FULL tier. - If
CI_PIPELINE_SOURCE=schedule→ FULL tier. - If the ref is
mainor the pipeline source ismerge_request_event→ STANDARD tier. - Otherwise → FAST tier.
allow_failure Status¶
The following table summarises all jobs where allow_failure is relevant. All other jobs default to blocking (allow_failure: false).
| Job | Tier | allow_failure | Notes |
|---|---|---|---|
types:python |
STANDARD | false | Hardened 2026-04-02, was true |
lint:deadcode |
STANDARD | false | Hardened 2026-04-02, was true |
iac:checkov |
STANDARD | false | Hardened 2026-04-02, was true |
iac:kubesec |
STANDARD | false | Hardened 2026-04-02, was true |
test:e2e |
STANDARD | false | Hardened 2026-04-02, was true |
mutation:typescript |
FULL | false | Hardened 2026-04-02, was true |
verify:health |
STANDARD | false | Hardened 2026-04-02, was true |
deploy:production |
FULL | — | Manual trigger, not a failure gate |
There are no remaining allow_failure: true entries on enforcement stages.
Related Documentation¶
- CI/CD Achievement — Full pipeline reference, stage-by-stage detail, compliance mapping
- CI/CD Implementation Plan — 9-phase roadmap, what is done and what remains
- TDD Pipeline — How specs and tests feed into CI
- CI/CD Infrastructure Pitfalls — Lessons learned during pipeline construction