stages:
  - build
  - test
  - deploy

static:
  image: node:20-slim
  stage: build
  only:
    - master
  cache:
    key: npm-$CI_COMMIT_REF_SLUG
    paths:
      - "$CI_PROJECT_DIR/.npm-cache"
  before_script:
    - apt update && apt install --yes curl
  script:
    - npm ci --cache .npm-cache --prefer-offline
    - npm run build
  artifacts:
    name: '$CI_JOB_ID-node_modules'
    paths:
      - ./node_modules
      - ./static/build
    expire_in: 2 hours

pip:
  image: python:3.12-slim
  stage: build
  only:
    - master
  variables:
    PIP_CACHE_DIR: $CI_PROJECT_DIR/.pip-cache
  cache:
    key: pip-$CI_COMMIT_REF_SLUG
    paths:
      - "$CI_PROJECT_DIR/.pip-cache"
  before_script:
    - apt-get update --yes
    - apt-get install --yes build-essential libpq-dev git
  script:
    - python -m venv env
    - source env/bin/activate
    - pip install -r dev-requirements.txt
  artifacts:
    name: 'venv-$CI_JOB_ID'
    paths:
      - ./env/
    expire_in: 2 hours

.python_test_template:
  image: python:3.12-slim
  stage: test
  dependencies:
    - pip
  before_script:
    - source env/bin/activate
  variables:
    SECRET_KEY: super-secret

test_python:
  extends: .python_test_template
  services:
    - postgres:14-alpine
  variables:
    POSTGRES_HOST_AUTH_METHOD: trust
    DATABASE_URL: postgres://postgres@postgres/postgres
    TEST: "true"
  script:
    - apt-get update && apt-get install --yes git libpq-dev
    - ./manage.py collectstatic --noinput --clear
    - coverage run ./manage.py test
    - coverage report
    - coverage xml
  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml
  dependencies:
    - pip
    - static

django_checks:
  extends: .python_test_template
  dependencies:
    - pip
    - static
  script:
    - apt-get update && apt-get install --yes libpq-dev
    - ./manage.py collectstatic --noinput --clear
    - ./manage.py check
    - ./manage.py makemigrations --check --noinput

black:
  extends: .python_test_template
  script:
    - black --check .

ruff:
  extends: .python_test_template
  script:
    - ruff check .

mypy:
  extends: .python_test_template
  script:
    - mypy .

djlint:
  extends: .python_test_template
  script:
    - djlint website/ --lint --check

npm_lint:
  image: node:20-slim
  stage: test
  dependencies:
    - static
  script:
    - npm run lint

crontab:
  image: alpine
  stage: test
  dependencies: []
  before_script:
    - apk add --no-cache supercronic
  script:
    - supercronic -test etc/crontab

container:
  image: docker:stable
  services:
    - docker:dind
  variables:
    DEV_IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    PROD_IMAGE_TAG: $CI_REGISTRY_IMAGE:latest
    DOCKER_BUILDKIT: 1
  dependencies: []
  stage: deploy
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build --target production -t $DEV_IMAGE_TAG -t $PROD_IMAGE_TAG .
    - docker push $CI_REGISTRY_IMAGE