Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/workflows/ci-rust-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ on:
- "libs/cua-driver/rust/crates/cua-driver-testkit/**"
- "libs/cua-driver/rust/crates/platform-windows/**"
- "libs/cua-driver/rust/crates/cua-driver-uia/**"
- "libs/cua-driver/rust/crates/focus-monitor-win/**"
- "libs/cua-driver/tests/fixtures/**"
- ".github/workflows/ci-rust-windows.yml"
push:
Expand Down Expand Up @@ -43,4 +42,4 @@ jobs:
working-directory: libs/cua-driver/rust
# Compile every Rust target without executing desktop-dependent integration
# tests; interactive behavior belongs in e2e-rust-windows.yml.
run: cargo test -p cua-driver -p cua-driver-core -p cua-driver-testkit -p platform-windows -p cua-driver-uia -p focus-monitor-win --all-targets --no-run --locked
run: cargo test -p cua-driver -p cua-driver-core -p cua-driver-testkit -p platform-windows -p cua-driver-uia --all-targets --no-run --locked
163 changes: 65 additions & 98 deletions .github/workflows/e2e-rust-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,9 @@ on:
workflow_dispatch:
inputs:
ref:
description: "Commit, branch, or tag to test"
required: true
default: "main"
suite:
description: "Rust desktop suite"
required: true
type: choice
options: [default, guard, shared, native, modality, all]
default: shared
description: "Optional full 40-character commit SHA; defaults to dispatch SHA"
required: false
default: ""
runner:
description: "Runner label; use the Azure RDP runner label for VM e2e"
required: true
Expand All @@ -23,83 +17,37 @@ permissions:
actions: read

jobs:
default:
if: inputs.suite == 'default' || inputs.suite == 'all'
name: "Windows / default Rust tests"
runs-on: ${{ inputs.runner }}
timeout-minutes: 90
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.ref }}
- name: Ensure FFmpeg for trajectory video
shell: pwsh
run: |
if (-not (Get-Command ffmpeg.exe -ErrorAction SilentlyContinue)) {
choco install ffmpeg -y --no-progress
}
ffmpeg -version
ffprobe -version
- name: Run default Rust tests
shell: pwsh
run: .\scripts\ci\windows\run-rust-e2e.ps1 -Suite default -RequireGui
- name: Collect logs
if: always()
shell: pwsh
run: .\scripts\ci\windows\collect-artifacts.ps1
- name: Upload default results
if: always()
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
with:
name: rust-windows-default
path: artifacts/cua-driver/windows
if-no-files-found: ignore
compression-level: 0
retention-days: 14

guard:
if: inputs.suite == 'guard' || inputs.suite == 'all'
name: "Windows / UX guards"
runs-on: ${{ inputs.runner }}
timeout-minutes: 90
source:
name: "Resolve exact source"
runs-on: ubuntu-latest
outputs:
sha: ${{ steps.resolve.outputs.sha }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.ref }}
- name: Ensure FFmpeg for trajectory video
shell: pwsh
- id: resolve
name: Validate source SHA
shell: bash
env:
REQUESTED_SHA: ${{ inputs.ref }}
DISPATCH_SHA: ${{ github.sha }}
run: |
if (-not (Get-Command ffmpeg.exe -ErrorAction SilentlyContinue)) {
choco install ffmpeg -y --no-progress
}
ffmpeg -version
ffprobe -version
- name: Run UX guard tests
shell: pwsh
run: .\scripts\ci\windows\run-rust-e2e.ps1 -Suite guard -RequireGui
- name: Collect logs
if: always()
shell: pwsh
run: .\scripts\ci\windows\collect-artifacts.ps1
- name: Upload guard results
if: always()
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
with:
name: rust-windows-guard
path: artifacts/cua-driver/windows
if-no-files-found: ignore
compression-level: 0
retention-days: 14
sha="${REQUESTED_SHA:-$DISPATCH_SHA}"
if [[ ! "$sha" =~ ^[0-9a-fA-F]{40}$ ]]; then
echo "ref must be a full 40-character commit SHA" >&2
exit 2
fi
echo "sha=${sha,,}" >> "$GITHUB_OUTPUT"

shared:
if: inputs.suite == 'shared' || inputs.suite == 'all'
name: "Windows / shared Electron + Tauri"
needs: source
runs-on: ${{ inputs.runner }}
timeout-minutes: 90
env:
CUA_E2E_SOURCE_SHA: ${{ needs.source.outputs.sha }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.ref }}
ref: ${{ needs.source.outputs.sha }}
- name: Ensure FFmpeg for trajectory video
shell: pwsh
run: |
Expand All @@ -110,7 +58,9 @@ jobs:
ffprobe -version
- name: Run shared Rust behavior matrix
shell: pwsh
run: .\scripts\ci\windows\run-rust-e2e.ps1 -Suite shared -RequireGui
env:
CUA_E2E_INTERNAL_LANE: shared
run: .\scripts\ci\windows\run-rust-e2e.ps1 -RequireGui
- name: Collect logs
if: always()
shell: pwsh
Expand All @@ -126,14 +76,16 @@ jobs:
retention-days: 14

native:
if: inputs.suite == 'native' || inputs.suite == 'all'
name: "Windows / native WPF + WebView2"
name: "Windows / native WPF + WinUI3 + WebView2"
needs: source
runs-on: ${{ inputs.runner }}
timeout-minutes: 90
env:
CUA_E2E_SOURCE_SHA: ${{ needs.source.outputs.sha }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.ref }}
ref: ${{ needs.source.outputs.sha }}
- name: Ensure FFmpeg for trajectory video
shell: pwsh
run: |
Expand All @@ -144,7 +96,9 @@ jobs:
ffprobe -version
- name: Run native Rust harnesses
shell: pwsh
run: .\scripts\ci\windows\run-rust-e2e.ps1 -Suite native -RequireGui
env:
CUA_E2E_INTERNAL_LANE: native
run: .\scripts\ci\windows\run-rust-e2e.ps1 -RequireGui
- name: Collect logs
if: always()
shell: pwsh
Expand All @@ -159,15 +113,17 @@ jobs:
compression-level: 0
retention-days: 14

modality:
if: inputs.suite == 'modality' || inputs.suite == 'all'
name: "Windows / modality input E2E"
capture:
name: "Windows / capture and desktop scope"
needs: source
runs-on: ${{ inputs.runner }}
timeout-minutes: 90
env:
CUA_E2E_SOURCE_SHA: ${{ needs.source.outputs.sha }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ inputs.ref }}
ref: ${{ needs.source.outputs.sha }}
- name: Ensure FFmpeg for trajectory video
shell: pwsh
run: |
Expand All @@ -176,30 +132,35 @@ jobs:
}
ffmpeg -version
ffprobe -version
- name: Run modality input E2E
- name: Run capture and desktop-scope contracts
shell: pwsh
run: .\scripts\ci\windows\run-rust-e2e.ps1 -Suite modality -RequireGui
env:
CUA_E2E_INTERNAL_LANE: capture
run: .\scripts\ci\windows\run-rust-e2e.ps1 -RequireGui
- name: Collect logs
if: always()
shell: pwsh
run: .\scripts\ci\windows\collect-artifacts.ps1
- name: Upload modality results
- name: Upload capture results
if: always()
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
with:
name: rust-windows-modality
name: rust-windows-capture
path: artifacts/cua-driver/windows
if-no-files-found: ignore
compression-level: 0
retention-days: 14

summary:
if: always()
needs: [default, guard, shared, native, modality]
needs: [source, shared, native, capture]
name: "Windows / matrix summary"
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
ref: ${{ needs.source.outputs.sha }}
- name: Download lane results
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4
with:
Expand All @@ -216,19 +177,27 @@ jobs:
echo "The lane jobs above are independent; a failure in one lane does not hide the others."
echo
} > "$summary_path"
artifacts_json=$(gh api \
"repos/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/artifacts?per_page=100")
found=0
while IFS= read -r summary; do
found=1
echo "## $(basename "$(dirname "$summary")")" >> "$summary_path"
cat "$summary" >> "$summary_path"
artifact=$(basename "$(dirname "$summary")")
echo "## $artifact" >> "$summary_path"
artifact_id=$(jq -r --arg name "$artifact" \
'.artifacts[] | select(.name == $name) | .id' <<< "$artifacts_json" | head -n 1)
if [[ -n "$artifact_id" && "$artifact_id" != "null" ]]; then
artifact_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/artifacts/$artifact_id"
scripts/ci/link-e2e-evidence.sh "$summary" "$artifact_url" >> "$summary_path"
else
cat "$summary" >> "$summary_path"
fi
echo >> "$summary_path"
done < <(find artifacts -type f -name summary.md -print | sort)
if [[ "$found" == 0 ]]; then
echo "No lane summary artifact was produced." >> "$summary_path"
fi

artifacts_json=$(gh api \
"repos/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/artifacts?per_page=100")
{
echo
echo "## Trajectory videos"
Expand All @@ -255,15 +224,13 @@ jobs:
fi
echo "| $lane | $video_count | $artifact_link |" >> "$summary_path"
done <<'EOF'
Default Rust|rust-windows-default
UX guards|rust-windows-guard
Electron + Tauri|rust-windows-shared
WPF + WinUI3 + WebView2|rust-windows-native
Modality input|rust-windows-modality
Capture + desktop scope|rust-windows-capture
EOF
{
echo
echo "Each artifact stores videos under \`recordings/<test-name>/recording.mp4\` with a matching \`trajectory.json\`."
echo "Each evidence link opens its owning lane artifact; the row text is the exact \`recordings/<cell-label>-pid<pid>-<sequence>/recording.mp4\` path, with an adjacent \`trajectory.json\`."
} >> "$summary_path"
cat "$summary_path" >> "$GITHUB_STEP_SUMMARY"
- name: Upload matrix summary
Expand Down
7 changes: 0 additions & 7 deletions libs/cua-driver/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion libs/cua-driver/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ members = [
"crates/platform-windows",
"crates/platform-linux",
"crates/cursor-overlay",
"crates/focus-monitor-win",
"crates/pip-preview",
]

Expand Down
1 change: 0 additions & 1 deletion libs/cua-driver/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ implementations, testkit, and helper crates.
| `platform-linux` | Linux AT-SPI, X11/Wayland, capture, and input support |
| `cua-driver-testkit` | Test-only helpers for spawning the daemon and parsing responses |
| `cua-driver-uia` | Windows UIAccess worker |
| `focus-monitor-win` | Windows focus sentinel used by UX guard tests |
| `cursor-overlay` | Cursor overlay support |
| `pip-preview` | Packaging preview helper |

Expand Down
Loading
Loading