Files
clawstor/.gitea/actions/cargo-cache/action.yml
T
Omar Sobh 89f5892e20
Build with clawstor cache / Cargo build (clawstor-cached) (pull_request) Failing after 4s
gitea: composite cargo-cache action + runner-integration doc
Ships the wire-up piece for real CI: a composite Gitea Action that
wraps `claw-cargo build` with cache-outcome reporting, plus a
matching workflow file that opts the clawstor repo itself into
being cache-hit-tested on every push. Also docs the one-time
per-runner provisioning (leaf cert, PATH install, config.toml).

* `.gitea/actions/cargo-cache/action.yml` — composite Action.
  Inputs: workspace, profile, no-upload, parallel-restore. Outputs:
  cache-outcome (HIT|MISS|POPULATED|SKIPPED), fingerprint,
  elapsed-seconds. Runner-side config lives in
  `~/.config/claw-cargo/config.toml` (not in the workflow — no
  secrets shipped from repos).
* `.gitea/workflows/build-with-cache.yml` — dogfoods the action on
  clawstor's own repo. `no-upload` set from event_name so PRs from
  forks can't poison the cache.
* `docs/runner-integration.md` — one-time setup steps, sample
  workflow snippet, expected numbers (Pi 5: 2.79× wall, tank:
  2.18×), and troubleshooting for the failures I hit in the tank
  and Pi pilots (bind_lan on fabric-only, missing CLI/config,
  rustc drift warn).

Test protocol: push this branch → main triggers the workflow → the
runner on tank has claw-cargo + tls + config provisioned already
(2026-07-13 pilot setup) → first build should MISS + populate,
subsequent build on same fingerprint should HIT.
2026-07-13 01:29:51 -07:00

109 lines
4.1 KiB
YAML

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
`~/.config/claw-cargo/config.toml` on the runner host — 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: Preflight check (claw-cargo + config)
shell: bash
run: |
set -euo pipefail
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
# The daemon config is per-runner; the action expects it to
# exist under $HOME/.config/claw-cargo/config.toml. We do not
# ship secrets from the workflow.
cfg="${HOME}/.config/claw-cargo/config.toml"
if [ ! -s "$cfg" ]; then
echo "::error::missing $cfg — fleet admin needs to provision peer + tls_dir for this runner"
exit 1
fi
- 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
args=(build --workspace "$WS" --profile "$PROFILE" --parallel-restore "$PAR_RESTORE")
if [ "$NO_UPLOAD" = "true" ]; then
args+=(--no-upload)
fi
started=$SECONDS
# Tee the summary so we can grep the outcome out for the output.
set +e
claw-cargo "${args[@]}" 2>&1 | tee /tmp/clawstor-build.out
rc=${PIPESTATUS[0]}
set -e
elapsed=$((SECONDS - started))
# Parse `cache:` line. Shapes we handle:
# cache: HIT (... bytes downloaded)
# cache: MISS
# cache: MISS -> populated (... bytes uploaded)
# cache: MISS (no upload performed)
outcome="SKIPPED"
if grep -q 'cache: *HIT' /tmp/clawstor-build.out; then
outcome="HIT"
elif grep -q 'cache: *MISS -> populated' /tmp/clawstor-build.out \
|| grep -q '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"