Skip to content

Commit 178192f

Browse files
Merge branch 'main' into fix/session-lock-release-before-teardown
2 parents 4bd7fe9 + b5d90ae commit 178192f

376 files changed

Lines changed: 14694 additions & 2512 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.crabbox.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ actions:
2929
- openclaw
3030
runnerVersion: latest
3131
ephemeral: true
32+
blacksmith:
33+
org: openclaw
34+
workflow: .github/workflows/ci-check-testbox.yml
35+
job: check
36+
ref: main
3237
aws:
3338
region: eu-west-1
3439
rootGB: 400

.github/actionlint.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ self-hosted-runner:
1414
- blacksmith-16vcpu-ubuntu-2404-arm
1515
- blacksmith-6vcpu-macos-latest
1616
- blacksmith-12vcpu-macos-latest
17+
- blacksmith-6vcpu-macos-15
18+
- blacksmith-12vcpu-macos-15
19+
- blacksmith-6vcpu-macos-26
20+
- blacksmith-12vcpu-macos-26
1721

1822
# Ignore patterns for known issues
1923
paths:

.github/actions/setup-node-env/action.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ inputs:
2020
required: false
2121
default: "true"
2222
use-actions-cache:
23-
description: Whether to restore and save the pnpm store with actions/cache.
23+
description: Whether to restore the pnpm store with actions/cache.
2424
required: false
2525
default: "true"
26+
save-actions-cache:
27+
description: Whether to save the pnpm store with actions/cache after install when no exact cache restored.
28+
required: false
29+
default: "false"
2630
runs:
2731
using: composite
2832
steps:
@@ -45,6 +49,7 @@ runs:
4549
openclaw_ensure_node "$REQUESTED_NODE_VERSION"
4650
4751
- name: Setup pnpm
52+
id: setup-pnpm
4853
uses: ./.github/actions/setup-pnpm-store-cache
4954
with:
5055
node-version: ${{ inputs.node-version }}
@@ -130,3 +135,10 @@ runs:
130135
ln -sfn "$PNPM_CONFIG_MODULES_DIR" node_modules
131136
ln -sfn . "$PNPM_CONFIG_MODULES_DIR/node_modules"
132137
fi
138+
139+
- name: Save pnpm store cache
140+
if: ${{ inputs.install-deps == 'true' && inputs.use-actions-cache == 'true' && inputs.save-actions-cache == 'true' && runner.os != 'Windows' && steps.setup-pnpm.outputs.store-cache-hit != 'true' }}
141+
uses: actions/cache/save@v5
142+
with:
143+
path: ${{ steps.setup-pnpm.outputs.store-path }}
144+
key: ${{ steps.setup-pnpm.outputs.store-cache-primary-key }}

.github/actions/setup-pnpm-store-cache/action.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ inputs:
1414
required: false
1515
default: ""
1616
use-actions-cache:
17-
description: Whether actions/cache should cache the pnpm store.
17+
description: Whether actions/cache should restore the pnpm store.
1818
required: false
1919
default: "true"
2020
outputs:
@@ -24,6 +24,15 @@ outputs:
2424
project-dir:
2525
description: Directory containing the packageManager file used for pnpm resolution.
2626
value: ${{ steps.setup-pnpm.outputs.project-dir }}
27+
store-cache-hit:
28+
description: Whether the pnpm store cache restored an exact key.
29+
value: ${{ steps.pnpm-store-cache.outputs.cache-hit }}
30+
store-cache-primary-key:
31+
description: Exact pnpm store cache key used for restore/save.
32+
value: ${{ steps.pnpm-store-cache.outputs.cache-primary-key }}
33+
store-path:
34+
description: Resolved pnpm store path.
35+
value: ${{ steps.pnpm-store.outputs.path }}
2736
runs:
2837
using: composite
2938
steps:
@@ -81,14 +90,15 @@ runs:
8190
echo "path=$store_path" >> "$GITHUB_OUTPUT"
8291
8392
- name: Restore pnpm store cache
93+
id: pnpm-store-cache
8494
if: ${{ inputs.use-actions-cache == 'true' && runner.os != 'Windows' }}
85-
uses: actions/cache@v5
95+
uses: actions/cache/restore@v5
8696
with:
8797
path: ${{ steps.pnpm-store.outputs.path }}
88-
key: pnpm-store-${{ runner.os }}-${{ inputs.node-version }}-${{ hashFiles(inputs.lockfile-path) }}
98+
key: pnpm-store-${{ runner.os }}-${{ runner.arch }}-${{ inputs.node-version }}-${{ hashFiles(inputs.package-manager-file) }}-${{ hashFiles(inputs.lockfile-path) }}
8999
restore-keys: |
90-
pnpm-store-${{ runner.os }}-${{ inputs.node-version }}-
91-
pnpm-store-${{ runner.os }}-
100+
pnpm-store-${{ runner.os }}-${{ runner.arch }}-${{ inputs.node-version }}-${{ hashFiles(inputs.package-manager-file) }}-
101+
pnpm-store-${{ runner.os }}-${{ runner.arch }}-${{ inputs.node-version }}-
92102
93103
- name: Record pnpm version
94104
id: pnpm-version

.github/actions/setup-pnpm-store-cache/ensure-node.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ openclaw_find_toolcache_node() {
9595
done
9696

9797
local node_root candidate candidate_version
98-
for node_root in "${roots[@]}"; do
98+
for node_root in ${roots[@]+"${roots[@]}"}; do
9999
while IFS= read -r candidate; do
100100
candidate_version="$("$candidate" -p 'process.versions.node' 2>/dev/null || true)"
101101
if openclaw_node_version_matches "$candidate_version" "$requested_node"; then

.github/workflows/ci.yml

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -414,13 +414,73 @@ jobs:
414414
- name: Audit production dependencies
415415
run: node scripts/pre-commit/pnpm-audit-prod.mjs --audit-level=high
416416

417+
# Warm the lockfile- and pnpm-pinned store once before Linux Node shards fan out.
418+
# On a cold key this job owns the save, so later shards restore the exact key.
419+
pnpm-store-warmup:
420+
permissions:
421+
contents: read
422+
needs: [preflight]
423+
if: needs.preflight.outputs.run_node == 'true' || needs.preflight.outputs.run_check_docs == 'true'
424+
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
425+
timeout-minutes: 20
426+
steps:
427+
- name: Checkout
428+
shell: bash
429+
env:
430+
CHECKOUT_REPO: ${{ github.repository }}
431+
CHECKOUT_SHA: ${{ needs.preflight.outputs.checkout_revision }}
432+
run: |
433+
set -euo pipefail
434+
435+
workdir="$GITHUB_WORKSPACE"
436+
reset_checkout_dir() {
437+
mkdir -p "$workdir"
438+
find "$workdir" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
439+
}
440+
441+
checkout_attempt() {
442+
local attempt="$1"
443+
444+
reset_checkout_dir
445+
git init "$workdir" >/dev/null
446+
git config --global --add safe.directory "$workdir"
447+
git -C "$workdir" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
448+
git -C "$workdir" config gc.auto 0
449+
450+
timeout --signal=TERM --kill-after=10s 30s git -C "$workdir" \
451+
-c protocol.version=2 \
452+
fetch --no-tags --prune --no-recurse-submodules --depth=1 origin \
453+
"+${CHECKOUT_SHA}:refs/remotes/origin/ci-target" || return 1
454+
455+
git -C "$workdir" checkout --force --detach "$CHECKOUT_SHA" || return 1
456+
test -f "$workdir/.github/actions/setup-node-env/action.yml" || return 1
457+
echo "checkout attempt ${attempt}/5 succeeded"
458+
}
459+
460+
for attempt in 1 2 3 4 5; do
461+
if checkout_attempt "$attempt"; then
462+
exit 0
463+
fi
464+
echo "checkout attempt ${attempt}/5 failed"
465+
sleep $((attempt * 5))
466+
done
467+
468+
echo "checkout failed after 5 attempts" >&2
469+
exit 1
470+
471+
- name: Setup Node environment
472+
uses: ./.github/actions/setup-node-env
473+
with:
474+
install-bun: "false"
475+
save-actions-cache: "true"
476+
417477
# Build dist once for Node-relevant changes and share it with downstream jobs.
418478
# Keep this overlapping with the fast correctness lanes so green PRs get heavy
419479
# test/build feedback sooner instead of waiting behind a full `check` pass.
420480
build-artifacts:
421481
permissions:
422482
contents: read
423-
needs: [preflight]
483+
needs: [preflight, pnpm-store-warmup]
424484
if: needs.preflight.outputs.run_build_artifacts == 'true'
425485
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-16vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
426486
timeout-minutes: 20
@@ -652,7 +712,7 @@ jobs:
652712
permissions:
653713
contents: read
654714
name: ${{ matrix.check_name }}
655-
needs: [preflight]
715+
needs: [preflight, pnpm-store-warmup]
656716
if: needs.preflight.outputs.run_checks_fast_core == 'true'
657717
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
658718
timeout-minutes: 60
@@ -741,7 +801,7 @@ jobs:
741801
permissions:
742802
contents: read
743803
name: ${{ matrix.checkName }}
744-
needs: [preflight]
804+
needs: [preflight, pnpm-store-warmup]
745805
if: needs.preflight.outputs.run_plugin_contracts_shards == 'true'
746806
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
747807
timeout-minutes: 60
@@ -821,7 +881,7 @@ jobs:
821881
permissions:
822882
contents: read
823883
name: ${{ matrix.checkName }}
824-
needs: [preflight]
884+
needs: [preflight, pnpm-store-warmup]
825885
if: needs.preflight.outputs.run_checks_fast == 'true'
826886
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
827887
timeout-minutes: 60
@@ -973,9 +1033,9 @@ jobs:
9731033
permissions:
9741034
contents: read
9751035
name: ${{ matrix.check_name }}
976-
needs: [preflight]
1036+
needs: [preflight, pnpm-store-warmup]
9771037
if: needs.preflight.outputs.run_checks_node_core_nondist == 'true'
978-
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (matrix.runner || 'ubuntu-24.04') || 'ubuntu-24.04') }}
1038+
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (matrix.runner || 'blacksmith-8vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
9791039
timeout-minutes: 60
9801040
strategy:
9811041
fail-fast: false
@@ -1079,9 +1139,9 @@ jobs:
10791139
permissions:
10801140
contents: read
10811141
name: ${{ matrix.check_name }}
1082-
needs: [preflight]
1083-
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check == 'true' }}
1084-
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && matrix.runner || 'ubuntu-24.04') }}
1142+
needs: [preflight, pnpm-store-warmup]
1143+
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check == 'true' && needs.pnpm-store-warmup.result == 'success' }}
1144+
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (matrix.runner || 'blacksmith-4vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
10851145
timeout-minutes: 20
10861146
strategy:
10871147
fail-fast: false
@@ -1210,8 +1270,8 @@ jobs:
12101270
permissions:
12111271
contents: read
12121272
name: ${{ matrix.check_name }}
1213-
needs: [preflight]
1214-
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check_additional == 'true' }}
1273+
needs: [preflight, pnpm-store-warmup]
1274+
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check_additional == 'true' && needs.pnpm-store-warmup.result == 'success' }}
12151275
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-8vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
12161276
timeout-minutes: 20
12171277
strategy:
@@ -1377,7 +1437,7 @@ jobs:
13771437
check-docs:
13781438
permissions:
13791439
contents: read
1380-
needs: [preflight]
1440+
needs: [preflight, pnpm-store-warmup]
13811441
if: needs.preflight.outputs.run_check_docs == 'true'
13821442
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
13831443
timeout-minutes: 20
@@ -1595,7 +1655,7 @@ jobs:
15951655
name: ${{ matrix.check_name }}
15961656
needs: [preflight]
15971657
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_macos_node == 'true' }}
1598-
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'macos-latest' || (github.repository == 'openclaw/openclaw' && 'blacksmith-6vcpu-macos-latest' || 'macos-latest') }}
1658+
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'macos-15' || (github.repository == 'openclaw/openclaw' && 'blacksmith-6vcpu-macos-15' || 'macos-15') }}
15991659
timeout-minutes: 20
16001660
strategy:
16011661
fail-fast: false
@@ -1644,7 +1704,7 @@ jobs:
16441704
name: "macos-swift"
16451705
needs: [preflight]
16461706
if: needs.preflight.outputs.run_macos_swift == 'true'
1647-
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'macos-26' || (github.repository == 'openclaw/openclaw' && 'blacksmith-12vcpu-macos-latest' || 'macos-26') }}
1707+
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'macos-26' || (github.repository == 'openclaw/openclaw' && 'blacksmith-12vcpu-macos-26' || 'macos-26') }}
16481708
timeout-minutes: 20
16491709
steps:
16501710
- name: Checkout

.github/workflows/codeql-macos-critical-security.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ permissions:
2020
jobs:
2121
macos:
2222
name: Critical Security (macOS)
23-
runs-on: blacksmith-6vcpu-macos-latest
23+
runs-on: blacksmith-6vcpu-macos-15
2424
timeout-minutes: 45
2525
steps:
2626
- name: Checkout

0 commit comments

Comments
 (0)