Skip to content

Add standalone PR Beacon plugin with agent summaries and approval #411

Add standalone PR Beacon plugin with agent summaries and approval

Add standalone PR Beacon plugin with agent summaries and approval #411

Workflow file for this run

name: CI
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CI: "true"
CARGO_TERM_COLOR: always
jobs:
javascript:
name: JavaScript
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: ./.github/actions/setup
- name: Lint and types
run: pnpm check
# check already ran TypeScript; do not repeat pnpm build's typecheck.
- name: Frontend build
run: pnpm exec vite build
- name: All Vitest tests
run: node scripts/ci-test-report.mjs kind=vitest report=test-results/ci/vitest.json evidence=test-results/ci/vitest-timing.json title="Vitest tests" -- pnpm exec vitest run --reporter=default --reporter=json --outputFile=test-results/ci/vitest.json
- name: Vitest timing evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: vitest-timing
path: test-results/ci
retention-days: 7
native:
name: Rust and tool integration
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: ./.github/actions/setup
- name: Tauri system libraries
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y dbus-daemon libwebkit2gtk-4.1-dev build-essential libssl-dev librsvg2-dev libayatana-appindicator3-dev patchelf
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
key: native
save-if: ${{ github.event_name == 'push' }}
- name: Rust formatting
run: cargo fmt --all --check
- name: Rust lint
run: cargo clippy --workspace --locked --all-targets -- -D warnings
# --workspace includes Tauri, unlike the default Cargo member selection.
- name: All Rust tests and doctests
run: cargo test --workspace --locked
- name: All Node integration tests
run: node --test tests/integration/*.test.mjs
windows-native:
name: Windows native notifications
runs-on: windows-2025
timeout-minutes: 20
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
# Hermit does not run on Windows. Use the same repository Rust pin with
# the hosted runner's standard rustup, not a second floating toolchain.
- name: Select pinned Rust
shell: pwsh
run: |
$pins = @(Get-ChildItem bin/.rust-*.pkg)
if ($pins.Count -ne 1) { throw "Expected exactly one repository Rust pin" }
$version = $pins[0].Name -replace '^\.rust-(.*)\.pkg$', '$1'
rustup toolchain install $version --profile minimal --component clippy
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
"RUSTUP_TOOLCHAIN=$version" >> $env:GITHUB_ENV
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
key: windows-native
save-if: ${{ github.event_name == 'push' }}
- name: Native lint including Windows backend
run: cargo clippy -p buzz-foundation --locked --all-targets -- -D warnings
- name: All native package tests
run: cargo test -p buzz-foundation --locked
measurements:
name: Browser measurements
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: ./.github/actions/setup
with:
browsers: "true"
# Preserve Chromium -> WebKit measurement dependencies; never shard or
# overlap the two measurement projects on this runner.
- name: Serial Chromium and WebKit measurements
env:
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/browser/ci-report.json
run: node scripts/ci-test-report.mjs kind=playwright report=test-results/browser/ci-report.json evidence=test-results/browser/ci-timing.json title="Browser measurements" -- pnpm test:browser:ci --project '*-measurements' --workers=1 --reporter=list,json
- name: Measurement evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: browser-measurements
path: test-results/browser
retention-days: 7
browser:
name: Browser journeys (${{ matrix.engine }}, ${{ matrix.shard }}/2)
# Measurements stay isolated on their own runner, not on our critical path.
# CI required still requires their success independently of these jobs.
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
engine: [chromium, webkit]
shard: [1, 2]
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- uses: ./.github/actions/setup
with:
browsers: "true"
# This journey uses a real native plugin-manager bridge. Provision it
# before Playwright starts: a cold Rust install/build is test setup, not
# browser behavior, and must not consume the journey's subprocess budget.
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
key: browser-fixture
save-if: ${{ github.event_name == 'push' }}
- name: Build native browser fixture
timeout-minutes: 8
run: cargo build --locked -p buzzodz-plugins --example fixture-bridge
# CI required enforces measurement success. --no-deps avoids repeating
# measurements here; the matrix covers both engines on separate runners.
- name: Functional journeys
env:
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/browser/ci-report.json
run: node scripts/ci-test-report.mjs kind=playwright report=test-results/browser/ci-report.json evidence=test-results/browser/ci-timing.json title="Browser journeys (${{ matrix.engine }}, ${{ matrix.shard }}/2)" -- pnpm test:browser:ci --project ${{ matrix.engine }} --no-deps --shard=${{ matrix.shard }}/2 --reporter=list,json
- name: Browser evidence
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: browser-journeys-${{ matrix.engine }}-${{ matrix.shard }}
path: test-results/browser
retention-days: 7
required:
name: CI required
if: always()
needs: [javascript, native, windows-native, measurements, browser]
runs-on: ubuntu-24.04
timeout-minutes: 2
steps:
- name: Require every lane and every shard
env:
JAVASCRIPT: ${{ needs.javascript.result }}
NATIVE: ${{ needs.native.result }}
WINDOWS_NATIVE: ${{ needs.windows-native.result }}
MEASUREMENTS: ${{ needs.measurements.result }}
BROWSER: ${{ needs.browser.result }}
run: |
for result in "$JAVASCRIPT" "$NATIVE" "$WINDOWS_NATIVE" "$MEASUREMENTS" "$BROWSER"; do
test "$result" = success || exit 1
done