# This is the tag of the docker image used for the build jobs. If the
# image doesn't exist yet, the containers stage generates it.
#
# In order to generate a new image, one should generally change the tag.
# While removing the image from the registry would also work, that's not
# recommended except for ephemeral images during development: Replacing
# an image after a significant amount of time might pull in newer
# versions of gcc/clang or other packages, which might break the build
# with older commits using the same tag.
#
# After merging a change resulting in generating a new image to the
# main repository, it's recommended to remove the image from the source
# repository's container registry, so that the image from the main
# repository's registry will be used there as well.
.templates_sha: &template_sha 567700e483aabed992d0a4fea84994a0472deff6 # see https://docs.gitlab.com/ee/ci/yaml/#includefile

include:
  - project: 'freedesktop/ci-templates'
    ref: *template_sha
    file:
    - '/templates/debian.yml'
    - '/templates/freebsd.yml'
    - '/templates/ci-fairy.yml'

variables:
  FDO_UPSTREAM_REPO: mesa/drm
  FDO_REPO_SUFFIX: "$BUILD_OS/$BUILD_ARCH"

stages:
  - "Base container"
  - "Build"

.ci-rules:
  rules:
    - when: on_success

# CONTAINERS

.os-debian:
  variables:
    BUILD_OS: debian
    FDO_DISTRIBUTION_VERSION: buster
    FDO_DISTRIBUTION_PACKAGES: 'build-essential docbook-xsl libatomic-ops-dev libcairo2-dev libcunit1-dev libpciaccess-dev meson ninja-build pkg-config python3 python3-pip python3-wheel python3-setuptools python3-docutils valgrind'
    FDO_DISTRIBUTION_EXEC: 'pip3 install meson==0.59.0'
    # bump this tag every time you change something which requires rebuilding the
    # base image
    FDO_DISTRIBUTION_TAG: "2023-09-01.0"

.debian-x86_64:
  extends:
    - .os-debian
  variables:
    BUILD_ARCH: "x86-64"

.debian-aarch64:
  extends:
    - .os-debian
  variables:
    BUILD_ARCH: "aarch64"

.debian-armv7:
  extends:
    - .os-debian
  variables:
    BUILD_ARCH: "armv7"

.os-freebsd:
  variables:
    BUILD_OS: freebsd
    FDO_DISTRIBUTION_VERSION: "13.2"
    FDO_DISTRIBUTION_PACKAGES: 'meson ninja pkgconf libpciaccess py39-docutils cairo'
    # bump this tag every time you change something which requires rebuilding the
    # base image
    FDO_DISTRIBUTION_TAG: "2023-07-20.0"

.freebsd-x86_64:
  extends:
    - .os-freebsd
  variables:
    BUILD_ARCH: "x86_64"

# Build our base container image, which contains the core distribution, the
# toolchain, and all our build dependencies. This will be reused in the build
# stage.
x86_64-debian-container_prep:
  extends:
    - .ci-rules
    - .debian-x86_64
    - .fdo.container-build@debian
  stage: "Base container"
  variables:
    GIT_STRATEGY: none

aarch64-debian-container_prep:
  extends:
    - .ci-rules
    - .debian-aarch64
    - .fdo.container-build@debian
  tags:
    - aarch64
  stage: "Base container"
  variables:
    GIT_STRATEGY: none

armv7-debian-container_prep:
  extends:
    - .ci-rules
    - .debian-armv7
    - .fdo.container-build@debian
  tags:
    - aarch64
  stage: "Base container"
  variables:
    GIT_STRATEGY: none
    FDO_BASE_IMAGE: "arm32v7/debian:$FDO_DISTRIBUTION_VERSION"

x86_64-freebsd-container_prep:
  extends:
    - .ci-rules
    - .freebsd-x86_64
    - .fdo.qemu-build@freebsd@x86_64
  stage: "Base container"
  variables:
    GIT_STRATEGY: none

# Core build environment.
.build-env:
  variables:
    MESON_BUILD_TYPE: "-Dbuildtype=debug -Doptimization=0 -Db_sanitize=address,undefined"

# OS/architecture-specific variants
.build-env-debian-x86_64:
  extends:
    - .fdo.suffixed-image@debian
    - .debian-x86_64
    - .build-env
  needs:
    - job: x86_64-debian-container_prep
      artifacts: false

.build-env-debian-aarch64:
  extends:
    - .fdo.suffixed-image@debian
    - .debian-aarch64
    - .build-env
  variables:
    # At least with the versions we have, the LSan runtime makes fork unusably
    # slow on AArch64, which is bad news since the test suite decides to fork
    # for every single subtest. For now, in order to get AArch64 builds and
    # tests into CI, just assume that we're not going to leak any more on
    # AArch64 than we would on ARMv7 or x86-64.
    ASAN_OPTIONS: "detect_leaks=0"
  tags:
    - aarch64
  needs:
    - job: aarch64-debian-container_prep
      artifacts: false

.build-env-debian-armv7:
  extends:
    - .fdo.suffixed-image@debian
    - .debian-armv7
    - .build-env
  tags:
    - aarch64
  needs:
    - job: armv7-debian-container_prep
      artifacts: false

.build-env-freebsd-x86_64:
  variables:
    # Compiling with ASan+UBSan appears to trigger an infinite loop in the
    # compiler shipped with FreeBSD 13.0, so we only use UBSan here.
    # Additionally, sanitizers can't be used with b_lundef on FreeBSD.
    MESON_BUILD_TYPE: "-Dbuildtype=debug -Db_sanitize=undefined -Db_lundef=false"
  extends:
    - .fdo.suffixed-image@freebsd
    - .freebsd-x86_64
    - .build-env
  needs:
    - job: x86_64-freebsd-container_prep
      artifacts: false

# BUILD

.do-build:
  extends:
    - .ci-rules
  stage: "Build"
  variables:
    GIT_DEPTH: 10
  script:
    - meson build
        --auto-features=enabled
        -D udev=true
    - ninja -C build
    - ninja -C build test
    - DESTDIR=$PWD/install ninja -C build install
  artifacts:
    when: on_failure
    paths:
      - build/meson-logs/*

.do-build-qemu:
  extends:
    - .ci-rules
  stage: "Build"
  script:
    # Start the VM and copy our workspace to the VM
    - /app/vmctl start
    - scp -r $PWD "vm:"
    # The `set +e is needed to ensure that we always copy the meson logs back to
    # the workspace to see details about the failed tests.
    - |
      set +e
      /app/vmctl exec "pkg info; cd $CI_PROJECT_NAME ; meson build --auto-features=enabled -D etnaviv=disabled -D nouveau=disabled -D valgrind=disabled && ninja -C build"
      set -ex
      scp -r vm:$CI_PROJECT_NAME/build/meson-logs .
      /app/vmctl exec "ninja -C $CI_PROJECT_NAME/build install"
      mkdir -p $PREFIX && scp -r vm:$PREFIX/ $PREFIX/
    # Finally, shut down the VM.
    - /app/vmctl stop
  artifacts:
    when: on_failure
    paths:
      - build/meson-logs/*

# Full build and test.
x86_64-debian-build:
  extends:
    - .build-env-debian-x86_64
    - .do-build

aarch64-debian-build:
  extends:
    - .build-env-debian-aarch64
    - .do-build

armv7-debian-build:
  extends:
    - .build-env-debian-armv7
    - .do-build

# Daily build
meson-arch-daily:
  rules:
    - if: '$SCHEDULE == "arch-daily"'
      when: on_success
    - when: never
  image: archlinux/archlinux:base-devel
  before_script:
    - pacman -Syu --noconfirm --needed
        cairo
        cunit
        libatomic_ops
        libpciaccess
        meson
        valgrind
        python-docutils
  extends: .do-build

x86_64-freebsd-build:
  extends:
    - .build-env-freebsd-x86_64
    - .do-build-qemu
