#
# To check this script syntax: https://gricad-gitlab.univ-grenoble-alpes.fr/CamiTK/CamiTK/-/ci/lint
#
# ------------------------
# Triggering the pipeline
# ------------------------
#
# There are two ways to run the pipeline:
# - call the REST web API using "curl"
# - add special flags to the commit messages
#
# When called from the API, the following variables may be set:
# CAMITK_CI_MODE  Continuous integration mode: can be Nightly, Continuous or Experimental (default is Experimental)
# CAMITK_CI_STAGE Stage to perform, see stage enum values below (default is 0, no job will be performed).
# If CAMITK_CI_STAGE is passed as a variable, all the jobs that correspond to the given CAMITK_CI_STAGE
# value (i.e., all the stage that have a lower or equal values) are performed.
#
# If a special flag (/check, /configure, /build, /test or /coverage) is present in the commit message 
# then the corresponding job is performed, otherwise it is skipped unless
# the CAMITK_CI_STAGE is given. In this case all the jobs that correspond to the given CAMITK_CI_STAGE
# value (i.e., all the stage that have a lower or equal values) are performed.
#
# --------------------------------------------------------
# .gitlab-ci.yml specification and implementation details
# --------------------------------------------------------
#
# This script declares different jobs for
# - different stages (check, configure, ...) 
# - different OS (debian stable, ubuntu LTS, ...)
#
# For all the stages from configure to coverage, everything is submitted to the cdash dashboard
# thanks to the sdk/cmake/ctest/ci-*.cmake macros
# The jobs will appear on the dashboard as 
# - Site "[Gitlab Runner] name of the OS"
# - Build name "compiler-arch-buildtype string SPACE name of the branch SPACE git abbreviated hash"
#
# ${PROJECT_BUILD_DIR} should be mounted on the container.
#
# As the job log might exceed the limit fixed by gitlab (500k lines), all log are recorded in a specific log/stage-name.log file
# When the log should not exceed the limit (as in the configure stage for instance), the log is also redirected to stdout
# so that the job results can be checked as it is running. 
# In any case, the job is available as an artifact and can be downloaded for 7 days.
# For the coverage stage, the artifact also contains the lcov generated web site.
#
# In order to reuse yaml code, three coding convention are used for YAML anchors:
# ".define_os" is used to define specific OS configuration
# ".define_script" is used to define specific script parts for a job and can be reused for different OS
# ".define_config" is used to define other specific parts for a job and can be reused for different job and different OS
#
# Nightly build clear the build/ directory automatically.
#
variables:
  # project name
  PROJECT_NAME:       "$CI_PROJECT_NAME"
  # path to CamiTK code source directory
  PROJECT_SOURCE_DIR: "$CI_PROJECT_DIR"
  # Stage enum to pass to the web API call
  STAGE_NONE:             0  # no job to run
  STAGE_CHECK:           10  # "/check" in commit message
  STAGE_CONFIGURE:       20  # "/configure" in commit message
  STAGE_BUILD:           30  # "/build" in commit message
  STAGE_TEST:            40  # "/test" in commit message
  STAGE_COVERAGE:        50  # "/coverage" in commit message
  STAGE_STATIC_ANALYSIS: 60
  STAGE_PACKAGE:         70
  STAGE_DEPLOY:          80
  # When using dind, it's wise to use the overlayfs driver for
  # improved performance. See https://docs.gitlab.com/ee/ci/docker/using_docker_build.html
  DOCKER_DRIVER: overlay2

stages:
  - check
  - configure
  - build
  - test
  - coverage

      
# -------------------------------------
#          trigger config
# -------------------------------------

.define_config: &triggered_by_api_call
  only:
    - triggers

.define_config: &triggered_by_schedules
  only:
    - schedules    

.define_config: &triggered_by_api_call_and_schedules
  only:
    - triggers
    - schedules    

# -------------------------------------
#    before script and tag
# -------------------------------------

.define_config: &default_job_config
  before_script:
    # use Linux before script
    - .gitlab/before.sh
  # uncomment next line if you want ci scripts to only be triggered by specific api call
  # <<: *triggered_by_api_call_and_schedules

# -------------------------------------
#              scripts
# -------------------------------------
.define_script: &check_pipeline_script
  stage: check
  script:
    # use Linux check script
    - .gitlab/check.sh

.define_script: &configure_script
  stage: configure
  script:
    # use Linux configure script
    - .gitlab/configure.sh

.define_script: &build_script
  stage: build
  script:
    # use Linux build script
    - .gitlab/build.sh

.define_script: &test_script
  stage: test
  script:
    # use Linux test script
    - .gitlab/test.sh

.define_script: &coverage_script
  stage: coverage
  script:
    # use Linux coverage script
    - .gitlab/coverage.sh

# -------------------------------------
#          artifacts config
# -------------------------------------

.define_config: &configure_artifacts
  artifacts:
    paths: 
    - ${PROJECT_LOG_DIR}/configure.log
    when: always
    expire_in: 7 days # 5 mins  # see https://docs.gitlab.com/ce/ci/yaml/README.html#artifacts-expire_in
    
.define_config: &build_artifacts
  artifacts:
    paths: 
    - ${PROJECT_LOG_DIR}/build.log
    when: always
    expire_in: 7 days 

.define_config: &test_artifacts
  artifacts:
    paths: 
    - ${PROJECT_LOG_DIR}/test.log
    - ${PROJECT_LOG_DIR}/ci-test.log
    when: always
    expire_in: 7 days 

.define_config: &coverage_artifacts
  artifacts:
    paths: 
    - ${PROJECT_LOG_DIR}/coverage.log
    - ${PROJECT_LOG_DIR}/camitk-ce-test-coverage/
    when: always
    expire_in: 7 days

# -------------------------------------
#         debian stable jobs
# -------------------------------------

.define_os: &debian_stable_image
  # The default image "debian:stable" from docker.io does not have all the build toolchain and dependencies
  # → use custom build local image: camitk/debian:stable-camitk 
  image: camitk/debian:stable-camitk
  variables:
    # OS Id
    OS: "debian-stable"
    # the name of the current machine 
    CDASH_SITE: "[Gitlab Runner] Debian stable"
    # compiler-arch-buildtype string
    COMPILER_CONFIG: "GCC-64bits-Debug"
    # path to the intended build directory
    PROJECT_BUILD_DIR: "/opt/build/${OS}-${CI_COMMIT_REF_SLUG}"
    # path to the intended log directory (cannot be an absolute path)
    PROJECT_LOG_DIR: "${OS}-${CI_COMMIT_REF_SLUG}/log"
  tags:
    - debian:stable

debian_stable_check:
  <<: *debian_stable_image
  <<: *default_job_config
  <<: *check_pipeline_script

debian_stable_configure:
  <<: *debian_stable_image
  <<: *default_job_config
  <<: *configure_artifacts
  <<: *configure_script

debian_stable_build:
  <<: *debian_stable_image
  <<: *default_job_config
  <<: *build_artifacts
  <<: *build_script

debian_stable_test:
  <<: *debian_stable_image
  <<: *default_job_config
  <<: *test_artifacts
  <<: *test_script

debian_stable_coverage:
  <<: *debian_stable_image
  <<: *default_job_config
  <<: *coverage_artifacts
  <<: *coverage_script
  coverage: '/  lines......: \d+\.\d+/'

 
# -------------------------------------
#         ubuntu LTS jobs
# -------------------------------------
.define_os: &ubuntu_lts_image
  # The default image "ubuntu:latest" from docker.io does not have all the build toolchain and dependencies
  # → use custom build local image: camitk/ubuntu:lts-camitk 
  image: camitk/ubuntu:lts-camitk
  variables:
    # OS Id
    OS: "ubuntu-lts"
    # the name of the current machine 
    CDASH_SITE: "[Gitlab Runner] Ubuntu LTS"
    # compiler-arch-buildtype string
    COMPILER_CONFIG: "GCC-64bits-Debug"
    # path to the intended build directory
    PROJECT_BUILD_DIR: "/opt/build/${OS}-${CI_COMMIT_REF_SLUG}"
    # path to the intended log directory (cannot be an absolute path)
    PROJECT_LOG_DIR: "${OS}-${CI_COMMIT_REF_SLUG}/log"
    # debug for now
    #CI_DEBUG_TRACE: "true"
  tags:
    - ubuntu:lts

ubuntu_lts_check:
  <<: *ubuntu_lts_image
  <<: *default_job_config
  <<: *check_pipeline_script

ubuntu_lts_configure:
  <<: *ubuntu_lts_image
  <<: *default_job_config
  <<: *configure_artifacts
  <<: *configure_script

ubuntu_lts_build:
  <<: *ubuntu_lts_image
  <<: *default_job_config
  <<: *build_artifacts
  <<: *build_script

ubuntu_lts_test:
  <<: *ubuntu_lts_image
  <<: *default_job_config
  <<: *test_artifacts
  <<: *test_script

ubuntu_lts_coverage:
  <<: *ubuntu_lts_image
  <<: *default_job_config
  <<: *coverage_artifacts
  <<: *coverage_script
  # on Ubuntu:
  coverage: '/  Percentage Coverage: \d+\.\d+/'

# -------------------------------------
#         debian oldstable jobs
# -------------------------------------

.define_os: &debian_oldstable_image
  # The default image "debian:oldstable" from docker.io does not have all the build toolchain and dependencies
  # → use custom build local image: camitk/debian:oldstable-camitk 
  image: camitk/debian:oldstable-camitk
  variables:
    # OS Id
    OS: "debian-oldstable"
    # the name of the current machine 
    CDASH_SITE: "[Gitlab Runner] Debian old stable"
    # compiler-arch-buildtype string
    COMPILER_CONFIG: "GCC-64bits-Debug"
    # path to the intended build directory
    PROJECT_BUILD_DIR: "/opt/build/${OS}-${CI_COMMIT_REF_SLUG}"
    # path to the intended log directory (cannot be an absolute path)
    PROJECT_LOG_DIR: "${OS}-${CI_COMMIT_REF_SLUG}/log"
  tags:
    - debian:oldstable

debian_oldstable_check:
  <<: *debian_oldstable_image
  <<: *default_job_config
  <<: *check_pipeline_script

debian_oldstable_configure:
  <<: *debian_oldstable_image
  <<: *default_job_config
  <<: *configure_artifacts
  <<: *configure_script

debian_oldstable_build:
  <<: *debian_oldstable_image
  <<: *default_job_config
  <<: *build_artifacts
  <<: *build_script

debian_oldstable_test:
  <<: *debian_oldstable_image
  <<: *default_job_config
  <<: *test_artifacts
  <<: *test_script

debian_oldstable_coverage:
  <<: *debian_oldstable_image
  <<: *default_job_config
  <<: *coverage_artifacts
  <<: *coverage_script
  coverage: '/  lines......: \d+\.\d+/'


# -------------------------------------
#         win7 jobs
# -------------------------------------

.define_os: &win7_config
  # on windows the executor is just a shell (not a docker)
  variables:
    # OS Id
    OS: "win7"
    # the name of the current machine 
    CDASH_SITE: "[Gitlab Runner] Win7"
    # compiler-arch-buildtype string (Ninja would be better instead of MSVC2015 to speed up compilation on VM)
    COMPILER_CONFIG: "MSVC2015-64bits-Debug"
    # path to the intended build directory
    PROJECT_BUILD_DIR: "/c/dev/gitlab-runner/builds/${OS}-${CI_COMMIT_REF_SLUG}"
    # path to the intended log directory (cannot be an absolute path)
    PROJECT_LOG_DIR: "${OS}-${CI_COMMIT_REF_SLUG}/log"
  tags:
    - win7

win7_check:
  <<: *win7_config
  <<: *default_job_config
  <<: *check_pipeline_script

win7_configure:
  <<: *win7_config
  <<: *default_job_config
  <<: *configure_artifacts
  <<: *configure_script
  
win7_build:
  <<: *win7_config
  <<: *default_job_config
  <<: *build_artifacts
  <<: *build_script

win7_test:
  <<: *win7_config
  <<: *default_job_config
  <<: *test_artifacts
  <<: *test_script
