variables:
  DEBIAN_FRONTEND: noninteractive

stages:
  - build
  - unit_test
  - hardware_test
  - deploy

#-------------------------------------------------------------------------------
# Windows
#-------------------------------------------------------------------------------

build windows/x64:
  stage: build
  script:
    - CMD.EXE /C ci\build-windows64.bat
  artifacts:
    when: always
    paths:
      - build
    expire_in: 3 days
  tags:
    - icsneo-windows

unit_test windows/x64:
  stage: unit_test
  script:
    - build\libicsneo-unit-tests.exe
  dependencies:
    - build windows/x64
  needs:
    - build windows/x64
  tags:
    - icsneo-windows
  timeout: 5m

build windows/x86:
  stage: build
  script:
    - CMD.EXE /C ci\build-windows32.bat
  artifacts:
    when: always
    paths:
      - build
    expire_in: 3 days
  tags:
    - icsneo-windows

unit_test windows/x86:
  stage: unit_test
  script:
    - build\libicsneo-unit-tests.exe
  dependencies:
    - build windows/x86
  needs:
    - build windows/x86
  tags:
    - icsneo-windows
  timeout: 5m

#-------------------------------------------------------------------------------
# Ubuntu
#-------------------------------------------------------------------------------

.build_linux_ubuntu_gcc: &build_linux_ubuntu_gcc
  stage: build
  script:
    - apt update -y
    - apt upgrade -y
    - apt install -y g++ ninja-build cmake libusb-1.0-0-dev libpcap-dev git
    - sh ci/build-posix.sh
  artifacts:
    when: always
    paths:
      - build
    expire_in: 3 days
  tags:
    - linux-build

.test_linux_ubuntu_gcc: &test_linux_ubuntu_gcc
  stage: unit_test
  script:
    - apt update -y
    - apt upgrade -y
    - apt install -y libusb-1.0-0-dev libpcap-dev
    - build/libicsneo-unit-tests
  tags:
    - linux-build
  timeout: 5m

.build_linux_ubuntu_clang: &build_linux_ubuntu_clang
  stage: build
  script:
    - apt update -y
    - apt upgrade -y
    - apt install -y clang lld ninja-build cmake libusb-1.0-0-dev libpcap-dev git
    - CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh
  artifacts:
    when: always
    paths:
      - build
    expire_in: 3 days
  tags:
    - linux-build

.test_linux_ubuntu_clang: &test_linux_ubuntu_clang
  stage: unit_test
  script:
    - apt update -y
    - apt upgrade -y
    - apt install -y libusb-1.0-0-dev libpcap-dev
    - build/libicsneo-unit-tests
  tags:
    - linux-build
  timeout: 5m

build linux/ubuntu/2004/amd64/gcc:
  <<: *build_linux_ubuntu_gcc
  image: ubuntu:20.04

unit_test linux/ubuntu/2004/amd64/gcc:
  <<: *test_linux_ubuntu_gcc
  image: ubuntu:20.04
  dependencies:
    - build linux/ubuntu/2004/amd64/gcc
  needs:
    - build linux/ubuntu/2004/amd64/gcc

build linux/ubuntu/2004/amd64/clang:
  <<: *build_linux_ubuntu_clang
  image: ubuntu:20.04

unit_test linux/ubuntu/2004/amd64/clang:
  <<: *test_linux_ubuntu_clang
  image: ubuntu:20.04
  dependencies:
    - build linux/ubuntu/2004/amd64/clang
  needs:
    - build linux/ubuntu/2004/amd64/clang

build linux/ubuntu/2204/amd64/gcc:
  <<: *build_linux_ubuntu_gcc
  image: ubuntu:22.04

unit_test linux/ubuntu/2204/amd64/gcc:
  <<: *test_linux_ubuntu_gcc
  image: ubuntu:22.04
  dependencies:
    - build linux/ubuntu/2204/amd64/gcc
  needs:
    - build linux/ubuntu/2204/amd64/gcc

build linux/ubuntu/2204/amd64/clang:
  <<: *build_linux_ubuntu_clang
  image: ubuntu:22.04

unit_test linux/ubuntu/2204/amd64/clang:
  <<: *test_linux_ubuntu_clang
  image: ubuntu:22.04
  dependencies:
    - build linux/ubuntu/2204/amd64/clang
  needs:
    - build linux/ubuntu/2204/amd64/clang

#-------------------------------------------------------------------------------
# Fedora
#-------------------------------------------------------------------------------

.build_linux_fedora_gcc: &build_linux_fedora_gcc
  stage: build
  cache:
    paths:
      - /var/cache/dnf
  script:
    - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
    - echo fastestmirror=True >>/etc/dnf/dnf.conf
    - dnf upgrade -y
    - dnf install -y g++ libpcap-devel cmake ninja-build libusb1-devel git
    - sh ci/build-posix.sh
  artifacts:
    when: always
    paths:
      - build
    expire_in: 3 days
  tags:
    - linux-build

.test_linux_fedora_gcc: &test_linux_fedora_gcc
  stage: unit_test
  cache:
    paths:
      - /var/cache/dnf
  script:
    - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
    - echo fastestmirror=True >>/etc/dnf/dnf.conf
    - dnf upgrade -y
    - dnf install -y libpcap-devel libusb1-devel
    - build/libicsneo-unit-tests
  tags:
    - linux-build
  timeout: 5m

.build_linux_fedora_clang: &build_linux_fedora_clang
  stage: build
  cache:
    paths:
      - /var/cache/dnf
  script:
    - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
    - echo fastestmirror=True >>/etc/dnf/dnf.conf
    - dnf upgrade -y
    - dnf install -y clang lld libpcap-devel cmake ninja-build libusb1-devel git
    - CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh
  artifacts:
    when: always
    paths:
      - build
    expire_in: 3 days
  tags:
    - linux-build

.test_linux_fedora_clang: &test_linux_fedora_clang
  stage: unit_test
  cache:
    paths:
      - /var/cache/dnf
  script:
    - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
    - echo fastestmirror=True >>/etc/dnf/dnf.conf
    - dnf upgrade -y
    - dnf install -y libpcap-devel libusb1-devel
    - build/libicsneo-unit-tests
  tags:
    - linux-build
  timeout: 5m

build linux/fedora/37/amd64/gcc:
  <<: *build_linux_fedora_gcc
  image: fedora:37

unit_test linux/fedora/37/amd64/gcc:
  <<: *test_linux_fedora_gcc
  image: fedora:37
  dependencies:
    - build linux/fedora/37/amd64/gcc
  needs:
    - build linux/fedora/37/amd64/gcc

build linux/fedora/37/amd64/clang:
  <<: *build_linux_fedora_clang
  image: fedora:37

unit_test linux/fedora/37/amd64/clang:
  <<: *test_linux_fedora_clang
  image: fedora:37
  dependencies:
    - build linux/fedora/37/amd64/clang
  needs:
    - build linux/fedora/37/amd64/clang

build linux/fedora/38/amd64/gcc:
  <<: *build_linux_fedora_gcc
  image: fedora:38

unit_test linux/fedora/38/amd64/gcc:
  <<: *test_linux_fedora_gcc
  image: fedora:38
  dependencies:
    - build linux/fedora/38/amd64/gcc
  needs:
    - build linux/fedora/38/amd64/gcc

build linux/fedora/38/amd64/clang:
  <<: *build_linux_fedora_clang
  image: fedora:38

unit_test linux/fedora/38/amd64/clang:
  <<: *test_linux_fedora_clang
  image: fedora:38
  dependencies:
    - build linux/fedora/38/amd64/clang
  needs:
    - build linux/fedora/38/amd64/clang

build linux/fedora/39/amd64/gcc:
  <<: *build_linux_fedora_gcc
  image: fedora:39

unit_test linux/fedora/39/amd64/gcc:
  <<: *test_linux_fedora_gcc
  image: fedora:39
  dependencies:
    - build linux/fedora/39/amd64/gcc
  needs:
    - build linux/fedora/39/amd64/gcc

build linux/fedora/39/amd64/clang:
  <<: *build_linux_fedora_clang
  image: fedora:39

unit_test linux/fedora/39/amd64/clang:
  <<: *test_linux_fedora_clang
  image: fedora:39
  dependencies:
    - build linux/fedora/39/amd64/clang
  needs:
    - build linux/fedora/39/amd64/clang

.hw_test: &hw_test
  stage: hardware_test
  tags:
    - libicsneo_hil
  timeout: 5m
  script:
    - echo $GUEST_OS_TAG
    - echo $DEVICE_PORT
    - /opt/libvirt-driver/prepare.sh
    - /opt/libvirt-driver/run.sh
  after_script:
    - /opt/libvirt-driver/cleanup.sh
  allow_failure: true

.fedora38_needs: &fedora38_needs
  needs:
    - job: build linux/fedora/38/amd64/clang
      artifacts: true

hardware_test fedora38-red2:
  <<: *hw_test
  <<: *fedora38_needs
  variables:
    GUEST_OS_TAG: fedora38
    DEVICE_PORT: ETH_A

hardware_test fedora38-vcan42:
  <<: *hw_test
  <<: *fedora38_needs
  variables:
    GUEST_OS_TAG: fedora38
    DEVICE_PORT: USB_D

hardware_test fedora38-fire3:
  <<: *hw_test
  <<: *fedora38_needs
  variables:
    GUEST_OS_TAG: fedora38
    DEVICE_PORT: ETH_B

hardware_test fedora38-vcan42-EL:
  <<: *hw_test
  <<: *fedora38_needs
  variables:
    GUEST_OS_TAG: fedora38
    DEVICE_PORT: USB_C

.ubuntu2204_needs: &ubuntu2204_needs
  needs:
    - job: build linux/ubuntu/2204/amd64/clang
      artifacts: true

hardware_test ubuntu2204-red2:
  <<: *hw_test
  <<: *ubuntu2204_needs
  variables:
    GUEST_OS_TAG: ubuntu22.04
    DEVICE_PORT: ETH_A

hardware_test ubuntu2204-vcan42:
  <<: *hw_test
  <<: *ubuntu2204_needs
  variables:
    GUEST_OS_TAG: ubuntu22.04
    DEVICE_PORT: USB_D

hardware_test ubuntu2204-fire3:
  <<: *hw_test
  <<: *ubuntu2204_needs
  variables:
    GUEST_OS_TAG: ubuntu22.04
    DEVICE_PORT: ETH_B

hardware_test ubuntu2204-vcan42-EL:
  <<: *hw_test
  <<: *ubuntu2204_needs
  variables:
    GUEST_OS_TAG: ubuntu22.04
    DEVICE_PORT: USB_C

.win10_needs: &win10_needs
  needs:
    - job: build windows/x64
      artifacts: true

hardware_test win10-red2:
  <<: *hw_test
  <<: *win10_needs
  variables:
    GUEST_OS_TAG: win10
    DEVICE_PORT: ETH_A

hardware_test win10-vcan42:
  <<: *hw_test
  <<: *win10_needs
  variables:
    GUEST_OS_TAG: win10
    DEVICE_PORT: USB_D

hardware_test win10-fire3:
  <<: *hw_test
  <<: *win10_needs
  variables:
    GUEST_OS_TAG: win10
    DEVICE_PORT: ETH_B

hardware_test win10-vcan42-EL:
  <<: *hw_test
  <<: *win10_needs
  variables:
    GUEST_OS_TAG: win10
    DEVICE_PORT: USB_C

#-------------------------------------------------------------------------------
# Python Module
#-------------------------------------------------------------------------------

build python/linux/amd64:
  stage: build
  tags:
    - linux-build
  image: python:3.12
  services:
    - name: docker:dind
      entrypoint: ["env", "-u", "DOCKER_HOST"]
      command: ["dockerd-entrypoint.sh"]
  variables:
    CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh
    CIBW_BUILD: "*manylinux*" # no musl
    CIBW_ARCHS: x86_64
    DOCKER_HOST: tcp://docker:2375/
    DOCKER_DRIVER: overlay2
    DOCKER_TLS_CERTDIR: ""
    CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install
  script:
    - curl -sSL https://get.docker.com/ | sh
    - sh ci/build-wheel-posix.sh
  artifacts:
    paths:
      - wheelhouse

build python/linux/arm64:
  stage: build
  tags:
    - arm64-linux-build
  variables:
    CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh
    CIBW_BUILD: "*manylinux*" # no musl
    CIBW_ARCHS: aarch64
    CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install
  script:
    - sh ci/build-wheel-posix.sh
  artifacts:
    paths:
      - wheelhouse

build python/macos:
  stage: build
  tags:
    - macos-arm64
  variables:
    CIBW_BEFORE_ALL: sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh
    CIBW_ARCHS: arm64
    CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/install:$CI_PROJECT_DIR/libusb/install
    MACOSX_DEPLOYMENT_TARGET: 10.14
  script:
    - sh ci/build-wheel-posix.sh
  artifacts:
    paths:
      - wheelhouse

build python/windows:
  stage: build
  tags:
    - libicsneo-win-x64
  variables:
    CIBW_ARCHS: AMD64
    CIBW_ENVIRONMENT: CMAKE_GENERATOR=Ninja
  script:
    - cmd /c ci\build-wheel-windows.bat
  artifacts:
    paths:
      - wheelhouse

deploy python/pypi:
  stage: deploy
  variables:
    TWINE_USERNAME: __token__
    TWINE_PASSWORD: $PYPI_TOKEN
  tags:
    - linux-build
  image: python:3.12
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    - python3 -m pip install -U twine
    - twine upload wheelhouse/*
  dependencies:
    - build python/linux/amd64
    - build python/linux/arm64
    - build python/macos
    - build python/windows
  needs:
    - build python/linux/amd64
    - build python/linux/arm64
    - build python/macos
    - build python/windows

push github:
  stage: deploy
  tags:
    - linux-build
  image: alpine:latest
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  dependencies:
    - deploy python/pypi
  needs:
    - deploy python/pypi
  script:
    - apk add git
    - git push https://$LIBICSNEO_GITHUB_USERNAME:$LIBICSNEO_GITHUB_TOKEN@github.com/intrepidcs/libicsneo.git HEAD:master
