include:
  - remote: "https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/ci-fairy.yml"
  - remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/alpine.yml'
  - remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/fedora.yml'
  - remote: 'https://gitlab.gnome.org/Infrastructure/freedesktop-ci-templates/-/raw/b61a03cabbf308e81289f7aaaf0b5a80a34ffb99/templates/debian.yml'
  - component: gitlab.gnome.org/GNOME/citemplates/release-service@master
    inputs:
      job-stage: "deploy"
      dist-job-name: "test-dist"
      tarball-artifact-path: "build/meson-dist/$CI_PROJECT_NAME-$CI_COMMIT_TAG.tar.xz"

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.
  TINYSPARQL_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
  - deploy

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

.tracker.fedora@common:
  variables:
    BASE_TAG: '2025-09-14.0'
    FDO_DISTRIBUTION_PACKAGES:
      asciidoc
      avahi-gobject-devel
      bash-completion-devel
      clang
      clang-analyzer
      cmake
      dbus-daemon
      diffutils
      file
      gcc
      gi-docgen
      git
      glib2-devel
      gobject-introspection-devel
      json-glib-devel
      libasan
      libicu-devel
      libsoup3-devel
      libstemmer-devel
      libubsan
      libxml2-devel
      man-db
      meson
      patch
      python-devel
      python3-gobject
      python3-jinja2
      python3-markdown
      python3-markupsafe
      python3-pip
      python3-pygments
      python3-typogrify
      sqlite-devel
      systemd-devel
      vala
      xmlto
      uncrustify

    FDO_DISTRIBUTION_EXEC: |
      # For tests, this isn't packaged in Fedora.
      pip3 install tap.py gcovr &&
      dnf clean all

.tracker.debian@common:
  variables:
    BASE_TAG: '2024-08-20.1'
    FDO_DISTRIBUTION_PACKAGES: 'ca-certificates python3-tap python3-pip umockdev libumockdev-dev upower asciidoc-base git man-db'
    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 &&
      # Prefer libsoup submodule, until we get libsoup >= 3.3.1
      apt-get -yq remove libsoup-3.0.dev &&
      pip3 install gcovr

.tracker.alpine@common:
  variables:
    BASE_TAG: '2024-08-16.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 libsoup3-dev libxml2-dev meson py3-gobject3 py3-setuptools py3-tappy sqlite-dev vala py3-pip mandoc'
    FDO_DISTRIBUTION_EXEC: |
      pip3 install gcovr

.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

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

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

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

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

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-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 setup 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 -Dstemmer=disabled --prefix /usr
    - meson compile -C build
  artifacts:
    expire_in: 1 day
    paths:
      - subprojects/packagecache
      - subprojects/libstemmer*/
      - 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

build-macos@arm64:
  stage: build
  tags:
    - macos
    - arm64
  needs:
    - check-commit-log
  variables:
    PKG_CONFIG_PATH: $CI_PROJECT_DIR/.venv/lib/pkgconfig
    SDKROOT: /opt/sdks/MacOSX11.3.sdk
  before_script:
    - |
      python3 -m venv .venv
      source .venv/bin/activate
      pip3 install meson==1.4.0 ninja==1.11.1.1
    # The introspection feature requires 'pkg-config' and 'bison'.
    - curl -L $CI_API_V4_URL/projects/30437/packages/generic/pkgconfig/v0.29.2+10/pkg-config-0.29.2+10_$(uname -m).tar.xz | tar -C .venv -xJ
    - curl -L $CI_API_V4_URL/projects/30438/packages/generic/bison/v3.8.2+3/bison-3.8.2+3_$(uname -m).tar.xz | tar -C .venv -xJ
    # The GLib subproject requires 'packaging'.
    - pip3 install packaging==24.2
    # Meson cannot handle circular dependencies in subprojects, so we have to build GLib and
    # GObject Introspection ourselves.
    - |
      git clone --depth 1 https://gitlab.gnome.org/gnome/glib.git
      meson setup -Dprefix=${CI_PROJECT_DIR}/.venv -Dintrospection=disabled -Dtests=false _glib_build glib
      meson compile -C_glib_build
      meson install -C_glib_build
    - |
      git clone --depth 1 --recurse-submodules https://gitlab.gnome.org/gnome/gobject-introspection.git
      meson setup -Dprefix=${CI_PROJECT_DIR}/.venv _gi_build gobject-introspection
      meson compile -C_gi_build
      meson install -C_gi_build
    - |
      meson configure -Dintrospection=enabled _glib_build
      meson compile -C_glib_build
      meson install -C_glib_build
  script:
    - meson setup build -Dlibsoup3:tests=false -Dlibsoup3:docs=disabled -Dlibsoup3:sysprof=disabled -Dlibsoup3:tls_check=false -Ddocs=false -Dman=false -Dintrospection=disabled -Dvapi=disabled -Dsystemd_user_services=false
    - meson compile -C build
  artifacts:
    expire_in: 1 day
    when: always
    paths:
      - build/meson-logs/

.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 --suite tinysparql -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=../subprojects
        --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 "TINYSPARQL_DEBUG: ${TINYSPARQL_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
  <<: *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-dist:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: test
  needs:
    - build-fedora@x86_64
  script:
    - |
      meson compile -C build
      dbus-run-session meson dist -C build --include-subprojects
  artifacts:
    expose_as: 'Tarball'
    paths:
      - build/meson-dist/

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-fedora-rawhide@x86_64
    - test-fedora-rawhide@aarch64
    # These currently break gcovr
    #- test-debian@x86_64
    #- test-alpine@x86_64

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 -Dstemmer=enabled
    - ../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

asan:
  extends:
    - .fdo.distribution-image@fedora
    - .tracker.fedora:latest@x86_64
  stage: analysis
  needs:
    - build-fedora-container@x86_64
  script:
    - meson --buildtype=debug build -Dsystemd_user_services=false -Db_sanitize=address
    - ninja -C build
    # Add verify_asan_link_order=0 over asan defaults, for functional tests with python interpreter
    - LOCALSEARCH_DEBUG=tests ASAN_OPTIONS=verify_asan_link_order=0:halt_on_error=1:abort_on_error=1:print_summary=1 dbus-run-session meson test -C build -t $MESON_TEST_TIMEOUT_MULTIPLIER --print-errorlogs
  artifacts:
    paths:
      - build/meson-logs

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