bitcoin-core-ci.yml raw

   1  # Copyright (c) The Bitcoin Core developers
   2  # Distributed under the MIT software license, see the accompanying
   3  # file COPYING or https://opensource.org/license/mit.
   4  
   5  # Test libmultiprocess inside Bitcoin Core by replacing the subtree copy
   6  # with the version from this PR, then building and running IPC-related
   7  # unit & functional tests.
   8  
   9  name: Bitcoin Core CI
  10  
  11  on:
  12    push:
  13    pull_request:
  14  
  15  concurrency:
  16    group: ${{ github.workflow }}-${{ github.ref }}
  17    cancel-in-progress: true
  18  
  19  env:
  20    BITCOIN_REPO: bitcoin/bitcoin
  21    LLVM_VERSION: 22
  22    LIBCXX_DIR: /tmp/libcxx-build/
  23  
  24  jobs:
  25    bitcoin-core:
  26      name: ${{ matrix.name }}
  27      runs-on: ${{ matrix.runner }}
  28      timeout-minutes: 120
  29  
  30      strategy:
  31        fail-fast: false
  32        matrix:
  33          include:
  34            - name: 'ASan + UBSan'
  35              unit_test_runs: 15
  36              functional_test_runs: 20
  37              nproc_multiplier: 2
  38              functional_timeout_factor: 40
  39              runner: ubuntu-24.04
  40              apt-llvm: true
  41              packages: >-
  42                ccache
  43                clang-22
  44                llvm-22
  45                libclang-rt-22-dev
  46                libboost-dev
  47                libsqlite3-dev
  48                libcapnp-dev
  49                capnproto
  50                ninja-build
  51                pkgconf
  52                python3-pip
  53              pip-packages: --break-system-packages pycapnp
  54              cmake-args: |-
  55                -DSANITIZERS=address,float-divide-by-zero,integer,undefined
  56                -DCMAKE_C_COMPILER=clang
  57                -DCMAKE_CXX_COMPILER=clang++
  58                -DCMAKE_C_FLAGS=-ftrivial-auto-var-init=pattern
  59                -DCMAKE_CXX_FLAGS=-ftrivial-auto-var-init=pattern
  60  
  61            - name: 'macOS'
  62              unit_test_runs: 50
  63              functional_test_runs: 20
  64              nproc_multiplier: 2
  65              functional_timeout_factor: 40
  66              runner: macos-15
  67              brew-packages: ccache capnp boost sqlite pkgconf ninja
  68              pip-packages: --break-system-packages pycapnp
  69              cmake-args: |-
  70                -DREDUCE_EXPORTS=ON
  71  
  72      env:
  73        CCACHE_MAXSIZE: 400M
  74        CCACHE_DIR: ${{ github.workspace }}/.ccache
  75  
  76      steps:
  77        - name: Checkout Bitcoin Core
  78          uses: actions/checkout@v4
  79          with:
  80            repository: ${{ env.BITCOIN_REPO }}
  81            fetch-depth: 1
  82  
  83        - name: Checkout libmultiprocess
  84          uses: actions/checkout@v4
  85          with:
  86            path: _libmultiprocess
  87  
  88        - name: Replace libmultiprocess subtree
  89          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh replace_subtree
  90  
  91        - name: Add LLVM apt repository
  92          if: matrix.apt-llvm
  93          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh add_llvm_apt_repository
  94  
  95        - name: Install APT packages
  96          if: matrix.packages
  97          run: _libmultiprocess/ci/scripts/ci_helpers.sh install_apt_packages ${{ matrix.packages }}
  98  
  99        - name: Configure LLVM alternatives
 100          if: matrix.packages
 101          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh install_llvm_alternatives
 102  
 103        - name: Install Homebrew packages
 104          if: matrix.brew-packages
 105          run: _libmultiprocess/ci/scripts/ci_helpers.sh install_homebrew_packages ${{ matrix.brew-packages }}
 106  
 107        - name: Install pip packages
 108          if: matrix.pip-packages
 109          run: _libmultiprocess/ci/scripts/ci_helpers.sh install_pip_packages ${{ matrix.pip-packages }}
 110  
 111        - name: Determine parallelism
 112          run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_parallelism "${{ matrix.nproc_multiplier }}"
 113  
 114        - name: Restore ccache
 115          id: ccache-restore
 116          uses: actions/cache/restore@v4
 117          with:
 118            path: ${{ env.CCACHE_DIR }}
 119            key: ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
 120            restore-keys: |
 121              ccache-${{ matrix.name }}-${{ github.ref }}-
 122              ccache-${{ matrix.name }}-
 123  
 124        - name: Reset ccache stats
 125          if: matrix.packages || matrix.brew-packages
 126          run: _libmultiprocess/ci/scripts/ci_helpers.sh reset_ccache_stats
 127  
 128        - name: CMake configure
 129          env:
 130            BITCOIN_CORE_CMAKE_ARGS: ${{ matrix.cmake-args }}
 131          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh configure_bitcoin_core
 132  
 133        - name: Build
 134          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_bitcoin_core
 135  
 136        - name: Show ccache stats
 137          if: matrix.packages || matrix.brew-packages
 138          run: _libmultiprocess/ci/scripts/ci_helpers.sh show_ccache_stats
 139  
 140        - name: Run IPC unit tests
 141          env:
 142            ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
 143            LSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/lsan
 144            UBSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1
 145          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_unit_tests "${{ matrix.unit_test_runs }}"
 146  
 147        - name: Run IPC functional tests
 148          env:
 149            ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
 150            LSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/lsan
 151            UBSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1
 152            CI_FAILFAST_TEST_LEAVE_DANGLING: 1
 153          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_functional_tests "${{ matrix.functional_test_runs }}" "${{ matrix.functional_timeout_factor }}"
 154  
 155        - name: Save ccache
 156          uses: actions/cache/save@v4
 157          if: github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true'
 158          with:
 159            path: ${{ env.CCACHE_DIR }}
 160            key: ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
 161  
 162    bitcoin-core-tsan:
 163      name: ${{ matrix.name }}
 164      runs-on: ubuntu-24.04
 165      timeout-minutes: 180
 166  
 167      strategy:
 168        matrix:
 169          include:
 170            - name: TSan
 171              unit_test_runs: 8
 172              functional_test_runs: 25
 173              nproc_multiplier: 2
 174              functional_timeout_factor: 40
 175  
 176      env:
 177        CCACHE_MAXSIZE: 400M
 178        CCACHE_DIR: ${{ github.workspace }}/.ccache
 179        LIBCXX_FLAGS: >-
 180          -fsanitize=thread
 181          -nostdinc++
 182          -nostdlib++
 183          -isystem /tmp/libcxx-build/include/c++/v1
 184          -L/tmp/libcxx-build/lib
 185          -Wl,-rpath,/tmp/libcxx-build/lib
 186          -lc++
 187          -lc++abi
 188          -lpthread
 189          -Wno-unused-command-line-argument
 190        TSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1
 191  
 192      steps:
 193        - name: Checkout Bitcoin Core
 194          uses: actions/checkout@v4
 195          with:
 196            repository: ${{ env.BITCOIN_REPO }}
 197            fetch-depth: 1
 198  
 199        - name: Checkout libmultiprocess
 200          uses: actions/checkout@v4
 201          with:
 202            path: _libmultiprocess
 203  
 204        - name: Add LLVM apt repository
 205          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh add_llvm_apt_repository
 206  
 207        - name: Install packages
 208          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh install_tsan_packages
 209  
 210        - name: Determine parallelism
 211          run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_parallelism "${{ matrix.nproc_multiplier }}"
 212  
 213        - name: Restore instrumented libc++ cache
 214          id: libcxx-cache
 215          uses: actions/cache@v4
 216          with:
 217            path: ${{ env.LIBCXX_DIR }}
 218            key: libcxx-Thread-llvmorg-${{ env.LLVM_VERSION }}.1.0
 219  
 220        - name: Build instrumented libc++
 221          if: steps.libcxx-cache.outputs.cache-hit != 'true'
 222          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_instrumented_libcxx
 223  
 224        - name: Determine host
 225          id: host
 226          run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_host
 227  
 228        - name: Restore depends cache
 229          id: depends-cache
 230          uses: actions/cache/restore@v4
 231          with:
 232            path: |
 233              depends/built
 234              depends/${{ steps.host.outputs.host }}
 235            key: depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }}
 236  
 237        - name: Build depends (stage 1, without IPC)
 238          if: steps.depends-cache.outputs.cache-hit != 'true'
 239          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_depends_without_ipc
 240  
 241        - name: Save depends cache
 242          uses: actions/cache/save@v4
 243          if: steps.depends-cache.outputs.cache-hit != 'true'
 244          with:
 245            path: |
 246              depends/built
 247              depends/${{ steps.host.outputs.host }}
 248            key: depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }}
 249  
 250        - name: Replace libmultiprocess subtree
 251          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh replace_subtree
 252  
 253        - name: Build depends (stage 2, IPC packages including libmultiprocess)
 254          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_depends_with_ipc
 255  
 256        - name: Restore ccache
 257          id: ccache-restore
 258          uses: actions/cache/restore@v4
 259          with:
 260            path: ${{ env.CCACHE_DIR }}
 261            key: ccache-TSan-${{ github.ref }}-${{ github.sha }}
 262            restore-keys: |
 263              ccache-TSan-${{ github.ref }}-
 264              ccache-TSan-
 265  
 266        - name: Reset ccache stats
 267          run: _libmultiprocess/ci/scripts/ci_helpers.sh reset_ccache_stats
 268  
 269        - name: CMake configure
 270          env:
 271            BITCOIN_CORE_CMAKE_ARGS: |-
 272              -DSANITIZERS=thread
 273              -DAPPEND_CPPFLAGS=-DARENA_DEBUG -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES
 274              -DCMAKE_TOOLCHAIN_FILE=depends/${{ steps.host.outputs.host }}/toolchain.cmake
 275          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh configure_bitcoin_core
 276  
 277        - name: Build
 278          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_bitcoin_core
 279  
 280        - name: Show ccache stats
 281          run: _libmultiprocess/ci/scripts/ci_helpers.sh show_ccache_stats
 282  
 283        - name: Run IPC unit tests
 284          env:
 285            LD_LIBRARY_PATH: depends/${{ steps.host.outputs.host }}/lib
 286          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_unit_tests "${{ matrix.unit_test_runs }}"
 287  
 288        - name: Run IPC functional tests
 289          env:
 290            LD_LIBRARY_PATH: depends/${{ steps.host.outputs.host }}/lib
 291            CI_FAILFAST_TEST_LEAVE_DANGLING: 1
 292          run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_functional_tests "${{ matrix.functional_test_runs }}" "${{ matrix.functional_timeout_factor }}"
 293  
 294        - name: Save ccache
 295          uses: actions/cache/save@v4
 296          if: github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true'
 297          with:
 298            path: ${{ env.CCACHE_DIR }}
 299            key: ccache-TSan-${{ github.ref }}-${{ github.sha }}
 300