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