---
kind: pipeline
type: docker
name: test and lint

trigger:
  branch:
    - main

steps:
  - name: database healthcheck
    image: &postgres 'postgres:17.0-alpine'
    environment:
      PGUSER: &db_user postgres
      PGPASSWORD: &db_pass postgres
      PGHOST: &db_host db
    commands:
      - while ! pg_isready; do sleep 1; done
    depends_on:
      - 'db'

  - name: restore cache
    image: &drone_cache 'meltwater/drone-cache:v1.4.0'
    environment:
      AWS_ACCESS_KEY_ID:
        from_secret: minio_user
      AWS_SECRET_ACCESS_KEY:
        from_secret: minio_password
    settings:
      archive_format: gzip
      bucket: trainlog-cache
      cache_key: '{{ .Repo.Name }}-{{ checksum ".tool-versions" }}-{{ checksum "mix.lock" }}'
      endpoint: minio:9000
      mount:
        - _build
        - deps
      path_style: true
      region: us-east-1
      restore: true
    volumes: &volumes
      - name: app_build
        path: /drone/src/_build
      - name: app_deps
        path: /drone/src/deps

  - name: dependencies and compile
    image: &elixir 'hexpm/elixir:1.17.3-erlang-27.1.2-debian-bookworm-20241016-slim'
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force, deps.get, deps.compile
      - mix compile --force --all-warnings --warnings-as-errors
    volumes: *volumes
    depends_on:
      - 'restore cache'

  - name: test
    image: *elixir
    environment:
      MIX_ENV: test
      POSTGRES_HOST: *db_host
      POSTGRES_USER: *db_user
      POSTGRES_PASS: *db_pass
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force
      - mix test --cover --trace --slowest 10
    volumes: *volumes
    depends_on:
      - 'database healthcheck'
      - 'dependencies and compile'

  - name: audit deps
    image: *elixir
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force
      - mix hex.audit
      - mix deps.audit
      - mix deps.unlock --check-unused
      # - mix hex.outdated
    volumes: *volumes
    depends_on:
      - 'dependencies and compile'

  - name: format check
    image: *elixir
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force
      - mix format --dry-run --check-formatted
    volumes: *volumes
    depends_on:
      - 'dependencies and compile'

  - name: credo check
    image: *elixir
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force
      - mix credo suggest --strict --format=flycheck
    volumes: *volumes
    depends_on:
      - 'dependencies and compile'

  - name: dialyzer check
    image: *elixir
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force
      - mix dialyzer --no-check --quiet --ignore-exit-status --format short
    volumes: *volumes
    depends_on:
      - 'dependencies and compile'

  - name: sobelow check
    image: *elixir
    commands:
      - apt-get update
      - apt-get install -y git make
      - mix do local.rebar --force, local.hex --force
      - mix sobelow
    volumes: *volumes
    depends_on:
      - 'dependencies and compile'

  - name: rebuild cache
    image: *drone_cache
    environment:
      AWS_ACCESS_KEY_ID:
        from_secret: minio_user
      AWS_SECRET_ACCESS_KEY:
        from_secret: minio_password
    settings:
      archive_format: gzip
      bucket: trainlog-cache
      cache_key: '{{ .Repo.Name }}-{{ checksum ".tool-versions" }}-{{ checksum "mix.lock" }}'
      endpoint: minio:9000
      exit_code: true
      mount:
        - _build
        - deps
      path_style: true
      rebuild: true
      region: us-east-1
    volumes: *volumes
    depends_on:
      - 'test'
      - 'audit deps'
      - 'format check'
      - 'credo check'
      - 'dialyzer check'
      - 'sobelow check'

services:
  - name: *db_host
    image: *postgres
    environment:
      POSTGRES_USER: *db_user
      POSTGRES_PASSWORD: *db_pass

volumes:
  - name: app_build
    temp: {}
  - name: app_deps
    temp: {}