Files
proxycast/.github/workflows/quality.yml
T

224 lines
6.9 KiB
YAML

name: Quality
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
jobs:
changed:
name: Detect changed areas
runs-on: ubuntu-latest
outputs:
bridge: ${{ steps.detect.outputs.bridge }}
changed_count: ${{ steps.detect.outputs.changed_count }}
docs: ${{ steps.detect.outputs.docs }}
docs_only: ${{ steps.detect.outputs.docs_only }}
fallback: ${{ steps.detect.outputs.fallback }}
frontend: ${{ steps.detect.outputs.frontend }}
gui_smoke: ${{ steps.detect.outputs.gui_smoke }}
integrity: ${{ steps.detect.outputs.integrity }}
rust: ${{ steps.detect.outputs.rust }}
workflow: ${{ steps.detect.outputs.workflow }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Detect tasks
id: detect
shell: bash
env:
BEFORE_SHA: ${{ github.event.before }}
run: |
args=(--format github)
if [[ "${{ github.event_name }}" == "push" && -n "${BEFORE_SHA}" && "${BEFORE_SHA}" != "0000000000000000000000000000000000000000" ]]; then
args+=(--base "${BEFORE_SHA}")
fi
node scripts/quality-task-selector.mjs "${args[@]}" >> "$GITHUB_OUTPUT"
# 当前仓库的 Rust 回归验证仍以既有 `.github/workflows/ci.yml`
# 中的 Windows OpenClaw regression 为主。这里先收口前端/契约/一致性
# 质量信号,后续再逐步补齐可稳定运行的 Rust 质量矩阵。
integrity:
name: Integrity
runs-on: ubuntu-latest
needs: changed
if: ${{ needs.changed.outputs.integrity == 'true' || needs.changed.outputs.fallback == 'true' || needs.changed.outputs.workflow == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: "pnpm-lock.yaml"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Verify app version consistency
run: npm run verify:app-version
frontend:
name: Frontend
runs-on: ubuntu-latest
needs: changed
if: ${{ needs.changed.outputs.frontend == 'true' || needs.changed.outputs.fallback == 'true' || needs.changed.outputs.workflow == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: "pnpm-lock.yaml"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: npm run lint
- name: Typecheck
run: npm run typecheck
- name: Vitest
run: npm test
bridge_contracts:
name: Bridge & Contracts
runs-on: ubuntu-latest
needs: changed
if: ${{ needs.changed.outputs.bridge == 'true' || needs.changed.outputs.fallback == 'true' || needs.changed.outputs.workflow == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: "pnpm-lock.yaml"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Bridge tests
run: npm run test:bridge
- name: Command contracts
run: npm run test:contracts
gui_smoke:
name: GUI Smoke
runs-on: macos-latest
timeout-minutes: 25
needs: changed
if: ${{ needs.changed.outputs.gui_smoke == 'true' || needs.changed.outputs.fallback == 'true' || needs.changed.outputs.workflow == 'true' }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "pnpm"
cache-dependency-path: "pnpm-lock.yaml"
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
shared-key: quality-gui-smoke
cache-on-failure: true
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run headless GUI smoke
run: npm run verify:gui-smoke -- --timeout-ms 480000
results:
name: Quality results
runs-on: ubuntu-latest
needs:
- changed
- integrity
- frontend
- bridge_contracts
- gui_smoke
if: always()
steps:
- name: Summarize
shell: bash
run: |
echo "changed_count: ${{ needs.changed.outputs.changed_count }}"
echo "docs_only : ${{ needs.changed.outputs.docs_only }}"
echo "integrity : ${{ needs.integrity.result }}"
echo "frontend : ${{ needs.frontend.result }}"
echo "bridge : ${{ needs.bridge_contracts.result }}"
echo "gui_smoke : ${{ needs.gui_smoke.result }}"
if [[ '${{ needs.changed.outputs.docs_only }}' == 'true' ]]; then
echo 'Only docs/markdown changes detected -> quality checks not required.'
exit 0
fi
if [[ '${{ needs.changed.outputs.integrity }}' == 'true' || '${{ needs.changed.outputs.fallback }}' == 'true' || '${{ needs.changed.outputs.workflow }}' == 'true' ]]; then
[[ '${{ needs.integrity.result }}' == 'success' ]] || { echo 'integrity failed'; exit 1; }
fi
if [[ '${{ needs.changed.outputs.frontend }}' == 'true' || '${{ needs.changed.outputs.fallback }}' == 'true' || '${{ needs.changed.outputs.workflow }}' == 'true' ]]; then
[[ '${{ needs.frontend.result }}' == 'success' ]] || { echo 'frontend failed'; exit 1; }
fi
if [[ '${{ needs.changed.outputs.bridge }}' == 'true' || '${{ needs.changed.outputs.fallback }}' == 'true' || '${{ needs.changed.outputs.workflow }}' == 'true' ]]; then
[[ '${{ needs.bridge_contracts.result }}' == 'success' ]] || { echo 'bridge/contracts failed'; exit 1; }
fi
if [[ '${{ needs.changed.outputs.gui_smoke }}' == 'true' || '${{ needs.changed.outputs.fallback }}' == 'true' || '${{ needs.changed.outputs.workflow }}' == 'true' ]]; then
[[ '${{ needs.gui_smoke.result }}' == 'success' ]] || { echo 'gui smoke failed'; exit 1; }
fi