Skip to content

Track Dashboard

Track Dashboard #2077

name: Track Dashboard
on:
schedule:
# Development follows OpenClaw main, so refresh it often enough to catch
# contract drift. The job usually finishes in a few minutes; concurrency
# below keeps slower runs from stacking up.
- cron: "7,22,37,52 * * * *"
workflow_dispatch:
inputs:
track:
description: "Crabpot track to refresh"
required: true
default: development
type: choice
options:
- development
- beta
- latest
- all
permissions:
contents: write
jobs:
dashboard:
name: Refresh ${{ matrix.track }} dashboard
runs-on: ubuntu-latest
concurrency:
group: crabpot-track-dashboard-${{ github.event_name == 'workflow_dispatch' && 'manual' || 'schedule' }}-${{ github.event_name == 'workflow_dispatch' && inputs.track || matrix.track }}-${{ matrix.track }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
include:
- track: latest
branch: main
fixture_set: ""
plugin_track: latest
- track: beta
branch: crab-beta
fixture_set: ""
plugin_track: beta
- track: development
branch: crab-development
fixture_set: openclaw-beta
plugin_track: source-pack
steps:
- name: Select requested track
id: select
shell: bash
run: |
run=false
if [ "${{ github.event_name }}" = "schedule" ] && [ "${{ matrix.track }}" = "development" ]; then
run=true
fi
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && { [ "${{ inputs.track }}" = "all" ] || [ "${{ inputs.track }}" = "${{ matrix.track }}" ]; }; then
run=true
fi
echo "run=${run}" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v6
if: ${{ steps.select.outputs.run == 'true' }}
with:
ref: main
submodules: recursive
- uses: actions/setup-node@v6
if: ${{ steps.select.outputs.run == 'true' }}
with:
node-version: 22
cache: npm
cache-dependency-path: |
plugins/**/package-lock.json
- name: Resolve OpenClaw track
if: ${{ steps.select.outputs.run == 'true' }}
id: openclaw-track
run: node scripts/resolve-openclaw-track.mjs --track "${{ matrix.track }}" --github-output
- uses: actions/checkout@v6
if: ${{ steps.select.outputs.run == 'true' }}
with:
repository: openclaw/openclaw
ref: ${{ steps.openclaw-track.outputs.ref }}
path: openclaw
- if: ${{ steps.select.outputs.run == 'true' }}
run: |
node scripts/run-static-suite.mjs \
--openclaw ./openclaw \
--policy dashboard \
--profile-runs 3 \
--plugin-inspector-smoke \
--openclaw-track "${{ matrix.track }}" \
--fixture-set "${{ matrix.fixture_set }}" \
--plugin-track "${{ matrix.plugin_track }}"
- name: Install OpenClaw lifecycle dependencies
if: ${{ steps.select.outputs.run == 'true' }}
run: |
corepack enable
corepack prepare "$(node -p "require('./openclaw/package.json').packageManager.split('+')[0]")" --activate
pnpm --dir openclaw install --frozen-lockfile --ignore-scripts
- name: Fetch main dashboard baseline
if: ${{ steps.select.outputs.run == 'true' && matrix.track != 'latest' }}
run: |
mkdir -p .crabpot/baseline
git fetch --no-tags --depth=1 origin main
git show origin/main:reports/crabpot-dashboard-data.json > .crabpot/baseline/main-dashboard-data.json || true
- name: Write branch dashboard
if: ${{ steps.select.outputs.run == 'true' }}
env:
CRABPOT_FIXTURE_SET: ${{ matrix.fixture_set }}
CRABPOT_OPENCLAW_TRACK: ${{ matrix.track }}
CRABPOT_PLUGIN_TRACK: ${{ matrix.plugin_track }}
CRABPOT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
CRABPOT_WORKSPACE_STEP_TIMEOUT_MS: "300000"
run: |
CRABPOT_SUMMARY_GENERATED_AT="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
export CRABPOT_SUMMARY_GENERATED_AT
rm -rf reports
mkdir -p reports
execution_fixture_set="${{ matrix.fixture_set }}"
if [ -z "${execution_fixture_set}" ]; then
execution_fixture_set="all"
fi
run_profile_step() {
local timeout_seconds="$1"
local warning="$2"
shift 2
if timeout "${timeout_seconds}s" "$@"; then
return 0
fi
echo "::warning::${warning}"
return 1
}
run_openclaw_import_loop_profile() {
if run_profile_step 180 "OpenClaw lifecycle import-loop profile failed or timed out; falling back to fixture-only import-loop profile" node scripts/import-loop-profile.mjs --openclaw ./openclaw --runs 3; then
return 0
fi
run_profile_step 90 "fixture-only import-loop profile failed or timed out; continuing without refreshed import-loop metrics" node scripts/import-loop-profile.mjs --runs 3 || true
}
run_openclaw_runtime_profile() {
if run_profile_step 240 "OpenClaw runtime profile failed or timed out; falling back to fixture-only runtime profile" node scripts/profile-contract-runtime.mjs --openclaw ./openclaw --runs 3; then
return 0
fi
run_profile_step 120 "fixture-only runtime profile failed or timed out; continuing without refreshed runtime metrics" node scripts/profile-contract-runtime.mjs --runs 3 || true
}
CRABPOT_EXECUTE_ISOLATED=1 node scripts/execute-workspace-plan.mjs --fixture-set "${execution_fixture_set}" --openclaw ./openclaw --continue-on-error
node scripts/summarize-execution-results.mjs --write
execution_results_args=(--execution-results reports/crabpot-execution-results.json)
node scripts/generate-report.mjs --openclaw ./openclaw "${execution_results_args[@]}"
node scripts/capture-contracts.mjs --openclaw ./openclaw
node scripts/synthetic-probes.mjs --openclaw ./openclaw
node scripts/cold-import-readiness.mjs --openclaw ./openclaw
node scripts/workspace-plan.mjs --openclaw ./openclaw
node scripts/platform-probes.mjs --openclaw ./openclaw
node scripts/check-generated-surface-fixture.mjs --openclaw ./openclaw
run_openclaw_import_loop_profile
run_openclaw_runtime_profile
if [ -f reports/crabpot-runtime-profile.json ]; then
node scripts/compare-runtime-profile.mjs
else
echo "::warning::Runtime profile was not refreshed; skipping runtime profile diff"
fi
node scripts/check-ci-policy.mjs
node scripts/write-ci-summary.mjs --mode "track:${{ matrix.track }}" --openclaw-label "${{ steps.openclaw-track.outputs.label }}"
node scripts/update-track-metadata.mjs --track "${{ matrix.track }}"
baseline_args=()
if [ -f .crabpot/baseline/main-dashboard-data.json ]; then
baseline_args=(--baseline-data .crabpot/baseline/main-dashboard-data.json)
fi
node scripts/update-readme-summary.mjs "${baseline_args[@]}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md reports/
if ! git diff --cached --quiet; then
git commit -m "chore(readme): refresh ${{ matrix.track }} dashboard [skip ci]"
if [ "${{ matrix.branch }}" = "main" ]; then
git push origin HEAD:${{ matrix.branch }}
else
git fetch --no-tags --depth=1 origin "+refs/heads/${{ matrix.branch }}:refs/remotes/origin/${{ matrix.branch }}"
lease="$(git rev-parse "refs/remotes/origin/${{ matrix.branch }}")"
git push --force-with-lease="refs/heads/${{ matrix.branch }}:${lease}" origin HEAD:${{ matrix.branch }}
fi
fi
- name: Upload track reports
if: ${{ always() && !cancelled() && steps.select.outputs.run == 'true' }}
uses: actions/upload-artifact@v7
with:
name: crabpot-track-${{ matrix.track }}-reports
path: reports/
if-no-files-found: warn