Skip to content

Commit 49bf536

Browse files
committed
ci: migrate primary CI jobs to ARM runners
Move depends-linux64 and its consumers (linux64, fuzz, sqlite, ubsan) to ARM runners, making aarch64 the primary CI architecture. This includes both build and test stages. Drop the aarch64-linux cross-compile job (depends + src) and its setup env script since we don't ship arm-linux-gnueabihf binaries and now have native aarch64 coverage through the migrated jobs. Jobs remaining on x86: - nowallet (build + test): sole x86_64 native coverage - mac, win64: cross-compile targets (x86 host) - lint: architecture-independent Update 00_setup_env_native_qt5.sh to dynamically detect HOST based on the runner architecture instead of hardcoding x86_64.
1 parent 9985e10 commit 49bf536

12 files changed

Lines changed: 104 additions & 95 deletions

.github/workflows/build-depends.yml

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@ on:
1111
description: "Path to built container at registry"
1212
required: true
1313
type: string
14+
base-image-digest:
15+
description: "Short hash of the CI base image manifest for cache busting"
16+
required: true
17+
type: string
1418
runs-on:
1519
description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)"
1620
required: true
1721
type: string
22+
effective-runs-on:
23+
description: "Optional runner label override used to execute the workflow jobs"
24+
required: false
25+
type: string
1826
outputs:
1927
key:
2028
description: "Key needed for restoring depends cache"
@@ -29,15 +37,16 @@ on:
2937
jobs:
3038
check-cache:
3139
name: Check cache
32-
runs-on: ${{ inputs.runs-on }}
40+
runs-on: ${{ inputs.effective-runs-on || inputs.runs-on }}
3341
outputs:
3442
cache-hit: ${{ steps.cache-check.outputs.cache-hit }}
3543
cache-key: ${{ steps.setup.outputs.cache-key }}
44+
cache-key-prefix: ${{ steps.setup.outputs.cache-key-prefix }}
3645
host: ${{ steps.setup.outputs.HOST }}
3746
dep-opts: ${{ steps.setup.outputs.DEP_OPTS }}
3847
steps:
3948
- name: Checkout code
40-
uses: actions/checkout@v4
49+
uses: actions/checkout@v6
4150
with:
4251
ref: ${{ github.event.pull_request.head.sha }}
4352
sparse-checkout: |
@@ -62,22 +71,24 @@ jobs:
6271
echo "DEP_HASH=${DEP_HASH}" >> "${GITHUB_OUTPUT}"
6372
DOCKERFILE_HASH="${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'contrib/containers/ci/ci-slim.Dockerfile') }}"
6473
PACKAGES_HASH="${{ hashFiles('depends/packages/*', 'depends/Makefile') }}"
65-
CACHE_KEY="depends-${DOCKERFILE_HASH}-${{ inputs.runs-on }}-${{ inputs.build-target }}-${DEP_HASH}-${PACKAGES_HASH}"
74+
CACHE_KEY_PREFIX="depends-${DOCKERFILE_HASH}-${{ inputs.base-image-digest }}-${{ inputs.runs-on }}-${{ inputs.build-target }}"
75+
CACHE_KEY="${CACHE_KEY_PREFIX}-${DEP_HASH}-${PACKAGES_HASH}"
76+
echo "cache-key-prefix=${CACHE_KEY_PREFIX}" >> "${GITHUB_OUTPUT}"
6677
echo "cache-key=${CACHE_KEY}" >> "${GITHUB_OUTPUT}"
6778
echo "Cache key: ${CACHE_KEY}"
6879
shell: bash
6980

7081
- name: Check for cached depends
7182
id: cache-check
72-
uses: actions/cache@v4
83+
uses: actions/cache@v5
7384
with:
7485
path: depends/built/${{ steps.setup.outputs.HOST }}
7586
key: ${{ steps.setup.outputs.cache-key }}
7687
lookup-only: true
7788

7889
- name: Cache SDKs
7990
id: cache-sdk-check
80-
uses: actions/cache@v4
91+
uses: actions/cache@v5
8192
if: inputs.build-target == 'mac'
8293
with:
8394
path: depends/SDKs
@@ -92,25 +103,25 @@ jobs:
92103
name: Build depends
93104
needs: [check-cache]
94105
if: needs.check-cache.outputs.cache-hit != 'true'
95-
runs-on: ${{ inputs.runs-on }}
106+
runs-on: ${{ inputs.effective-runs-on || inputs.runs-on }}
96107
container:
97108
image: ${{ inputs.container-path }}
98109
options: --user root
99110
steps:
100111
- name: Checkout code
101-
uses: actions/checkout@v4
112+
uses: actions/checkout@v6
102113
with:
103114
ref: ${{ github.event.pull_request.head.sha }}
104115

105116
- name: Restore depends sources
106-
uses: actions/cache/restore@v4
117+
uses: actions/cache/restore@v5
107118
with:
108119
path: depends/sources
109120
key: depends-sources-${{ hashFiles('depends/packages/*') }}
110121
restore-keys: depends-sources-
111122

112123
- name: Restore SDKs cache
113-
uses: actions/cache/restore@v4
124+
uses: actions/cache/restore@v5
114125
if: inputs.build-target == 'mac'
115126
with:
116127
path: depends/SDKs
@@ -119,20 +130,20 @@ jobs:
119130
fail-on-cache-miss: true
120131

121132
- name: Restore cached depends
122-
uses: actions/cache/restore@v4
133+
uses: actions/cache/restore@v5
123134
with:
124135
path: depends/built/${{ needs.check-cache.outputs.host }}
125136
key: ${{ needs.check-cache.outputs.cache-key }}
126137
restore-keys: |
127-
depends-${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'contrib/containers/ci/ci-slim.Dockerfile') }}-${{ inputs.build-target }}-
138+
${{ needs.check-cache.outputs.cache-key-prefix }}-
128139
129140
- name: Build depends
130141
run: |
131142
export HOST="${{ needs.check-cache.outputs.host }}"
132143
env ${{ needs.check-cache.outputs.dep-opts }} make -j$(nproc) -C depends
133144
134145
- name: Save depends cache
135-
uses: actions/cache/save@v4
146+
uses: actions/cache/save@v5
136147
with:
137148
path: depends/built/${{ needs.check-cache.outputs.host }}
138149
key: ${{ needs.check-cache.outputs.cache-key }}

.github/workflows/build.yml

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
use-blacksmith: ${{ steps.select-runner.outputs.use_blacksmith }}
3030
backlog-count: ${{ steps.select-runner.outputs.backlog_count }}
3131
decision-reason: ${{ steps.select-runner.outputs.decision_reason }}
32+
base-image-digest: ${{ steps.base-image.outputs.digest }}
3233
steps:
3334
- name: Check skip environment variables
3435
id: skip-check
@@ -45,7 +46,7 @@ jobs:
4546
4647
- name: Checkout code
4748
if: ${{ steps.skip-check.outputs.skip == 'false' }}
48-
uses: actions/checkout@v4
49+
uses: actions/checkout@v6
4950

5051
- name: Select runners
5152
id: select-runner
@@ -58,6 +59,26 @@ jobs:
5859
run: |
5960
python3 .github/workflows/select_dynamic_runner.py
6061
62+
- name: Get base image digest
63+
id: base-image
64+
if: ${{ steps.skip-check.outputs.skip == 'false' }}
65+
run: |
66+
# Fetch the canonical manifest digest for ubuntu:noble so the
67+
# depends cache key changes when Canonical pushes base image
68+
# updates (which may bump compiler versions).
69+
# Falls back to "unknown" on failure so CI is not blocked.
70+
TOKEN="$(curl -fsSL --max-time 10 \
71+
'https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull' \
72+
| jq -r '.token')" || true
73+
if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
74+
DIGEST="$(curl -fsSL --max-time 10 \
75+
-H "Authorization: Bearer $TOKEN" \
76+
-H 'Accept: application/vnd.docker.distribution.manifest.list.v2+json' \
77+
'https://registry-1.docker.io/v2/library/ubuntu/manifests/noble' \
78+
-o /dev/null -D - | grep -i docker-content-digest | awk '{print $2}' | tr -d '\r' | sed 's/^sha256://')" || true
79+
fi
80+
echo "digest=${DIGEST:-unknown}" >> "$GITHUB_OUTPUT"
81+
6182
cache-sources:
6283
name: Cache depends sources
6384
needs: [check-skip]
@@ -94,14 +115,15 @@ jobs:
94115
name: aarch64-linux-gnu
95116
uses: ./.github/workflows/build-depends.yml
96117
needs: [check-skip, container, cache-sources]
97-
if: ${{ vars.SKIP_ARM_LINUX == '' }}
118+
if: ${{ false && vars.SKIP_ARM_LINUX == '' }}
98119
with:
99120
build-target: aarch64-linux
100121
container-path: ${{ needs.container.outputs.path }}
122+
base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }}
101123
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
102124

103125
depends-linux64:
104-
name: x86_64-pc-linux-gnu
126+
name: linux64 (native)
105127
uses: ./.github/workflows/build-depends.yml
106128
needs: [check-skip, container, cache-sources]
107129
if: |
@@ -112,7 +134,9 @@ jobs:
112134
with:
113135
build-target: linux64
114136
container-path: ${{ needs.container.outputs.path }}
137+
base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }}
115138
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
139+
effective-runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
116140

117141
depends-linux64_multiprocess:
118142
name: linux64_multiprocess
@@ -124,6 +148,7 @@ jobs:
124148
with:
125149
build-target: linux64_multiprocess
126150
container-path: ${{ needs.container.outputs.path }}
151+
base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }}
127152
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
128153

129154
depends-linux64_nowallet:
@@ -134,6 +159,7 @@ jobs:
134159
with:
135160
build-target: linux64_nowallet
136161
container-path: ${{ needs.container.outputs.path }}
162+
base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }}
137163
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
138164

139165
depends-mac:
@@ -144,6 +170,7 @@ jobs:
144170
with:
145171
build-target: mac
146172
container-path: ${{ needs.container.outputs.path }}
173+
base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }}
147174
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
148175

149176
depends-win64:
@@ -154,6 +181,7 @@ jobs:
154181
with:
155182
build-target: win64
156183
container-path: ${{ needs.container.outputs.path }}
184+
base-image-digest: ${{ needs.check-skip.outputs.base-image-digest }}
157185
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
158186

159187
lint:
@@ -166,6 +194,7 @@ jobs:
166194

167195
src-aarch64-linux:
168196
name: aarch64-linux-build
197+
if: ${{ false }}
169198
uses: ./.github/workflows/build-src.yml
170199
needs: [check-skip, container, depends-aarch64-linux]
171200
with:
@@ -187,7 +216,7 @@ jobs:
187216
depends-key: ${{ needs.depends-linux64.outputs.key }}
188217
depends-host: ${{ needs.depends-linux64.outputs.host }}
189218
depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }}
190-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
219+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
191220

192221
src-linux64_fuzz:
193222
name: linux64_fuzz-build
@@ -200,7 +229,7 @@ jobs:
200229
depends-key: ${{ needs.depends-linux64.outputs.key }}
201230
depends-host: ${{ needs.depends-linux64.outputs.host }}
202231
depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }}
203-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
232+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
204233

205234
src-linux64_multiprocess:
206235
name: linux64_multiprocess-build
@@ -238,7 +267,7 @@ jobs:
238267
depends-key: ${{ needs.depends-linux64.outputs.key }}
239268
depends-host: ${{ needs.depends-linux64.outputs.host }}
240269
depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }}
241-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
270+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
242271

243272
src-linux64_tsan:
244273
name: linux64_tsan-build
@@ -264,7 +293,7 @@ jobs:
264293
depends-key: ${{ needs.depends-linux64.outputs.key }}
265294
depends-host: ${{ needs.depends-linux64.outputs.host }}
266295
depends-dep-opts: ${{ needs.depends-linux64.outputs.dep-opts }}
267-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
296+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
268297

269298
src-mac:
270299
name: mac-build
@@ -298,7 +327,7 @@ jobs:
298327
bundle-key: ${{ needs.src-linux64.outputs.key }}
299328
build-target: linux64
300329
container-path: ${{ needs.container-slim.outputs.path }}
301-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
330+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
302331

303332
test-linux64_multiprocess:
304333
name: linux64_multiprocess-test
@@ -328,7 +357,7 @@ jobs:
328357
bundle-key: ${{ needs.src-linux64_sqlite.outputs.key }}
329358
build-target: linux64_sqlite
330359
container-path: ${{ needs.container-slim.outputs.path }}
331-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
360+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}
332361

333362
test-linux64_tsan:
334363
name: linux64_tsan-test
@@ -348,4 +377,4 @@ jobs:
348377
bundle-key: ${{ needs.src-linux64_ubsan.outputs.key }}
349378
build-target: linux64_ubsan
350379
container-path: ${{ needs.container-slim.outputs.path }}
351-
runs-on: ${{ needs.check-skip.outputs['runner-amd64'] }}
380+
runs-on: ${{ needs.check-skip.outputs['runner-arm64'] }}

.github/workflows/test-src.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
with:
5050
path: |
5151
releases
52-
key: releases-${{ hashFiles('ci/test/00_setup_env_native_qt5.sh', 'test/get_previous_releases.py') }}
52+
key: releases-${{ runner.arch }}-${{ hashFiles('ci/test/00_setup_env_native_qt5.sh', 'test/get_previous_releases.py') }}
5353

5454
- name: Run functional tests
5555
id: test

ci/dash/matrix.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ export LSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/l
1616
export TSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/tsan:halt_on_error=1"
1717
export UBSAN_OPTIONS="suppressions=${BASE_ROOT_DIR}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1"
1818

19-
if [ "$BUILD_TARGET" = "aarch64-linux" ]; then
20-
source ./ci/test/00_setup_env_aarch64.sh
21-
elif [ "$BUILD_TARGET" = "linux64" ]; then
19+
if [ "$BUILD_TARGET" = "linux64" ]; then
2220
source ./ci/test/00_setup_env_native_qt5.sh
2321
elif [ "$BUILD_TARGET" = "linux64_asan" ]; then
2422
source ./ci/test/00_setup_env_native_asan.sh

ci/dash/test_integrationtests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export LD_LIBRARY_PATH=$DEPENDS_DIR/$HOST/lib
2323
if [ "$DOWNLOAD_PREVIOUS_RELEASES" = "true" ]; then
2424
echo "Downloading previous releases..."
2525
# shellcheck disable=SC2086
26-
./test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR"
26+
./test/get_previous_releases.py -b -t "$PREVIOUS_RELEASES_DIR" ${PREVIOUS_RELEASES_TAGS:-}
2727
fi
2828

2929
cd "build-ci/dashcore-$BUILD_TARGET"

ci/test/00_setup_env.sh

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,31 @@ export MAKEJOBS=${MAKEJOBS:--j$(nproc)}
3131
export BASE_SCRATCH_DIR=${BASE_SCRATCH_DIR:-$BASE_ROOT_DIR/ci/scratch}
3232
# What host to compile for. See also ./depends/README.md
3333
# Tests that need cross-compilation export the appropriate HOST.
34-
# Tests that run natively guess the host
35-
export HOST=${HOST:-$("$BASE_ROOT_DIR/depends/config.guess")}
34+
# Tests that run natively detect the host based on architecture.
35+
# We use explicit triplets rather than config.guess to ensure they match
36+
# the triplets used by depends (e.g. aarch64-linux-gnu, not aarch64-unknown-linux-gnu).
37+
if [ -z "$HOST" ]; then
38+
case "$(uname -m)" in
39+
aarch64)
40+
export HOST=aarch64-linux-gnu
41+
;;
42+
x86_64)
43+
export HOST=x86_64-pc-linux-gnu
44+
;;
45+
*)
46+
if command -v dpkg >/dev/null 2>&1; then
47+
arch="$(dpkg --print-architecture)"
48+
if [ "${arch}" = "arm64" ]; then
49+
export HOST=aarch64-linux-gnu
50+
elif [ "${arch}" = "amd64" ]; then
51+
export HOST=x86_64-pc-linux-gnu
52+
fi
53+
fi
54+
# Final fallback to config.guess
55+
export HOST=${HOST:-$("$BASE_ROOT_DIR/depends/config.guess")}
56+
;;
57+
esac
58+
fi
3659
# Whether to prefer BusyBox over GNU utilities
3760
export USE_BUSY_BOX=${USE_BUSY_BOX:-false}
3861

ci/test/00_setup_env_aarch64.sh

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)