Skip to content

CI Template Reference

Every hidden job provided by orchestrator/ci-templates, with its Docker image, required variables, and purpose. Extend these jobs in your project's .gitlab-ci.yml using the extends: keyword.


How to Use a Template Job

All template jobs are defined as hidden jobs (names start with .). Extend them in your pipeline and override only what differs:

lint:
  extends: .python-lint
  stage: validate
  tags:
    - small
  variables:
    SOURCE_PATH: src

Any key you define in your job overrides the corresponding key from the template. Keys not specified in your job are inherited from the template.


Python Templates (.gitlab-ci-python.yml)

For FastAPI services, background workers, the executor CLI, and cwiq-common.

Template Job Image Required Variables Purpose
.python-lint python:3.12-slim SOURCE_PATH Runs ruff check and ruff format --check against $SOURCE_PATH
.python-typecheck python:3.12-slim SOURCE_PATH Runs mypy $SOURCE_PATH for static type checking
.python-test python:3.12-slim SOURCE_PATH Runs pytest with coverage; includes PostgreSQL and Redis as GitLab services
.python-integration-test python:3.12-slim SOURCE_PATH Integration tests; runs only on main and develop; uses the large runner
.python-semgrep semgrep/semgrep:latest SAST scan with rulesets p/python, p/secrets, p/owasp-top-ten; outputs semgrep-results.sarif and semgrep-results.json
.python-build python:3.12-slim Builds a Python wheel with python -m build
.python-publish python:3.12-slim Publishes the wheel to the GitLab Package Registry via Twine; runs on version tags only

Example: Python Service Pipeline

include:
  - project: 'orchestrator/ci-templates'
    ref: main
    file:
      - '/.gitlab-ci-common.yml'
      - '/.gitlab-ci-python.yml'
      - '/.gitlab-ci-trivy.yml'
      - '/.gitlab-ci-scan.yml'

variables:
  SOURCE_PATH: src

lint:
  extends: .python-lint
  stage: validate
  tags: [small]

typecheck:
  extends: .python-typecheck
  stage: validate
  tags: [small]

semgrep:
  extends: .python-semgrep
  stage: validate
  tags: [small]

test:
  extends: .python-test
  stage: test
  tags: [small]

Node.js Templates (.gitlab-ci-node.yml)

For the UI project (React 18 / TypeScript).

Template Job Image Required Variables Purpose
.node-lint node:20-alpine Runs npm run lint (ESLint)
.node-typecheck node:20-alpine Runs tsc --noEmit to check TypeScript types
.node-test node:20-alpine Runs npm run test -- --run with Vitest coverage
.node-semgrep semgrep/semgrep:latest SAST scan with rulesets p/javascript, p/typescript, p/react, p/secrets
.node-build node:20-alpine Runs npm run build; produces the dist/ static bundle
.node-e2e playwright:v1.40.0-focal E2E_ADMIN_USERNAME, E2E_ADMIN_PASSWORD Playwright E2E tests against DEV; runs on main and develop only
.node-publish node:20-alpine Publishes the npm package to the GitLab npm registry; version tags only

E2E tests require a running DEV environment

The .node-e2e template runs against https://orchestrator.dev.cwiq.io. It will fail if the DEV environment is down. E2E credentials are fetched from Vault (secret/orchestrator/e2e-test-user) at runtime.


Common Templates (.gitlab-ci-common.yml)

Shared infrastructure templates used by both Python and Node.js services.

Template Job Image Purpose
.docker-build gcr.io/kaniko-project/executor:debug (via Nexus proxy) Builds the Docker image with Kaniko and pushes to Nexus; writes build.env with IMAGE_TAG
.docker-push-latest docker:27 + dind service Re-tags the image as latest and pushes to Nexus; main branch only
.ansible-deploy cytopia/ansible-runner Runs an Ansible playbook on the ansible server via SSH; used for infrastructure-level deployments
.health-check curlimages/curl Curls a health endpoint with 30 retries at 5-second intervals; fails if the endpoint does not return 200 within the retry window

Scan Templates (.gitlab-ci-trivy.yml and .gitlab-ci-scan.yml)

Template Job Image Purpose
.trivy-fs-scan aquasec/trivy:0.69.3 Scans the repository filesystem for secrets and misconfigurations; exits non-zero on CRITICAL secrets findings
.trivy-image-scan aquasec/trivy:0.69.3 Scans the built Docker image for CVEs; runs on main only; uses IMAGE_TAG from build.env
.defectdojo-import alpine:latest Uploads Trivy image scan results to DefectDojo via REST API; uses Vault JWT to fetch the API token
.sonarqube-scan sonarsource/sonar-scanner-cli:latest Runs SonarQube analysis and uploads to sonarqube.shared.cwiq.io; uses Vault JWT to fetch the project token; main branch only

Deprecated security templates

The templates .python-security and .node-security still exist in the file for backward compatibility but are deprecated. Do not use them in new or existing pipelines. Use .python-semgrep and .node-semgrep instead. The deprecated templates will be removed in a future release of ci-templates.


Vault Authentication in Templates

Templates that call external services (SonarQube, DefectDojo, Nexus) authenticate via Vault JWT. The pattern is the same in every template:

before_script:
  - |
    # Fetch Vault token using GitLab CI_JOB_JWT_V2
    VAULT_TOKEN=$(curl -s --request POST \
      "${VAULT_ADDR}/v1/auth/jwt/login" \
      --data "{\"jwt\": \"${CI_JOB_JWT_V2}\", \"role\": \"gitlab-ci\"}" \
      | python3 -c "import sys, json; print(json.load(sys.stdin)['auth']['client_token'])")
    # Fetch service credentials from Vault
    NEXUS_CREDS=$(curl -s --header "X-Vault-Token: ${VAULT_TOKEN}" \
      "${VAULT_ADDR}/v1/secret/nexus/svc-orchestrator")

The VAULT_ADDR variable comes from the group-level CI/CD variable. The Vault JWT role gitlab-ci is pre-configured with policies that allow reading the secrets each template needs.