Skip to content

chore(ci): bump codecov/codecov-action from 5 to 6 #893

chore(ci): bump codecov/codecov-action from 5 to 6

chore(ci): bump codecov/codecov-action from 5 to 6 #893

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '22'
PYTHON_VERSION: '3.12'
jobs:
# ─── Group 0: All parallel, no inter-dependencies ──────────────────────────
lint:
name: Lint & Format
runs-on: self-hosted
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
- name: Format check
run: pnpm format:check
typecheck:
name: Type Check
runs-on: self-hosted
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build workspace packages
run: pnpm -r build
- name: Type check
run: pnpm typecheck
test:
name: Unit Tests
runs-on: self-hosted
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build workspace packages
run: pnpm -r build
- name: Run tests with coverage
run: pnpm test -- --coverage
- name: Upload coverage report
uses: actions/upload-artifact@v7
if: always()
with:
name: coverage-report
path: coverage/
if-no-files-found: warn
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v6
continue-on-error: true
with:
files: ./coverage/lcov.info
fail_ci_if_error: false
verbose: true
skip_validation: 'true'
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
codegen-check:
name: Codegen Freshness
runs-on: self-hosted
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build shared package
run: pnpm --filter @openclawworld/shared build
- name: Run all code generators
run: pnpm generate
- name: Format generated files
run: pnpm format
- name: Check for uncommitted changes
run: |
CHANGED_FILES=$(git status --porcelain \
"packages/plugin/src/generated/" \
"packages/server/src/generated/" \
"packages/client/src/generated/" \
".claude/commands/ocw-tools.md" \
".opencode/command/" \
".gemini/commands/" \
".codex/")
if [[ -n "$CHANGED_FILES" ]]; then
echo "❌ Generated code is out of sync!"
echo ""
echo "The following files have changed:"
echo "$CHANGED_FILES"
echo ""
echo "Please run 'pnpm generate' and commit the changes."
exit 1
fi
echo "✅ Generated code is up to date"
- name: Check OpenAPI spec is up to date
run: |
pnpm generate:openapi
if ! git diff --exit-code packages/server/src/openapi.ts; then
echo "❌ packages/server/src/openapi.ts is out of sync with schemas.ts"
echo "Run 'pnpm generate:openapi' and commit the changes."
exit 1
fi
echo "✅ OpenAPI spec is up to date"
- name: Check Colyseus client schemas are up to date
run: |
pnpm generate:schemas
pnpm exec prettier --write "packages/client/src/generated/schemas/"
if ! git diff --exit-code packages/client/src/generated/schemas/; then
echo "❌ Colyseus client schemas are out of sync with server schemas"
echo "Run 'pnpm generate:schemas' and commit the changes."
exit 1
fi
echo "✅ Colyseus client schemas are up to date"
map-consistency:
name: Map Consistency
runs-on: self-hosted
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check for map-impacting changes
id: check-map
run: |
if [[ "${{ github.event_name }}" == "push" ]]; then
BASE_SHA="${{ github.event.before }}"
else
BASE_SHA="${{ github.event.pull_request.base.sha }}"
fi
MAP_PATTERNS=(
'world/packs/base/maps/**'
'packages/server/assets/maps/**'
'packages/client/public/assets/maps/**'
'tools/kenney-curation.json'
'world/packs/base/assets/tilesets/**'
'scripts/sync-maps.mjs'
'scripts/verify-map-stack-consistency.mjs'
'world/packs/base/npcs/**'
'world/packs/base/facilities/**'
'world/packs/base/manifest.json'
'packages/server/src/world/**'
'packages/shared/src/world.ts'
)
CHANGED_FILES=$(git diff --name-only "$BASE_SHA"...HEAD 2>/dev/null || git diff --name-only HEAD~1...HEAD)
MAP_CHANGED=false
for pattern in "${MAP_PATTERNS[@]}"; do
if echo "$CHANGED_FILES" | grep -q "^${pattern/\*\*/.*}"; then
MAP_CHANGED=true
echo "📍 Matched pattern: $pattern"
break
fi
done
echo "map_changed=$MAP_CHANGED" >> "$GITHUB_OUTPUT"
if [[ "$MAP_CHANGED" == "true" ]]; then
echo "📍 Map-impacting files detected:"
echo "$CHANGED_FILES" | grep -E "(world/|maps/|tileset|sync-maps|verify-map)" || true
else
echo "✅ No map-impacting files changed"
fi
- name: Setup pnpm
if: steps.check-map.outputs.map_changed == 'true'
uses: pnpm/action-setup@v4
- name: Setup Node.js
if: steps.check-map.outputs.map_changed == 'true'
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
if: steps.check-map.outputs.map_changed == 'true'
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
if: steps.check-map.outputs.map_changed == 'true'
run: pnpm install --frozen-lockfile
- name: Build shared package
if: steps.check-map.outputs.map_changed == 'true'
run: pnpm --filter @openclawworld/shared build
- name: Verify map sync
if: steps.check-map.outputs.map_changed == 'true'
run: |
pnpm sync-maps
SYNC_DIFF=$(git status --porcelain packages/server/assets/maps/ packages/client/public/assets/maps/)
if [[ -n "$SYNC_DIFF" ]]; then
echo "❌ Map files are out of sync!"
echo "$SYNC_DIFF"
echo "Run 'pnpm sync-maps' and commit the changes."
exit 1
fi
echo "✅ Map files are in sync"
- name: Run map stack consistency check
if: steps.check-map.outputs.map_changed == 'true'
run: node scripts/verify-map-stack-consistency.mjs
openapi-validate:
name: OpenAPI Spec Validation
runs-on: self-hosted
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build workspace packages
run: pnpm -r build
- name: Validate OpenAPI spec
run: pnpm validate:openapi
# ─── Group 1: Build validation (needs lint + typecheck to pass) ────────────
build:
name: Build
runs-on: self-hosted
timeout-minutes: 15
needs: [lint, typecheck]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
# ─── Final gate ────────────────────────────────────────────────────────────
api-fuzz:
name: API Fuzzing (schemathesis)
runs-on: [self-hosted, macOS, ARM64]
needs: build
continue-on-error: true
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Cache node_modules
uses: actions/cache@v5
with:
path: |
node_modules
packages/*/node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
node-modules-${{ runner.os }}-${{ runner.arch }}-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Setup Python ${{ env.PYTHON_VERSION }} & Install schemathesis
run: |
# Ensure Homebrew is on PATH (ARM64: /opt/homebrew, Intel: /usr/local)
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:$PATH"
echo "/opt/homebrew/bin" >> "$GITHUB_PATH"
# Always use versioned brew Python to avoid macOS Xcode bundle (3.9)
if ! brew list "python@${{ env.PYTHON_VERSION }}" &>/dev/null; then
echo "Installing Python ${{ env.PYTHON_VERSION }} via brew..."
brew install "python@${{ env.PYTHON_VERSION }}"
fi
BREW_PYTHON_BIN="$(brew --prefix "python@${{ env.PYTHON_VERSION }}")/libexec/bin"
export PATH="$BREW_PYTHON_BIN:$PATH"
echo "$BREW_PYTHON_BIN" >> "$GITHUB_PATH"
python3 --version
python3 -m pip install --user --break-system-packages schemathesis 2>/dev/null \
|| python3 -m pip install --user schemathesis
echo "$(python3 -m site --user-base)/bin" >> "$GITHUB_PATH"
- name: Run API fuzzing
run: bash scripts/schemathesis-fuzz.sh
env:
SCHEMATHESIS_PORT: '2567'
SCHEMATHESIS_MAX_EXAMPLES: '50'
- name: Upload fuzzing report
if: always()
uses: actions/upload-artifact@v7
with:
name: schemathesis-report
path: schemathesis-report.xml
if-no-files-found: warn
all-checks:
name: All Checks Passed
runs-on: self-hosted
timeout-minutes: 5
needs: [codegen-check, typecheck, lint, build, test, map-consistency, openapi-validate]
if: always()
steps:
- name: Check all jobs
run: |
if [[ "${{ needs.codegen-check.result }}" != "success" ]] || \
[[ "${{ needs.typecheck.result }}" != "success" ]] || \
[[ "${{ needs.lint.result }}" != "success" ]] || \
[[ "${{ needs.build.result }}" != "success" ]] || \
[[ "${{ needs.test.result }}" != "success" ]] || \
[[ "${{ needs.map-consistency.result }}" != "success" ]] || \
[[ "${{ needs.openapi-validate.result }}" != "success" ]]; then
echo "One or more jobs failed"
exit 1
fi
echo "All checks passed!"