Skip to content

feat: add RuntimeAdapter interface and OpenClawGatewayAdapter (Phase 1) #549

feat: add RuntimeAdapter interface and OpenClawGatewayAdapter (Phase 1)

feat: add RuntimeAdapter interface and OpenClawGatewayAdapter (Phase 1) #549

Workflow file for this run

name: PR Check
on:
pull_request:
branches: [main]
concurrency:
group: pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
quality: ${{ steps.plan.outputs.quality }}
architecture: ${{ steps.plan.outputs.architecture }}
ui_contract: ${{ steps.plan.outputs.ui_contract }}
renderer_copy: ${{ steps.plan.outputs.renderer_copy }}
i18n: ${{ steps.plan.outputs.i18n }}
dead_code: ${{ steps.plan.outputs.dead_code }}
typecheck_shared: ${{ steps.plan.outputs.typecheck_shared }}
typecheck_core: ${{ steps.plan.outputs.typecheck_core }}
typecheck_desktop: ${{ steps.plan.outputs.typecheck_desktop }}
typecheck_pwa: ${{ steps.plan.outputs.typecheck_pwa }}
typecheck_website: ${{ steps.plan.outputs.typecheck_website }}
test_shared: ${{ steps.plan.outputs.test_shared }}
test_core: ${{ steps.plan.outputs.test_core }}
test_desktop: ${{ steps.plan.outputs.test_desktop }}
test_pwa: ${{ steps.plan.outputs.test_pwa }}
build_desktop: ${{ steps.plan.outputs.build_desktop }}
test_job: ${{ steps.plan.outputs.test_job }}
steps:
- uses: actions/checkout@v6
- id: filter
uses: dorny/paths-filter@v4
with:
filters: |
global:
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'tsconfig.base.json'
- 'eslint.config.mjs'
- 'knip.json'
- 'scripts/**'
- '.github/workflows/pr-check.yml'
- '.github/workflows/e2e.yml'
shared:
- 'packages/shared/**'
core:
- 'packages/core/**'
desktop_renderer:
- 'packages/desktop/src/renderer/**'
- 'packages/desktop/test/**/*.tsx'
desktop_main:
- 'packages/desktop/src/main/**'
- 'packages/desktop/src/preload/**'
- 'packages/desktop/test/**/*.ts'
desktop_package:
- 'packages/desktop/package.json'
- 'packages/desktop/electron.vite.config.ts'
- 'packages/desktop/scripts/**'
pwa:
- 'packages/pwa/**'
website:
- 'website/**'
- '.github/workflows/website.yml'
keynote:
- 'keynote/**'
- id: plan
env:
GLOBAL: ${{ steps.filter.outputs.global }}
SHARED: ${{ steps.filter.outputs.shared }}
CORE: ${{ steps.filter.outputs.core }}
DESKTOP_RENDERER: ${{ steps.filter.outputs.desktop_renderer }}
DESKTOP_MAIN: ${{ steps.filter.outputs.desktop_main }}
DESKTOP_PACKAGE: ${{ steps.filter.outputs.desktop_package }}
PWA: ${{ steps.filter.outputs.pwa }}
WEBSITE: ${{ steps.filter.outputs.website }}
KEYNOTE: ${{ steps.filter.outputs.keynote }}
run: |
set_flag() {
local name="$1"
shift
local value=false
for item in "$@"; do
if [ "$item" = "true" ]; then
value=true
break
fi
done
echo "$name=$value" >> "$GITHUB_OUTPUT"
}
set_flag quality "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$DESKTOP_MAIN" "$DESKTOP_PACKAGE" "$PWA" "$WEBSITE"
set_flag architecture "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_MAIN"
set_flag ui_contract "$GLOBAL" "$DESKTOP_RENDERER" "$PWA"
set_flag renderer_copy "$GLOBAL" "$DESKTOP_RENDERER"
set_flag i18n "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$PWA"
set_flag dead_code "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$DESKTOP_MAIN" "$DESKTOP_PACKAGE" "$PWA" "$WEBSITE"
set_flag typecheck_shared "$GLOBAL" "$SHARED"
set_flag typecheck_core "$GLOBAL" "$SHARED" "$CORE"
set_flag typecheck_desktop "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$DESKTOP_MAIN" "$DESKTOP_PACKAGE"
set_flag typecheck_pwa "$GLOBAL" "$SHARED" "$CORE" "$PWA"
set_flag typecheck_website "$GLOBAL" "$WEBSITE"
set_flag test_shared "$GLOBAL" "$SHARED"
set_flag test_core "$GLOBAL" "$SHARED" "$CORE"
set_flag test_desktop "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$DESKTOP_MAIN" "$DESKTOP_PACKAGE"
set_flag test_pwa "$GLOBAL" "$SHARED" "$CORE" "$PWA"
set_flag build_desktop "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$DESKTOP_MAIN" "$DESKTOP_PACKAGE"
set_flag test_job "$GLOBAL" "$SHARED" "$CORE" "$DESKTOP_RENDERER" "$DESKTOP_MAIN" "$DESKTOP_PACKAGE" "$PWA" "$WEBSITE"
quality:
needs: [changes]
if: needs.changes.outputs.quality == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v5
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
- name: Format check
run: pnpm format:check
- name: Architecture guardrails
if: needs.changes.outputs.architecture == 'true'
run: pnpm check:architecture
- name: UI contract
if: needs.changes.outputs.ui_contract == 'true'
run: pnpm check:ui-contract
- name: Renderer copy contract
if: needs.changes.outputs.renderer_copy == 'true'
run: pnpm check:renderer-copy
- name: i18n key parity
if: needs.changes.outputs.i18n == 'true'
run: pnpm check:i18n
- name: Dead code detection
if: needs.changes.outputs.dead_code == 'true'
run: pnpm check:dead-code
test:
needs: [changes]
if: needs.changes.outputs.test_job == 'true'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v5
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Type check shared
if: needs.changes.outputs.typecheck_shared == 'true' || needs.changes.outputs.typecheck_core == 'true' || needs.changes.outputs.typecheck_desktop == 'true' || needs.changes.outputs.typecheck_pwa == 'true'
run: pnpm --filter @clawwork/shared exec tsc -b
- name: Type check core
if: needs.changes.outputs.typecheck_core == 'true' || needs.changes.outputs.typecheck_desktop == 'true' || needs.changes.outputs.typecheck_pwa == 'true'
run: pnpm --filter @clawwork/core exec tsc -b
- name: Type check desktop
if: needs.changes.outputs.typecheck_desktop == 'true'
run: pnpm --filter @clawwork/desktop exec tsc --noEmit
- name: Type check PWA
if: needs.changes.outputs.typecheck_pwa == 'true'
run: pnpm --filter @clawwork/pwa exec tsc --noEmit
- name: Type check website
if: needs.changes.outputs.typecheck_website == 'true'
run: pnpm --filter @clawwork/website exec tsc --noEmit
- name: Type check shared tests
if: needs.changes.outputs.test_shared == 'true'
run: pnpm --filter @clawwork/shared exec tsc --noEmit -p tsconfig.test.json
- name: Type check core tests
if: needs.changes.outputs.test_core == 'true'
run: pnpm --filter @clawwork/core exec tsc --noEmit -p tsconfig.test.json
- name: Type check desktop tests
if: needs.changes.outputs.test_desktop == 'true'
run: pnpm --filter @clawwork/desktop exec tsc --noEmit -p tsconfig.test.json
- name: Type check PWA tests
if: needs.changes.outputs.test_pwa == 'true'
run: pnpm --filter @clawwork/pwa exec tsc --noEmit -p tsconfig.test.json
- name: Test shared
if: needs.changes.outputs.test_shared == 'true'
run: pnpm --filter @clawwork/shared test
- name: Test core
if: needs.changes.outputs.test_core == 'true'
run: pnpm --filter @clawwork/core test
- name: Test desktop
if: needs.changes.outputs.test_desktop == 'true'
run: pnpm --filter @clawwork/desktop test
- name: Test PWA
if: needs.changes.outputs.test_pwa == 'true'
run: pnpm --filter @clawwork/pwa test
build:
needs: [changes, quality, test]
if: needs.changes.outputs.build_desktop == 'true' && needs.quality.result != 'failure' && needs.test.result != 'failure'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v5
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build Electron app
run: pnpm --filter @clawwork/desktop build
- name: Package Linux smoke build
run: pnpm --filter @clawwork/desktop exec electron-builder --linux --x64 --publish never
secrets-scan:
runs-on: ubuntu-latest
permissions:
contents: read
env:
GITLEAKS_VERSION: 8.30.1
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install gitleaks
run: |
curl -fsSL \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
| tar -xz -C /usr/local/bin gitleaks
gitleaks version
- name: Scan PR diff
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: gitleaks detect --source . --log-opts "${BASE_SHA}..${HEAD_SHA}" --redact --verbose --no-banner
ci-passed:
needs: [changes, quality, test, build, secrets-scan]
if: always()
runs-on: ubuntu-latest
steps:
- name: Verify aggregate status
env:
NEEDS: ${{ toJson(needs) }}
run: |
echo "$NEEDS"
failed=$(jq -r '[to_entries[] | select(.value.result == "failure" or .value.result == "cancelled") | .key] | join(", ")' <<< "$NEEDS")
if [ -n "$failed" ]; then
echo "::error::Required gates failed or cancelled: $failed"
exit 1
fi
echo "All required gates passed or skipped cleanly."