Skip to Content
CI/CD Pipeline

CI/CD Pipeline

The CI pipeline lives in xred-eln-integrations  and runs automatically for changed apps only. Deployment to Minerva is handled by a separate manually-triggered workflow.

CI Pipeline

The pipeline detects which apps changed using git diff and runs jobs only for those apps via a matrix strategy. Repo-wide checks run once regardless.

Pre-Commit

Static analysis and hygiene checks that run in parallel.

  • Ruff — Python linter and formatter (replaces flake8, isort, black) — per app
  • ESLint — JavaScript/TypeScript linting — per app
  • React Doctor — Detects common React anti-patterns and compatibility issues — per app
  • Secrets Scan — Scans git history for leaked credentials using gitleaks  — repo-wide
  • Big Files — Rejects files larger than 5 MB — repo-wide
  • YAML Lint — Validates YAML syntax across the repo — repo-wide

Test

Runs after all pre-commit checks pass.

  • Pytest — Runs the backend test suite with coverage reporting
  • Ruff Warn — Runs all Ruff rules in advisory mode (non-blocking) to surface potential improvements

Security

Three layers of security scanning:

  • CodeQL — GitHub’s code scanning engine. Analyses Python and JavaScript/TypeScript for vulnerabilities (injection, auth issues, etc.) on every push and PR. Enabled automatically by the roche-innersource org — no configuration needed.
  • Dependabot — Monitors pip, npm, and GitHub Actions dependencies for known vulnerabilities and opens PRs to update them. Configured via .github/dependabot.yml. Alerts must be enabled per-repo in Settings → Code security.
  • uv audit — Audits Python dependencies against the PyPI advisory database using uv’s built-in auditing. Generates a JSON report as a build artifact.

Build

Builds and pushes Docker images for the frontend and backend to ghcr.io. Runs on push to environment branches (main, develop, uat, sandbox).

Docker image tagging

Each image gets a rolling branch tag and a pinned tag with the CI run number:

BranchTags
main:main, :main.42
develop:develop, :develop.42
uat:uat, :uat.42
sandbox:sandbox, :sandbox.42

The run number (.42) gives each build a unique, ordered identifier. Use the rolling tag (:develop) for always-latest, or pin to a specific build (:develop.42) for reproducibility.

Images are scoped per app: ghcr.io/roche-innersource/xred-eln-integrations/<app>/backend and <app>/frontend.

Deploy workflow

Deployment to Minerva is a separate, manually-triggered workflow. It updates (or scaffolds) the Kubernetes manifests in the infrastructure repo , and ArgoCD picks up the change automatically.

How to deploy

  1. Go to Actions → Deploy 
  2. Click Run workflow
  3. Select the branch that matches your target environment
  4. Enter the app name and select components (backend, frontend, or both)
BranchEnvironmentImage tagDomain
developDEV:developminerva.sandbox.pcloud.roche.com
uatUAT:uatapps.uat.minerva.roche.com
mainPROD:mainapps.minerva.roche.com

Preflight checks

Before deploying, the workflow validates:

  • Valid branch — must be develop, uat, or main
  • App exists — the app directory must exist under apps/
  • Dockerfiles present — the requested components must have Dockerfiles
  • CI passed — the latest CI run on the branch must have succeeded
  • Docker image exists — the image must be available in GHCR
  • Infra token configured — the INFRA_REPO_TOKEN secret must be set

If any check fails, deployment is blocked with a clear error message.

First deploy vs update

  • First deploy — if the app’s K8s directory doesn’t exist in the infrastructure repo, the workflow scaffolds all manifests (deployment, service, ingress, kustomization) with the correct Minerva labels, hostnames, and TLS configuration.
  • Subsequent deploys — updates the image tag in the existing deployment manifest.

Deployments to UAT and PROD can only be triggered from the uat or main branch respectively. This ensures only merged and reviewed code gets deployed.

ArgoCD

After the workflow pushes to the infrastructure repo, ArgoCD syncs the changes:

Roche CA certificates

Docker images include Roche CA certificates from certs/ at the repo root. These are downloaded from certinfo.roche.com  and committed to the repo so builds work on GitHub-hosted runners without VPN access.

Last updated on