name: 'Clawstor cargo cache' description: > Wraps `cargo build` with a peer-cache lookup: HIT restores the target dir from the runner-local clawstor daemon (skipping dep compile); MISS runs cargo build then captures + uploads the target dir to the daemon. Config comes from the runner user's home (~/.config/claw-cargo/config.toml or the legacy ~/.claw-cargo/) — provisioned by the fleet-admin, not from the workflow. inputs: workspace: description: 'Path to the cargo workspace root' required: false default: '.' profile: description: 'Cargo profile (dev, release, custom)' required: false default: 'dev' no-upload: description: > When "true", skip capture + upload on a miss. Useful for read-only CI jobs (PR builds, forks). Defaults to false so main-branch jobs populate the cache. required: false default: 'false' parallel-restore: description: > Concurrent chunk fetches on cache HIT. Default 1 (sequential BlobGetStream) — measured faster than parallel on loopback. Set to 8+ on cross-node deployments where per-stream throughput caps bite. required: false default: '1' outputs: cache-outcome: description: 'One of: HIT, MISS, POPULATED, SKIPPED' value: ${{ steps.build.outputs.cache-outcome }} fingerprint: description: 'The fingerprint claw-cargo computed for this build' value: ${{ steps.build.outputs.fingerprint }} elapsed-seconds: description: 'Wall-clock seconds elapsed in the build step' value: ${{ steps.build.outputs.elapsed-seconds }} runs: using: 'composite' steps: - name: Build with clawstor cache id: build shell: bash env: WS: ${{ inputs.workspace }} PROFILE: ${{ inputs.profile }} NO_UPLOAD: ${{ inputs.no-upload }} PAR_RESTORE: ${{ inputs.parallel-restore }} run: | set -euo pipefail # Field finding 2026-07-13: Gitea Actions composite steps run # with a stripped PATH that omits /usr/local/bin. Force it + # the runner user's cargo bin, so the CLI is found regardless # of how the workflow was invoked. export PATH="/usr/local/bin:$HOME/.cargo/bin:$PATH" if ! command -v claw-cargo >/dev/null 2>&1; then echo "::error::claw-cargo not on PATH - fleet admin needs to install /usr/local/bin/claw-cargo on this runner" exit 1 fi claw-cargo --version # Accept both the XDG-style path and the legacy dotfile # location. client_config resolves them in the same order. cfg="" for cand in \ "${XDG_CONFIG_HOME:-$HOME/.config}/claw-cargo/config.toml" \ "$HOME/.claw-cargo/config.toml"; do if [ -s "$cand" ]; then cfg="$cand" break fi done if [ -z "$cfg" ]; then echo "::error::no claw-cargo config found under \$HOME/.config/claw-cargo/ or \$HOME/.claw-cargo/ - fleet admin needs to provision peer + tls_dir for this runner" exit 1 fi args=(build --workspace "$WS" --profile "$PROFILE" --parallel-restore "$PAR_RESTORE") if [ "$NO_UPLOAD" = "true" ]; then args+=(--no-upload) fi started=$SECONDS set +e claw-cargo "${args[@]}" 2>&1 | tee /tmp/clawstor-build.out rc=${PIPESTATUS[0]} set -e elapsed=$((SECONDS - started)) outcome=SKIPPED if grep -q 'cache: *HIT' /tmp/clawstor-build.out; then outcome=HIT elif grep -qE 'cache: *MISS.*populated' /tmp/clawstor-build.out; then outcome=POPULATED elif grep -q 'cache: *MISS' /tmp/clawstor-build.out; then outcome=MISS fi fingerprint="$(grep -oE 'fingerprint: *[0-9a-f]+' /tmp/clawstor-build.out | head -1 | awk '{print $2}')" echo "cache-outcome=$outcome" >> "$GITHUB_OUTPUT" echo "fingerprint=${fingerprint:-unknown}" >> "$GITHUB_OUTPUT" echo "elapsed-seconds=$elapsed" >> "$GITHUB_OUTPUT" echo "::notice::clawstor $outcome fingerprint=${fingerprint:-unknown} elapsed=${elapsed}s" exit "$rc"