variables:
  GIT_DEPTH: 100

stages:
  - containers
  - builds
  - sanity_checks

.script_variables: &script_variables |
  export CCACHE_BASEDIR="$(pwd)"
  export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
  export CCACHE_MAXSIZE="500M"
  export PATH="$CCACHE_WRAPPERSDIR:$PATH"
  export VIR_TEST_VERBOSE="1"
  export VIR_TEST_DEBUG="1"

# Common templates

.container_job:
  image: docker:stable
  stage: containers
  needs: []
  services:
    - docker:dind
  rules:
    - if: "$TEMPORARILY_DISABLED"
      allow_failure: true
    - when: on_success
  before_script:
    - export TAG="$CI_REGISTRY_IMAGE/ci-$NAME:latest"
    - export COMMON_TAG="$CI_REGISTRY/libvirt/libvirt/ci-$NAME:latest"
    - docker info
    - docker login registry.gitlab.com -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
  script:
    - docker pull "$TAG" || docker pull "$COMMON_TAG" || true
    - docker build --cache-from "$TAG" --cache-from "$COMMON_TAG" --tag "$TAG" -f "ci/containers/$NAME.Dockerfile" ci/containers
    - docker push "$TAG"
  after_script:
    - docker logout

# We build many containers which can be useful to debug problems but are not
# needed for the pipeline itself to complete: those sometimes fail, and when
# that happens it's mostly because of temporary issues with Debian sid. We
# don't want those failures to affect the overall pipeline status
.container_optional_job:
  extends: .container_job
  allow_failure: true

.native_build_job:
  stage: builds
  image: $CI_REGISTRY_IMAGE/ci-$NAME:latest
  rules:
    - if: "$TEMPORARILY_DISABLED"
      allow_failure: true
    - when: on_success
  cache:
    paths:
      - ccache/
    key: "$CI_JOB_NAME"
  before_script:
    - *script_variables
  script:
    - meson setup build --werror || (cat build/meson-logs/meson-log.txt && exit 1)
    - meson dist -C build --no-tests
    - if test -x /usr/bin/rpmbuild && test "$RPM" != "skip";
      then
        rpmbuild --nodeps -ta build/meson-dist/libvirt-*.tar.xz;
      else
        meson compile -C build;
        meson test -C build --no-suite syntax-check --print-errorlogs;
      fi

.sanitizer_build_job:
  stage: builds
  image: $CI_REGISTRY_IMAGE/ci-ubuntu-2004:latest
  needs:
    - x64-ubuntu-2004-container
  rules:
    - if: "$TEMPORARILY_DISABLED"
      allow_failure: true
    - when: on_success
  cache:
    paths:
      - ccache/
    key: "$CI_JOB_NAME"
  before_script:
    - *script_variables
  script:
    - meson build --werror -Ddocs=disabled -Db_lundef=false -Db_sanitize="$SANITIZER"
    - ninja -C build;
    - ninja -C build test;

# Jobs that we delegate to Cirrus CI because they require an operating
# system other than Linux. These jobs will only run if the required
# setup has been performed on the GitLab account (see ci/README.rst).
#
# The Cirrus CI configuration is generated by replacing target-specific
# variables in a generic template: some of these variables are provided
# when the GitLab CI job is defined, others are taken from a shell
# snippet generated using lcitool.
#
# Note that the $PATH environment variable has to be treated with
# special care, because we can't just override it at the GitLab CI job
# definition level or we risk breaking it completely.
.cirrus_build_job:
  stage: builds
  image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master
  needs: []
  script:
    - source ci/cirrus/$NAME.vars
    - sed -e "s|[@]CI_REPOSITORY_URL@|$CI_REPOSITORY_URL|g"
          -e "s|[@]CI_COMMIT_REF_NAME@|$CI_COMMIT_REF_NAME|g"
          -e "s|[@]CI_COMMIT_SHA@|$CI_COMMIT_SHA|g"
          -e "s|[@]CIRRUS_VM_INSTANCE_TYPE@|$CIRRUS_VM_INSTANCE_TYPE|g"
          -e "s|[@]CIRRUS_VM_IMAGE_SELECTOR@|$CIRRUS_VM_IMAGE_SELECTOR|g"
          -e "s|[@]CIRRUS_VM_IMAGE_NAME@|$CIRRUS_VM_IMAGE_NAME|g"
          -e "s|[@]UPDATE_COMMAND@|$UPDATE_COMMAND|g"
          -e "s|[@]UPGRADE_COMMAND@|$UPGRADE_COMMAND|g"
          -e "s|[@]INSTALL_COMMAND@|$INSTALL_COMMAND|g"
          -e "s|[@]PATH@|$PATH_EXTRA${PATH_EXTRA:+:}\$PATH|g"
          -e "s|[@]PKG_CONFIG_PATH@|$PKG_CONFIG_PATH|g"
          -e "s|[@]PKGS@|$PKGS|g"
          -e "s|[@]MAKE@|$MAKE|g"
          -e "s|[@]PYTHON@|$PYTHON|g"
          -e "s|[@]PIP3@|$PIP3|g"
          -e "s|[@]PYPI_PKGS@|$PYPI_PKGS|g"
      <ci/cirrus/build.yml >ci/cirrus/$NAME.yml
    - cat ci/cirrus/$NAME.yml
    - cirrus-run -v --show-build-log always ci/cirrus/$NAME.yml
  rules:
    - if: "$TEMPORARILY_DISABLED"
      allow_failure: true
    - if: "$CIRRUS_GITHUB_REPO && $CIRRUS_API_TOKEN"

.cross_build_job:
  stage: builds
  image: $CI_REGISTRY_IMAGE/ci-$NAME-cross-$CROSS:latest
  cache:
    paths:
      - ccache/
    key: "$CI_JOB_NAME"
  rules:
    - if: "$TEMPORARILY_DISABLED"
      allow_failure: true
    - when: on_success
  before_script:
    - *script_variables
  script:
    - meson setup build --werror $MESON_OPTS || (cat build/meson-logs/meson-log.txt && exit 1)
    - meson compile -C build
    - if test "$CROSS" = "i686" ; then meson test -C build --no-suite syntax-check --print-errorlogs ; fi


# Native container build jobs

x64-centos-8-container:
  extends: .container_job
  variables:
    NAME: centos-8

x64-centos-stream-8-container:
  extends: .container_job
  variables:
    NAME: centos-stream-8

x64-debian-10-container:
  extends: .container_job
  variables:
    NAME: debian-10

x64-debian-sid-container:
  extends: .container_job
  variables:
    NAME: debian-sid

x64-fedora-33-container:
  extends: .container_job
  variables:
    NAME: fedora-33

x64-fedora-34-container:
  extends: .container_job
  variables:
    NAME: fedora-34

x64-fedora-rawhide-container:
  extends: .container_job
  variables:
    NAME: fedora-rawhide

x64-opensuse-leap-152-container:
  extends: .container_job
  variables:
    NAME: opensuse-leap-152

x64-opensuse-tumbleweed-container:
  extends: .container_job
  variables:
    NAME: opensuse-tumbleweed

x64-ubuntu-1804-container:
  extends: .container_job
  variables:
    NAME: ubuntu-1804

x64-ubuntu-2004-container:
  extends: .container_job
  variables:
    NAME: ubuntu-2004


# Cross-build containers build jobs

aarch64-debian-10-container:
  extends: .container_optional_job
  variables:
    NAME: debian-10-cross-aarch64

armv6l-debian-10-container:
  extends: .container_job
  variables:
    NAME: debian-10-cross-armv6l

armv7l-debian-10-container:
  extends: .container_job
  variables:
    NAME: debian-10-cross-armv7l

i686-debian-10-container:
  extends: .container_optional_job
  variables:
    NAME: debian-10-cross-i686

mips-debian-10-container:
  extends: .container_job
  variables:
    NAME: debian-10-cross-mips

mips64el-debian-10-container:
  extends: .container_optional_job
  variables:
    NAME: debian-10-cross-mips64el

mipsel-debian-10-container:
  extends: .container_job
  variables:
    NAME: debian-10-cross-mipsel

ppc64le-debian-10-container:
  extends: .container_job
  variables:
    NAME: debian-10-cross-ppc64le

s390x-debian-10-container:
  extends: .container_optional_job
  variables:
    NAME: debian-10-cross-s390x

aarch64-debian-sid-container:
  extends: .container_job
  variables:
    NAME: debian-sid-cross-aarch64

armv6l-debian-sid-container:
  extends: .container_optional_job
  variables:
    NAME: debian-sid-cross-armv6l

armv7l-debian-sid-container:
  extends: .container_optional_job
  variables:
    NAME: debian-sid-cross-armv7l

i686-debian-sid-container:
  extends: .container_job
  variables:
    NAME: debian-sid-cross-i686

mips64el-debian-sid-container:
  extends: .container_job
  variables:
    NAME: debian-sid-cross-mips64el

mipsel-debian-sid-container:
  extends: .container_optional_job
  variables:
    NAME: debian-sid-cross-mipsel

ppc64le-debian-sid-container:
  extends: .container_optional_job
  variables:
    NAME: debian-sid-cross-ppc64le

s390x-debian-sid-container:
  extends: .container_job
  variables:
    NAME: debian-sid-cross-s390x

mingw32-fedora-rawhide-container:
  extends: .container_job
  variables:
    NAME: fedora-rawhide-cross-mingw32

mingw64-fedora-rawhide-container:
  extends: .container_job
  variables:
    NAME: fedora-rawhide-cross-mingw64


# Native architecture build + test jobs

x64-debian-10:
  extends: .native_build_job
  needs:
    - x64-debian-10-container
  variables:
    NAME: debian-10

x64-debian-10-clang:
  extends: .native_build_job
  needs:
    - x64-debian-10-container
  variables:
    NAME: debian-10
    CC: clang

x64-debian-sid:
  extends: .native_build_job
  needs:
    - x64-debian-sid-container
  variables:
    NAME: debian-sid

x64-centos-8:
  extends: .native_build_job
  needs:
    - x64-centos-8-container
  variables:
    NAME: centos-8
    RPM: skip

x64-centos-8-clang:
  extends: .native_build_job
  needs:
    - x64-centos-8-container
  variables:
    NAME: centos-8
    CC: clang
    RPM: skip

x64-centos-stream-8:
  extends: .native_build_job
  needs:
    - x64-centos-stream-8-container
  variables:
    NAME: centos-stream-8
    RPM: skip

x64-fedora-33:
  extends: .native_build_job
  needs:
    - x64-fedora-33-container
  variables:
    NAME: fedora-33

x64-fedora-34:
  extends: .native_build_job
  needs:
    - x64-fedora-34-container
  variables:
    NAME: fedora-34

x64-fedora-rawhide:
  extends: .native_build_job
  needs:
    - x64-fedora-rawhide-container
  variables:
    NAME: fedora-rawhide

x64-fedora-rawhide-clang:
  extends: .native_build_job
  needs:
    - x64-fedora-rawhide-container
  variables:
    NAME: fedora-rawhide
    CC: clang
    RPM: skip

x64-opensuse-leap-152:
  extends: .native_build_job
  needs:
    - x64-opensuse-leap-152-container
  variables:
    NAME: opensuse-leap-152
    RPM: skip

x64-opensuse-tumbleweed:
  extends: .native_build_job
  needs:
    - x64-opensuse-tumbleweed-container
  variables:
    NAME: opensuse-tumbleweed
    RPM: skip

x64-ubuntu-1804:
  extends: .native_build_job
  needs:
    - x64-ubuntu-1804-container
  variables:
    NAME: ubuntu-1804

x64-ubuntu-2004:
  extends: .native_build_job
  needs:
    - x64-ubuntu-2004-container
  variables:
    NAME: ubuntu-2004

x64-freebsd-12-build:
  extends: .cirrus_build_job
  variables:
    NAME: freebsd-12
    CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
    CIRRUS_VM_IMAGE_SELECTOR: image_family
    CIRRUS_VM_IMAGE_NAME: freebsd-12-2
    UPDATE_COMMAND: pkg update
    UPGRADE_COMMAND: pkg upgrade -y
    INSTALL_COMMAND: pkg install -y

x64-freebsd-13-build:
  extends: .cirrus_build_job
  variables:
    NAME: freebsd-13
    CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
    CIRRUS_VM_IMAGE_SELECTOR: image_family
    CIRRUS_VM_IMAGE_NAME: freebsd-13-0
    UPDATE_COMMAND: pkg update
    UPGRADE_COMMAND: pkg upgrade -y
    INSTALL_COMMAND: pkg install -y

x64-macos-11-build:
  extends: .cirrus_build_job
  variables:
    NAME: macos-11
    CIRRUS_VM_INSTANCE_TYPE: osx_instance
    CIRRUS_VM_IMAGE_SELECTOR: image
    CIRRUS_VM_IMAGE_NAME: big-sur-base
    UPDATE_COMMAND: brew update
    UPGRADE_COMMAND: brew upgrade
    INSTALL_COMMAND: brew install
    PATH_EXTRA: /usr/local/opt/ccache/libexec:/usr/local/opt/gettext/bin:/usr/local/opt/libpcap/bin:/usr/local/opt/libxslt/bin:/usr/local/opt/rpcgen/bin
    PKG_CONFIG_PATH: /usr/local/opt/curl/lib/pkgconfig:/usr/local/opt/libpcap/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig:/usr/local/opt/ncurses/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig


# Cross compiled build jobs

aarch64-debian-sid:
  extends: .cross_build_job
  needs:
    - aarch64-debian-sid-container
  variables:
    NAME: debian-sid
    CROSS: aarch64

armv6l-debian-10:
  extends: .cross_build_job
  needs:
    - armv6l-debian-10-container
  variables:
    NAME: debian-10
    CROSS: armv6l

armv7l-debian-10:
  extends: .cross_build_job
  needs:
    - armv7l-debian-10-container
  variables:
    NAME: debian-10
    CROSS: armv7l

i686-debian-sid:
  extends: .cross_build_job
  needs:
    - i686-debian-sid-container
  variables:
    NAME: debian-sid
    CROSS: i686

mips-debian-10:
  extends: .cross_build_job
  needs:
    - mips-debian-10-container
  variables:
    NAME: debian-10
    CROSS: mips

mips64el-debian-sid:
  extends: .cross_build_job
  needs:
    - mips64el-debian-sid-container
  variables:
    NAME: debian-sid
    CROSS: mips64el

mipsel-debian-10:
  extends: .cross_build_job
  needs:
    - mipsel-debian-10-container
  variables:
    NAME: debian-10
    CROSS: mipsel

ppc64le-debian-10:
  extends: .cross_build_job
  needs:
    - ppc64le-debian-10-container
  variables:
    NAME: debian-10
    CROSS: ppc64le

s390x-debian-sid:
  extends: .cross_build_job
  needs:
    - s390x-debian-sid-container
  variables:
    NAME: debian-sid
    CROSS: s390x

mingw32-fedora-rawhide:
  extends: .cross_build_job
  needs:
    - mingw32-fedora-rawhide-container
  variables:
    NAME: fedora-rawhide
    CROSS: mingw32

mingw64-fedora-rawhide:
  extends: .cross_build_job
  needs:
    - mingw64-fedora-rawhide-container
  variables:
    NAME: fedora-rawhide
    CROSS: mingw64

# Sanitizers

sanitize-gcc:
  extends: .sanitizer_build_job
  variables:
    ASAN_OPTIONS: verify_asan_link_order=0
    CC: gcc
    SANITIZER: address,undefined

sanitize-clang:
  extends: .sanitizer_build_job
  variables:
    CC: clang
    SANITIZER: address,undefined


# This artifact published by this job is downloaded by libvirt.org to
# be deployed to the web root:
#    https://gitlab.com/libvirt/libvirt/-/jobs/artifacts/master/download?job=website
website:
  stage: builds
  image: $CI_REGISTRY_IMAGE/ci-centos-8:latest
  needs:
    - x64-centos-8-container
  before_script:
    - *script_variables
  script:
    - meson setup build --werror --prefix=$(pwd)/vroot || (cat build/meson-logs/meson-log.txt && exit 1)
    - ninja -C build install-web
    - mv vroot/share/doc/libvirt/html/ website
  artifacts:
    expose_as: 'Website'
    name: 'website'
    when: on_success
    expire_in: 30 days
    paths:
      - website


codestyle:
  stage: builds
  image: $CI_REGISTRY_IMAGE/ci-opensuse-leap-152:latest
  needs:
    - x64-opensuse-leap-152-container
  before_script:
    - *script_variables
  script:
    - meson setup build --werror || (cat build/meson-logs/meson-log.txt && exit 1)
    - ninja -C build libvirt-pot-dep
    - meson test -C build --suite syntax-check --no-rebuild --print-errorlogs


# This artifact published by this job is downloaded to push to Weblate
# for translation usage:
#    https://gitlab.com/libvirt/libvirt/-/jobs/artifacts/master/download?job=potfile
potfile:
  stage: builds
  image: $CI_REGISTRY_IMAGE/ci-centos-8:latest
  needs:
    - x64-centos-8-container
  rules:
    - if: "$CI_COMMIT_BRANCH == 'master'"
  before_script:
    - *script_variables
  script:
    - meson setup build --werror || (cat build/meson-logs/meson-log.txt && exit 1)
    - ninja -C build libvirt-pot-dep
    - ninja -C build libvirt-pot
    - cp po/libvirt.pot libvirt.pot
  artifacts:
    expose_as: 'Potfile'
    name: 'potfile'
    when: on_success
    expire_in: 30 days
    paths:
      - libvirt.pot


# Check that all commits are signed-off for the DCO.
# Skip on "libvirt" namespace, since we only need to run
# this test on developer's personal forks from which
# merge requests are submitted
check-dco:
  stage: sanity_checks
  needs: []
  image: registry.gitlab.com/libvirt/libvirt-ci/check-dco:master
  script:
    - /check-dco
  rules:
    - if: "$CI_PROJECT_NAMESPACE != 'libvirt'"
  variables:
    GIT_DEPTH: 1000


# Coverity job that is run only by schedules
coverity:
  image: $CI_REGISTRY_IMAGE/ci-centos-8:latest
  needs:
    - x64-centos-8-container
  stage: builds
  script:
    - curl https://scan.coverity.com/download/linux64 --form project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN -o /tmp/cov-analysis-linux64.tgz
    - tar xfz /tmp/cov-analysis-linux64.tgz
    - meson setup build --werror || (cat build/meson-logs/meson-log.txt && exit 1)
    - cov-analysis-linux64-*/bin/cov-build --dir cov-int meson compile -C build
    - tar cfz cov-int.tar.gz cov-int
    - curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL --form file=@cov-int.tar.gz --form version="$(git describe --tags)" --form description="$(git describe --tags) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
  rules:
    - if: "$CI_PIPELINE_SOURCE == 'schedule' && $COVERITY_SCAN_PROJECT_NAME && $COVERITY_SCAN_TOKEN"