workflow:
   rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: never
    - when: always

# Functions that should be executed before the build script is run

variables:
  HELM_VERSION: "3.9.3"
  IMAGE_NAME: "df-wiki"
  # dev
  HOST_DEV: 'defense-finder.dev.pasteur.cloud'
  MEILI_HOST_DEV: 'defense-finder-meilisearch.dev.pasteur.cloud'
  # prod
  HOST_PROD: 'defense-finder.pasteur.cloud'
  MEILI_HOST_PROD: 'defense-finder-meilisearch.pasteur.cloud'


cache:
  paths:
    - node_modules/
    - .output/public
    

stages:
  - delete-release
  - build-df-cli
  - get-data
  - deploy-meilisearch
  - update-meilisearch-indexes
  - get-meili-key
  - build
  - deploy


.docker-login: &docker-login
  - i=0; while [ "$i" -lt 12 ]; do docker info && break; sleep 5; i=$(( i + 1 )) ; done
  - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY



# Build df-wiki-cli package


build:df-wiki-cli:
  stage: build-df-cli
  image: python:3.11-bullseye
  before_script:
    - cd packages/df-wiki-cli/
    - pip install poetry
    - poetry install
    - source `poetry env info --path`/bin/activate

  script:
    - echo "This is the build stage"
    - poetry config repositories.gitlab "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi"
    - poetry config http-basic.gitlab gitlab-ci-token "$CI_JOB_TOKEN"
    - echo "Repository gitlab configured ..."
    - poetry build
    - echo "Build done ..."
    - poetry publish --repository gitlab --skip-existing
    - echo "Publishing done!"
  rules:
    - changes:
      - packages/df-wiki-cli/**/*.{py, toml} # ... or whatever your file extension is
  allow_failure: true
################ DEPLOY MEILISEARCH #################

.deploy:meilisearch:
  stage: deploy-meilisearch
  image: harbor.pasteur.fr/kube-system/helm-kubectl:$HELM_VERSION
  variables:
    CI_DEBUG_TRACE: "false"
    ENV: development
  before_script:
    - helm dependency update deploy/meilisearch/ 
  script: 
    - >
      helm upgrade --install 
      ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}-meilisearch 
      ./deploy/meilisearch 
      --namespace=${KUBE_NAMESPACE}
      --set meilisearch.ingress.hosts[0]=${PUBLIC_URL}
      --set meilisearch.environment.MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
      --set meilisearch.environment.MEILI_ENV=${ENV:-development}
      --set env=${ENV:-development}
      --values deploy/meilisearch/values.yaml
      --values deploy/meilisearch/values.${ENV:-development}.yaml
    # wait for it to start
    - MEILI_POD=$(kubectl -n=${KUBE_NAMESPACE} get po -l app.kubernetes.io\/instance=${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}-meilisearch,app.kubernetes.io\/name=meilisearch --output jsonpath='{.items[0].metadata.name}')
    - |
      until kubectl -n=${KUBE_NAMESPACE} wait --for=condition=ready pod ${MEILI_POD} --timeout=1s
      do
        date
        sleep 1
        kubectl -n=${KUBE_NAMESPACE} get po
      done


deploy:meilisearch:dev:
  extends: .deploy:meilisearch
  rules:
    - if: $CI_COMMIT_BRANCH != "main"
  variables:
    CI_DEBUG_TRACE: "true"
    ENV: "development"
    PUBLIC_URL: "$MEILI_HOST_DEV"
    KUBE_NAMESPACE: "defense-finder-dev"

  environment:
      name: k8sdev-01
      url: "https://${MEILI_HOST_DEV}"


deploy:meilisearch:prod:
  extends: .deploy:meilisearch
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  variables:
    CI_DEBUG_TRACE: "false"
    ENV: "production"
    PUBLIC_URL: $MEILI_HOST_PROD
    KUBE_NAMESPACE: "defense-finder-prod"
  environment:
      name: k8sprod-02
      url: "https://${MEILI_HOST_PROD}"




delete-meili-helm-release:
  rules:
    - if: $CI_COMMIT_BRANCH != "main"
  stage: delete-release
  when: manual
  image: harbor.pasteur.fr/kube-system/helm-kubectl:$HELM_VERSION
  variables:
    GIT_STRATEGY: none # important to not checkout source when branch is deleted
    NAMESPACE: "defense-finder-dev"
  environment:
    name: "k8sdev-01"
    action: stop
  script:
    - echo "Removing $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME-meilisearch"
    - helm delete -n ${NAMESPACE} ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}-meilisearch 


delete-meili-helm-release:prod:
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  stage: delete-release
  when: manual
  image: harbor.pasteur.fr/kube-system/helm-kubectl:$HELM_VERSION
  variables:
    GIT_STRATEGY: none # important to not checkout source when branch is deleted
    NAMESPACE: "defense-finder-prod"
  environment:
    name: "k8sprod-02"
    action: stop
  script:
    - echo "Removing $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME-meilisearch"
    - helm delete -n ${NAMESPACE} ${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}-meilisearch 


# Update Meili search indexes

.update-meilisearch-index:
  stage: update-meilisearch-indexes
  image: python:3.11-bullseye
  variables:
    MEILI_HOST: "http://localhost:7700"
  before_script:
    - pip install df-wiki-cli --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.pasteur.fr/api/v4/projects/5222/packages/pypi/simple
  script:
    - >
      df-wiki-cli
      meilisearch 
      --host ${MEILI_HOST} 
      --key ${MEILI_MASTER_KEY}
      update
      --file data/refseq_res.csv
      --document refseq
    - >
      df-wiki-cli
      meilisearch 
      --host ${MEILI_HOST} 
      --key ${MEILI_MASTER_KEY}
      update
      --file data/all_predictions_statistics.csv
      --document structure

update-meilisearch-index:dev:
  rules:
    - if: $CI_COMMIT_BRANCH != "main"
  extends: .update-meilisearch-index
  needs: 
    - deploy:meilisearch:dev
  variables:
    MEILI_HOST: "https://${MEILI_HOST_DEV}"


update-meilisearch-index:prod:
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  extends: .update-meilisearch-index
  needs: 
    - deploy:meilisearch:prod
  variables:
    MEILI_HOST: "https://${MEILI_HOST_PROD}"

############# get-meili-key ###############

.set-meili-env:
  image: python:3.11-bullseye
  stage: get-meili-key
  variables:
    MEILI_HOST: "http://localhost:7700"
  before_script:
    - pip install df-wiki-cli --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.pasteur.fr/api/v4/projects/5222/packages/pypi/simple
  script:
    - > 
      df-wiki-cli 
      meilisearch 
      --key "${MEILI_MASTER_KEY}" 
      --host ${MEILI_HOST} 
      get-env-var
      --output build.env
  artifacts:
      reports:
        dotenv: build.env


set-meili-env:dev:
  extends: .set-meili-env
  needs: 
    - deploy:meilisearch:dev
  variables:
    MEILI_HOST: "https://${MEILI_HOST_DEV}"
  rules:
    - if: $CI_COMMIT_BRANCH != "main"  

set-meili-env:prod:
  extends: .set-meili-env
  variables:
    MEILI_HOST: "https://${MEILI_HOST_PROD}"
  rules:
    - if: $CI_COMMIT_BRANCH == "main"  

##############################
get-zotero:
  image: python:3.11-bullseye
  stage: get-data
  before_script:
    - pip install df-wiki-cli --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.pasteur.fr/api/v4/projects/5222/packages/pypi/simple
  script:
    - df-wiki-cli articles --key ${ZOTERO_API_KEY} --output public/articles.json
  artifacts:
    paths:
      - public/articles.json
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

get-pfam:
  image: python:3.11-bullseye
  stage: get-data
  before_script:
    - pip install df-wiki-cli --index-url https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.pasteur.fr/api/v4/projects/5222/packages/pypi/simple
  script:
    - df-wiki-cli pfam --output public/pfam-a-hmm.csv
  artifacts:
    paths:
      - public/pfam-a-hmm.csv
  # rules:
  #   - if: $CI_COMMIT_BRANCH == "main"



################ BUILD ##########################

.build:
  stage: build
  image: docker:24
  variables:
    CONTEXT: "."
    DOCKERFILE: "Dockerfile"
    BASE_URL: /wiki/
    MEILI_HOST: "http://localhost:7700"
  before_script:
    - *docker-login
  script:
    - >
      docker buildx build --pull -t "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA" 
      --build-arg "BASE_URL=$BASE_URL" 
      --build-arg "MEILI_HOST=$MEILI_HOST" 
      --build-arg "MEILI_API_KEY=$MEILI_API_KEY" 
      -f $DOCKERFILE $CONTEXT
    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA"



build:dev:wiki:
  extends: .build
  needs:
    - set-meili-env:dev
    - get-pfam
  variables:
    BASE_URL: /wiki/
  rules:
    - if: $CI_COMMIT_BRANCH != "main"  


build:prod:wiki:
  extends: .build
  needs:
    - set-meili-env:prod
    - get-zotero
    - get-pfam
  variables:
    BASE_URL: /wiki/
  rules:
    - if: $CI_COMMIT_BRANCH == "main"  


################ DEPLOY ##########################
.deploy:
  stage: deploy
  image: harbor.pasteur.fr/kube-system/helm-kubectl:$HELM_VERSION
  variables:
    CI_DEBUG_TRACE: "false"
    TEAM_ID: "df"
  script:
    - >
      helm upgrade --install $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME ./deploy/df-wiki --namespace=${KUBE_NAMESPACE}
      --set registry.image=${CI_REGISTRY_IMAGE}
      --set registry.username=${DEPLOY_USER}
      --set registry.password=${DEPLOY_TOKEN}
      --set registry.host=${CI_REGISTRY}
      --set ingress.hosts[0].host="${PUBLIC_URL}"
      --set imagePullSecrets[0].name="registry-pull-secret-${CI_COMMIT_REF_SLUG}"
      --set image.repository="$CI_REGISTRY_IMAGE/$IMAGE_NAME"
      --set image.tag="$CI_COMMIT_SHORT_SHA"
      --set env="${ENV:-development}"
      --values deploy/df-wiki/values.yaml
      --values deploy/df-wiki/values.${ENV:-development}.yaml

deploy:dev:
  extends: .deploy
  rules:
    - if: $CI_COMMIT_BRANCH != "main"
  needs:
    - "build:dev:wiki"
  when: manual
  variables:
    NODE_ENV: "development"
    KUBE_NAMESPACE: "defense-finder-dev"
    PUBLIC_URL: "${HOST_DEV}"
    CI_DEBUG_TRACE: "true"
    ENV: "development"
  environment:
    name: k8sdev-01
    url: "https://${HOST_DEV}"


deploy:prod:
  extends: .deploy
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  needs:
    - "build:prod:wiki"
  when: manual
  variables:
    NODE_ENV: "production"
    KUBE_NAMESPACE: "defense-finder-prod"
    PUBLIC_URL: "${HOST_PROD}"
    CI_DEBUG_TRACE: "false"
    ENV: "production"
  environment:
    name: k8sprod-02
    url: "https://${HOST_PROD}"

delete-helm-release:dev:
  rules:
    - if: $CI_COMMIT_BRANCH != "main"
  stage: delete-release
  when: manual
  image: harbor.pasteur.fr/kube-system/helm-kubectl:$HELM_VERSION
  variables:
    GIT_STRATEGY: none # important to not checkout source when branch is deleted
    NAMESPACE: "defense-finder-dev"
  environment:
    name: "k8sdev-01"
    action: stop
  script:
    - echo "Removing $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME"
    - helm delete -n ${NAMESPACE} $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME

delete-helm-release:prod:
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  stage: delete-release
  when: manual
  image: harbor.pasteur.fr/kube-system/helm-kubectl:$HELM_VERSION
  variables:
    GIT_STRATEGY: none # important to not checkout source when branch is deleted
    NAMESPACE: "defense-finder-prod"
  environment:
    name: "k8sprod-02"
    action: stop
  script:
    - echo "Removing $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME"
    - helm delete -n ${NAMESPACE} $CI_PROJECT_NAME-$CI_ENVIRONMENT_NAME
