mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 11:25:50 -06:00
fix(ci): persist warm runtime caches across runs (#110363)
* ci: make cache persistence verifiable * test: fix cache guard CI failures * test: narrow cache maintenance env * fix(ci): stabilize vitest cache fingerprint * test: stabilize lagging-history outbox check
This commit is contained in:
committed by
GitHub
parent
f93bfc240b
commit
64f3397874
@@ -43,10 +43,6 @@ inputs:
|
||||
snapshot.
|
||||
required: false
|
||||
default: "false"
|
||||
runtime-cache-sticky-disk:
|
||||
description: Whether runtime caches should use Blacksmith sticky disks instead of actions/cache.
|
||||
required: false
|
||||
default: "false"
|
||||
vitest-fs-cache:
|
||||
description: Whether to persist Vitest's experimental filesystem module cache.
|
||||
required: false
|
||||
@@ -64,10 +60,7 @@ inputs:
|
||||
required: false
|
||||
default: "false"
|
||||
save-vitest-fs-cache:
|
||||
description: >
|
||||
Whether this job may save the shared Vitest filesystem module cache.
|
||||
Only honored outside pull_request events for sticky disks; PR jobs
|
||||
always mount the protected snapshot read-only.
|
||||
description: Whether this job may save the shared Vitest filesystem module cache.
|
||||
required: false
|
||||
default: "false"
|
||||
build-all-cache-scope:
|
||||
@@ -122,15 +115,15 @@ runs:
|
||||
|
||||
- name: Mount dependency sticky disk
|
||||
if: inputs.sticky-disk == 'true'
|
||||
uses: useblacksmith/stickydisk@5b350170ae4ef55b536b548ef5f5896e76a6b54f # v1.4.0
|
||||
uses: useblacksmith/stickydisk@6d373c96a74cbde0c99fedc5ea5d3a7ba66ba494 # main (post-v1.4.0 hot-attach fix)
|
||||
with:
|
||||
# One stable disk per Node line. v4 resets the v3 lineage after
|
||||
# Blacksmith repeatedly acknowledged commits but kept restoring its
|
||||
# original snapshot. The v2 per-PR/per-manifest-hash keys
|
||||
# One stable disk per Node line. v5 starts a fresh lineage for the
|
||||
# preflight-serialized writer after Blacksmith acknowledged repeated v4
|
||||
# commits but kept restoring its original snapshot. The v2 per-PR/per-manifest-hash keys
|
||||
# saturated Blacksmith's installation-wide sticky-disk budget. Install
|
||||
# inputs, runner platform, and the exact Node patch live in the runtime
|
||||
# marker below, so changes refresh this disk in place.
|
||||
key: ${{ github.repository }}-node-deps-bind-v4-${{ inputs.node-version }}
|
||||
key: ${{ github.repository }}-node-deps-bind-v5-${{ inputs.node-version }}
|
||||
path: /var/tmp/openclaw-node-deps
|
||||
# Single semantic writer: only the designated trusted-push job may
|
||||
# commit, so pull_request clones stay read-only. Like every sticky
|
||||
@@ -139,58 +132,37 @@ runs:
|
||||
# and same-repo PR authors already hold repository write access.
|
||||
# Explicit true (not on-change) because the allocated-byte heuristic
|
||||
# can miss a fingerprint refresh whose reinstall keeps disk usage
|
||||
# stable, permanently stranding consumers on a stale marker. v1.4.0
|
||||
# skips commit after failed/cancelled steps, so a broken install
|
||||
# cannot seed this key.
|
||||
# stable, permanently stranding consumers on a stale marker. The action
|
||||
# skips commit after failed/cancelled steps, so a broken install cannot
|
||||
# seed this key.
|
||||
commit: ${{ inputs.save-sticky-disk == 'true' && github.event_name != 'pull_request' && 'true' || 'false' }}
|
||||
|
||||
- name: Mount Vitest transform cache sticky disk
|
||||
if: inputs.vitest-fs-cache == 'true' && (inputs.sticky-disk == 'true' || inputs.runtime-cache-sticky-disk == 'true') && runner.os != 'Windows'
|
||||
uses: useblacksmith/stickydisk@5b350170ae4ef55b536b548ef5f5896e76a6b54f # v1.4.0
|
||||
with:
|
||||
# One stable disk per runner shape. The old per-PR overlay disks
|
||||
# minted a new backing disk for every PR and helped saturate
|
||||
# Blacksmith's installation-wide sticky-disk budget, 429-failing every
|
||||
# mount. Cache entries are content-hash keyed (id+content+env), so PRs
|
||||
# can safely read the protected snapshot directly; PR-local misses are
|
||||
# rebuilt in the discarded mount. The generation guard below clears
|
||||
# incompatible transform inputs without leaking one disk per lockfile.
|
||||
key: ${{ github.repository }}-vitest-fs-v2-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}
|
||||
path: /var/tmp/openclaw-vitest-fs-cache
|
||||
# Single semantic writer: only the designated non-PR writer commits;
|
||||
# pull_request mounts stay read-only clones. Explicit true avoids
|
||||
# stickydisk's allocated-byte heuristic missing equal-size
|
||||
# replacements or prune-balanced writes.
|
||||
commit: ${{ inputs.save-vitest-fs-cache == 'true' && github.event_name != 'pull_request' && 'true' || 'false' }}
|
||||
|
||||
- name: Restore and save Vitest transform cache
|
||||
if: inputs.vitest-fs-cache == 'true' && inputs.sticky-disk != 'true' && inputs.runtime-cache-sticky-disk != 'true' && inputs.save-vitest-fs-cache == 'true' && runner.os != 'Windows'
|
||||
if: inputs.vitest-fs-cache == 'true' && inputs.save-vitest-fs-cache == 'true' && runner.os != 'Windows'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: /var/tmp/openclaw-vitest-fs-cache
|
||||
# actions/cache entries are immutable. One matrix job writes a new
|
||||
# run key; every job restores the newest cache through coarse prefixes.
|
||||
key: ${{ github.repository }}-vitest-fs-v2-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
# Blacksmith transparently accelerates the upstream Actions cache API.
|
||||
# The scheduled/dispatch warmer writes one immutable protected archive;
|
||||
# all CI shards restore it into isolated runner-local directories.
|
||||
key: ${{ github.repository }}-vitest-fs-v3-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**', '!**/node_modules/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
restore-keys: |
|
||||
${{ github.repository }}-vitest-fs-v2-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**') }}-
|
||||
${{ github.repository }}-vitest-fs-v3-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**', '!**/node_modules/**') }}-
|
||||
|
||||
- name: Restore Vitest transform cache
|
||||
if: inputs.vitest-fs-cache == 'true' && inputs.sticky-disk != 'true' && inputs.runtime-cache-sticky-disk != 'true' && inputs.save-vitest-fs-cache != 'true' && runner.os != 'Windows'
|
||||
if: inputs.vitest-fs-cache == 'true' && inputs.save-vitest-fs-cache != 'true' && runner.os != 'Windows'
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: /var/tmp/openclaw-vitest-fs-cache
|
||||
key: ${{ github.repository }}-vitest-fs-v2-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
key: ${{ github.repository }}-vitest-fs-v3-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**', '!**/node_modules/**') }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
restore-keys: |
|
||||
${{ github.repository }}-vitest-fs-v2-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**') }}-
|
||||
${{ github.repository }}-vitest-fs-v3-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**', '!**/node_modules/**') }}-
|
||||
|
||||
- name: Configure Vitest transform cache
|
||||
if: inputs.vitest-fs-cache == 'true' && runner.os != 'Windows'
|
||||
env:
|
||||
CACHE_GENERATION: ${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**') }}
|
||||
# Sticky PR mounts never commit, so pruning there would only burn
|
||||
# shard wall clock on a discarded clone; non-sticky (actions/cache)
|
||||
# writers still prune their PR-scoped archives.
|
||||
CACHE_WRITER: ${{ inputs.save-vitest-fs-cache == 'true' && ((inputs.sticky-disk != 'true' && inputs.runtime-cache-sticky-disk != 'true') || github.event_name != 'pull_request') && '1' || '0' }}
|
||||
CACHE_GENERATION: ${{ hashFiles('pnpm-lock.yaml', 'pnpm-workspace.yaml', '**/package.json', '**/tsconfig*.json', 'vitest.config.*', 'test/vitest/**', '!**/node_modules/**') }}
|
||||
CACHE_WRITER: ${{ inputs.save-vitest-fs-cache == 'true' && '1' || '0' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -202,9 +174,8 @@ runs:
|
||||
cache_generation="$(<"$generation_file")"
|
||||
fi
|
||||
cache_entry="$(find "$cache_root" -mindepth 1 -maxdepth 1 -print -quit)"
|
||||
# Read-only PR mounts clear a mismatched generation too: the wipe only
|
||||
# affects the discarded local clone, and mixing generations could
|
||||
# false-hit transforms produced under incompatible tsconfig/lockfile.
|
||||
# Every restore is runner-local. Never mix incompatible transform
|
||||
# inputs even when an older archive was selected through a prefix.
|
||||
if [[ -n "$cache_entry" ]] && [[ "$cache_generation" != "$CACHE_GENERATION" ]]; then
|
||||
echo "Vitest transform inputs changed; clearing incompatible cache generation"
|
||||
find "$cache_root" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
|
||||
@@ -215,39 +186,42 @@ runs:
|
||||
echo "OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=$cache_root" >> "$GITHUB_ENV"
|
||||
echo "OPENCLAW_VITEST_FS_MODULE_CACHE_WRITER=$CACHE_WRITER" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Mount Node compile cache sticky disk
|
||||
if: inputs.node-compile-cache == 'true' && (inputs.sticky-disk == 'true' || inputs.runtime-cache-sticky-disk == 'true') && runner.os != 'Windows'
|
||||
uses: useblacksmith/stickydisk@5b350170ae4ef55b536b548ef5f5896e76a6b54f # v1.4.0
|
||||
with:
|
||||
# Trusted PRs read the protected dependency bytecode seed but cannot
|
||||
# publish feature-branch code into it. Node isolates exact versions and
|
||||
# invalidates bytecode when module contents change.
|
||||
key: ${{ github.repository }}-node-compile-v2-${{ inputs.node-compile-cache-scope }}-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}
|
||||
path: /var/tmp/openclaw-node-compile-cache
|
||||
commit: ${{ inputs.save-node-compile-cache == 'true' && github.event_name != 'pull_request' && 'true' || 'false' }}
|
||||
- name: Select Node compile cache epoch
|
||||
id: node-compile-cache-epoch
|
||||
if: inputs.node-compile-cache == 'true' && runner.os != 'Windows'
|
||||
shell: bash
|
||||
env:
|
||||
CACHE_SCOPE: ${{ inputs.node-compile-cache-scope }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ "$CACHE_SCOPE" = "build" ]; then
|
||||
echo "value=$(date -u +%Y%m%d)" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "value=${GITHUB_RUN_ID:?}-${GITHUB_RUN_ATTEMPT:?}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Restore and save Node compile cache
|
||||
if: inputs.node-compile-cache == 'true' && inputs.sticky-disk != 'true' && inputs.runtime-cache-sticky-disk != 'true' && inputs.save-node-compile-cache == 'true' && runner.os != 'Windows'
|
||||
if: inputs.node-compile-cache == 'true' && inputs.save-node-compile-cache == 'true' && runner.os != 'Windows'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: /var/tmp/openclaw-node-compile-cache
|
||||
key: ${{ github.repository }}-node-compile-v2-${{ inputs.node-compile-cache-scope }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
key: ${{ github.repository }}-node-compile-v3-${{ inputs.node-compile-cache-scope }}-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ steps.node-compile-cache-epoch.outputs.value }}
|
||||
restore-keys: |
|
||||
${{ github.repository }}-node-compile-v2-${{ inputs.node-compile-cache-scope }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-
|
||||
${{ github.repository }}-node-compile-v3-${{ inputs.node-compile-cache-scope }}-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-
|
||||
|
||||
- name: Restore Node compile cache
|
||||
if: inputs.node-compile-cache == 'true' && inputs.sticky-disk != 'true' && inputs.runtime-cache-sticky-disk != 'true' && inputs.save-node-compile-cache != 'true' && runner.os != 'Windows'
|
||||
if: inputs.node-compile-cache == 'true' && inputs.save-node-compile-cache != 'true' && runner.os != 'Windows'
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: /var/tmp/openclaw-node-compile-cache
|
||||
key: ${{ github.repository }}-node-compile-v2-${{ inputs.node-compile-cache-scope }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
key: ${{ github.repository }}-node-compile-v3-${{ inputs.node-compile-cache-scope }}-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-${{ steps.node-compile-cache-epoch.outputs.value }}
|
||||
restore-keys: |
|
||||
${{ github.repository }}-node-compile-v2-${{ inputs.node-compile-cache-scope }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'protected' }}-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-
|
||||
${{ github.repository }}-node-compile-v3-${{ inputs.node-compile-cache-scope }}-protected-${{ runner.os }}-${{ runner.arch }}-node-${{ inputs.node-version }}-
|
||||
|
||||
- name: Configure Node compile cache
|
||||
if: inputs.node-compile-cache == 'true' && runner.os != 'Windows'
|
||||
env:
|
||||
CACHE_WRITER: ${{ inputs.save-node-compile-cache == 'true' && ((inputs.sticky-disk != 'true' && inputs.runtime-cache-sticky-disk != 'true') || github.event_name != 'pull_request') && '1' || '0' }}
|
||||
CACHE_WRITER: ${{ inputs.save-node-compile-cache == 'true' && '1' || '0' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
@@ -1 +1,22 @@
|
||||
[]
|
||||
[
|
||||
{
|
||||
"key": "openclaw/openclaw-node-compile-v2-build-protected-Linux-X64-node-24.x",
|
||||
"architecture": "amd64",
|
||||
"region": "eu-west"
|
||||
},
|
||||
{
|
||||
"key": "openclaw/openclaw-node-compile-v2-test-protected-Linux-X64-node-24.x",
|
||||
"architecture": "amd64",
|
||||
"region": "eu-west"
|
||||
},
|
||||
{
|
||||
"key": "openclaw/openclaw-node-deps-bind-v4-24.x",
|
||||
"architecture": "amd64",
|
||||
"region": "eu-west"
|
||||
},
|
||||
{
|
||||
"key": "openclaw/openclaw-vitest-fs-v2-protected-Linux-X64-node-24.x",
|
||||
"architecture": "amd64",
|
||||
"region": "eu-west"
|
||||
}
|
||||
]
|
||||
|
||||
+53
-13
@@ -745,6 +745,51 @@ jobs:
|
||||
if: steps.manifest.outputs.run_protocol_event_coverage == 'true'
|
||||
run: node scripts/check-protocol-event-coverage.mjs
|
||||
|
||||
# Canonical main cannot be cancelled by a newer push. Publish the sole
|
||||
# dependency snapshot here before fanout. Blacksmith may expose a fresh
|
||||
# commit only to a later run; readers retain the marker-checked fallback.
|
||||
- name: Refresh sticky dependency snapshot
|
||||
if: github.repository == 'openclaw/openclaw' && github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.manifest.outputs.run_node == 'true'
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
install-bun: "false"
|
||||
save-sticky-disk: "true"
|
||||
sticky-disk: "true"
|
||||
use-actions-cache: "false"
|
||||
|
||||
- name: Maintain sticky dependency store budget
|
||||
if: github.repository == 'openclaw/openclaw' && github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.manifest.outputs.run_node == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
OPENCLAW_PNPM_STORE_MAX_KIB: "8388608"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
store_dir="${PNPM_CONFIG_STORE_DIR:?}"
|
||||
before_kib="$(du -sk "$store_dir" | cut -f1)"
|
||||
after_kib="$before_kib"
|
||||
pruned=false
|
||||
|
||||
if [ "$before_kib" -gt "$OPENCLAW_PNPM_STORE_MAX_KIB" ]; then
|
||||
echo "pnpm store is ${before_kib} KiB; pruning above ${OPENCLAW_PNPM_STORE_MAX_KIB} KiB ceiling"
|
||||
PNPM_CONFIG_STORE_DIR="$store_dir" pnpm store prune
|
||||
after_kib="$(du -sk "$store_dir" | cut -f1)"
|
||||
pruned=true
|
||||
else
|
||||
echo "pnpm store is ${before_kib} KiB; below ${OPENCLAW_PNPM_STORE_MAX_KIB} KiB ceiling"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "### Dependency store maintenance"
|
||||
echo
|
||||
echo "- Before: ${before_kib} KiB"
|
||||
echo "- After: ${after_kib} KiB"
|
||||
echo "- Pruned: ${pruned}"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
if [ "$after_kib" -gt "$OPENCLAW_PNPM_STORE_MAX_KIB" ]; then
|
||||
echo "::warning::pnpm store remains above its 8 GiB maintenance ceiling after prune"
|
||||
fi
|
||||
|
||||
# Run dependency-free security checks on a hosted runner in parallel with
|
||||
# scope detection. No downstream job waits for Python/pre-commit setup.
|
||||
security-fast:
|
||||
@@ -909,13 +954,13 @@ jobs:
|
||||
- name: Audit production dependencies
|
||||
run: node scripts/pre-commit/pnpm-audit-prod.mjs --audit-level=high
|
||||
|
||||
# Warm the lockfile- and pnpm-pinned store without blocking Linux Node shards.
|
||||
# On a cold key this job owns the save for later workflow runs.
|
||||
# Warm the lockfile- and pnpm-pinned Actions cache for PR and manual runs.
|
||||
# Canonical main publishes its sticky snapshot in preflight before fanout.
|
||||
pnpm-store-warmup:
|
||||
permissions:
|
||||
contents: read
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_node == 'true' || needs.preflight.outputs.run_check_docs == 'true'
|
||||
if: ${{ (needs.preflight.outputs.run_node == 'true' || needs.preflight.outputs.run_check_docs == 'true') && !(github.repository == 'openclaw/openclaw' && github.event_name == 'push' && github.ref == 'refs/heads/main') }}
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
@@ -1007,7 +1052,6 @@ jobs:
|
||||
# repository-global state and must never be produced by fork code.
|
||||
sticky-disk: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'true' || 'false' }}
|
||||
use-actions-cache: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'false' || 'true' }}
|
||||
runtime-cache-sticky-disk: ${{ github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'true' || 'false' }}
|
||||
save-node-compile-cache: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && 'true' || 'false' }}
|
||||
|
||||
- name: Restore build-all step cache
|
||||
@@ -1805,16 +1849,12 @@ jobs:
|
||||
# Fork PRs must keep actions/cache: sticky snapshots are writable,
|
||||
# repository-global state and must never be produced by fork code.
|
||||
sticky-disk: ${{ (matrix.node_version == null || matrix.node_version == '24.x') && github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'true' || 'false' }}
|
||||
runtime-cache-sticky-disk: ${{ (matrix.node_version == null || matrix.node_version == '24.x') && github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'true' || 'false' }}
|
||||
use-actions-cache: ${{ (matrix.node_version == null || matrix.node_version == '24.x') && github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw') && 'false' || 'true' }}
|
||||
vitest-fs-cache: "true"
|
||||
node-compile-cache: "true"
|
||||
node-compile-cache-scope: "test"
|
||||
# One matrix job is the designated warm-seed writer; the action only
|
||||
# honors it outside pull_request events, so PR shards always read the
|
||||
# protected snapshot without committing competing writes.
|
||||
save-vitest-fs-cache: ${{ matrix.save_vitest_fs_cache && 'true' || 'false' }}
|
||||
save-node-compile-cache: ${{ matrix.save_vitest_fs_cache && 'true' || 'false' }}
|
||||
# CI shards only read the protected immutable seed. The scheduled or
|
||||
# explicitly dispatched warmer is the sole test-cache writer.
|
||||
|
||||
- name: Setup Go for docs i18n
|
||||
if: matrix.requires_go == true
|
||||
@@ -1962,7 +2002,7 @@ jobs:
|
||||
# protected boundary lane may publish this repository-global snapshot.
|
||||
- name: Mount extension boundary sticky disk
|
||||
if: matrix.task == 'lint' && github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw')
|
||||
uses: useblacksmith/stickydisk@5b350170ae4ef55b536b548ef5f5896e76a6b54f # v1.4.0
|
||||
uses: useblacksmith/stickydisk@6d373c96a74cbde0c99fedc5ea5d3a7ba66ba494 # main (post-v1.4.0 hot-attach fix)
|
||||
with:
|
||||
# One stable disk for the whole repository. The v1 per-PR/per-config
|
||||
# keys minted a new backing disk for every PR and toolchain change
|
||||
@@ -2205,7 +2245,7 @@ jobs:
|
||||
# repository-global snapshots, so they keep the GitHub cache path.
|
||||
- name: Mount extension boundary sticky disk
|
||||
if: matrix.group == 'extension-package-boundary' && github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw')
|
||||
uses: useblacksmith/stickydisk@5b350170ae4ef55b536b548ef5f5896e76a6b54f # v1.4.0
|
||||
uses: useblacksmith/stickydisk@6d373c96a74cbde0c99fedc5ea5d3a7ba66ba494 # main (post-v1.4.0 hot-attach fix)
|
||||
with:
|
||||
# One stable disk for the whole repository. The v1 per-PR/per-config
|
||||
# keys minted a new backing disk for every PR and toolchain change
|
||||
@@ -3131,7 +3171,7 @@ jobs:
|
||||
# runs-on already selects non-Blacksmith ubuntu-24.04 runners).
|
||||
- name: Mount Gradle sticky disk
|
||||
if: github.event_name != 'workflow_dispatch' && github.repository == 'openclaw/openclaw' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'openclaw/openclaw')
|
||||
uses: useblacksmith/stickydisk@5b350170ae4ef55b536b548ef5f5896e76a6b54f # v1.4.0
|
||||
uses: useblacksmith/stickydisk@6d373c96a74cbde0c99fedc5ea5d3a7ba66ba494 # main (post-v1.4.0 hot-attach fix)
|
||||
with:
|
||||
# One stable disk per matrix task. The v1 per-PR/per-dependency-hash
|
||||
# keys minted a new backing disk for every PR and dependency bump
|
||||
|
||||
@@ -5,10 +5,6 @@ on:
|
||||
types: [vitest-cache-warm]
|
||||
schedule:
|
||||
- cron: "17 8 * * *"
|
||||
workflow_run: # zizmor: ignore[dangerous-triggers] successful main-push CI only; read-only default-branch checkout, no artifacts or untrusted ref
|
||||
workflows: [CI]
|
||||
branches: [main]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -19,73 +15,29 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
warm:
|
||||
# Canonical main CI is single-flight, so only a completed green integration
|
||||
# cycle may refresh the dependency snapshot. Scheduled/dispatch runs remain
|
||||
# the transform and compile cache writers.
|
||||
if: github.repository == 'openclaw/openclaw' && (github.event_name != 'workflow_run' || (github.event.workflow_run.event == 'push' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.head_branch == 'main'))
|
||||
# Dependency snapshots are serialized before main CI fanout. This workflow
|
||||
# writes only the transform and compile caches from scheduled/trusted runs.
|
||||
if: github.repository == 'openclaw/openclaw'
|
||||
runs-on: blacksmith-8vcpu-ubuntu-2404
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
# workflow_run's github.sha follows the current default-branch tip,
|
||||
# which can be newer than the green run that authorized this write.
|
||||
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.sha }}
|
||||
|
||||
- name: Setup Node environment
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
install-bun: "false"
|
||||
node-compile-cache: ${{ github.event_name != 'workflow_run' && 'true' || 'false' }}
|
||||
node-compile-cache: "true"
|
||||
node-compile-cache-scope: "test"
|
||||
runtime-cache-sticky-disk: ${{ github.event_name != 'workflow_run' && 'true' || 'false' }}
|
||||
save-node-compile-cache: ${{ github.event_name != 'workflow_run' && 'true' || 'false' }}
|
||||
# This disposable, non-cancelled workflow is the sole dependency
|
||||
# snapshot writer. Main CI completion coalesces refreshes without
|
||||
# putting required build jobs in a cancel-on-pending mutex.
|
||||
save-sticky-disk: "true"
|
||||
save-vitest-fs-cache: ${{ github.event_name != 'workflow_run' && 'true' || 'false' }}
|
||||
sticky-disk: "true"
|
||||
use-actions-cache: "false"
|
||||
vitest-fs-cache: ${{ github.event_name != 'workflow_run' && 'true' || 'false' }}
|
||||
|
||||
- name: Maintain dependency store budget
|
||||
shell: bash
|
||||
env:
|
||||
# The current store is well below this ceiling. Prune only after
|
||||
# accumulated retired package versions exceed 8 GiB.
|
||||
OPENCLAW_PNPM_STORE_MAX_KIB: "8388608"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
store_dir="${PNPM_CONFIG_STORE_DIR:?}"
|
||||
before_kib="$(du -sk "$store_dir" | cut -f1)"
|
||||
after_kib="$before_kib"
|
||||
pruned=false
|
||||
|
||||
if [ "$before_kib" -gt "$OPENCLAW_PNPM_STORE_MAX_KIB" ]; then
|
||||
echo "pnpm store is ${before_kib} KiB; pruning above ${OPENCLAW_PNPM_STORE_MAX_KIB} KiB ceiling"
|
||||
PNPM_CONFIG_STORE_DIR="$store_dir" pnpm store prune
|
||||
after_kib="$(du -sk "$store_dir" | cut -f1)"
|
||||
pruned=true
|
||||
else
|
||||
echo "pnpm store is ${before_kib} KiB; below ${OPENCLAW_PNPM_STORE_MAX_KIB} KiB ceiling"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "### Dependency store maintenance"
|
||||
echo
|
||||
echo "- Before: ${before_kib} KiB"
|
||||
echo "- After: ${after_kib} KiB"
|
||||
echo "- Pruned: ${pruned}"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
if [ "$after_kib" -gt "$OPENCLAW_PNPM_STORE_MAX_KIB" ]; then
|
||||
echo "::warning::pnpm store remains above its 8 GiB maintenance ceiling after prune"
|
||||
fi
|
||||
save-actions-cache: "true"
|
||||
save-node-compile-cache: "true"
|
||||
save-vitest-fs-cache: "true"
|
||||
sticky-disk: "false"
|
||||
use-actions-cache: "true"
|
||||
vitest-fs-cache: "true"
|
||||
|
||||
- name: Select broad cache seed
|
||||
if: github.event_name != 'workflow_run'
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -113,5 +65,4 @@ jobs:
|
||||
EOF
|
||||
|
||||
- name: Warm transform and compile caches
|
||||
if: github.event_name != 'workflow_run'
|
||||
run: node scripts/ci-run-node-test-shard.mjs
|
||||
|
||||
Reference in New Issue
Block a user