variables:
    # detect_leaks=0 – many of the tests currently trigger ASan memory leak
    #   detections, so disable these for now
    # detect_stack_use_after_return=1 – stronger checks on variable lifetimes
    # exitcode=42 – allow distinguishing ASan crashes from regular error exits
    ASAN_OPTIONS: detect_leaks=0,detect_stack_use_after_return=1,exitcode=42
    FF_TIMESTAMPS: true
    # exitcode=42 – allow distinguishing UBSan crashes from regular error exits
    # print_stacktrace=1 – show a usable backtrace on error
    UBSAN_OPTIONS: exitcode=42,print_stacktrace=1

stages:
    - build_docker_images
    - push_docker_images
    - source
    - build
    - test
    - deploy

# generate doxygen documentation from sources for https://graphviz.gitlab.io/graphviz/doxygen/
pages:
    needs:
        - job: docker_build_ubuntu-24.04
          artifacts: false
        - job: portable-source
          artifacts: true
    script:
        - ci/pages.sh
        - echo "Preview:" "https://${CI_PROJECT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_NAME}/-/jobs/${CI_JOB_ID}/artifacts/public/doxygen/index.html"
    artifacts:
        expire_in: 1 week
        paths:
            - public
    image: "$CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA"
    variables:
        IMAGE: ubuntu-24.04
    except:
        - tags
    # GitLab Pages only allow one hosted root per repository.
    # We don't want non-main branches overwriting this one hosted root.
    # Contributors wanting to test pages changes should push to their own
    # repo's main branch.
    only:
        - main
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

portable-source:
    # Doesn't have to wait for all the previous stages, only a docker image of
    # ubuntu-22.04 is required
    needs:
      - docker_build_ubuntu-22.04
    stage: source
    tags:
        - saas-linux-small-amd64
    image: "$CI_REGISTRY_IMAGE/ubuntu-22.04:$CI_COMMIT_SHA"
    script:
        - ./autogen.sh
        - ./configure --enable-man-pdfs
        - make dist
        - make dist-xz
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
            - graphviz-*.tar.gz
            - graphviz-*.tar.xz
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

.build_template: &rpm_build_definition
    stage: build
    script:
        - ci/linux-build-job-script.sh
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
            - Packages/*/*.tar.xz
            - Packages/*/*.rpm
            - Metadata/*/*/configure.log
        reports:
            metrics: metrics.txt
    except:
        - tags
    image: "$CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA"
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

.build_template: &deb_build_definition
    stage: build
    script:
        - source /opt/virtualenv/bin/activate
        - ci/linux-build-job-script.sh
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
            - Packages/*/*.tar.xz
            - Packages/*/*deb
            - Metadata/*/*/configure.log
        reports:
            metrics: metrics.txt
    except:
        - tags
    image: "$CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA"
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

.build_template: &macos_build_definition
    stage: build
    script:
        - source ci/macos-install-build-dependencies.sh
        - logfile=`mktemp`
        - ci/build.sh 2>&1 | tee $logfile
        - echo "$CI_JOB_NAME-warnings `grep -c 'warning:' $logfile`" | tee metrics.txt
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
            - Packages/*/*.zip
            - Packages/*/*.pkg
        reports:
            metrics: metrics.txt
    except:
        - tags
    image: macos-14-xcode-15
    # Most submitters don't have access to the macOS runners, and if they try
    # to run macOS pipeline jobs, the jobs will hang forever.  This variable is
    # only set on repos that have access to macOS runners, in GitLab repo
    # settings.
    # https://gitlab.com/graphviz/graphviz/-/settings/ci_cd
    only:
        variables:
          - $ENABLE_GRAPHVIZ_MACOS_CI
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout


.build_template: &windows_build_definition
    stage: build
    needs: []
    script:
        # abort on cmdlet non-terminating errors
        - $ErrorActionPreference = "Stop"
        # make sub-scripts default to aborting on cmdlet non-terminating errors
        - $PSDefaultParameterValues['*:ErrorAction']='Stop'
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
        - python --version
        - if (-not $?) { throw "command failed" }
        # Install and set PATH
        - $Env:graphviz_install_dir = "C:\Graphviz"
        # Build
        - Set-ExecutionPolicy Bypass -Force -Scope Process
        - python ci/windows_build.py --platform $Env:project_platform --configuration $Env:configuration --build-shared-libs=$Env:BUILD_SHARED_LIBS
        - if (-not $?) { throw "command failed" }
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
        - Packages/*/*.exe
        - Packages/*/*.zip
        reports:
            metrics: metrics.txt
            junit: report.xml
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

.test_template: &test_definition
    stage: test
    script:
        - source /opt/virtualenv/bin/activate
        - ci/test-job-script.sh
    artifacts:
        reports:
            junit: report.xml
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

.linux_test_template: &linux_test_definition
    <<: *test_definition
    image: "$CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA"

rocky8-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_rocky8
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky8

rocky9-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_rocky9
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky9

rocky10-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_rocky10
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky10

fedora43-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_fedora43
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: fedora43

ubuntu-22.04-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-22.04
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-22.04

ubuntu-26.04-debug-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
        - job: portable-source
          artifacts: true
    before_script:
        - export CFLAGS="-DDEBUG"
        - export CXXFLAGS="-DDEBUG"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

ubuntu-26.04-static-build:
    <<: *deb_build_definition
    before_script:
        - export CONFIGURE_OPTIONS="--disable-shared --enable-static"
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
        - job: portable-source
          artifacts: true
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
            - Metadata/*/*/configure.log
        reports:
            metrics: metrics.txt
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

ubuntu-24.04-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-24.04
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-24.04

ubuntu-25.10-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-25.10
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-25.10

ubuntu-26.04-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

out-of-source-build:
    <<: *deb_build_definition
    script:
        - logfile=`mktemp`
        - ci/out-of-source-build.sh |& tee $logfile
        - echo "$CI_JOB_NAME-warnings `grep -c 'warning:' $logfile`" | tee metrics.txt
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
        - job: portable-source
          artifacts: true
    tags:
        - saas-linux-small-amd64
    artifacts:
        when: on_success
        expire_in: 1 week
        reports:
            metrics: metrics.txt
    variables:
      IMAGE: ubuntu-26.04

macos-autotools-build:
    <<: *macos_build_definition
    needs:
        - job: portable-source
          artifacts: true
    before_script:
        - export build_system="autotools"
    tags:
        - saas-macos-medium-m1

windows-mingw64-build:
    stage: build
    needs:
        - job: portable-source
          artifacts: true
    script:
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ci\mingw-prepare.ps1
        - $Env:build_system = "autotools"
        - $Env:use_autogen = "yes"
        - C:\msys64\msys2_shell.cmd -defterm -mingw64 -here -no-start -l -c 'cd $CI_PROJECT_DIR && ci/mingw-build.sh'
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

windows-mingw64-static-build:
    stage: build
    needs:
        - job: portable-source
          artifacts: true
    script:
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ci\mingw-prepare.ps1
        - $Env:build_system = "autotools"
        - $Env:CONFIGURE_OPTIONS = "--disable-shared --enable-static"
        - $Env:use_autogen = "yes"
        - C:\msys64\msys2_shell.cmd -defterm -mingw64 -here -no-start -l -c 'cd $CI_PROJECT_DIR && ci/mingw-build.sh'
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

windows-cygwin-build:
    stage: build
    needs:
        - job: portable-source
          artifacts: true
    script:
        # drop environment variables we do not need
        - $Env:CI_COMMIT_DESCRIPTION = $null
        - $Env:CI_COMMIT_MESSAGE = $null
        - $Env:CI_COMMIT_TITLE = $null
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - wget https://cygwin.com/setup-x86_64.exe -OutFile C:\setup-x86_64.exe
        - Start-Process "C:\setup-x86_64.exe" -ArgumentList "--quiet-mode --site https://mirrors.kernel.org/sourceware/cygwin --wait" -wait
        - $Env:Path = "C:\cygwin64\bin;" + $Env:Path
        - $Env:build_system = "autotools"
        - C:\cygwin64\bin\bash -l -c 'cd $CI_PROJECT_DIR && ci/cygwin-build.sh'
    artifacts:
        when: always
        expire_in: 1 week
        paths:
            - Packages/*/*.xz
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

windows-cygwin-build-using-autogen:
    stage: build
    needs: []
    script:
        # drop environment variables we do not need
        - $Env:CI_COMMIT_DESCRIPTION = $null
        - $Env:CI_COMMIT_MESSAGE = $null
        - $Env:CI_COMMIT_TITLE = $null
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - wget https://cygwin.com/setup-x86_64.exe -OutFile C:\setup-x86_64.exe
        - Start-Process "C:\setup-x86_64.exe" -ArgumentList "--quiet-mode --site https://mirrors.kernel.org/sourceware/cygwin --wait" -wait
        - $Env:Path = "C:\cygwin64\bin;" + $Env:Path
        - $Env:build_system = "autotools"
        - $Env:use_autogen = "yes"
        - C:\cygwin64\bin\bash -l -c 'cd $CI_PROJECT_DIR && ci/cygwin-build.sh'
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

ubuntu-22.04-cmake-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-22.04
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="-Dwith_cxx_api=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_SMYRNA=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-22.04

ubuntu-24.04-cmake-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-24.04
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_SMYRNA=ON"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-24.04

ubuntu-25.10-cmake-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-25.10
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_SMYRNA=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_RUBY=OFF"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-25.10

ubuntu-26.04-cmake-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_SMYRNA=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_RUBY=OFF"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

ubuntu-26.04-cmake-minimal-build:
    <<: *deb_build_definition
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS=""
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_LTDL=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -Dwith_digcola=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -Dwith_ipsepcola=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -Dwith_ortho=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -Dwith_sfdp=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_SMYRNA=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_TCL=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_SWIG=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GDK=OFF"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

ubuntu-26.04-cmake-ASan-build-and-test-including-ctest:
    stage: build
    needs:
        - job: docker_build_ubuntu-26.04
          artifacts: false
    script:
        - source /opt/virtualenv/bin/activate
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=address,undefined -g -Werror"
        - export CXXFLAGS="-fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=address,undefined -g -Werror -DBOOST_ALLOW_DEPRECATED_HEADERS"
        - export LDFLAGS="-fno-omit-frame-pointer -fsanitize=address,undefined -fno-sanitize-recover=address,undefined -g -Werror"
        - export CMAKE_OPTIONS="-Duse_coverage=ON -Dwith_cxx_tests=ON -Dwith_cxx_api=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_SMYRNA=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_RUBY=OFF"
        - ci/linux-build-job-script.sh
        - echo 'leak:*libfontconfig*' > suppressions.txt
        - export LSAN_OPTIONS=suppressions=$(pwd)/suppressions.txt
        - ci/linux-test-including-ctest-job-script.sh
    # enable test coverage visualization in MR diff view
    coverage: '/  lines\.{6}: \d+\.\d+%/'
    artifacts:
        paths:
            - coverage/**
            # Test artifacts for manual inspection in case the ctest suite fails
            - build/tests/test_artifacts/**
        reports:
            junit: [./report.xml, build/tests/test_*.xml]
            coverage_report:
                coverage_format: cobertura
                path: coverage.xml
            metrics: metrics.txt
    except:
        - tags
    tags:
        - saas-linux-small-amd64
    image: "$CI_REGISTRY_IMAGE/ubuntu-26.04:$CI_COMMIT_SHA"
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

rocky8-cmake-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_rocky8
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror -Wno-error=missing-braces"
        - export CXXFLAGS="-Werror -Wno-error=missing-braces"
        - export CMAKE_OPTIONS="-DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky8

rocky9-cmake-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_rocky9
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror -Wno-error=missing-braces"
        - export CXXFLAGS="-Werror -Wno-error=missing-braces"
        - export CMAKE_OPTIONS="-DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky9

rocky10-cmake-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_rocky10
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror -Wno-error=missing-braces"
        - export CXXFLAGS="-Werror -Wno-error=missing-braces"
        - export CMAKE_OPTIONS="-DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky10

fedora43-cmake-build:
    <<: *rpm_build_definition
    needs:
        - job: docker_build_fedora43
          artifacts: false
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="-DWITH_SMYRNA=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: fedora43

macos-cmake-build:
    <<: *macos_build_definition
    needs: []
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror -Wno-error=implicit-fallthrough"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="-Dwith_cxx_api=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_QUARTZ=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
        # disable Ruby bindings because Ruby headers are buggy on macOS
        # https://gitlab.com/graphviz/graphviz/-/issues/2625
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_RUBY=OFF"
    tags:
        - saas-macos-medium-m1

macos-cmake-static-build:
    <<: *macos_build_definition
    needs: []
    before_script:
        - export build_system="cmake"
        # fail on any compiler warnings
        - export CFLAGS="-Werror -Wno-error=implicit-fallthrough"
        - export CXXFLAGS="-Werror"
        - export CMAKE_OPTIONS="-Dwith_cxx_api=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_LTDL=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_EXPAT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_GVEDIT=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_QUARTZ=ON"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DWITH_ZLIB=ON"
        # disable Ruby bindings because Ruby headers are buggy on macOS
        # https://gitlab.com/graphviz/graphviz/-/issues/2625
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_RUBY=OFF"
        - export CMAKE_OPTIONS="$CMAKE_OPTIONS -DBUILD_SHARED_LIBS=OFF"
    tags:
        - saas-macos-medium-m1

windows-cmake-Win32-release-build:
    <<: *windows_build_definition
    before_script:
        - $Env:project_platform = "Win32"
        - $Env:configuration = "Release"
        - $Env:BUILD_SHARED_LIBS = "ON"

windows-cmake-Win32-debug-build:
    <<: *windows_build_definition
    before_script:
        - $Env:project_platform = "Win32"
        - $Env:configuration = "Debug"
        - $Env:BUILD_SHARED_LIBS = "ON"

windows-cmake-x64-release-build:
    <<: *windows_build_definition
    before_script:
        - $Env:project_platform = "x64"
        - $Env:configuration = "Release"
        - $Env:BUILD_SHARED_LIBS = "ON"

windows-cmake-x64-debug-build:
    <<: *windows_build_definition
    before_script:
        - $Env:project_platform = "x64"
        - $Env:configuration = "Debug"
        - $Env:BUILD_SHARED_LIBS = "ON"

.build_template: &windows_build_without_artifacts_definition
    <<: *windows_build_definition
    artifacts:
        when: on_success
        expire_in: 1 week
        reports:
            metrics: metrics.txt
            junit: report.xml

windows-cmake-Win32-asan-debug-build:
    <<: *windows_build_without_artifacts_definition
    before_script:
        - $Env:project_platform = "Win32"
        - $Env:configuration = "Debug"
        - $Env:BUILD_SHARED_LIBS = "ON"
        - $Env:CFLAGS = "-fsanitize=address"
        - $Env:CXXFLAGS = "-fsanitize=address"
        # Ensure `clang_rt.asan_dynamic-i386.dll` is found
        - $msvc_path = "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC"
        - $msvc_version = & invoke-Expression "Get-ChildItem -Path '$msvc_path' -Name"
        - $Env:Path += ";$msvc_path\$msvc_version\bin\Hostx64\x86"
    timeout: 2 hours

windows-cmake-x64-asan-debug-build:
    <<: *windows_build_without_artifacts_definition
    before_script:
        - $Env:project_platform = "x64"
        - $Env:configuration = "Debug"
        - $Env:BUILD_SHARED_LIBS = "ON"
        - $Env:CFLAGS = "-fsanitize=address"
        - $Env:CXXFLAGS = "-fsanitize=address"
        # Ensure `clang_rt.asan_dynamic-x86_64.dll` is found
        - $msvc_path = "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC"
        - $msvc_version = & invoke-Expression "Get-ChildItem -Path '$msvc_path' -Name"
        - $Env:Path += ";$msvc_path\$msvc_version\bin\Hostx64\x64"
    timeout: 2 hours

windows-cmake-x64-debug-static-build:
    <<: *windows_build_without_artifacts_definition
    before_script:
        - $Env:project_platform = "x64"
        - $Env:configuration = "Debug"
        - $Env:BUILD_SHARED_LIBS = "OFF"

windows-mingw64-cmake-build:
    stage: build
    needs: []
    script:
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ci\mingw-prepare.ps1
        - $Env:build_system = "cmake"
        - C:\msys64\msys2_shell.cmd -defterm -mingw64 -here -no-start -l -c 'cd $CI_PROJECT_DIR && ci/mingw-build.sh'
    artifacts:
        when: always
        expire_in: 1 week
        paths:
            - Packages/*/*.exe
            - Packages/*/*.zip
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

windows-mingw64-cmake-release-build:
    stage: build
    needs: []
    script:
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ci\mingw-prepare.ps1
        - $Env:build_system = "cmake"
        - $Env:CMAKE_OPTIONS = "-DCMAKE_BUILD_TYPE=Release"
        - C:\msys64\msys2_shell.cmd -defterm -mingw64 -here -no-start -l -c 'cd $CI_PROJECT_DIR && ci/mingw-build.sh'
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

windows-cygwin-cmake-build:
    stage: build
    needs: []
    script:
        # drop environment variables we do not need
        - $Env:CI_COMMIT_DESCRIPTION = $null
        - $Env:CI_COMMIT_MESSAGE = $null
        - $Env:CI_COMMIT_TITLE = $null
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        # remove pre-installed Windows Python to avoid CMake picking it up
        - Remove-Item -Path 'C:\Python313' -Recurse -Force
        - wget https://cygwin.com/setup-x86_64.exe -OutFile C:\setup-x86_64.exe
        - Start-Process "C:\setup-x86_64.exe" -ArgumentList "--quiet-mode --site https://mirrors.kernel.org/sourceware/cygwin --wait" -wait
        - $Env:Path = "C:\cygwin64\bin;" + $Env:Path
        - $Env:build_system = "cmake"
        # fail on any compiler warnings
        - $Env:CFLAGS = "-Werror"
        - $Env:CXXFLAGS = "-Werror"
        - C:\cygwin64\bin\bash -l -c 'cd $CI_PROJECT_DIR && ci/cygwin-build.sh'
    artifacts:
        when: always
        expire_in: 1 week
        paths:
            - Packages/*/*.bz2
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

meta-data:
    stage: test
    script:
        - CONFIGURE_LOGS=Metadata/*/*/configure.log
        - ci/generate_configuration_table.py ${CONFIGURE_LOGS} > configuration-long-no-color.html
        - ci/generate_configuration_table.py --short ${CONFIGURE_LOGS} > configuration-short-no-color.html
        - ci/generate_configuration_table.py --short --color ${CONFIGURE_LOGS} > configuration-short-color-green-red.html
        - ci/generate_configuration_table.py --short --colors black:red ${CONFIGURE_LOGS} > configuration-short-color-red-only.html
    artifacts:
        paths:
            - configuration-*.html
    except:
        - tags
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

ubuntu-22.04-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "ubuntu-22.04-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-22.04

ubuntu-24.04-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "ubuntu-24.04-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-24.04

ubuntu-25.10-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "ubuntu-25.10-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-25.10

ubuntu-26.04-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "ubuntu-26.04-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

rocky8-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "rocky8-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky8

rocky9-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "rocky9-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky9

rocky10-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "rocky10-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky10

fedora43-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="autotools"
    needs:
        - job: "fedora43-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: fedora43

macos-autotools-test:
    <<: *test_definition
    before_script:
        - source ci/macos-install-runtime-dependencies.sh
        - export build_system="autotools"
    needs:
        - job: "macos-autotools-build"
          artifacts: true
    tags:
        - saas-macos-medium-m1
    image: macos-14-xcode-15
    # Most submitters don't have access to the macOS runners, and if they try
    # to run macOS pipeline jobs, the jobs will hang forever.  This variable is
    # only set on repos that have access to macOS runners, in GitLab repo
    # settings.
    # https://gitlab.com/graphviz/graphviz/-/settings/ci_cd
    only:
        variables:
          - $ENABLE_GRAPHVIZ_MACOS_CI

ubuntu-22.04-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "ubuntu-22.04-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-22.04

ubuntu-24.04-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "ubuntu-24.04-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-24.04

ubuntu-25.10-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "ubuntu-25.10-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-25.10

ubuntu-26.04-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "ubuntu-26.04-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: ubuntu-26.04

rocky8-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "rocky8-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky8

rocky9-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "rocky9-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky9

rocky10-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "rocky10-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: rocky10

fedora43-cmake-test:
    <<: *linux_test_definition
    before_script:
        - export build_system="cmake"
    needs:
        - job: "fedora43-cmake-build"
          artifacts: true
    tags:
        - saas-linux-small-amd64
    variables:
      IMAGE: fedora43

macos-cmake-test:
    <<: *test_definition
    before_script:
        - source ci/macos-install-runtime-dependencies.sh
        - export build_system="cmake"
    needs:
        - job: "macos-cmake-build"
          artifacts: true
    tags:
        - saas-macos-medium-m1
    image: macos-14-xcode-15
    # Most submitters don't have access to the macOS runners, and if they try
    # to run macOS pipeline jobs, the jobs will hang forever.  This variable is
    # only set on repos that have access to macOS runners, in GitLab repo
    # settings.
    # https://gitlab.com/graphviz/graphviz/-/settings/ci_cd
    only:
        variables:
          - $ENABLE_GRAPHVIZ_MACOS_CI

windows-mingw64-cmake-test:
    script:
        # disable Windows Defender
        - Set-MpPreference -DisableRealtimeMonitoring $true
        - powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command ci\mingw-prepare.ps1
        - $Env:build_system = "cmake"
        - C:\msys64\msys2_shell.cmd -defterm -mingw64 -here -no-start -l -c 'cd $CI_PROJECT_DIR && ci/mingw-install.sh'
        - $Env:graphviz_install_dir = "C:\Graphviz"
        - Invoke-Expression "./Packages/windows-mingw64-cmake-build/*.exe /S /D=$Env:graphviz_install_dir" | Out-Null
        - $Env:Path = $Env:graphviz_install_dir + "\bin" + ";" + $Env:Path
        - C:\msys64\msys2_shell.cmd -defterm -mingw64 -here -no-start -l -c 'cd $CI_PROJECT_DIR && ci/mingw-test.sh'
    needs:
        - job: "windows-mingw64-cmake-build"
          artifacts: true
    tags:
        - saas-windows-medium-amd64
    except:
        - tags
    artifacts:
        reports:
            junit: report.xml
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

deployment:
    stage: deploy
    image: registry.gitlab.com/gitlab-org/release-cli:latest@sha256:3f52d526f48e8d10625c722fa6d6423ee82aadeae1b1aa91f07b62551d96dacf
    # do not re-run this job for new Git tags of previously seen commits
    except:
        - tags
    before_script:
        - apk add --update-cache curl
        - apk add --update-cache python3
    script:
        - python3 ci/deploy.py
    # do not run this job for MRs, developer’s forks, etc.
    only:
        - main@graphviz/graphviz
    artifacts:
        when: on_success
        expire_in: 1 week
        paths:
            - graphviz-*.json
    retry:
        max: 1
        when:
            - stuck_or_timeout_failure
            - runner_system_failure
            - job_execution_timeout

.docker_template: &docker_definition
  image: docker:29.0.0-cli@sha256:87858a6dd14149240f4a2c33e0ec0f32a5ac1bb2548c04f5a20694ea25cb6157
  services:
    - docker:29.0.0-dind@sha256:96789d56621ae702a2f8aa316c87a1a1875dd3f02bf67cdcb56a524a09fa3af9
  before_script:
    # Docker prefers passwords passed on stdin rather than as arguments,
    # presumably because stdin isn't visible to other processes.
    # $CI_JOB_TOKEN is documented at
    # https://docs.gitlab.com/ee/user/project/new_ci_build_permissions_model.html#job-token
    - echo -n $CI_JOB_TOKEN | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY
  # do not re-run this job for new Git tags of previously seen commits
  except:
    - tags
  retry:
    max: 1
    when:
      - stuck_or_timeout_failure
      - runner_system_failure
      - job_execution_timeout

.docker_build_template: &docker_build_definition
  <<: *docker_definition
  stage: build_docker_images
  script:
    # fetches the :latest image (not failing if image is not found) for caching
    - docker pull $CI_REGISTRY_IMAGE/$IMAGE:latest || true
    # Build and push with git commit SHA tag, reusing layers from the :latest image if possible
    - DOCKER_BUILDKIT=1 docker build -t $CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA --cache-from $CI_REGISTRY_IMAGE/$IMAGE:latest -f ci/$IMAGE/Dockerfile --build-arg BUILDKIT_INLINE_CACHE=1 .
    - docker push $CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA

.docker_push_template: &docker_push_definition
  <<: *docker_definition
  stage: push_docker_images
  variables:
    # Docker pull and push doesn't need GitLab to clone the source code.
    # Skipping code checkout should speed up execution a little.
    GIT_STRATEGY: none
  only:
    refs:
      # Only main should be pushed to :latest, not unmerged merge-requests.
      # It's ok for this to run on other repos (not just graphviz/graphviz) as
      # they have their own container registries.
      - main
  script:
    - docker pull $CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA
    # Re-tag, push to :latest tag
    - docker tag $CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE/$IMAGE:latest
    - docker push     $CI_REGISTRY_IMAGE/$IMAGE:latest

docker_build_rocky8:
  <<: *docker_build_definition
  variables:
    IMAGE: rocky8

docker_build_rocky9:
  <<: *docker_build_definition
  variables:
    IMAGE: rocky9

docker_build_rocky10:
  <<: *docker_build_definition
  variables:
    IMAGE: rocky10

docker_build_fedora43:
  <<: *docker_build_definition
  variables:
    IMAGE: fedora43

docker_build_ubuntu-22.04:
  <<: *docker_build_definition
  variables:
    IMAGE: ubuntu-22.04

docker_build_ubuntu-24.04:
  <<: *docker_build_definition
  variables:
    IMAGE: ubuntu-24.04

docker_build_ubuntu-25.10:
  <<: *docker_build_definition
  variables:
    IMAGE: ubuntu-25.10

docker_build_ubuntu-26.04:
  <<: *docker_build_definition
  variables:
    IMAGE: ubuntu-26.04

docker_push_rocky8:
  <<: *docker_push_definition
  variables:
    IMAGE: rocky8
  needs:
    - docker_build_rocky8

docker_push_rocky9:
  <<: *docker_push_definition
  variables:
    IMAGE: rocky9
  needs:
    - docker_build_rocky9

docker_push_rocky10:
  <<: *docker_push_definition
  variables:
    IMAGE: rocky10
  needs:
    - docker_build_rocky10

docker_push_fedora43:
  <<: *docker_push_definition
  variables:
    IMAGE: fedora43
  needs:
    - docker_build_fedora43

docker_push_ubuntu-22.04:
  <<: *docker_push_definition
  variables:
    IMAGE: ubuntu-22.04
  needs:
    - docker_build_ubuntu-22.04

docker_push_ubuntu-24.04:
  <<: *docker_push_definition
  variables:
    IMAGE: ubuntu-24.04
  needs:
    - docker_build_ubuntu-24.04

docker_push_ubuntu-25.10:
  <<: *docker_push_definition
  variables:
    IMAGE: ubuntu-25.10
  needs:
    - docker_build_ubuntu-25.10

docker_push_ubuntu-26.04:
  <<: *docker_push_definition
  variables:
    IMAGE: ubuntu-26.04
  needs:
    - docker_build_ubuntu-26.04

lint_clang_format:
  stage: test
  needs: [] # no dependencies
  script:
    - env DEBIAN_FRONTEND=noninteractive apt-get update -y
    - env DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y clang-format-19
    # output some info into the logs for debugging
    - clang-format-19 --version
    - cat /etc/os-release
    - uname -rms
    # check file formatting
    - python3 ci/clang_format.py
  except:
    - tags
  retry:
    max: 1
    when:
      - stuck_or_timeout_failure
      - runner_system_failure
      - job_execution_timeout

lint_cpplint:
  stage: test
  needs: [] # no dependencies
  script:
    - env DEBIAN_FRONTEND=noninteractive apt-get update -y
    - env DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y cpplint
    # output some info into the logs for debugging
    - cpplint --version
    - cat /etc/os-release
    - uname -rms
    # check file formatting
    - git ls-files -z -- lib/cgraph++ lib/gvc++ | xargs -0 -- cpplint
    - git ls-files -z -- lib/xdot | xargs -0 -- cpplint --filter=-readability/casting
  except:
    - tags
  retry:
    max: 1
    when:
      - stuck_or_timeout_failure
      - runner_system_failure
      - job_execution_timeout

lint_cmake_format:
  stage: test
  needs: [] # no dependencies
  script:
    - env DEBIAN_FRONTEND=noninteractive apt-get update -y
    - env DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y python3-venv
    # output some info into the logs for debugging
    - python3 --version
    - cat /etc/os-release
    - uname -rms
    - python3 -m venv /opt/virtualenv
    - source /opt/virtualenv/bin/activate
    - python3 -m pip install uv
    - python3 -m uv pip install --requirement requirements.txt
    - python3 -m uv pip install --requirement doc/infosrc/requirements.txt
    - git ls-files -z -- ':(glob)**/CMakeLists.txt' ':(glob)**/*.cmake' ':(glob)**/*.cmake.in' | xargs -0 -- python3 -m cmakelang.lint
  except:
    - tags
  retry:
    max: 1
    when:
      - stuck_or_timeout_failure
      - runner_system_failure
      - job_execution_timeout

lint_html:
  stage: test
  needs: [] # no dependencies
  script:
    - env DEBIAN_FRONTEND=noninteractive apt-get update -y
    - env DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y libxml2-utils
    # output some info into the logs for debugging
    - xmllint --version
    - cat /etc/os-release
    - uname -rms
    # check file formatting
    - git ls-files -z -- '**/*.html' | xargs -0 -- xmllint --nonet --noout --html --valid
  except:
    - tags
  retry:
    max: 1
    when:
      - stuck_or_timeout_failure
      - runner_system_failure
      - job_execution_timeout

lint_python:
  image: "$CI_REGISTRY_IMAGE/ubuntu-26.04:$CI_COMMIT_SHA"
  stage: test
  needs:
    - job: "ubuntu-26.04-build"
      artifacts: true
  tags:
    - saas-linux-small-amd64
  before_script:
    - export build_system="autotools"
  script:
    # grant virtualenv access to system-installed `gv` package
    - echo 'include-system-site-packages = true' >> /opt/virtualenv/pyvenv.cfg
    - source /opt/virtualenv/bin/activate
    - ci/install-packages.sh
    # output some info into the logs for debugging
    - python3 --version
    - cat /etc/os-release
    - uname -rms
    - git ls-files -z -- cmd/dot/dot_sandbox '**.py' | xargs -0 -- python3 -m pylint --rcfile=.pylintrc --disable=fixme
    - git ls-files -z -- cmd/dot/dot_sandbox '**.py' | xargs -0 -- python3 -m black --check
    - git ls-files -z -- cmd/dot/dot_sandbox '**.py' | xargs -0 -- python3 -m isort --profile=black --check
  except:
    - tags
  retry:
    max: 1
    when:
      - stuck_or_timeout_failure
      - runner_system_failure
      - job_execution_timeout
