ci: add comprehensive GitLab CI with warnings-as-errors and optimal caching
Added new .gitlab-ci.yml with: **Quality & Testing:** - Compile job with --warnings-as-errors to catch all warnings - Test job with coverage reporting - Code quality checks (format, credo, dialyzer) - PostgreSQL 17 service for tests **Caching Strategy:** - Hex/Mix packages cached by Elixir/OTP version - Dependencies cached by mix.lock + branch - Build artifacts cached and reused between jobs - System packages (apt) cached to speed up dependency installation - Separate cache update job for scheduled/lock file changes **Pipeline Stages:** 1. Test: compile, test, quality checks (parallel) 2. Build: Docker image build and push to registry 3. Deploy: Manual deployment to production via kubectl **Performance Improvements:** - Jobs reuse compiled artifacts via GitLab cache - System dependencies cached in apt-cache/ - Parallel execution of test, compile, and quality jobs - Pull-only cache policy for most jobs (faster) The existing .gitlab-ci.yml.nix remains for Nix-based builds if needed.
This commit is contained in:
parent
10e4690e97
commit
5356c2f37e
1 changed files with 182 additions and 0 deletions
182
.gitlab-ci.yml
Normal file
182
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
image: hexpm/elixir:1.19.5-erlang-28.0-debian-bookworm-20250113-slim
|
||||
|
||||
variables:
|
||||
MIX_ENV: test
|
||||
# Use GitLab's cache to speed up builds
|
||||
MIX_HOME: $CI_PROJECT_DIR/.mix
|
||||
HEX_HOME: $CI_PROJECT_DIR/.hex
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- deploy
|
||||
|
||||
# Define cache configuration for maximum reuse
|
||||
.mix_cache: &mix_cache
|
||||
key:
|
||||
files:
|
||||
- mix.lock
|
||||
prefix: $CI_COMMIT_REF_SLUG-mix
|
||||
paths:
|
||||
- deps/
|
||||
- _build/test/
|
||||
policy: pull
|
||||
|
||||
.hex_cache: &hex_cache
|
||||
key:
|
||||
prefix: hex-1.19.5-otp-28
|
||||
paths:
|
||||
- .hex/
|
||||
- .mix/
|
||||
policy: pull
|
||||
|
||||
# System dependencies cache
|
||||
.system_cache: &system_cache
|
||||
key:
|
||||
prefix: system-deps-v1
|
||||
paths:
|
||||
- apt-cache/
|
||||
policy: pull
|
||||
|
||||
before_script:
|
||||
- apt-get update -qq
|
||||
# Configure apt cache
|
||||
- mkdir -p apt-cache
|
||||
- export APT_CACHE_DIR=$CI_PROJECT_DIR/apt-cache
|
||||
# Install system dependencies
|
||||
- apt-get install -y -qq --no-install-recommends
|
||||
libsnmp-dev snmp-mibs-downloader
|
||||
build-essential git curl ca-certificates
|
||||
-o dir::cache::archives=$APT_CACHE_DIR
|
||||
# Install Hex and Rebar
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
|
||||
# Job to update caches (runs on schedule or manual trigger)
|
||||
update_deps:
|
||||
stage: test
|
||||
cache:
|
||||
- <<: *hex_cache
|
||||
policy: pull-push
|
||||
- <<: *mix_cache
|
||||
policy: pull-push
|
||||
- <<: *system_cache
|
||||
policy: pull-push
|
||||
script:
|
||||
- mix deps.get
|
||||
- mix deps.compile
|
||||
- mix compile
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
changes:
|
||||
- mix.lock
|
||||
|
||||
# Compile with warnings as errors
|
||||
compile:
|
||||
stage: test
|
||||
cache:
|
||||
- *hex_cache
|
||||
- *mix_cache
|
||||
- *system_cache
|
||||
script:
|
||||
- mix deps.get
|
||||
- echo "Compiling with warnings as errors..."
|
||||
- mix compile --warnings-as-errors
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/test/
|
||||
expire_in: 1 hour
|
||||
|
||||
# Run tests
|
||||
test:
|
||||
stage: test
|
||||
needs: [compile]
|
||||
services:
|
||||
- postgres:17-alpine
|
||||
variables:
|
||||
POSTGRES_DB: towerops_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_HOST: postgres
|
||||
cache:
|
||||
- *hex_cache
|
||||
- *mix_cache
|
||||
- *system_cache
|
||||
script:
|
||||
- mix ecto.create
|
||||
- mix ecto.migrate
|
||||
- mix test --warnings-as-errors
|
||||
coverage: '/\d+\.\d+\%\s+\|\s+Total/'
|
||||
artifacts:
|
||||
reports:
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: coverage.xml
|
||||
when: always
|
||||
expire_in: 7 days
|
||||
|
||||
# Code quality checks
|
||||
quality:
|
||||
stage: test
|
||||
needs: [compile]
|
||||
cache:
|
||||
- *hex_cache
|
||||
- *mix_cache
|
||||
- *system_cache
|
||||
script:
|
||||
- mix format --check-formatted
|
||||
- mix credo --strict
|
||||
- mix dialyzer
|
||||
allow_failure: true # Don't block on dialyzer warnings
|
||||
|
||||
# Build Docker image (existing Nix build or standard build)
|
||||
build:
|
||||
stage: build
|
||||
needs: [test, quality]
|
||||
tags:
|
||||
- docker
|
||||
image: docker:24
|
||||
services:
|
||||
- docker:24-dind
|
||||
before_script:
|
||||
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
|
||||
script:
|
||||
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
|
||||
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
||||
# Tag as latest for main branch
|
||||
- |
|
||||
if [ "$CI_COMMIT_BRANCH" = "main" ]; then
|
||||
docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest
|
||||
docker push $CI_REGISTRY_IMAGE:latest
|
||||
fi
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
- if: $CI_COMMIT_TAG
|
||||
|
||||
# Deploy to production
|
||||
deploy:
|
||||
stage: deploy
|
||||
needs:
|
||||
- job: build
|
||||
artifacts: false
|
||||
tags:
|
||||
- home
|
||||
image:
|
||||
name: bitnami/kubectl:latest
|
||||
entrypoint: [""]
|
||||
script:
|
||||
- kubectl config use-context towerops/towerops:home-cluster-agent
|
||||
- DEPLOY_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
- echo "Deploying at $DEPLOY_TIMESTAMP"
|
||||
- kubectl set image deployment/towerops towerops=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n towerops
|
||||
- kubectl set env deployment/towerops DEPLOY_TIMESTAMP=$DEPLOY_TIMESTAMP -n towerops
|
||||
environment:
|
||||
name: production
|
||||
kubernetes:
|
||||
namespace: towerops
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "main"
|
||||
when: manual
|
||||
Loading…
Add table
Reference in a new issue