image: python:3.13 stages: - test - tag 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 - source $HOME/.local/bin/env workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # ── Tests ───────────────────────────────────────────────────────────────────── test:cli: stage: test before_script: - *uv_setup script: - uv sync --all-packages - uv run pytest tests/ test:sqlmesh: stage: test before_script: - *uv_setup script: - uv sync --all-packages - cd transform/sqlmesh_materia && uv run sqlmesh test test:web: stage: test before_script: - *uv_setup script: - uv sync --all-packages - cd web && uv run pytest tests/ -x -q - uv run ruff check . # ── Tag (pull-based deploy) ─────────────────────────────────────────────────── # Creates v tag after all tests pass. The on-server supervisor polls for new # tags every 60s and deploys automatically. No SSH keys or deploy credentials # needed in CI — only the built-in CI_JOB_TOKEN. tag: stage: tag image: alpine:latest before_script: - apk add --no-cache git script: - git tag "v${CI_PIPELINE_IID}" - git push "https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "v${CI_PIPELINE_IID}" rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH