image: python:3.13 stages: - lint - test - deploy variables: UV_CACHE_DIR: "$CI_PROJECT_DIR/.uv-cache" cache: paths: - .uv-cache/ .uv_setup: &uv_setup - curl -LsSf https://astral.sh/uv/install.sh | sh - export PATH="$HOME/.cargo/bin:$PATH" - source $HOME/.local/bin/env workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_TAG lint: stage: lint before_script: - *uv_setup script: - uv sync - uv run ruff check . test:cli: stage: test before_script: - *uv_setup script: - uv sync - uv run pytest tests/ -v --cov=src/materia --cov-report=xml --cov-report=term coverage: '/TOTAL.*\s+(\d+%)$/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage.xml test:sqlmesh: stage: test before_script: - *uv_setup script: - uv sync - cd transform/sqlmesh_materia && uv run sqlmesh test deploy:infra: stage: deploy image: pulumi/pulumi:latest before_script: - pulumi login --token ${PULUMI_ACCESS_TOKEN} script: - cd infra - pulumi stack select prod - pulumi up --yes rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH deploy:supervisor: stage: deploy image: alpine:latest before_script: - apk add --no-cache openssh-client curl bash - curl -fsSL https://get.pulumi.com/esc/install.sh | sh - export PATH="$HOME/.pulumi/bin:$PATH" - esc login --token ${PULUMI_ACCESS_TOKEN} - eval $(esc env open beanflows/prod --format shell) # Install Pulumi CLI to get stack outputs - | apk add --no-cache pulumi-bin || { curl -fsSL https://get.pulumi.com/install.sh | sh export PATH="$HOME/.pulumi/bin:$PATH" } - pulumi login --token ${PULUMI_ACCESS_TOKEN} script: - | # Get supervisor IP from Pulumi cd infra SUPERVISOR_IP=$(pulumi stack output supervisor_ip -s prod) cd .. # Check if supervisor exists if [ -z "$SUPERVISOR_IP" ] || [ "$SUPERVISOR_IP" = "null" ]; then echo "No supervisor instance found. Run 'pulumi up' first." exit 1 fi echo "Deploying to supervisor at ${SUPERVISOR_IP}..." # Setup SSH mkdir -p ~/.ssh echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -H $SUPERVISOR_IP >> ~/.ssh/known_hosts # Check if supervisor is bootstrapped if ssh -o ConnectTimeout=10 root@${SUPERVISOR_IP} "test -d /opt/materia/repo/.git"; then echo "Supervisor already bootstrapped, triggering update..." # Just signal supervisor to pull latest - it will do so on next check cycle ssh root@${SUPERVISOR_IP} "systemctl is-active materia-supervisor || echo 'Service not running, may need bootstrap'" else echo "Supervisor not bootstrapped yet. Run bootstrap script:" echo " export PULUMI_ACCESS_TOKEN=\${PULUMI_ACCESS_TOKEN}" echo " ssh root@${SUPERVISOR_IP} 'bash -s' < infra/bootstrap_supervisor.sh" fi dependencies: - deploy:infra rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH