mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
255deb6c28
* ci: fold single-grep jobs into steps, call named pnpm scripts - Merge ios-runner-swift-compat and no-test-di-seams (each just checkout + one rg assertion) into steps of a new static-checks job, keeping each step's own failure message. Removes two job-scheduling/ checkout overheads and two PR status-check lines. - Replace the layering-guard job's inlined copies of check:layering and depgraph:test with the named pnpm scripts, removing the silent-drift risk between the workflow and package.json. - Fix the same drift in conformance-regenerate.yml, which inlined maestro:conformance:regenerate byte-for-byte. - Leave affected-selector's inline node invocation as-is: R8's zero-dep closure check (scripts/layering/zero-dep-jobs.ts) finds a job's entry scripts by matching literal paths in the run: block, so switching to `pnpm check:affected:test` would zero out its entries and make R8 fail closed. Documented inline why this one stays inlined. - Leave publish-mcp-registry.yml's sync-mcp-metadata --check alone: that job never runs the setup-node-pnpm action, so pnpm isn't provisioned there at all. Refs #1462 * ci: teach R8 to resolve pnpm script names, drop affected-selector's inline copy R8's zero-dep-job entry scan matched literal script paths in a run: block, so a bare `pnpm <script>` invocation found zero entries and R8 failed closed — the reason affected-selector kept an inline node command instead of calling pnpm check:affected:test (#1462). zeroDepJobs now also resolves a pnpm script name against package.json and scans the resolved command for entry paths, so affected-selector can call the named script like every other job. Also replaced the other workflows' inlined copies of named package.json scripts (test:replay:*, perf, perf:android, maestro:conformance:differential, check:mcp-metadata, size) with their pnpm names, keeping each job's CI-specific trailing flags — found via a repo-wide sweep for any run: block whose text duplicates a scripts entry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L67kDSTAJwaoLCwANEJFRM * fix: revert publish-mcp-registry pnpm regression, recurse R8 alias resolution publish-mcp-registry.yml's job only provisions Node via actions/setup-node, never the repo's setup-node-pnpm action, so pnpm is never installed there — the earlier sweep's `pnpm check:mcp-metadata` would have broken the release path. Reverted to the direct node invocation with a comment explaining why, matching the PR's own stated rationale for leaving it alone. zeroDepJobs' pnpm-alias resolution only expanded one level: a resolved script that itself invoked another named pnpm script had its entries silently dropped from R8's closure. resolveRunEntries now recurses through chained aliases with a per-chain visited set, so a nested alias's entries are found and a cycle stops re-expanding a repeated name instead of recursing forever. Added coverage for both the chained and cyclic cases. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L67kDSTAJwaoLCwANEJFRM --------- Co-authored-by: Claude <noreply@anthropic.com>
120 lines
4.0 KiB
YAML
120 lines
4.0 KiB
YAML
name: Linux
|
|
|
|
on:
|
|
pull_request:
|
|
paths-ignore:
|
|
- 'docs/**'
|
|
- 'website/**'
|
|
- 'README.md'
|
|
- '.github/actions/build-docs/action.yml'
|
|
- '.github/workflows/deploy.yml'
|
|
- '.github/workflows/pr-preview.yml'
|
|
- '.github/workflows/pr-preview-cleanup.yml'
|
|
push:
|
|
branches:
|
|
- main
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
smoke-linux:
|
|
name: Smoke Tests
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
env:
|
|
# Force X11 mode (Xvfb) — no Wayland on CI.
|
|
XDG_SESSION_TYPE: x11
|
|
DISPLAY: ':99'
|
|
# Headless GTK: avoid dconf issues, enable accessibility bridge.
|
|
GSETTINGS_BACKEND: memory
|
|
NO_AT_BRIDGE: '0'
|
|
GTK_A11Y: atspi
|
|
GTK_MODULES: 'gail:atk-bridge'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Install Linux desktop dependencies
|
|
run: |
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq \
|
|
xvfb \
|
|
xdotool \
|
|
scrot \
|
|
at-spi2-core \
|
|
python3-gi \
|
|
gir1.2-atspi-2.0 \
|
|
libatk-adaptor \
|
|
dbus-x11 \
|
|
gnome-calculator \
|
|
wmctrl
|
|
|
|
- name: Setup toolchain
|
|
uses: ./.github/actions/setup-node-pnpm
|
|
|
|
- name: Start Xvfb and D-Bus
|
|
run: |
|
|
# Start virtual framebuffer (1280x1024, 24-bit color)
|
|
Xvfb :99 -screen 0 1280x1024x24 &
|
|
sleep 1
|
|
|
|
# Start a D-Bus session and export its env vars for subsequent steps.
|
|
# dbus-launch forks a persistent daemon, so it survives the step.
|
|
eval "$(dbus-launch --sh-syntax)"
|
|
echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >> "$GITHUB_ENV"
|
|
echo "DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" >> "$GITHUB_ENV"
|
|
|
|
- name: Start AT-SPI2 registry
|
|
run: |
|
|
# The registry must start AFTER DBUS_SESSION_BUS_ADDRESS is available
|
|
# (it was written to GITHUB_ENV in the previous step).
|
|
ATSPI_REG=$(find /usr -name at-spi2-registryd -type f 2>/dev/null | head -1)
|
|
if [ -z "$ATSPI_REG" ]; then
|
|
echo "::error::at-spi2-registryd not found. Install at-spi2-core."
|
|
exit 1
|
|
fi
|
|
"$ATSPI_REG" &
|
|
sleep 2
|
|
# Health probe: verify the registry is reachable on the a11y bus
|
|
if python3 -c "import gi; gi.require_version('Atspi','2.0'); from gi.repository import Atspi; d=Atspi.get_desktop(0); assert d is not None, 'desktop is None'; print(f'AT-SPI2 OK — {d.get_child_count()} apps')"; then
|
|
echo "AT-SPI2 registry healthy"
|
|
else
|
|
echo "::error::AT-SPI2 registry started but health probe failed"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Verify environment
|
|
run: |
|
|
echo "=== Display ==="
|
|
xdotool getdisplaygeometry
|
|
echo "=== D-Bus ==="
|
|
echo "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS"
|
|
echo "=== AT-SPI2 Python bindings ==="
|
|
python3 -c "import gi; gi.require_version('Atspi', '2.0'); from gi.repository import Atspi; print('OK')"
|
|
echo "=== AT-SPI2 tree dump (quick test) ==="
|
|
python3 linux/atspi-dump.py --surface desktop --max-nodes 5 | python3 -m json.tool | head -20 || echo "::warning::AT-SPI2 tree dump returned no nodes (expected before any app is launched)"
|
|
echo "=== xdotool ==="
|
|
xdotool version
|
|
|
|
- name: Run Linux replay smoke test
|
|
run: |
|
|
pnpm clean:daemon
|
|
pnpm test:replay:linux \
|
|
--retries 2 \
|
|
--report-junit test/artifacts/replays-linux.junit.xml
|
|
|
|
- name: Upload Linux artifacts
|
|
if: always()
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: linux-artifacts
|
|
if-no-files-found: ignore
|
|
path: |
|
|
test/artifacts/**
|
|
test/screenshots/**
|