forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 2
382 lines (332 loc) · 15.3 KB
/
Copy pathci.yml
File metadata and controls
382 lines (332 loc) · 15.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# Copyright (c) 2023-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit.
name: CI
on:
# See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request.
pull_request:
# See: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#push.
push:
branches:
- '**'
tags-ignore:
- '**'
concurrency:
group: ${{ github.event_name != 'pull_request' && github.run_id || github.ref }}
cancel-in-progress: true
env:
CI_FAILFAST_TEST_LEAVE_DANGLING: 1 # GHA does not care about dangling processes and setting this variable avoids killing the CI script itself on error
REPO_USE_WARP_RUNNERS: 'bitcoin/bitcoin' # Use warp runners for this repo, instead of falling back to the slow GHA runners
defaults:
run:
# Enforce fail-fast behavior for all platforms.
# See: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash
jobs:
runners:
name: '[meta] determine runners'
runs-on: ubuntu-slim
outputs:
provider: ${{ steps.runners.outputs.provider }}
steps:
- &ANNOTATION_PR_NUMBER
name: Annotate with pull request number
# This annotation is machine-readable and can be used to assign a check
# run to its corresponding pull request. Running in all check runs is
# required, because check re-runs discard the annotations of other
# tasks in the test suite.
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "::notice title=debug_pull_request_number_str::${{ github.event.number }}"
fi
- id: runners
run: |
if [[ "${REPO_USE_WARP_RUNNERS}" == "${{ github.repository }}" ]]; then
echo "provider=warp" >> "$GITHUB_OUTPUT"
echo "::notice title=Runner Selection::Using Warp Runners"
else
echo "provider=gha" >> "$GITHUB_OUTPUT"
echo "::notice title=Runner Selection::Using GitHub-hosted runners"
fi
test-each-commit:
name: 'test ancestor commits'
needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'warp' && 'warp-ubuntu-latest-x64-8x' || 'ubuntu-latest' }}
env:
TEST_RUNNER_PORT_MIN: "14000" # Use a larger port range to avoid colliding with other CI services.
if: github.event_name == 'pull_request' && github.event.pull_request.commits != 1
timeout-minutes: 360 # Use maximum time, see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes.
steps:
- name: Determine fetch depth
run: echo "FETCH_DEPTH=$((${{ github.event.pull_request.commits }} + 2))" >> "$GITHUB_ENV"
- *ANNOTATION_PR_NUMBER
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: ${{ env.FETCH_DEPTH }}
- name: Determine commit range
run: |
# Checkout HEAD~ and find the test base commit.
# Checkout HEAD~ because it would be wasteful to rerun
# tests on the PR head commit that are already run
# by other jobs.
git checkout HEAD~
# Moreover, pull requests that contain a merge commit
# are generally draft pull requests that merge in other
# pull requests, so only check the relevant commits
# after the last merge commit. A merge commit could
# also be a subtree merge commit, which may be
# worthwhile to check. However, it is rare that the
# subtree merge commit is not the top commit (which
# would be skipped anyway by this task, because it is
# run by all other tasks). Also, `git rebase --exec`
# does not work on merge commits, so if this was
# important to check, the logic would have to be
# rewritten.
#
# Figure out test base commit by listing ancestors of
# HEAD, excluding ancestors of the most recent merge
# commit, ordering them from oldest to newest, and
# taking the first one.
#
# In the command below, the ^@ suffix is used to refer
# to all parents of the merge commit as described in:
# https://git-scm.com/docs/git-rev-parse#_other_rev_parent_shorthand_notations
# and the ^ prefix is used to exclude these parents
# and all their ancestors from the rev-list output
# as described in:
# https://git-scm.com/docs/git-rev-list
MERGE_BASE=$(git rev-list -n1 --merges HEAD)
EXCLUDE_MERGE_BASE_ANCESTORS=
# MERGE_BASE can be empty due to limited fetch-depth
if test -n "$MERGE_BASE"; then
EXCLUDE_MERGE_BASE_ANCESTORS=^${MERGE_BASE}^@
fi
echo "TEST_BASE=$(git rev-list -n${{ github.event.pull_request.commits }} --reverse HEAD $EXCLUDE_MERGE_BASE_ANCESTORS | head -1)" >> "$GITHUB_ENV"
- run: |
git fetch origin "${GITHUB_BASE_REF}"
git config user.email "ci@example.com"
git config user.name "CI"
- run: |
sudo apt-get update
sudo apt-get install clang mold ccache build-essential cmake ninja-build pkgconf python3-zmq libevent-dev libboost-dev systemtap-sdt-dev libzmq3-dev capnproto libcapnp-dev -y
sudo pip3 install --break-system-packages pycapnp
- name: Compile and run tests
run: |
# Run tests on commits after the last merge commit and before the PR head commit
git rebase --exec "git merge --no-commit origin/${GITHUB_BASE_REF} && python3 ./.github/ci-test-each-commit-exec.py && git reset --hard" ${{ env.TEST_BASE }}
macos-native-arm64:
name: ${{ matrix.job-name }}
# Use any image to support the xcode-select below, but hardcode version to avoid silent upgrades (and breaks).
# See: https://github.com/actions/runner-images#available-images.
runs-on: macos-15
# When a contributor maintains a fork of the repo, any pull request they make
# to their own fork, or to the main repository, will trigger two CI runs:
# one for the branch push and one for the pull request.
# This can be avoided by setting SKIP_BRANCH_PUSH=true as a custom env variable
# in Github repository settings.
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
job-type: [standard, fuzz]
include:
- job-type: standard
file-env: './ci/test/00_setup_env_mac_native.sh'
job-name: 'macOS native'
- job-type: fuzz
file-env: './ci/test/00_setup_env_mac_native_fuzz.sh'
job-name: 'macOS native, fuzz'
env:
DANGER_RUN_CI_ON_HOST: 1
BASE_ROOT_DIR: ${{ github.workspace }}/repo_archive
steps:
- *ANNOTATION_PR_NUMBER
- &CHECKOUT
name: Checkout
uses: actions/checkout@v6
with:
# Ensure the latest merged pull request state is used, even on re-runs.
ref: &CHECKOUT_REF_TMPL ${{ github.event_name == 'pull_request' && github.ref || '' }}
- name: Clang version
run: |
# Use the latest Xcode supported by the version of macOS denoted in
# doc/release-notes-empty-template.md and providing at least the
# minimum clang version denoted in doc/dependencies.md.
# See: https://developer.apple.com/documentation/xcode-release-notes/xcode-16_2-release-notes
sudo xcode-select --switch /Applications/Xcode_16.2.app
clang --version
- name: Install Homebrew packages
env:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
run: |
# A workaround for "The `brew link` step did not complete successfully" error.
brew install --quiet python@3 || brew link --overwrite python@3
brew install --quiet coreutils ninja pkgconf ccache boost libevent zeromq capnp
- name: Set Ccache directory
run: echo "CCACHE_DIR=${RUNNER_TEMP}/ccache_dir" >> "$GITHUB_ENV"
- name: Restore Ccache cache
id: ccache-cache
uses: actions/cache/restore@v5
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ github.job }}-${{ matrix.job-type }}-ccache-${{ github.run_id }}
restore-keys: ${{ github.job }}-${{ matrix.job-type }}-ccache-
- name: Create git archive
run: |
git log -1
git archive --format=tar --prefix=repo_archive/ --output=repo.tar HEAD
tar -xf repo.tar
- name: CI script
run: |
cd repo_archive
./ci/test_run_all.sh
env:
FILE_ENV: ${{ matrix.file-env }}
- name: Save Ccache cache
uses: actions/cache/save@v5
if: github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch && steps.ccache-cache.outputs.cache-hit != 'true'
with:
path: ${{ env.CCACHE_DIR }}
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
key: ${{ steps.ccache-cache.outputs.cache-primary-key }}
ci-matrix:
name: ${{ matrix.name }}
needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'warp' && matrix.warp-runner || matrix.fallback-runner }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: ${{ matrix.timeout-minutes }}
env:
DANGER_CI_ON_HOST_FOLDERS: 1
FILE_ENV: ${{ matrix.file-env }}
strategy:
fail-fast: false
matrix:
include:
- name: 'iwyu'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_iwyu.sh'
- name: '32 bit ARM'
warp-runner: 'ubuntu-24.04-arm' # Warp's Arm runners don't support 32-bit mode currently
fallback-runner: 'ubuntu-24.04-arm'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_arm.sh'
provider: 'gha'
- name: 'ASan + LSan + UBSan + integer'
warp-runner: 'warp-ubuntu-2404-x64-8x' # has to match container in ci/test/00_setup_env_native_asan.sh for tracing tools
fallback-runner: 'ubuntu-24.04'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_asan.sh'
- name: 'macOS-cross to arm64'
warp-runner: 'warp-ubuntu-latest-x64-4x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_mac_cross.sh'
- name: 'macOS-cross to x86_64'
warp-runner: 'warp-ubuntu-latest-x64-4x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_mac_cross_intel.sh'
- name: 'FreeBSD Cross'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_freebsd_cross.sh'
- name: 'i686'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_i686.sh'
- name: 'fuzzer,address,undefined,integer'
warp-runner: 'warp-ubuntu-latest-x64-16x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 240
file-env: './ci/test/00_setup_env_native_fuzz.sh'
- name: 'previous releases'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_previous_releases.sh'
- name: 'Alpine (musl)'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_alpine_musl.sh'
- name: 'tidy'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_tidy.sh'
- name: 'TSan'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_tsan.sh'
- name: 'MSan, fuzz'
warp-runner: 'warp-ubuntu-latest-x64-8x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 150
file-env: './ci/test/00_setup_env_native_fuzz_with_msan.sh'
- name: 'MSan'
warp-runner: 'warp-ubuntu-latest-x64-16x'
fallback-runner: 'ubuntu-latest'
timeout-minutes: 120
file-env: './ci/test/00_setup_env_native_msan.sh'
steps:
- *ANNOTATION_PR_NUMBER
- *CHECKOUT
- name: Configure environment
uses: ./.github/actions/configure-environment
- name: Restore caches
id: restore-cache
uses: ./.github/actions/cache/restore
with:
provider: ${{ matrix.provider || needs.runners.outputs.provider }}
- name: Configure Docker
uses: ./.github/actions/configure-docker
with:
provider: ${{ matrix.provider || needs.runners.outputs.provider }}
- name: Clear unnecessary files
if: ${{ needs.runners.outputs.provider == 'gha' && true || false }} # Only needed on GHA runners
uses: ./.github/actions/clear-files
- name: Enable bpfcc script
if: ${{ env.CONTAINER_NAME == 'ci_native_asan' }}
# In the image build step, no external environment variables are available,
# so any settings will need to be written to the settings env file:
run: sed -i "s|\${INSTALL_BCC_TRACING_TOOLS}|true|g" ./ci/test/00_setup_env_native_asan.sh
- name: Set mmap_rnd_bits
if: ${{ env.CONTAINER_NAME == 'ci_native_tsan' || env.CONTAINER_NAME == 'ci_native_msan' || env.CONTAINER_NAME == 'ci_native_fuzz_msan' }}
# Prevents crashes due to high ASLR entropy
run: sudo sysctl -w vm.mmap_rnd_bits=28
- name: CI script
run: ./ci/test_run_all.sh
- name: Save caches
uses: ./.github/actions/cache/save
with:
provider: ${{ matrix.provider || needs.runners.outputs.provider }}
lint:
name: 'lint'
needs: runners
runs-on: ${{ needs.runners.outputs.provider == 'warp' && 'warp-ubuntu-latest-x64-2x' || 'ubuntu-latest' }}
if: ${{ vars.SKIP_BRANCH_PUSH != 'true' || github.event_name == 'pull_request' }}
timeout-minutes: 20
env:
CONTAINER_NAME: "bitcoin-linter"
steps:
- *ANNOTATION_PR_NUMBER
- name: Checkout
uses: actions/checkout@v6
with:
ref: *CHECKOUT_REF_TMPL
fetch-depth: 0
- name: Configure Docker
uses: ./.github/actions/configure-docker
with:
provider: ${{ needs.runners.outputs.provider }}
- name: CI script
run: |
git worktree add ../lint-worktree HEAD
../lint-worktree/ci/lint.py