include:
  - remote: "https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/ci-fairy.yml"
  - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/alpine.yml'
  - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/fedora.yml'
  - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/debian.yml'

variables:
  FDO_UPSTREAM_REPO: GNOME/tinysparql
  MESON_TEST_TIMEOUT_MULTIPLIER: 3
  # These can be used to see verbose log output from the functional-tests.
  # See HACKING.md for more information.
  TRACKER_DEBUG: ""

  # This can be used when debugging test failures that only occur within GitLab CI.
  MESON_TEST_EXTRA_ARGS: ""

stages:
  - check
  - review
  - prepare
  - code-review
  - build
  - test
  - analysis
  - website

workflow:
  rules:
    # Allow to switch from branch pipelines to MR pipelines seamlessly
    # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    # Don't trigger a branch pipeline if there is an open MR
    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
      when: never
    - if: '$CI_COMMIT_BRANCH'
    - if: '$CI_COMMIT_TAG'

.manual-pipeline-guard:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_TAG'
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    - if: '$CI_COMMIT_BRANCH =~ /^tracker-[0-9-]\.[0-9-]+$/'
    # Avoid catchall `when: manual` rule which might
    # cause duplicate pipelines to be triggered.
    # https://docs.gitlab.com/ee/ci/jobs/job_control.html#avoid-duplicate-pipelines
    #
    # Also make it so pipelines without MR need to be started
    # manually, since their state will most likely be WIP
    - if: '$CI_COMMIT_BRANCH'
      when: 'manual'

.check-template: &check
  extends:
    - .fdo.ci-fairy
  artifacts:
    expire_in: 1 week
    paths:
      - check-junit-report.xml
    reports:
      junit: check-junit-report.xml

repo-sanity:
  stage: check
  script:
    - >
      if [[ -z "$CI_REGISTRY_IMAGE" ]] ;
      then
        .gitlab-ci/simple-junit-report.sh check-junit-report.xml \
          repo-sanity "The container registry should be enabled in the project general settings panel at $CI_PROJECT_URL/edit" ;
        exit 1 ;
      fi
  rules:
    - !reference [.manual-pipeline-guard, rules]
  <<: *check

check-commit-log:
  variables:
    GIT_DEPTH: "100"
  stage: review
  script:
    - ci-fairy check-commits --junit-xml=check-junit-report.xml && exit 0;
      if [[ -z "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]] ;
      then
        echo "'ci-fairy check-commits' found commit messages with unexpected format, see https://wiki.gnome.org/Git/CommitMessages for the recommended guidelines. Please fix those before filing a merge request, this will be handled as a pipeline failure there." ;
        exit 255 ;
      fi ;
      exit 1
  allow_failure:
    exit_codes:
      - 255
  needs:
    - repo-sanity
  <<: *check

check-merge-request:
  variables:
    GIT_STRATEGY: none
  stage: review
  script:
    - if [[ x"$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" != "x" ]] ;
      then
        ci-fairy check-merge-request --require-allow-collaboration --junit-xml=check-junit-report.xml ;
      else
        echo "Not a merge request" ;
      fi
  needs:
    - repo-sanity
  <<: *check

.tracker.fedora@common:
  variables:
    BASE_TAG: '2024-06-05.2'
    FDO_DISTRIBUTION_PACKAGES:
      clang
      clang-analyzer
      cmake
      diffutils
      gcovr
      git
      libasan
      libsoup-devel
      libubsan
      patch
      python-devel
      python3-gobject
      python3-jinja2
      python3-markdown
      python3-markupsafe
      python3-pip
      python3-pygments
      python3-typogrify
      umockdev-devel
      xmlto
      uncrustify

    FDO_DISTRIBUTION_EXEC: |
      if [ -z $(command -v dnf5) ]; then
        dnf install -y 'dnf-command(builddep)' 'dnf-command(download)';
      else
        dnf install -y 'dnf5-command(builddep)' 'dnf5-command(download)';
      fi &&
      dnf builddep -y tracker --setopt=install_weak_deps=False &&
      # For tests, this isn't packaged in Fedora.
      pip3 install tap.py &&
      dnf clean all &&
      # Prefer gi-docgen from the submodule
      dnf remove -y gi-docgen --noautoremove

.tracker.debian@common:
  variables:
    BASE_TAG: '2024-06-06.1'
    FDO_DISTRIBUTION_PACKAGES: 'ca-certificates python3-tap umockdev libumockdev-dev upower asciidoc-base git gcovr'
    FDO_DISTRIBUTION_EXEC: |
      export DEBIAN_FRONTEND=noninteractive &&
      sed -i 's/^Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/debian.sources &&
      apt-get -yq update && apt-get -yq upgrade &&
      apt-get -yq build-dep tracker &&
      rm -f /etc/subgid /etc/subuid &&
      rm -Rf /home/debian

.tracker.alpine@common:
  variables:
    BASE_TAG: '2024-03-09.0'
    FDO_DISTRIBUTION_PACKAGES: 'alpine-sdk asciidoc bash-completion dbus dbus-dev git glib-dev gobject-introspection-dev gtk-doc icu-dev json-glib-dev libsoup-dev libxml2-dev meson py3-gobject3 py3-setuptools py3-tappy sqlite-dev gcovr vala'

.tracker.fedora:latest@x86_64:
  extends: .tracker.fedora@common
  variables:
    FDO_DISTRIBUTION_VERSION: latest
    FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"

.tracker.fedora:rawhide@x86_64:
  extends: .tracker.fedora@common
  variables:
    FDO_DISTRIBUTION_VERSION: rawhide
    FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"

.tracker.fedora:latest@aarch64:
  extends: .tracker.fedora@common
  variables:
    FDO_DISTRIBUTION_VERSION: latest
    FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}"
  tags:
    - aarch64

.tracker.fedora:rawhide@aarch64:
  extends: .tracker.fedora@common
  variables:
    FDO_DISTRIBUTION_VERSION: rawhide
    FDO_DISTRIBUTION_TAG: "aarch64-${BASE_TAG}"
  tags:
    - aarch64

.tracker.debian:stable@x86_64:
  extends: .tracker.debian@common
  variables:
    FDO_DISTRIBUTION_VERSION: stable
    FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"

.tracker.alpine:latest@x86_64:
  extends: .tracker.alpine@common
  variables:
    FDO_DISTRIBUTION_VERSION: latest
    FDO_DISTRIBUTION_TAG: "x86_64-${BASE_TAG}"

build-fedora-container@x86_64:
  extends:
    - .fdo.container-build@fedora
    - .tracker.fedora:latest@x86_64
  stage: prepare
  variables:
    GIT_STRATEGY: none
  needs:
    - check-commit-log
    - check-merge-request

build-fedora-rawhide-container@x86_64:
  extends:
    - .fdo.container-build@fedora
    - .tracker.fedora:rawhide@x86_64
  stage: prepare
  variables:
    GIT_STRATEGY: none
  allow_failure: true
  needs:
    - check-commit-log
    - check-merge-request

build-fedora-container@aarch64:
  extends:
    - .fdo.container-build@fedora
    - .tracker.fedora:latest@aarch64
  stage: prepare
  variables:
    GIT_STRATEGY: none
  needs:
    - check-commit-log
    - check-merge-request

build-fedora-rawhide-container@aarch64:
  extends:
    - .fdo.container-build@fedora
    - .tracker.fedora:rawhide@aarch64
  stage: prepare
  variables:
    GIT_STRATEGY: none
  allow_failure: true
  needs:
    - check-commit-log
    - check-merge-request

build-debian-container@x86_64:
  extends:
    - .fdo.container-build@debian
    - .tracker.debian:stable@x86_64
  stage: prepare
  variables:
    GIT_STRATEGY: none
  needs:
    - check-commit-log
    - check-merge-request

build-alpine-container@x86_64:
  extends:
    - .fdo.container-build@alpine
    - .tracker.alpine:latest@x86_64
  stage: prepare
  variables:
    GIT_STRATEGY: none
  needs:
    - check-commit-log
    - check-merge-request

check-code-style:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  needs:
    - build-fedora-container@x86_64
  stage: code-review
  script:
    - git fetch origin main;
      export common_parent_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1) ;
      python3 -u ./check-style.py --dry-run --sha $common_parent_sha ;
  allow_failure: true

.build-template: &build
  stage: build
  script:
    - meson . build -Ddocs=$([ -z "$NO_DOCS" ] && echo "true" || echo "false") -Db_coverage=true -Db_lto=true -Dsystemd_user_services=false -Dtests_tap_protocol=true -Davahi=disabled --prefix /usr
    - ninja -C build
  artifacts:
    expire_in: 1 day
    paths:
      - build

build-fedora@x86_64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  needs:
    - build-fedora-container@x86_64
  <<: *build

build-fedora-rawhide@x86_64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:rawhide@x86_64
  needs:
    - build-fedora-rawhide-container@x86_64
  allow_failure: true
  <<: *build

build-fedora@aarch64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@aarch64
  needs:
    - build-fedora-container@aarch64
  allow_failure: true
  variables:
    NO_DOCS: "true"
  <<: *build

build-fedora-rawhide@aarch64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:rawhide@aarch64
  needs:
    - build-fedora-rawhide-container@aarch64
  allow_failure: true
  variables:
    NO_DOCS: "true"
  <<: *build

build-debian-stable@x86_64:
  extends:
    - .fdo.distribution-image@debian
    - .tracker.debian:stable@x86_64
  needs:
    - build-debian-container@x86_64
  variables:
    NO_DOCS: "true"
  <<: *build

build-alpine-latest@x86_64:
  extends:
    - .fdo.distribution-image@alpine
    - .tracker.alpine:latest@x86_64
  needs:
    - build-alpine-container@x86_64
  variables:
    NO_DOCS: "true"
  <<: *build

.test-template: &test
  stage: test
  variables:
    G_SLICE: "always-malloc"
    MALLOC_CHECK_: "3"
  script:
    - cd build
    - |
      # Remove the many "CI_" variables from the environment. Meson dumps the
      # whole environment for every failed test, and that gives a whole
      # screenful of junk each time unless we strip these.
      unset $(env|grep -o '^CI_[^=]*')
      ninja clean; ninja
      env LANG=C.UTF-8 LC_ALL=C.UTF-8 dbus-run-session meson test -t $MESON_TEST_TIMEOUT_MULTIPLIER --print-errorlogs ${MESON_TEST_EXTRA_ARGS}
  after_script:
    - pushd build
    - gcovr --root=.. --filter='\.\./src/'
        --exclude=../utils --exclude=../examples --exclude=../docs/reference
        --exclude='\.\./build/.*\.[ch]$' --exclude='.*/tests/.*\.[ch]$'
        --merge-mode-functions=separate
        --gcov-ignore-parse-errors=negative_hits.warn
        --json --print-summary --output=../coverage-${CI_JOB_NAME}.json
    - popd
    - |
      echo "Distribution: "
      echo
      grep -e '^NAME=' -e '^VERSION=' /etc/os-release
      echo
      echo "Test suite settings:"
      echo
      echo "G_MESSAGES_DEBUG: ${G_MESSAGES_DEBUG}"
      echo "TRACKER_DEBUG: ${TRACKER_DEBUG}"
      echo "MESON_TEST_EXTRA_ARGS: ${MESON_TEST_EXTRA_ARGS}"
      echo
      echo "These values can be set at https://gitlab.gnome.org/GNOME/tinysparql/pipelines/new"
  artifacts:
    expire_in: 1 day
    when: always
    paths:
    - build
    - coverage-*.json
    reports:
      junit: "build/meson-logs/testlog.junit.xml"

test-fedora@x86_64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  needs:
    - build-fedora@x86_64
  <<: *test

test-fedora-rawhide@x86_64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:rawhide@x86_64
  needs:
    - build-fedora-rawhide@x86_64
  allow_failure: true
  tags:
    # There is a mismatch between syscalls and seccomp rules in
    # some runners, using `crun` is advised in the mean time, see
    # https://gitlab.gnome.org/Infrastructure/GitLab/-/issues/545
    - crun
  <<: *test

test-fedora@aarch64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@aarch64
  needs:
    - build-fedora@aarch64
  allow_failure: true
  <<: *test

test-fedora-rawhide@aarch64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:rawhide@aarch64
  needs:
    - build-fedora-rawhide@aarch64
  allow_failure: true
  <<: *test

test-debian@x86_64:
  extends:
    - .fdo.distribution-image@debian
    - .tracker.debian:stable@x86_64
  needs:
    - build-debian-stable@x86_64
  <<: *test

test-alpine@x86_64:
  extends:
    - .fdo.distribution-image@alpine
    - .tracker.alpine:latest@x86_64
  needs:
    - build-alpine-latest@x86_64
  <<: *test

test-website:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: test
  script:
    - export install_prefix="$(pwd)/tracker-install"
    # Build tracker and install.
    - mkdir website-build; pushd website-build; meson .. --prefix="$install_prefix" -Dsystemd_user_services=false; ninja; ninja install; popd
    # Copy the gi-docgen website out of the install tree
    - cp -a $install_prefix/share/doc/Tsparql-3.0 ./website
    # Add the redirects
    - cp docs/website/redirect-to-website.html docs/website/_redirects ./website
  artifacts:
    expose_as: 'Website'
    paths:
      - website
      - website/index.html
  needs:
    - build-fedora-container@x86_64
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
      when: never
    - when: always

test-soup2@x86_64:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  needs:
    - build-fedora@x86_64
  before_script:
    - meson configure -Dsoup=soup2 build
  <<: *test

coverage:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: analysis
  allow_failure: true
  script:
    - mkdir coveragereport
    - gcovr --add-tracefile 'coverage-*.json'
        --merge-mode-functions=separate
        --html-details --print-summary --output coveragereport/index.html
    - gcovr --add-tracefile 'coverage-*.json'
        --merge-mode-functions=separate
        --xml --output coveragereport/coverage.xml
  coverage: '/^lines: (\d+\.\d+\%)/'
  artifacts:
    expose_as: 'Coverage'
    when: always
    paths:
    - coveragereport
    - coveragereport/index.html
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coveragereport/coverage.xml
  needs:
    - test-fedora@x86_64
    - test-fedora@aarch64
    - test-alpine@x86_64
    - test-soup2@x86_64
    # As of 2024-06-06, Fedora Rawhide has gcovr 7.2, other distros have
    # 6.0. The "format_version" in the JSON output is "0.6" for gcovr 7.2,
    # and "0.5" for older versions. This produces an incompatibility error
    # when merging, so we temporarily exclude rawhide from coverage.
    #- test-fedora-rawhide@x86_64
    #- test-fedora-rawhide@aarch64

coverity:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: analysis
  allow_failure: true
  script:
    - curl https://scan.coverity.com/download/linux64 --data "token=$COVERITY_TOKEN&project=Tracker" --output /tmp/coverity_tool.tgz
    - tar zxf /tmp/coverity_tool.tgz
    - mkdir coverity-build
    - cd coverity-build
    - env CC=clang meson setup .. -Dsystemd_user_services=false
    - ../cov-analysis-linux64-*/bin/cov-build --dir cov-int ninja
    - tar czf cov-int.tar.gz cov-int
    - curl https://scan.coverity.com/builds?project=Tracker
      --form token=$COVERITY_TOKEN --form email=carlosg@gnome.org
      --form file=@cov-int.tar.gz --form version="`git describe --tags`"
      --form description="gitlab CI build"
  needs:
    - build-fedora-container@x86_64
  only:
    - main
  except:
    changes:
      - po/*.po

static-scan:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: analysis
  needs:
    - build-fedora-container@x86_64
  script:
    - meson --buildtype=debug _scan_build -Dsystemd_user_services=false
    - ninja -C _scan_build scan-build
  artifacts:
    paths:
      - _scan_build/meson-logs
  allow_failure: true

pages:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: website
  script:
    - mv website public
  artifacts:
    paths:
      - public
  needs:
    - test-website
  only:
    - main
