################################################################################
# Gitlab CI YAML configuration file
################################################################################

################################################################################
# Global definitions

image: debian:testing

# Our general workflow rules, see relevant documentation here:
# https://docs.gitlab.com/ee/ci/pipelines/merge_request_pipelines.html
# https://docs.gitlab.com/ee/ci/yaml/#rules
#
# We also run everything for schedules (which you can't tell from looking
# at these rule alone).
workflow:
  rules:
    # run merge request pipelines
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    # do not run branch pipelines if corresponding merge requests exist...
    # (this avoids duplicate pipelines)
    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never
    # ...but otherwise run branch pipelines
    - if: '$CI_COMMIT_BRANCH'
    # run tag pipelines
    - if: '$CI_COMMIT_TAG'

# A few jobs are only supposed to run either on demand, on schedule (i.e.
# weekly) or on tag (i.e. release).
.run_ondemand_schedule_tag: &run_ondemand_schedule_tag
  - if: '$CI_PIPELINE_SOURCE == "schedule"'
  - if: '$CI_COMMIT_TAG'
  - when: manual

stages:
  - prepare
  - dependencies
  - siril
  - packaging
  - distribution
  - analysis

variables:
  GIT_DEPTH: "1"
  IMAGE_TAG: "${CI_COMMIT_REF_SLUG}"
  BUILD_DIR: "_build"
  INSTALL_DIR: "siril"
  INSTALL_PREFIX: "${CI_PROJECT_DIR}/${INSTALL_DIR}"
  CROSSROAD_OUT: "crossroad-out"
  APT_CACHE: "$CI_PROJECT_DIR/apt-cache"

################################################################################
# Prepare Dockers images

# Image for GNU/Linux build
build-image:
  stage: prepare
  cache: {}
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context build/build-image/ --dockerfile build/build-image/Dockerfile.debian-latest --destination $CI_REGISTRY_IMAGE/$IMAGE_TAG:build-debian-latest --cache=true --cache-ttl=120h

# Image for GNU/Linux build
build-image-oldstable:
  stage: prepare
  cache: {}
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context build/build-image/ --dockerfile build/build-image/Dockerfile.debian-oldstable --destination $CI_REGISTRY_IMAGE/$IMAGE_TAG:build-debian-oldstable --cache=true --cache-ttl=120h

################################################################################
# GNU/Linux 64-bit CIs

# Currently Siril does not need dependency compilation, so we can skip that.
deps-debian:
  stage: dependencies
  image: $CI_REGISTRY_IMAGE/$IMAGE_TAG:build-debian-latest
  cache:
    paths:
    - apt-cache
  artifacts:
    expire_in: 2 hours
    when: always
    paths:
    - "${INSTALL_DIR}"
    - _Criterion/_build
  before_script:
    - git clone --recurse-submodules --depth=1 -b bleeding https://github.com/Snaipe/Criterion.git _Criterion
    - export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/pkgconfig"
    - export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/`gcc -print-multiarch`/pkgconfig/:$PKG_CONFIG_PATH"
    - export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}"
    - export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib/`gcc -print-multiarch`:$LD_LIBRARY_PATH"
    - export XDG_DATA_DIRS="${INSTALL_PREFIX}/share:/usr/local/share:/usr/share"
  script:
    - cd _Criterion
    - patch --binary -p1 < ../build/criterion.patch
    - meson setup _build --prefix ${INSTALL_PREFIX}
    - ninja -C _build install
  needs: ["build-image"]

.siril-debian/testing-base:
  stage: siril
  image: $CI_REGISTRY_IMAGE/$IMAGE_TAG:build-debian-latest
  dependencies:
    - deps-debian
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  cache:
    paths:
      - apt-cache
  artifacts:
    expire_in: 1 week
    when: always
    name: "app-build-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
    paths:
      - ${BUILD_DIR}
      - ${INSTALL_DIR}
  before_script:
    - export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/pkgconfig:${INSTALL_PREFIX}/share/pkgconfig"
    - export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/`gcc -print-multiarch`/pkgconfig/:$PKG_CONFIG_PATH"
    - export PKG_CONFIG_PATH="${INSTALL_PREFIX}/share/`gcc -print-multiarch`/pkgconfig/:$PKG_CONFIG_PATH"
    - export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}"
    - export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib/`gcc -print-multiarch`:$LD_LIBRARY_PATH"
    - export XDG_DATA_DIRS="${INSTALL_PREFIX}/share:/usr/local/share:/usr/share"
    - export PATH="${INSTALL_PREFIX}/bin:$PATH"
  needs: ["deps-debian"]

siril-deb-meson:
  extends: .siril-debian/testing-base
  script:
    - meson setup --prefix="${INSTALL_PREFIX}" ${BUILD_DIR} -Db_coverage=true -Dcriterion=true
    - ninja -C ${BUILD_DIR} install
    - meson test -C ${BUILD_DIR} -v --no-suite perfs
    - cd ${BUILD_DIR}
#    - gcovr --xml-pretty --exclude-unreachable-branches --exclude-directories subprojects --exclude-directories  src/tests  --root ../ -o coverage.xml --print-summary
    - cd ..
  artifacts:
    paths:
      - ${BUILD_DIR}/meson-logs/testlog.junit.xml
      - ${BUILD_DIR}/coverage.xml
    reports:
      junit: ${BUILD_DIR}/meson-logs/testlog.junit.xml
      coverage_report:
        coverage_format: cobertura
        path: ${BUILD_DIR}/coverage.xml


################################################################################
# Packaging

################################################################################
# macOS CI

macos:
  stage: packaging
  parallel:
    matrix:
      - ARCHITECTURE: [ "arm64", "x86_64" ]
  rules:
    - if: $CI_PROJECT_NAMESPACE != "free-astro" && $CI_PROJECT_NAMESPACE != "dehesselle"
      when: never  # job requires custom runner, not suitable outside the project
    - if: $ARCHITECTURE == "x86_64"
      when: manual
      allow_failure: true
    - when: on_success
  tags:
    - macos
    - ${ARCHITECTURE}
  cache:
    - key: ccache-$CI_JOB_NAME_SLUG
      paths:
        - ccache
  variables:
    CCACHE_DIR: $CI_PROJECT_DIR/ccache
    CCACHE_MAXSIZE: "500Mi"
    ORKA_RUNNER: sonoma-2
    PACKAGE_REGISTRY_URL: $CI_API_V4_URL/projects/$CI_PROJECT_ID/packages/generic
    REP_DIR: $CI_PROJECT_DIR
    SDKROOT: /opt/sdks/MacOSX11.3.sdk
    SIRIL_BUILD: $CI_PIPELINE_IID
    SM_REPO_REF: 5bcfbecdf28cd11a89e820118a36df0019cb5281
    SM_REPO_URL: https://gitlab.com/free-astro/siril_macos.git
  script:
    # Clone the repo containing all the build scripts.
    - |
      git clone $SM_REPO_URL sm
      git -C sm checkout $SM_REPO_REF
      git -C sm submodule update --recursive --init
    # Build the dependencies and then Siril. Dependencies are uploaded to the
    # package registry so they don't have to be rebuilt every time if there
    # haven't been any changes. Changes to dependencies are detected by
    # checksumming all the files and using that checksum as a version number.
    - |
      echo $CI_PROJECT_DIR > sm/ci_project_dir.txt
      SM_SHA=$(LANG=C find -s sm -type f -not -wholename '*.git/*' -exec cat {} \+ | shasum | awk '{ print $1 }')
      VER_DIR=$(sm/jhb/usr/bin/config get VER_DIR)
      PACKAGE_URL=${PACKAGE_REGISTRY_URL}/macos-deps/${SM_SHA}/$(basename $VER_DIR)_${ARCHITECTURE}.dmg
      if ! curl -H "JOB-TOKEN: $CI_JOB_TOKEN" -fLO $PACKAGE_URL; then
        sm/build_toolset.sh
        rm $VER_DIR/var/cache/pkg/.skip
        sm/jhb/usr/bin/jhb run rustup self uninstall -y || true
        sm/jhb/usr/bin/archive remove_nonessentials
        sm/jhb/usr/bin/archive create_dmg
        curl --fail-with-body -H "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file $(basename $PACKAGE_URL) $PACKAGE_URL
        rm -rf ${VER_DIR:?}
      fi
    - sm/jhb/usr/bin/archive install_dmg
    - sm/build_siril.sh
  after_script:
    - sm/jhb/usr/bin/archive uninstall_dmg
  needs: []
  artifacts:
    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
    expire_in: 1 week
    paths:
      - Siril*.dmg

# Fetch msys2 image from siril-windows
# Build siril and package it
win64-native:
  stage: packaging
  parallel:
    matrix:
      - MSYSTEM: [ "MINGW64", "UCRT64" ]
  cache:
    key: "cache-windows-small1-${MSYSTEM}"
    paths:
      - ccache
      - DLLcache # cache for the DLL txt files recording all files to be copied to the package
    when: always
  variables:
    CCACHE_DIR: $CI_PROJECT_DIR/ccache
    CCACHE_MAXSIZE: "50M"
    CHERE_INVOKING: "yes"
    # SDW = Siril Deps Windows, https://gitlab.com/free-astro/siril_windows
    SDW_VERSION: 56
    SDW_NAME: siril${SDW_VERSION}_${MSYSTEM}
    SDW_RELEASE_URL: $CI_API_V4_URL/projects/47854290/packages/generic/windows/r$SDW_VERSION/$SDW_NAME.7z
    # SPW = Siril Python Windows, https://gitlab.com/free-astro/siril-windows-python
    SPW_VERSION: 23
    SPW_NAME: siril-python$SPW_VERSION
    SPW_RELEASE_URL: $CI_API_V4_URL/projects/64372315/packages/generic/windows-python/r$SPW_VERSION/$SPW_NAME.7z
    PY_OUT: "/c/siril-python" #used in siril-package.sh
  tags:
    - saas-windows-medium-amd64
  needs: []
  artifacts:
    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${MSYSTEM}"
    when: always
    expire_in: 1 week
    paths:
    - ${INSTALL_DIR}
  before_script:
    - wget.exe --quiet --no-check-certificate $SPW_RELEASE_URL
    - 7z x -oC:/ "$Env:SPW_NAME.7z"
    - wget.exe --quiet --no-check-certificate $SDW_RELEASE_URL
    - 7z x -oC:/ "$Env:SDW_NAME.7z"
    # Set W64_OUT dynamically based on MSYSTEM
    # used in siril-package.sh
    - $Env:W64_OUT = "/c/$Env:SDW_NAME/$($Env:MSYSTEM.ToLower())"
    - echo "W64_OUT=$Env:W64_OUT"
  script:
    - . "C:/$Env:SDW_NAME/msys2_shell.cmd" -defterm -no-start -$($Env:MSYSTEM.ToLower()) -c "bash -x ./build/windows/native-gitlab-ci/siril-build.sh"
    - . "C:/$Env:SDW_NAME/msys2_shell.cmd" -defterm -no-start -$($Env:MSYSTEM.ToLower()) -c "bash -x ./build/windows/native-gitlab-ci/siril-package.sh"
    - . "C:/$Env:SDW_NAME/msys2_shell.cmd" -defterm -no-start -$($Env:MSYSTEM.ToLower()) -c "ccache -s"

flatpak:
  rules:
    *run_ondemand_schedule_tag
  image: 'quay.io/gnome_infrastructure/gnome-runtime-images:gnome-49'
  stage: packaging
  variables:
    MANIFEST_PATH: "build/flatpak/org.siril.Siril.json"
    FLATPAK_MODULE: "siril"
    APP_ID: "org.siril.Siril"
    RUNTIME_REPO: "https://flathub.org/repo/flathub.flatpakrepo"
    BUNDLE: "org.siril.Siril.flatpak"
    GIT_SUBMODULE_STRATEGY: recursive
  script:
    - flatpak-builder --verbose --disable-rofiles-fuse --ccache --repo=repo ${BRANCH:+--default-branch=$BRANCH} flatpak_app ${MANIFEST_PATH}
    - flatpak build-bundle repo ${BUNDLE} --runtime-repo=${RUNTIME_REPO} ${APP_ID} ${BRANCH}
  artifacts:
    name: "Flatpak artifacts"
    expose_as: "Get Flatpak bundle here"
    when: always
    paths:
      - "${BUNDLE}"
      - "repo/"
    expire_in: 1 week
  cache:
    # key: "$CI_JOB_NAME"
    paths:
      - ".flatpak-builder/downloads"
      - ".flatpak-builder/git"
      - ".flatpak-builder/cache"
      - ".flatpak-builder/ccache"
  needs: []
  allow_failure: true


appimage:
  stage: packaging
  image: $CI_REGISTRY_IMAGE/$IMAGE_TAG:build-debian-oldstable
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  cache:
    paths:
      - apt-cache
  before_script:
    - apt-get update
    - apt-get install -y wget squashfs-tools
  script:
    - bash -ex build/appimage/generate.sh
  artifacts:
    expire_in: 1 week
    paths:
      - build/appimage/Siril*.AppImage*
  needs: ["build-image-oldstable"]
  allow_failure: true

################################################################################
# Analysis

cppcheck:
  stage: analysis
  before_script:
    - apt-get update
    - apt-get install -y cppcheck
  script:
    - cppcheck -q -j8 --enable=all --force --output-file=cppcheck.xml --xml --xml-version=2
        -i _build -i _deps -i ${INSTALL_PREFIX} -i subprojects  -i src/rt -i src/io/avi_pipp -i .local -i .cache .
    - mkdir report
    - cppcheck-htmlreport --source-dir=. --title=siril --file=cppcheck.xml --report-dir=report
  artifacts:
    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
    expire_in: 1 week
    when: always
    paths:
      - report
  needs: []

################################################################################
# Distribution
################################################################################
# Distribution
win64-native-installer:
  rules:
    *run_ondemand_schedule_tag
  parallel:
    matrix:
      - MSYSTEM: [ "MINGW64", "UCRT64" ]
  variables:
    CHERE_INVOKING: "yes"
  tags:
    - saas-windows-medium-amd64
  stage: distribution
  artifacts:
    name: "${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${MSYSTEM}"
    when: always
    expire_in: 1 week
    paths:
    - WinInstaller
    - installer.log
  script:
    - choco install innosetup -y
    - powershell -File .\build\windows\installer\siril-win-installer.ps1 2>&1 > installer.log
  needs: 
    - job: win64-native
      artifacts: true
  allow_failure: true

################################################################################
build-paper:
  rules:
    *run_ondemand_schedule_tag
  stage: distribution
  image: docker:latest
  services:
    - docker:dind
  artifacts:
    expire_in: 1 week
    when: always
    paths:
    - paper/paper.pdf
  before_script:
    - apk update
    - apk add --no-cache docker-compose
  script:
    - docker run --rm --volume "$CI_PROJECT_DIR/paper:/data" --user "$(id -u):$(id -g)" --env JOURNAL=joss openjournals/inara
  needs: []
  dependencies: []
  allow_failure: true
