Deploy now runs kubectl apply on manifests first (picking up config changes), then updates images to the commit SHA. Adds GitLab environment tracking for production. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
220 lines
8.0 KiB
YAML
220 lines
8.0 KiB
YAML
# GitLab CI/CD — Foxhunt
|
|
# Runs on ci-build pool (GP1-XS, scale-to-zero)
|
|
# Uses sccache for Rust build caching, Kaniko for Docker builds
|
|
|
|
stages:
|
|
- check
|
|
- test
|
|
- build
|
|
- deploy
|
|
|
|
variables:
|
|
SQLX_OFFLINE: "true"
|
|
CARGO_TERM_COLOR: always
|
|
SCCACHE_BUCKET: $SCCACHE_BUCKET
|
|
SCCACHE_ENDPOINT: $SCCACHE_ENDPOINT
|
|
SCCACHE_S3_USE_SSL: "true"
|
|
AWS_ACCESS_KEY_ID: $SCW_ACCESS_KEY
|
|
AWS_SECRET_ACCESS_KEY: $SCW_SECRET_KEY
|
|
RUSTC_WRAPPER: /usr/local/bin/sccache
|
|
REGISTRY: ${CI_REGISTRY_IMAGE}
|
|
|
|
# Base template for Rust jobs
|
|
.rust-base:
|
|
image: rust:1.89-slim
|
|
tags:
|
|
- kapsule
|
|
- rust
|
|
before_script:
|
|
- apt-get update && apt-get install -y protobuf-compiler curl pkg-config libssl-dev
|
|
- curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.8.1/sccache-v0.8.1-x86_64-unknown-linux-musl.tar.gz
|
|
| tar xz --strip-components=1 -C /usr/local/bin sccache-v0.8.1-x86_64-unknown-linux-musl/sccache
|
|
- chmod +x /usr/local/bin/sccache
|
|
- rustup component add clippy
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Stage 1: cargo check + clippy
|
|
# --------------------------------------------------------------------------
|
|
check:
|
|
extends: .rust-base
|
|
stage: check
|
|
script:
|
|
- cargo check --workspace
|
|
- cargo clippy --workspace -- -D warnings
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Stage 2: tests
|
|
# --------------------------------------------------------------------------
|
|
test:
|
|
extends: .rust-base
|
|
stage: test
|
|
needs: [check]
|
|
script:
|
|
- cargo test --workspace --lib
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Stage 3: Build + push images (main only, Kaniko)
|
|
# --------------------------------------------------------------------------
|
|
.kaniko-base:
|
|
stage: build
|
|
needs: [test]
|
|
image:
|
|
name: gcr.io/kaniko-project/executor:debug
|
|
entrypoint: [""]
|
|
tags:
|
|
- kapsule
|
|
rules:
|
|
- if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
|
|
before_script:
|
|
- mkdir -p /kaniko/.docker
|
|
- echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf '%s:%s' "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
|
|
|
|
build-trading-service:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
|
--build-arg SERVICE=trading_service
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/trading_service:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/trading_service:latest"
|
|
|
|
build-api-gateway:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
|
--build-arg SERVICE=api_gateway
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/api_gateway:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/api_gateway:latest"
|
|
|
|
build-broker-gateway:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
|
--build-arg SERVICE=broker_gateway_service
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/broker_gateway_service:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/broker_gateway_service:latest"
|
|
|
|
build-ml-training:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
|
--build-arg SERVICE=ml_training_service
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/ml_training_service:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/ml_training_service:latest"
|
|
|
|
build-backtesting:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
|
--build-arg SERVICE=backtesting_service
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/backtesting_service:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/backtesting_service:latest"
|
|
|
|
build-trading-agent:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.service"
|
|
--build-arg SERVICE=trading_agent_service
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/trading_agent_service:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/trading_agent_service:latest"
|
|
|
|
build-web-gateway:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.web-gateway"
|
|
--destination "${REGISTRY}/web-gateway:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/web-gateway:latest"
|
|
|
|
build-training:
|
|
extends: .kaniko-base
|
|
script:
|
|
- /kaniko/executor
|
|
--context "${CI_PROJECT_DIR}"
|
|
--dockerfile "${CI_PROJECT_DIR}/infra/docker/Dockerfile.training"
|
|
--build-arg SCCACHE_BUCKET=${SCCACHE_BUCKET}
|
|
--build-arg AWS_ACCESS_KEY_ID=${SCW_ACCESS_KEY}
|
|
--build-arg AWS_SECRET_ACCESS_KEY=${SCW_SECRET_KEY}
|
|
--build-arg SCCACHE_ENDPOINT=${SCCACHE_ENDPOINT}
|
|
--destination "${REGISTRY}/training:${CI_COMMIT_SHA}"
|
|
--destination "${REGISTRY}/training:latest"
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Stage 4: Deploy to Kapsule (main only)
|
|
# --------------------------------------------------------------------------
|
|
deploy:
|
|
stage: deploy
|
|
image: bitnami/kubectl:latest
|
|
tags:
|
|
- kapsule
|
|
needs:
|
|
- build-trading-service
|
|
- build-api-gateway
|
|
- build-broker-gateway
|
|
- build-ml-training
|
|
- build-backtesting
|
|
- build-trading-agent
|
|
- build-web-gateway
|
|
- build-training
|
|
rules:
|
|
- if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
|
|
before_script:
|
|
- mkdir -p ~/.kube
|
|
- echo "$KUBECONFIG_DATA" | base64 -d > ~/.kube/config
|
|
- chmod 600 ~/.kube/config
|
|
environment:
|
|
name: production
|
|
kubernetes:
|
|
namespace: foxhunt
|
|
script:
|
|
# Apply manifests (picks up any config/resource changes)
|
|
- kubectl apply -f infra/k8s/databases/
|
|
- kubectl apply -f infra/k8s/services/
|
|
# Update images to this commit's build
|
|
- |
|
|
for svc in trading-service api-gateway broker-gateway-service ml-training-service backtesting-service trading-agent-service; do
|
|
kubectl -n foxhunt set image deployment/${svc} ${svc}=${REGISTRY}/${svc}:${CI_COMMIT_SHA} || true
|
|
done
|
|
kubectl -n foxhunt set image deployment/web-gateway web-gateway=${REGISTRY}/web-gateway:${CI_COMMIT_SHA} || true
|
|
# Wait for rollouts
|
|
- |
|
|
for svc in trading-service api-gateway broker-gateway-service ml-training-service backtesting-service trading-agent-service web-gateway; do
|
|
kubectl -n foxhunt rollout status deployment/${svc} --timeout=300s || true
|
|
done
|