stages:
  - build
  - test
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""
  REGISTRY: $CI_REGISTRY
  API_IMAGE: $CI_REGISTRY_IMAGE/api
  WORKER_IMAGE: $CI_REGISTRY_IMAGE/worker
  DASHBOARD_IMAGE: $CI_REGISTRY_IMAGE/dashboard

# Cache node_modules between jobs
.node_cache: &node_cache
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
      - apps/wcag-ada/*/node_modules/
      - .bun/

# Docker login before each job
before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

# Build stage
build:api:
  stage: build
  image: docker:24-dind
  services:
    - docker:24-dind
  script:
    - docker build -f apps/wcag-ada/api/Dockerfile -t $API_IMAGE:$CI_COMMIT_SHA .
    - docker tag $API_IMAGE:$CI_COMMIT_SHA $API_IMAGE:latest
    - docker push $API_IMAGE:$CI_COMMIT_SHA
    - docker push $API_IMAGE:latest
  only:
    - main
    - develop
    - merge_requests
  tags:
    - docker

build:worker:
  stage: build
  image: docker:24-dind
  services:
    - docker:24-dind
  script:
    - docker build -f apps/wcag-ada/worker/Dockerfile -t $WORKER_IMAGE:$CI_COMMIT_SHA .
    - docker tag $WORKER_IMAGE:$CI_COMMIT_SHA $WORKER_IMAGE:latest
    - docker push $WORKER_IMAGE:$CI_COMMIT_SHA
    - docker push $WORKER_IMAGE:latest
  only:
    - main
    - develop
    - merge_requests
  tags:
    - docker

build:dashboard:
  stage: build
  image: docker:24-dind
  services:
    - docker:24-dind
  script:
    - docker build -f apps/wcag-ada/dashboard/Dockerfile -t $DASHBOARD_IMAGE:$CI_COMMIT_SHA .
    - docker tag $DASHBOARD_IMAGE:$CI_COMMIT_SHA $DASHBOARD_IMAGE:latest
    - docker push $DASHBOARD_IMAGE:$CI_COMMIT_SHA
    - docker push $DASHBOARD_IMAGE:latest
  only:
    - main
    - develop
    - merge_requests
  tags:
    - docker

# Test stage
test:unit:
  stage: test
  image: oven/bun:1-alpine
  <<: *node_cache
  before_script:
    - cd apps/wcag-ada
    - bun install
  script:
    - bun test
  only:
    - merge_requests
  tags:
    - docker

test:lint:
  stage: test
  image: oven/bun:1-alpine
  <<: *node_cache
  before_script:
    - cd apps/wcag-ada
    - bun install
  script:
    - bun run lint
  only:
    - merge_requests
  tags:
    - docker

test:typecheck:
  stage: test
  image: oven/bun:1-alpine
  <<: *node_cache
  before_script:
    - cd apps/wcag-ada
    - bun install
  script:
    - bun run typecheck
  only:
    - merge_requests
  tags:
    - docker

# Deploy to staging
deploy:staging:
  stage: deploy
  image: bitnami/kubectl:latest
  before_script:
    - kubectl config set-cluster k8s --server="$KUBE_URL" --insecure-skip-tls-verify=true
    - kubectl config set-credentials gitlab --token="$KUBE_TOKEN"
    - kubectl config set-context default --cluster=k8s --user=gitlab
    - kubectl config use-context default
  script:
    - kubectl apply -f apps/wcag-ada/k8s/namespace.yaml
    - kubectl apply -f apps/wcag-ada/k8s/configmap.yaml
    - kubectl apply -f apps/wcag-ada/k8s/secrets.yaml
    - kubectl apply -f apps/wcag-ada/k8s/postgres.yaml
    - kubectl apply -f apps/wcag-ada/k8s/redis.yaml
    - |
      kubectl set image deployment/wcag-ada-api api=$API_IMAGE:$CI_COMMIT_SHA -n wcag-ada
      kubectl set image deployment/wcag-ada-worker worker=$WORKER_IMAGE:$CI_COMMIT_SHA -n wcag-ada
      kubectl set image deployment/wcag-ada-dashboard dashboard=$DASHBOARD_IMAGE:$CI_COMMIT_SHA -n wcag-ada
    - kubectl rollout status deployment/wcag-ada-api -n wcag-ada
    - kubectl rollout status deployment/wcag-ada-worker -n wcag-ada
    - kubectl rollout status deployment/wcag-ada-dashboard -n wcag-ada
  environment:
    name: staging
    url: https://staging.wcag-ada.example.com
  only:
    - develop
  tags:
    - docker

# Deploy to production
deploy:production:
  stage: deploy
  image: bitnami/kubectl:latest
  before_script:
    - kubectl config set-cluster k8s --server="$KUBE_URL_PROD" --insecure-skip-tls-verify=true
    - kubectl config set-credentials gitlab --token="$KUBE_TOKEN_PROD"
    - kubectl config set-context default --cluster=k8s --user=gitlab
    - kubectl config use-context default
  script:
    - kubectl apply -f apps/wcag-ada/k8s/namespace.yaml
    - kubectl apply -f apps/wcag-ada/k8s/configmap.yaml
    - kubectl apply -f apps/wcag-ada/k8s/secrets.yaml
    - kubectl apply -f apps/wcag-ada/k8s/postgres.yaml
    - kubectl apply -f apps/wcag-ada/k8s/redis.yaml
    - |
      kubectl set image deployment/wcag-ada-api api=$API_IMAGE:$CI_COMMIT_SHA -n wcag-ada
      kubectl set image deployment/wcag-ada-worker worker=$WORKER_IMAGE:$CI_COMMIT_SHA -n wcag-ada
      kubectl set image deployment/wcag-ada-dashboard dashboard=$DASHBOARD_IMAGE:$CI_COMMIT_SHA -n wcag-ada
    - kubectl rollout status deployment/wcag-ada-api -n wcag-ada
    - kubectl rollout status deployment/wcag-ada-worker -n wcag-ada
    - kubectl rollout status deployment/wcag-ada-dashboard -n wcag-ada
  environment:
    name: production
    url: https://wcag-ada.example.com
  only:
    - main
  when: manual
  tags:
    - docker