GI

GitLab CI/CD

infrastructure v16+

GitLab CI/CD

Version: 16+

Overview

GitLab CI/CD is the Prismatic Platform's automation backbone, running all testing, quality enforcement, and deployment pipelines. Every commit triggers a comprehensive pipeline that compiles with zero warnings, runs the full test suite, checks Credo and Dialyzer compliance, and deploys to Fly.io -- all enforced by the platform's NO MERCY quality doctrine. The pipeline serves as the final automated quality gate between development and production, ensuring that no code reaching the deployment stage has any known quality deficiency.

The Prismatic Platform's GitLab pipeline implements a 9-phase quality gate system: compilation, formatting, Credo analysis, Dialyzer type checking, unit tests, integration tests, security scans, performance benchmarks, and deployment. Every phase must pass before the pipeline proceeds, creating a strict sequential guarantee that later phases can rely on the validation performed by earlier ones. A formatting violation blocks testing; a test failure blocks deployment. There are no overrides, no manual bypasses, and no exceptions.

GitLab's pipeline-as-code approach through .gitlab-ci.yml enables the platform to version-control its entire CI/CD configuration alongside the codebase, with merge request pipelines providing pre-merge quality validation. This means the quality enforcement rules themselves are subject to the same review and versioning discipline as the application code.

Key Features

  • Pipeline as Code: YAML-defined CI/CD pipelines in version control, reviewed alongside application changes
  • Parallel Jobs: Run independent pipeline stages concurrently to minimize total pipeline duration
  • Cache/Artifacts: Efficient dependency caching and build artifact sharing between stages
  • Environments: Staging and production deployment management with environment-specific variables
  • Merge Request Pipelines: Pre-merge quality validation that blocks merge until all checks pass
  • Protected Branches: Deployment restrictions ensuring only the main branch can deploy to production
  • Job Templates: Reusable YAML anchors and extends for DRY pipeline definitions
  • Scheduled Pipelines: Periodic quality sweeps and dependency vulnerability scanning

Platform Integration

GitLab CI/CD enforces the platform's quality gates on every commit with a multi-stage pipeline that mirrors the local Git hook enforcement.

# .gitlab-ci.yml - Prismatic Platform CI/CD pipeline
image: elixir:1.19-otp-27

stages:
  - compile
  - quality
  - test
  - security
  - deploy

variables:
  MIX_ENV: test
  POSTGRES_DB: prismatic_test
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: postgres
  LANG: C.UTF-8

# Dependency cache shared across all stages
cache:
  key: "$CI_COMMIT_REF_SLUG"
  paths:
    - deps/
    - _build/
    - priv/plts/

compile:
  stage: compile
  script:
    - mix deps.get
    - mix compile --warnings-as-errors --force
  artifacts:
    paths:
      - _build/
      - deps/
    expire_in: 1 hour

format_check:
  stage: quality
  script:
    - mix format --check-formatted
  needs: [compile]

credo:
  stage: quality
  script:
    - mix credo --strict
  needs: [compile]

dialyzer:
  stage: quality
  script:
    - mix dialyzer
  needs: [compile]
  cache:
    key: dialyzer-plt
    paths:
      - priv/plts/

test:
  stage: test
  script:
    - mix test --cover
  services:
    - postgres:16
    - redis:7
  needs: [compile, format_check, credo]
  coverage: '/(\d+\.\d+)% coverage/'

deploy_staging:
  stage: deploy
  script:
    - flyctl deploy --app prismatic-staging --strategy rolling
  only:
    - main
  environment:
    name: staging
    url: https://prismatic-staging.fly.dev

deploy_production:
  stage: deploy
  script:
    - flyctl deploy --app prismatic --strategy rolling
  when: manual
  only:
    - main
  environment:
    name: production
    url: https://prismatic-prod.fly.dev

Architecture

The GitLab CI/CD pipeline architecture enforces a strict phase ordering where each stage validates a different aspect of code quality before allowing progression.

StagePhaseDurationGate TypeFailure Response
1Compilation~60sBlockingZero warnings tolerance
2Format Check~10sBlockingReject until formatted
3Credo Analysis~30sBlockingReject until compliant
4Dialyzer~120sBlockingReject until type-safe
5Unit Tests~180sBlockingReject until passing
6Integration Tests~120sBlockingReject until passing
7Security Scan~60sWarningAlert but continue
8Performance Check~90sBlockingReject if > 250ms page load
9Deployment~120sManual (prod)Rollback on failure

The total pipeline duration is approximately 8-12 minutes, with parallel execution of independent quality checks (format, Credo, and Dialyzer run concurrently in the quality stage).

Pipeline Configuration Patterns

The platform enforces specific YAML patterns in GitLab CI to avoid the 10-level nesting limit and maintain readability.

PatternStatusReason
- commandREQUIREDSimple, clear command execution
- 'cmd; cmd'REQUIREDMultiple commands on one line
- | (literal block)FORBIDDENNesting depth issues
- >- (folded block)FORBIDDENNesting depth issues
<< EOF (heredoc)FORBIDDENNot supported in GitLab YAML

Complex logic is extracted to shell scripts in the scripts/ directory rather than embedded in YAML.

# CORRECT: Simple commands, complex logic in scripts
security_scan:
  stage: security
  script:
    - ./scripts/security-scan.sh
    - ./scripts/dependency-audit.sh

# FORBIDDEN: Multi-line blocks in YAML
# security_scan:
#   script:
#     - |
#       if [ condition ]; then
#         complex_logic
#       fi

Performance Characteristics

Pipeline performance directly impacts developer productivity. The platform tracks and optimizes CI/CD execution times.

MetricTargetCurrentOptimization
Total pipeline time< 15 min~10 minParallel quality stages
Compilation stage< 90s~60sIncremental builds with cache
Test stage< 300s~180sParallel test execution
Dialyzer stage< 180s~120sPLT caching across builds
Deployment stage< 180s~120sRolling strategy
Cache hit rate> 90%~95%Branch-based cache keys
Artifact transfer< 30s~15sScoped artifact paths

Caching is the most impactful optimization. The deps/ and _build/ directories are cached across pipeline runs using the branch name as the cache key, reducing compilation time from minutes to seconds for incremental changes.

Environment Management

GitLab CI/CD manages the platform's deployment environments with distinct configurations for each stage.

# Environment-specific deployment configuration
.deploy_template: &deploy_defaults
  image: flyio/flyctl:latest
  before_script:
    - flyctl auth token "$FLY_API_TOKEN"

deploy_staging:
  <<: *deploy_defaults
  stage: deploy
  script:
    - flyctl deploy --app prismatic-staging --strategy rolling
    - flyctl status --app prismatic-staging
  environment:
    name: staging
    url: https://prismatic-staging.fly.dev
  only:
    - main

deploy_production:
  <<: *deploy_defaults
  stage: deploy
  script:
    - flyctl deploy --app prismatic --strategy rolling
    - flyctl status --app prismatic
  environment:
    name: production
    url: https://prismatic-prod.fly.dev
  when: manual
  only:
    - main
EnvironmentURLDeploymentApproval
DevelopmentLocalManualNone
Stagingprismatic-staging.fly.devAutomatic on mainCI gates
Productionprismatic-prod.fly.devManual triggerHuman + CI gates

Configuration

Pipeline variables and secrets are managed through GitLab's CI/CD settings, with sensitive values stored as protected or masked variables.

# Pipeline variables
variables:
  MIX_ENV: test
  POSTGRES_DB: prismatic_test
  POSTGRES_USER: postgres
  POSTGRES_PASSWORD: postgres
  ELIXIR_VERSION: "1.19"
  OTP_VERSION: "27"
  FLY_API_TOKEN: $FLY_API_TOKEN    # Protected variable
  GITLAB_TOKEN: $GITLAB_TOKEN       # Protected variable

# Service containers for testing
services:
  - name: postgres:16
    alias: postgres
  - name: redis:7
    alias: redis
  - name: getmeili/meilisearch:v1.6
    alias: meilisearch

Best Practices

  • Keep scripts simple -- extract complex logic to scripts/*.sh files rather than embedding multi-line scripts in YAML
  • Use needs for dependency management -- explicitly declare job dependencies to enable maximum parallelism
  • Cache aggressively -- cache deps/, _build/, and PLT files to avoid redundant compilation across pipeline runs
  • Scope artifacts -- only pass necessary build artifacts between stages to minimize transfer time
  • Use protected variables -- store API keys, tokens, and deployment credentials as protected masked variables
  • Run merge request pipelines -- validate every merge request before it reaches the main branch
  • Monitor pipeline duration -- track total pipeline time and investigate regressions; target under 15 minutes
  • Never skip stages -- every stage in the pipeline serves a purpose; skipping a quality stage is an L3 violation

Comparison with Alternatives

FeatureGitLab CI/CDGitHub ActionsJenkinsCircleCIBuildkite
ConfigurationYAML in repoYAML in repoGroovy/UIYAML in repoYAML + plugins
Built-in RegistryContainer + PackageContainer + PackageNoneNoneNone
EnvironmentsBuilt-inBuilt-inPluginManualManual
Merge PipelinesNativeWorkflow dispatchPluginNot nativeNot native
Self-hostedYes (free)Yes (enterprise)Yes (primary)NoYes (agents)
Elixir SupportNative DockerNative DockerPluginOrbDocker
Secret ManagementBuilt-inBuilt-inCredentialsContextsHooks

GitLab CI/CD was chosen for the Prismatic Platform because it provides a unified DevOps platform -- issue tracking, code hosting, CI/CD, container registry, and deployment management in a single integrated system.

  • Docker - Container builds and service containers in CI pipeline
  • Fly.io - Deployment target for staging and production environments
  • Dialyzer - Static type checking executed in the quality stage
  • Credo - Code quality analysis executed in the quality stage
  • Git - Version control triggering pipeline execution
  • PostgreSQL - Service container for test database
  • Redis - Service container for cache testing
  • Meilisearch - Service container for search testing
  • All 90 Prismatic Platform applications share the unified CI/CD pipeline
  • prismatic_safety - Quality gates enforced by pipeline stages
  • prismatic_web - Primary deployment target
  • prismatic_api - API gateway deployment target

Connect & Contribute

Created by Tomáš Korcak (korczis) | Open Source under GHL