Skip to content

Commit dfcbb0b

Browse files
committed
ci: widen persistent self-hosted Conan home to coin-matrix, CI and gate lanes
The Conan cache-lock flake is not CodeQL-specific. Job 88179349495 (Coin matrix / ltc smoke) and 88188892260 (CI / Linux x86_64) fail the same way: actions/cache reports a hit, the restore of the multi-hundred-MB conan2 tree onto VM905 then times out ("Failed to restore: The operation cannot be completed in timeout"), the home is left empty, and all eight runners fall into a simultaneous cold from-source rebuild whose I/O storm blows the 20s sqlite lock timeout ("Conan failed to acquire database lock"). Apply the same three-part fix everywhere the pattern appears: * CONAN_HOME on self-hosted becomes $HOME/.conan2-ci/$RUNNER_NAME -- persistent, so the cache-service restore is off the hot path, and keyed on the runner instance, which executes one job at a time, so it is never contended and keeps the per-job isolation of #704/#710. github-hosted forks keep RUNNER_TEMP/conan2 + actions/cache unchanged. * actions/cache conan2 steps are gated to runner.environment == github-hosted. * conan install gets a bounded 3x retry; remote downloads are the only network step left. Also scopes coin-matrix orphaned-tempfile cleanup to $CONAN_HOME instead of the shared ~/.conan2, which it was mutating out from under peer jobs, and repoints the CodeQL home from .conan2-codeql to the same per-runner path (that one was still shared across runners on concurrent refs). Windows (VM217) lanes are untouched: no restore flake reported there.
1 parent 6568ae0 commit dfcbb0b

8 files changed

Lines changed: 232 additions & 36 deletions

.github/workflows/bch-gate-g3a-regtest-block-production.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,21 @@ jobs:
3434
- uses: actions/checkout@v6
3535

3636
- name: Set per-job Conan home
37-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
37+
run: |
38+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
39+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
40+
# executes one job at a time, so this home is never contended (no
41+
# sqlite "failed to acquire database lock in 20s") while still keeping
42+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
43+
# Being persistent, it also takes the GH cache-service restore off the
44+
# hot path: that restore times out on VM905 ("Failed to restore: The
45+
# operation cannot be completed in timeout") and its miss cascaded into
46+
# a cold from-source Boost rebuild on all 8 runners at once.
47+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
48+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
49+
else
50+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
51+
fi
3852
3953
- name: Check gate entrypoint presence
4054
id: presence
@@ -72,7 +86,8 @@ jobs:
7286
if: steps.presence.outputs.exists == '1'
7387
run: conan profile show -pr:a=ci/conan/linux-gcc13.profile
7488

75-
- name: Restore Conan cache
89+
- name: Restore Conan cache (github-hosted only)
90+
if: runner.environment == 'github-hosted'
7691
if: steps.presence.outputs.exists == '1'
7792
uses: actions/cache@v5
7893
with:

.github/workflows/bch-gate-g3b-genuine-activation.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,21 @@ jobs:
3131
- uses: actions/checkout@v6
3232

3333
- name: Set per-job Conan home
34-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
34+
run: |
35+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
36+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
37+
# executes one job at a time, so this home is never contended (no
38+
# sqlite "failed to acquire database lock in 20s") while still keeping
39+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
40+
# Being persistent, it also takes the GH cache-service restore off the
41+
# hot path: that restore times out on VM905 ("Failed to restore: The
42+
# operation cannot be completed in timeout") and its miss cascaded into
43+
# a cold from-source Boost rebuild on all 8 runners at once.
44+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
45+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
46+
else
47+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
48+
fi
3549
3650
- name: Check gate entrypoint presence
3751
id: presence
@@ -69,7 +83,8 @@ jobs:
6983
if: steps.presence.outputs.exists == '1'
7084
run: conan profile show -pr:a=ci/conan/linux-gcc13.profile
7185

72-
- name: Restore Conan cache
86+
- name: Restore Conan cache (github-hosted only)
87+
if: runner.environment == 'github-hosted'
7388
if: steps.presence.outputs.exists == '1'
7489
uses: actions/cache@v5
7590
with:

.github/workflows/build.yml

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,21 @@ jobs:
4848
# 1.90.0 torn-header flakes). RUNNER_TEMP is only valid at step scope, so
4949
# export it via $GITHUB_ENV -- a job-level `env: runner.temp` fails to parse.
5050
- name: Set per-job Conan home
51-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
51+
run: |
52+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
53+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
54+
# executes one job at a time, so this home is never contended (no
55+
# sqlite "failed to acquire database lock in 20s") while still keeping
56+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
57+
# Being persistent, it also takes the GH cache-service restore off the
58+
# hot path: that restore times out on VM905 ("Failed to restore: The
59+
# operation cannot be completed in timeout") and its miss cascaded into
60+
# a cold from-source Boost rebuild on all 8 runners at once.
61+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
62+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
63+
else
64+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
65+
fi
5266
5367
- name: Install system dependencies
5468
if: runner.environment == 'github-hosted'
@@ -74,7 +88,8 @@ jobs:
7488
- name: Show committed Conan profile
7589
run: conan profile show -pr:a=ci/conan/linux-gcc13.profile
7690

77-
- name: Restore Conan cache
91+
- name: Restore Conan cache (github-hosted only)
92+
if: runner.environment == 'github-hosted'
7893
uses: actions/cache@v5
7994
with:
8095
path: ${{ runner.temp }}/conan2
@@ -90,7 +105,16 @@ jobs:
90105
run: rm -rf build_ci
91106

92107
- name: Conan install
93-
run: conan install . -pr:a=ci/conan/linux-gcc13.profile --build=missing --output-folder=build_ci
108+
run: |
109+
# Bounded retry: remote package downloads are the only network step
110+
# left here; a transient CDN/remote hiccup must not red a good PR.
111+
for attempt in 1 2 3; do
112+
if conan install . -pr:a=ci/conan/linux-gcc13.profile --build=missing --output-folder=build_ci; then exit 0; fi
113+
echo "conan install failed (attempt $attempt/3); retrying in $((attempt * 15))s"
114+
sleep $((attempt * 15))
115+
done
116+
echo "conan install failed after 3 attempts" >&2
117+
exit 1
94118
95119
- name: Configure
96120
run: cmake -S . -B build_ci -DCMAKE_TOOLCHAIN_FILE=build_ci/conan_toolchain.cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Release -DCOIN_DGB=ON
@@ -194,7 +218,21 @@ jobs:
194218
# torn-cache reds). Export via $GITHUB_ENV -- a job-level `env: runner.temp`
195219
# fails to parse.
196220
- name: Set per-job Conan home
197-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
221+
run: |
222+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
223+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
224+
# executes one job at a time, so this home is never contended (no
225+
# sqlite "failed to acquire database lock in 20s") while still keeping
226+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
227+
# Being persistent, it also takes the GH cache-service restore off the
228+
# hot path: that restore times out on VM905 ("Failed to restore: The
229+
# operation cannot be completed in timeout") and its miss cascaded into
230+
# a cold from-source Boost rebuild on all 8 runners at once.
231+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
232+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
233+
else
234+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
235+
fi
198236
199237
- name: Install system dependencies
200238
if: runner.environment == 'github-hosted'
@@ -220,7 +258,8 @@ jobs:
220258
conan profile detect --force
221259
sed -i 's/compiler.cppstd=.*/compiler.cppstd=20/' "$(conan profile path default)"
222260
223-
- name: Restore Conan cache
261+
- name: Restore Conan cache (github-hosted only)
262+
if: runner.environment == 'github-hosted'
224263
uses: actions/cache@v5
225264
with:
226265
path: ${{ runner.temp }}/conan2
@@ -236,7 +275,16 @@ jobs:
236275
run: rm -rf build_asan
237276

238277
- name: Conan install
239-
run: conan install . --build=missing --output-folder=build_asan --settings=build_type=Release
278+
run: |
279+
# Bounded retry: remote package downloads are the only network step
280+
# left here; a transient CDN/remote hiccup must not red a good PR.
281+
for attempt in 1 2 3; do
282+
if conan install . --build=missing --output-folder=build_asan --settings=build_type=Release; then exit 0; fi
283+
echo "conan install failed (attempt $attempt/3); retrying in $((attempt * 15))s"
284+
sleep $((attempt * 15))
285+
done
286+
echo "conan install failed after 3 attempts" >&2
287+
exit 1
240288
241289
- name: Configure (Release + AsAN + UBSan)
242290
# NOTE 1: must match the build_type passed to `conan install` (Release).
@@ -325,7 +373,21 @@ jobs:
325373
# torn-cache reds). Export via $GITHUB_ENV -- a job-level `env: runner.temp`
326374
# fails to parse.
327375
- name: Set per-job Conan home
328-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
376+
run: |
377+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
378+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
379+
# executes one job at a time, so this home is never contended (no
380+
# sqlite "failed to acquire database lock in 20s") while still keeping
381+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
382+
# Being persistent, it also takes the GH cache-service restore off the
383+
# hot path: that restore times out on VM905 ("Failed to restore: The
384+
# operation cannot be completed in timeout") and its miss cascaded into
385+
# a cold from-source Boost rebuild on all 8 runners at once.
386+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
387+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
388+
else
389+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
390+
fi
329391
330392
- name: Install system dependencies
331393
if: runner.environment == 'github-hosted'
@@ -351,7 +413,8 @@ jobs:
351413
conan profile detect --force
352414
sed -i 's/compiler.cppstd=.*/compiler.cppstd=20/' "$(conan profile path default)"
353415
354-
- name: Restore Conan cache
416+
- name: Restore Conan cache (github-hosted only)
417+
if: runner.environment == 'github-hosted'
355418
uses: actions/cache@v5
356419
with:
357420
path: ${{ runner.temp }}/conan2
@@ -367,7 +430,16 @@ jobs:
367430
run: rm -rf build_bch
368431

369432
- name: Conan install
370-
run: conan install . --build=missing --output-folder=build_bch --settings=build_type=Release
433+
run: |
434+
# Bounded retry: remote package downloads are the only network step
435+
# left here; a transient CDN/remote hiccup must not red a good PR.
436+
for attempt in 1 2 3; do
437+
if conan install . --build=missing --output-folder=build_bch --settings=build_type=Release; then exit 0; fi
438+
echo "conan install failed (attempt $attempt/3); retrying in $((attempt * 15))s"
439+
sleep $((attempt * 15))
440+
done
441+
echo "conan install failed after 3 attempts" >&2
442+
exit 1
371443
372444
- name: Configure (-DCOIN_BCH=ON)
373445
run: cmake -S . -B build_bch -DCMAKE_TOOLCHAIN_FILE=build_bch/conan_toolchain.cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Release -DCOIN_BCH=ON
@@ -421,7 +493,21 @@ jobs:
421493
# torn-cache reds). Export via $GITHUB_ENV -- a job-level `env: runner.temp`
422494
# fails to parse.
423495
- name: Set per-job Conan home
424-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
496+
run: |
497+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
498+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
499+
# executes one job at a time, so this home is never contended (no
500+
# sqlite "failed to acquire database lock in 20s") while still keeping
501+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
502+
# Being persistent, it also takes the GH cache-service restore off the
503+
# hot path: that restore times out on VM905 ("Failed to restore: The
504+
# operation cannot be completed in timeout") and its miss cascaded into
505+
# a cold from-source Boost rebuild on all 8 runners at once.
506+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
507+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
508+
else
509+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
510+
fi
425511
426512
- name: Install system dependencies
427513
if: runner.environment == 'github-hosted'
@@ -447,7 +533,8 @@ jobs:
447533
conan profile detect --force
448534
sed -i 's/compiler.cppstd=.*/compiler.cppstd=20/' "$(conan profile path default)"
449535
450-
- name: Restore Conan cache
536+
- name: Restore Conan cache (github-hosted only)
537+
if: runner.environment == 'github-hosted'
451538
uses: actions/cache@v5
452539
with:
453540
path: ${{ runner.temp }}/conan2
@@ -463,7 +550,16 @@ jobs:
463550
run: rm -rf build_bch_asan
464551

465552
- name: Conan install
466-
run: conan install . --build=missing --output-folder=build_bch_asan --settings=build_type=Release
553+
run: |
554+
# Bounded retry: remote package downloads are the only network step
555+
# left here; a transient CDN/remote hiccup must not red a good PR.
556+
for attempt in 1 2 3; do
557+
if conan install . --build=missing --output-folder=build_bch_asan --settings=build_type=Release; then exit 0; fi
558+
echo "conan install failed (attempt $attempt/3); retrying in $((attempt * 15))s"
559+
sleep $((attempt * 15))
560+
done
561+
echo "conan install failed after 3 attempts" >&2
562+
exit 1
467563
468564
- name: Configure (Release + AsAN + UBSan, -DCOIN_BCH=ON)
469565
run: |

.github/workflows/codeql-analysis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ jobs:
5656
# the flake ("Failed to restore: The operation cannot be completed in
5757
# timeout"), and on a miss it forced a from-source boost rebuild too.
5858
# A local persistent home takes the network off the hot path.
59-
# Dedicated path (NOT the shared ~/.conan2) preserves the torn-cache
60-
# isolation from #704/#710; this workflow's concurrency group
61-
# serialises CodeQL per ref, so nothing else writes this home.
59+
# Keyed on the runner instance (NOT the shared ~/.conan2): a runner runs
60+
# one job at a time, so this home is never contended even across refs,
61+
# preserving the torn-cache isolation of #704/#710.
6262
if [ "${{ runner.environment }}" = "github-hosted" ]; then
6363
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
6464
else
65-
echo "CONAN_HOME=$HOME/.conan2-codeql" >> "$GITHUB_ENV"
65+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
6666
fi
6767
6868
# ── C++ build (manual mode only) ─────────────────────────────────────

.github/workflows/coin-matrix.yml

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,21 @@ jobs:
3838
- uses: actions/checkout@v6
3939

4040
- name: Set per-job Conan home
41-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
41+
run: |
42+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
43+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
44+
# executes one job at a time, so this home is never contended (no
45+
# sqlite "failed to acquire database lock in 20s") while still keeping
46+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
47+
# Being persistent, it also takes the GH cache-service restore off the
48+
# hot path: that restore times out on VM905 ("Failed to restore: The
49+
# operation cannot be completed in timeout") and its miss cascaded into
50+
# a cold from-source Boost rebuild on all 8 runners at once.
51+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
52+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
53+
else
54+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
55+
fi
4256
4357
- name: Check source presence
4458
id: presence
@@ -76,7 +90,8 @@ jobs:
7690
if: steps.presence.outputs.exists == '1'
7791
run: conan profile show -pr:a=ci/conan/linux-gcc13.profile
7892

79-
- name: Restore Conan cache
93+
- name: Restore Conan cache (github-hosted only)
94+
if: runner.environment == 'github-hosted'
8095
if: steps.presence.outputs.exists == '1'
8196
uses: actions/cache@v5
8297
with:
@@ -93,21 +108,31 @@ jobs:
93108
- name: Clear orphaned Conan download tempfiles (self-hosted cache is reused)
94109
if: steps.presence.outputs.exists == '1' && runner.environment != 'github-hosted'
95110
# An interrupted or racing conan download can leave a partial conan_package.tgz
96-
# in ~/.conan2 that makes the next `conan install` abort with
111+
# in $CONAN_HOME that makes the next `conan install` abort with
97112
# "the file to download already exists". Delete these staging archives so a
98113
# missing binary package can be re-fetched cleanly; extracted packages are untouched.
99114
run: |
100-
find ~/.conan2/p -type f \( -name 'conan_package.tgz' -o -name 'conan_sources.tgz' \) -delete 2>/dev/null || true
115+
find "$CONAN_HOME/p" -type f \( -name 'conan_package.tgz' -o -name 'conan_sources.tgz' \) -delete 2>/dev/null || true
101116
102117
- name: Conan install
103118
if: steps.presence.outputs.exists == '1'
104119
run: |
105-
conan install . \
106-
-pr:a=ci/conan/linux-gcc13.profile \
107-
--lockfile=conan.lock \
108-
--build=missing \
109-
--output-folder=build_${{ matrix.coin }} \
110-
--settings=build_type=Release
120+
# Bounded retry: remote package downloads are the only network step
121+
# left here; a transient CDN/remote hiccup must not red a good PR.
122+
for attempt in 1 2 3; do
123+
if \
124+
conan install . \
125+
-pr:a=ci/conan/linux-gcc13.profile \
126+
--lockfile=conan.lock \
127+
--build=missing \
128+
--output-folder=build_${{ matrix.coin }} \
129+
--settings=build_type=Release
130+
then exit 0; fi
131+
echo "conan install failed (attempt $attempt/3); retrying in $((attempt * 15))s"
132+
sleep $((attempt * 15))
133+
done
134+
echo "conan install failed after 3 attempts" >&2
135+
exit 1
111136
112137
- name: Configure
113138
if: steps.presence.outputs.exists == '1'

.github/workflows/dash-gate-g1-byte-parity.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,21 @@ jobs:
3232
- uses: actions/checkout@v6
3333

3434
- name: Set per-job Conan home
35-
run: echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
35+
run: |
36+
# github-hosted: ephemeral per-job home, warmed by actions/cache below.
37+
# self-hosted: PERSISTENT home keyed on the runner instance. A runner
38+
# executes one job at a time, so this home is never contended (no
39+
# sqlite "failed to acquire database lock in 20s") while still keeping
40+
# the per-job isolation of #704/#710 -- no two concurrent jobs share it.
41+
# Being persistent, it also takes the GH cache-service restore off the
42+
# hot path: that restore times out on VM905 ("Failed to restore: The
43+
# operation cannot be completed in timeout") and its miss cascaded into
44+
# a cold from-source Boost rebuild on all 8 runners at once.
45+
if [ "${{ runner.environment }}" = "github-hosted" ]; then
46+
echo "CONAN_HOME=$RUNNER_TEMP/conan2" >> "$GITHUB_ENV"
47+
else
48+
echo "CONAN_HOME=$HOME/.conan2-ci/$RUNNER_NAME" >> "$GITHUB_ENV"
49+
fi
3650
3751
- name: Check gate entrypoint presence
3852
id: presence
@@ -70,7 +84,8 @@ jobs:
7084
if: steps.presence.outputs.exists == '1'
7185
run: conan profile show -pr:a=ci/conan/linux-gcc13.profile
7286

73-
- name: Restore Conan cache
87+
- name: Restore Conan cache (github-hosted only)
88+
if: runner.environment == 'github-hosted'
7489
if: steps.presence.outputs.exists == '1'
7590
uses: actions/cache@v5
7691
with:

0 commit comments

Comments
 (0)