env:  # Global defaults
  PACKAGE_MANAGER_INSTALL: "apt-get update && apt-get install -y"
  MAKEJOBS: "-j10"
  TEST_RUNNER_PORT_MIN: "14000"  # Must be larger than 12321, which is used for the http cache. See https://cirrus-ci.org/guide/writing-tasks/#http-cache
  CI_FAILFAST_TEST_LEAVE_DANGLING: "1"  # Cirrus CI does not care about dangling process and setting this variable avoids killing the CI script itself on error
  CCACHE_SIZE: "200M"
  CCACHE_DIR: "/tmp/ccache_dir"
  CCACHE_NOHASHDIR: "1"  # Debug info might contain a stale path if the build dir changes, but this is fine

cirrus_ephemeral_worker_template_env: &CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
  DANGER_RUN_CI_ON_HOST: "1"  # Containers will be discarded after the run, so there is no risk that the ci scripts modify the system

persistent_worker_template_env: &PERSISTENT_WORKER_TEMPLATE_ENV
  RESTART_CI_DOCKER_BEFORE_RUN: "1"

persistent_worker_template: &PERSISTENT_WORKER_TEMPLATE
  persistent_worker: {}  # https://cirrus-ci.org/guide/persistent-workers/

# https://cirrus-ci.org/guide/tips-and-tricks/#sharing-configuration-between-tasks
filter_template: &FILTER_TEMPLATE
  skip: $CIRRUS_REPO_FULL_NAME == "bitcoin-core/gui" && $CIRRUS_PR == ""  # No need to run on the read-only mirror, unless it is a PR. https://cirrus-ci.org/guide/writing-tasks/#conditional-task-execution
  stateful: false  # https://cirrus-ci.org/guide/writing-tasks/#stateful-tasks

base_template: &BASE_TEMPLATE
  << : *FILTER_TEMPLATE
  merge_base_script:
    # Unconditionally install git (used in fingerprint_script) and set the
    # default git author name (used in verify-commits.py)
    - bash -c "$PACKAGE_MANAGER_INSTALL git"
    - git config --global user.email "ci@ci.ci"
    - git config --global user.name "ci"
    - if [ "$CIRRUS_PR" = "" ]; then exit 0; fi
    - git fetch $CIRRUS_REPO_CLONE_URL $CIRRUS_BASE_BRANCH
    - git merge FETCH_HEAD  # Merge base to detect silent merge conflicts

main_template: &MAIN_TEMPLATE
  timeout_in: 120m  # https://cirrus-ci.org/faq/#instance-timed-out
  ccache_cache:
    folder: "/tmp/ccache_dir"
  ci_script:
    - ./ci/test_run_all.sh

global_task_template: &GLOBAL_TASK_TEMPLATE
  << : *BASE_TEMPLATE
  container:
    # https://cirrus-ci.org/faq/#are-there-any-limits
    # Each project has 16 CPU in total, assign 2 to each container, so that 8 tasks run in parallel
    cpu: 2
    greedy: true
    memory: 8G  # Set to 8GB to avoid OOM. https://cirrus-ci.org/guide/linux/#linux-containers
  depends_built_cache:
    folder: "depends/built"
    fingerprint_script: echo $CIRRUS_TASK_NAME $(git rev-list -1 HEAD ./depends)
  << : *MAIN_TEMPLATE

macos_native_task_template: &MACOS_NATIVE_TASK_TEMPLATE
  << : *BASE_TEMPLATE
  check_clang_script:
    - clang --version
  brew_install_script:
    - brew install boost libevent qt@5 miniupnpc libnatpmp ccache zeromq qrencode libtool automake gnu-getopt
  << : *MAIN_TEMPLATE

compute_credits_template: &CREDITS_TEMPLATE
  # https://cirrus-ci.org/pricing/#compute-credits
  # Only use credits for pull requests to the main repo
  use_compute_credits: $CIRRUS_REPO_FULL_NAME == 'bitcoin/bitcoin' && $CIRRUS_PR != ""

task:
  name: 'lint [bionic]'
  << : *BASE_TEMPLATE
  container:
    image: ubuntu:bionic  # For python 3.6, oldest supported version according to doc/dependencies.md
    cpu: 1
    memory: 1G
  # For faster CI feedback, immediately schedule the linters
  << : *CREDITS_TEMPLATE
  lint_script:
    - ./ci/lint_run_all.sh
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV

task:
  name: 'tidy [jammy]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:jammy
    cpu: 2
    memory: 5G
  # For faster CI feedback, immediately schedule the linters
  << : *CREDITS_TEMPLATE
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_native_tidy.sh"

task:
  name: "Win64 native [vs2022]"
  << : *FILTER_TEMPLATE
  windows_container:
    cpu: 6
    memory: 12G
    image: cirrusci/windowsservercore:visualstudio2022
  timeout_in: 120m
  env:
    PATH: 'C:\jom;C:\Python39;C:\Python39\Scripts;C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin;%PATH%'
    PYTHONUTF8: 1
    CI_VCPKG_TAG: '2022.06.16.1'
    VCPKG_DOWNLOADS: 'C:\Users\ContainerAdministrator\AppData\Local\vcpkg\downloads'
    VCPKG_DEFAULT_BINARY_CACHE: 'C:\Users\ContainerAdministrator\AppData\Local\vcpkg\archives'
    CCACHE_DIR: 'C:\Users\ContainerAdministrator\AppData\Local\ccache'
    WRAPPED_CL: 'C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\ci\test\wrapped-cl.bat'
    QT_DOWNLOAD_URL: 'https://download.qt.io/official_releases/qt/5.15/5.15.5/single/qt-everywhere-opensource-src-5.15.5.zip'
    QT_LOCAL_PATH: 'C:\qt-everywhere-opensource-src-5.15.5.zip'
    QT_SOURCE_DIR: 'C:\qt-everywhere-src-5.15.5'
    QTBASEDIR: 'C:\Qt_static'
    x64_NATIVE_TOOLS: '"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat"'
    QT_CONFIGURE_COMMAND: '..\configure -release -silent -opensource -confirm-license -opengl desktop -static -static-runtime -mp -qt-zlib -qt-pcre -qt-libpng -nomake examples -nomake tests -nomake tools -no-angle -no-dbus -no-gif -no-gtk -no-ico -no-icu -no-libjpeg -no-libudev -no-sql-sqlite -no-sql-odbc -no-sqlite -no-vulkan -skip qt3d -skip qtactiveqt -skip qtandroidextras -skip qtcharts -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip doc -skip qtdoc -skip qtgamepad -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtlottie -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquick3d -skip qtquickcontrols -skip qtquickcontrols2 -skip qtquicktimeline -skip qtremoteobjects -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtsvg -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebglplugin -skip qtwebsockets -skip qtwebview -skip qtx11extras -skip qtxmlpatterns -no-openssl -no-feature-bearermanagement -no-feature-printdialog -no-feature-printer -no-feature-printpreviewdialog -no-feature-printpreviewwidget -no-feature-sql -no-feature-sqlmodel -no-feature-textbrowser -no-feature-textmarkdownwriter -no-feature-textodfwriter -no-feature-xml'
    IgnoreWarnIntDirInTempDetected: 'true'
  merge_script:
    - git config --global user.email "ci@ci.ci"
    - git config --global user.name "ci"
    # Windows filesystem loses the executable bit, and all of the executable
    # files are considered "modified" now. It will break the following `git merge`
    # command. The next two commands make git ignore this issue.
    - git config core.filemode false
    - git reset --hard
    - PowerShell -NoLogo -Command if ($env:CIRRUS_PR -ne $null) { git fetch $env:CIRRUS_REPO_CLONE_URL $env:CIRRUS_BASE_BRANCH; git merge FETCH_HEAD; }
  msvc_qt_built_cache:
    folder: "%QTBASEDIR%"
    reupload_on_changes: false
    fingerprint_script:
      - echo %QT_DOWNLOAD_URL% %QT_CONFIGURE_COMMAND%
      - msbuild -version
    populate_script:
      - curl -L -o C:\jom.zip http://download.qt.io/official_releases/jom/jom.zip
      - mkdir C:\jom
      - tar -xf C:\jom.zip -C C:\jom
      - curl -L -o %QT_LOCAL_PATH% %QT_DOWNLOAD_URL%
      - tar -xf %QT_LOCAL_PATH% -C C:\
      - '%x64_NATIVE_TOOLS%'
      - cd %QT_SOURCE_DIR%
      - mkdir build
      - cd build
      - '%QT_CONFIGURE_COMMAND% -prefix %QTBASEDIR%'
      - jom
      - jom install
  vcpkg_tools_cache:
    folder: '%VCPKG_DOWNLOADS%\tools'
    reupload_on_changes: false
    fingerprint_script:
      - echo %CI_VCPKG_TAG%
      - msbuild -version
  vcpkg_binary_cache:
    folder: '%VCPKG_DEFAULT_BINARY_CACHE%'
    reupload_on_changes: true
    fingerprint_script:
      - echo %CI_VCPKG_TAG%
      - type build_msvc\vcpkg.json
      - msbuild -version
    populate_script:
      - mkdir %VCPKG_DEFAULT_BINARY_CACHE%
  ccache_cache:
    folder: '%CCACHE_DIR%'
  install_tools_script:
    - choco install --yes --no-progress ccache --version=4.6.1
    - choco install --yes --no-progress python3 --version=3.9.6
    - pip install zmq
    - ccache --version
    - python -VV
  install_vcpkg_script:
    - cd ..
    - git clone --quiet https://github.com/microsoft/vcpkg.git
    - cd vcpkg
    - git -c advice.detachedHead=false checkout %CI_VCPKG_TAG%
    - .\bootstrap-vcpkg -disableMetrics
    - echo set(VCPKG_BUILD_TYPE release) >> triplets\x64-windows-static.cmake
    - .\vcpkg integrate install
    - .\vcpkg version
  build_script:
    - '%x64_NATIVE_TOOLS%'
    - cd %CIRRUS_WORKING_DIR%
    - ccache --zero-stats --max-size=%CCACHE_SIZE%
    - python build_msvc\msvc-autogen.py
    - msbuild build_msvc\bitcoin.sln -property:CLToolExe=%WRAPPED_CL% -property:Configuration=Release -maxCpuCount -verbosity:minimal -noLogo
    - ccache --show-stats
  unit_tests_script:
    - src\test_bitcoin.exe -l test_suite
    - src\bench_bitcoin.exe > NUL
    - python test\util\test_runner.py
    - python test\util\rpcauth-test.py
  functional_tests_script:
    # Increase the dynamic port range to the maximum allowed value to mitigate "OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted".
    # See: https://docs.microsoft.com/en-us/biztalk/technical-guides/settings-that-can-be-modified-to-improve-network-performance
    - netsh int ipv4 set dynamicport tcp start=1025 num=64511
    - netsh int ipv6 set dynamicport tcp start=1025 num=64511
    # Exclude feature_dbcrash for now due to timeout
    - python test\functional\test_runner.py --nocleanup --ci --quiet --combinedlogslen=4000 --jobs=4 --timeout-factor=8 --extended --exclude feature_dbcrash

task:
  name: 'ARM [unit tests, no functional tests] [bullseye]'
  << : *GLOBAL_TASK_TEMPLATE
  arm_container:
    image: debian:bullseye
    cpu: 2
    memory: 8G
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_arm.sh"
    QEMU_USER_CMD: ""  # Disable qemu and run the test natively

task:
  name: 'Win64 [unit tests, no gui tests, no boost::process, no functional tests] [jammy]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:jammy
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_win64.sh"

task:
  name: '32-bit + dash [gui] [CentOS 8]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: quay.io/centos/centos:stream8
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    PACKAGE_MANAGER_INSTALL: "yum install -y"
    FILE_ENV: "./ci/test/00_setup_env_i686_centos.sh"

task:
  name: '[previous releases, uses qt5 dev package and some depends packages, DEBUG] [unsigned char] [buster]'
  previous_releases_cache:
    folder: "releases"
  << : *GLOBAL_TASK_TEMPLATE
  << : *PERSISTENT_WORKER_TEMPLATE
  env:
    << : *PERSISTENT_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_native_qt5.sh"

task:
  name: '[TSan, depends, gui] [jammy]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:jammy
    cpu: 6  # Increase CPU and Memory to avoid timeout
    memory: 24G
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_native_tsan.sh"

task:
  name: '[MSan, depends] [focal]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:focal
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_native_msan.sh"
    MAKEJOBS: "-j4"  # Avoid excessive memory use due to MSan

task:
  name: '[ASan + LSan + UBSan + integer, no depends, USDT] [jammy]'
  << : *GLOBAL_TASK_TEMPLATE
  # We can't use a 'container' for the USDT interface tests as the CirrusCI
  # containers don't have privileges to hook into bitcoind. CirrusCI uses
  # Google Compute Engine instances: https://cirrus-ci.org/guide/custom-vms/
  # Images can be found here: https://cloud.google.com/compute/docs/images/os-details
  compute_engine_instance:
    image_project: ubuntu-os-cloud
    image: family/ubuntu-2204-lts # when upgrading, check if we can drop "ADD_UNTRUSTED_BPFCC_PPA"
    cpu: 4
    memory: 12G
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    HOME: /root/  # Only needed for compute_engine_instance
    FILE_ENV: "./ci/test/00_setup_env_native_asan.sh"
    MAKEJOBS: "-j4"  # Avoid excessive memory use

task:
  name: '[fuzzer,address,undefined,integer, no depends] [jammy]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:jammy
    cpu: 4  # Increase CPU and memory to avoid timeout
    memory: 16G
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_native_fuzz.sh"

task:
  name: '[multiprocess, i686, DEBUG] [focal]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:focal
    cpu: 4
    memory: 16G  # The default memory is sometimes just a bit too small, so double everything
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_i686_multiprocess.sh"

task:
  name: '[no wallet, libbitcoinkernel] [bionic]'
  << : *GLOBAL_TASK_TEMPLATE
  container:
    image: ubuntu:bionic
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_native_nowallet_libbitcoinkernel.sh"

task:
  name: 'macOS 10.15 [gui, no tests] [focal]'
  << : *BASE_TEMPLATE
  macos_sdk_cache:
    folder: "depends/SDKs/$MACOS_SDK"
    fingerprint_key: "$MACOS_SDK"
  << : *MAIN_TEMPLATE
  container:
    image: ubuntu:focal
  env:
    MACOS_SDK: "Xcode-12.2-12B45b-extracted-SDK-with-libcxx-headers"
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_mac.sh"

task:
  name: 'macOS 12 native x86_64 [gui, system sqlite] [no depends]'
  macos_instance:
    # Use latest image, but hardcode version to avoid silent upgrades (and breaks)
    image: monterey-xcode-13.3  # https://cirrus-ci.org/guide/macOS
  << : *MACOS_NATIVE_TASK_TEMPLATE
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    CI_USE_APT_INSTALL: "no"
    PACKAGE_MANAGER_INSTALL: "echo"  # Nothing to do
    FILE_ENV: "./ci/test/00_setup_env_mac_native_x86_64.sh"

task:
  name: 'ARM64 Android APK [focal]'
  << : *BASE_TEMPLATE
  android_sdk_cache:
    folder: "depends/SDKs/android"
    fingerprint_key: "ANDROID_API_LEVEL=28 ANDROID_BUILD_TOOLS_VERSION=28.0.3 ANDROID_NDK_VERSION=23.2.8568313"
  depends_sources_cache:
    folder: "depends/sources"
    fingerprint_script: git rev-list -1 HEAD ./depends
  << : *MAIN_TEMPLATE
  container:
    image: ubuntu:focal
  env:
    << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV
    FILE_ENV: "./ci/test/00_setup_env_android.sh"