crabpot/.github/workflows/check.yml
2026-05-05 23:59:22 -07:00

299 lines
13 KiB
YAML

name: Check
on:
# Keep these events path-unfiltered. Plugin submodule gitlink bumps under
# plugins/** must retest on Dependabot PRs and again after merge to main.
pull_request:
push:
branches: [main, crab-beta, crab-development]
workflow_dispatch:
permissions:
contents: read
jobs:
manifest:
name: Static checks (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: |
plugins/**/package-lock.json
- name: Resolve OpenClaw track
id: openclaw-track
run: node scripts/resolve-openclaw-track.mjs --github-output
- uses: actions/checkout@v6
with:
repository: openclaw/openclaw
ref: ${{ steps.openclaw-track.outputs.ref }}
path: openclaw
- shell: bash
run: |
plugin_track="${{ steps.openclaw-track.outputs.track }}"
extra_args=(--openclaw-track "${{ steps.openclaw-track.outputs.track }}" --plugin-track "${plugin_track}")
if [ "${{ steps.openclaw-track.outputs.track }}" = "development" ]; then
extra_args=(--openclaw-track "${{ steps.openclaw-track.outputs.track }}" --fixture-set openclaw-beta --plugin-track source-pack)
fi
node scripts/run-static-suite.mjs --openclaw ./openclaw --policy dashboard --profile-runs 3 --plugin-inspector-smoke "${extra_args[@]}"
- name: Write CI summary artifacts
if: always()
continue-on-error: true
env:
CRABPOT_FIXTURE_SET: ${{ steps.openclaw-track.outputs.track == 'development' && 'openclaw-beta' || '' }}
CRABPOT_OPENCLAW_TRACK: ${{ steps.openclaw-track.outputs.track }}
CRABPOT_PLUGIN_TRACK: ${{ steps.openclaw-track.outputs.track == 'development' && 'source-pack' || steps.openclaw-track.outputs.track }}
run: |
node scripts/generate-report.mjs --openclaw ./openclaw
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
node scripts/import-loop-profile.mjs
node scripts/profile-contract-runtime.mjs --openclaw ./openclaw --runs 3
node scripts/compare-runtime-profile.mjs
node scripts/check-ci-policy.mjs
node scripts/write-ci-summary.mjs --mode check --openclaw-label "${{ steps.openclaw-track.outputs.label }}" --github-step-summary
- name: Upload CI reports
if: always()
uses: actions/upload-artifact@v7
with:
name: crabpot-check-reports-${{ matrix.os }}
path: reports/
if-no-files-found: warn
container-smoke:
name: Container static checks
runs-on: ubuntu-latest
container:
image: node:22-bookworm
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- name: Resolve OpenClaw track
id: openclaw-track
run: node scripts/resolve-openclaw-track.mjs --github-output
- uses: actions/checkout@v6
with:
repository: openclaw/openclaw
ref: ${{ steps.openclaw-track.outputs.ref }}
path: openclaw
- run: node --version
- shell: bash
run: |
plugin_track="${{ steps.openclaw-track.outputs.track }}"
extra_args=(--openclaw-track "${{ steps.openclaw-track.outputs.track }}" --plugin-track "${plugin_track}")
if [ "${{ steps.openclaw-track.outputs.track }}" = "development" ]; then
extra_args=(--openclaw-track "${{ steps.openclaw-track.outputs.track }}" --fixture-set openclaw-beta --plugin-track source-pack)
fi
node scripts/run-static-suite.mjs --openclaw ./openclaw --policy dashboard --profile-runs 3 --plugin-inspector-smoke "${extra_args[@]}"
changed-fixture-plan:
name: Resolve changed fixture matrix
runs-on: ubuntu-latest
if: ${{ github.event_name == 'pull_request' || github.event_name == 'push' }}
outputs:
matrix: ${{ steps.resolve.outputs.matrix }}
count: ${{ steps.resolve.outputs.count }}
fixtures: ${{ steps.resolve.outputs.fixtures }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: |
plugins/**/package-lock.json
- name: Resolve OpenClaw track
id: openclaw-track
run: node scripts/resolve-openclaw-track.mjs --github-output
- uses: actions/checkout@v6
with:
repository: openclaw/openclaw
ref: ${{ steps.openclaw-track.outputs.ref }}
path: openclaw
- name: Resolve diff refs
id: refs
shell: bash
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
base="${{ github.event.pull_request.base.sha }}"
head="${{ github.event.pull_request.head.sha }}"
else
base="${{ github.event.before }}"
head="${{ github.sha }}"
if [ -z "$base" ] || [[ "$base" =~ ^0+$ ]]; then
base="$(git rev-parse HEAD^ 2>/dev/null || true)"
fi
fi
git fetch --no-tags --depth=1 origin "$base" "$head" || true
echo "base=${base}" >> "$GITHUB_OUTPUT"
echo "head=${head}" >> "$GITHUB_OUTPUT"
- name: Resolve changed fixture matrix
id: resolve
shell: bash
run: |
node scripts/resolve-fixture-set.mjs \
--fixture-set changed-submodules \
--base-ref "${{ steps.refs.outputs.base }}" \
--head-ref "${{ steps.refs.outputs.head }}" \
--openclaw ./openclaw \
--allow-empty \
--github-output >> "$GITHUB_OUTPUT"
- name: Show selected fixtures
run: echo "fixtures=${{ steps.resolve.outputs.fixtures }}"
changed-isolated-fixture:
name: Isolated changed fixture ${{ matrix.id }}
runs-on: ubuntu-latest
needs: changed-fixture-plan
if: ${{ needs.changed-fixture-plan.outputs.count != '0' }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.changed-fixture-plan.outputs.matrix) }}
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: |
plugins/**/package-lock.json
- name: Resolve OpenClaw track
id: openclaw-track
run: node scripts/resolve-openclaw-track.mjs --github-output
- uses: actions/checkout@v6
with:
repository: openclaw/openclaw
ref: ${{ steps.openclaw-track.outputs.ref }}
path: openclaw
- name: Validate workspace plan
run: node scripts/workspace-plan.mjs --check --openclaw ./openclaw
- name: Execute fixture lane
id: execute
continue-on-error: true
env:
CRABPOT_EXECUTE_ISOLATED: "1"
run: npm run workspace:execute -- --fixture "${{ matrix.id }}" --allow-empty --openclaw ./openclaw
- name: Summarize execution artifacts
if: always()
continue-on-error: true
run: npm run execution:report
- name: Reconcile compatibility report with runtime evidence
if: always()
continue-on-error: true
run: node scripts/generate-report.mjs --openclaw ./openclaw --execution-results reports/crabpot-execution-results.json --fixture-set "${{ matrix.id }}"
- name: Run execution policy
id: policy
if: always()
continue-on-error: true
run: node scripts/check-ci-policy.mjs
- name: Write isolated summary
if: always()
continue-on-error: true
run: node scripts/write-ci-summary.mjs --mode changed-isolated --openclaw-label "${{ steps.openclaw-track.outputs.label }}" --github-step-summary
- name: Upload isolated execution artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: crabpot-changed-isolated-${{ matrix.id }}
path: |
.crabpot/results/
reports/crabpot-report.*
reports/crabpot-issues.*
reports/crabpot-execution-results.*
reports/crabpot-ci-policy.*
reports/crabpot-ci-summary.*
if-no-files-found: warn
- name: Fail if isolated policy failed
if: ${{ steps.policy.outcome == 'failure' }}
run: exit 1
dashboard:
runs-on: ubuntu-latest
needs: [manifest, container-smoke, changed-fixture-plan, changed-isolated-fixture]
if: ${{ always() && github.event_name != 'pull_request' && github.actor != 'github-actions[bot]' && needs.manifest.result == 'success' && needs.container-smoke.result == 'success' && (needs.changed-isolated-fixture.result == 'success' || needs.changed-isolated-fixture.result == 'skipped') }}
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
cache-dependency-path: |
plugins/**/package-lock.json
- name: Resolve OpenClaw track
id: openclaw-track
run: node scripts/resolve-openclaw-track.mjs --github-output
- uses: actions/checkout@v6
with:
repository: openclaw/openclaw
ref: ${{ steps.openclaw-track.outputs.ref }}
path: openclaw
- run: node scripts/sync-fixtures.mjs --materialize --openclaw ./openclaw
env:
CRABPOT_FIXTURE_SET: ${{ steps.openclaw-track.outputs.track == 'development' && 'openclaw-beta' || '' }}
CRABPOT_PLUGIN_TRACK: ${{ steps.openclaw-track.outputs.track == 'development' && 'source-pack' || steps.openclaw-track.outputs.track }}
- name: Install OpenClaw lifecycle dependencies
run: |
corepack enable
pnpm --dir openclaw install --frozen-lockfile --ignore-scripts
- name: Fetch main dashboard baseline
if: ${{ steps.openclaw-track.outputs.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 README dashboard
env:
CRABPOT_FIXTURE_SET: ${{ steps.openclaw-track.outputs.track == 'development' && 'openclaw-beta' || '' }}
CRABPOT_OPENCLAW_TRACK: ${{ steps.openclaw-track.outputs.track }}
CRABPOT_PLUGIN_TRACK: ${{ steps.openclaw-track.outputs.track == 'development' && 'source-pack' || steps.openclaw-track.outputs.track }}
CRABPOT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
export CRABPOT_SUMMARY_GENERATED_AT="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
node scripts/generate-report.mjs --openclaw ./openclaw
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/import-loop-profile.mjs --openclaw ./openclaw --runs 3
node scripts/profile-contract-runtime.mjs --openclaw ./openclaw --runs 3
node scripts/compare-runtime-profile.mjs
node scripts/check-ci-policy.mjs
node scripts/write-ci-summary.mjs --mode check --openclaw-label "${{ steps.openclaw-track.outputs.label }}"
node scripts/update-track-metadata.mjs
baseline_arg=""
if [ -f .crabpot/baseline/main-dashboard-data.json ]; then
baseline_arg="--baseline-data .crabpot/baseline/main-dashboard-data.json"
fi
node scripts/update-readme-summary.mjs ${baseline_arg}
git add README.md reports/
if ! git diff --cached --quiet; then
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git commit -m "chore(readme): update crabpot dashboard [skip ci]"
git push || echo "::notice::Skipped stale dashboard push because ${GITHUB_REF_NAME} moved; a newer check run will refresh it."
fi