Skip to content

ci(cua-driver): add distro-compat smoke-test workflow (CUA-606) - #1960

Merged
r33drichards merged 3 commits into
mainfrom
f/cua-606-create-cua-driver-release-candidate-for-distro-ci-workflow
Jun 21, 2026
Merged

ci(cua-driver): add distro-compat smoke-test workflow (CUA-606)#1960
r33drichards merged 3 commits into
mainfrom
f/cua-606-create-cua-driver-release-candidate-for-distro-ci-workflow

Conversation

@r33drichards

@r33drichards r33drichards commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

cua-driver distro-compat CI — Release candidate workflow

Creates the distro-compat CI workflow for cua-driver with full X11 + Wayland runtime dependency support across 5 Linux distributions.

Distros

  • debian:12, ubuntu:22.04, ubuntu:24.04, rockylinux:9, fedora:41

Key fixes

  • X11 runtime deps: libx11-6/libxi6/libxtst6/libxext6 (deb), libX11/libXi/libXtst/libXext (rpm)
  • Rocky Linux 9: --allowerasing for curl (conflicts with curl-minimal)

Review changes (commit 41d213c)

  • Wayland runtime dep added: libwayland-client0 (deb) / libwayland-client (rpm) — cua-driver links against native Wayland backend (added in wayland support #1910); missing from minimal containers causes silent linker failure
  • Typo fix: manifstmanifest

Follow-up (tracked in Linear comments)

  • Add arm64 matrix rows (blocked on runner stability)
  • Remove continue-on-error: true once stable
  • Add DEBIAN_FRONTEND=noninteractive to debian:12

…e deps

Add .github/workflows/ci-distro-compat-cua-driver.yml from PR #1959
(f/cua-599-nixos-cua-driver-test-suite-has-blind-spots-for-real-distro)
with a fix for the X11 runtime dependency issue.

The workflow smoke-tests the released cua-driver-rs binary across 5 distros
(debian:12, ubuntu:22.04, ubuntu:24.04, rockylinux:9, fedora:41) to catch
glibc ABI floor regressions.

**Fix from original PR:** The pkg_install matrix entries now include the
required X11 runtime libs (libx11-6 libxi6 libxtst6 libxext6 on Debian/Ubuntu;
libX11 libXi libXtst libXext on Rocky/Fedora). Without these, the cua-driver
binary fails with exit 127 (dynamic linker cannot resolve libXi.so.6 etc.)
before main() even runs -- which the smoke-test correctly interprets as an
ABI failure.

The cua-driver-rs-v0.5.8 release (published 2026-06-21) provides the binary
assets this workflow downloads. The binary URL pattern matches:
  https://github.com/trycua/cua/releases/download/cua-driver-rs-v{VERSION}/
    cua-driver-rs-{VERSION}-linux-x86_64-binary.tar.gz

Fixes: CUA-606
Related: CUA-599, PR #1959
@vercel

vercel Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jun 21, 2026 10:31pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

A new GitHub Actions workflow (ci-distro-compat-cua-driver.yml) is added that smoke-tests the released cua-driver linux x86_64 binary across Debian/Ubuntu and RPM-family distro containers. It includes a version-resolution job, a non-blocking per-distro matrix job (glibc-floor logging, --version validation, doctor execution), and an always-run summary gate job.

Changes

Distro Compatibility Smoke-Test Workflow

Layer / File(s) Summary
Workflow triggers and version resolution
.github/workflows/ci-distro-compat-cua-driver.yml
Defines PR/push/tag/dispatch triggers with read-only permissions and a resolve-version job that selects the release version from manual input, current git tag, or latest GitHub Release via gh api, outputting the binary download URL or none when no release is found.
Distro smoke matrix job
.github/workflows/ci-distro-compat-cua-driver.yml
Runs continue-on-error in real distro containers (Debian/Ubuntu, RPM-family); installs runtime deps, conditionally skips when no release exists, downloads and extracts the tarball, logs glibc-floor symbol requirements, validates --version against a semver pattern, and runs doctor with special handling for exit codes 126/127 as ABI failures.
Summary and workflow gate
.github/workflows/ci-distro-compat-cua-driver.yml
Always-runs distro-compat-summary job that fails only if resolve-version itself failed; otherwise reports completion and delegates per-distro pass/fail to individual matrix logs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • trycua/cua#1919: Directly related — lowers the glibc requirement from 2.39 to 2.31 via containerized compilation, which this workflow's glibc-floor logging step is designed to validate across distros.

Poem

🐇 Hop across each distro lane,
Debian, Ubuntu, RPM chain,
glibc floors checked with care,
--version semver floating there,
no release found? skip and wait —
the rabbit guards the workflow gate! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a distro-compat smoke-test workflow for cua-driver, which is the primary purpose of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch f/cua-606-create-cua-driver-release-candidate-for-distro-ci-workflow

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci-distro-compat-cua-driver.yml:
- Around line 223-229: The exit code validation in the smoke gate test is
incomplete. Currently, the condition starting with `if [[ $EXIT_CODE -eq 127 ||
$EXIT_CODE -eq 126 ]]` only rejects those two specific exit codes, but allows
other non-zero exits (like 132, 134, 139 from signal terminations) to pass as
success. You need to add an additional validation after the existing check to
ensure that only exit codes 0 or 1 are treated as success, explicitly rejecting
all other non-zero exit codes. This will align the code behavior with the stated
intent in the comment that follows.
- Around line 82-84: The GitHub API query for the cua-driver-rs release version
only retrieves the first page of releases (30 per page by default), but with 528
total releases in the repository, cua-driver-rs-v* tags could exist on later
pages. Add pagination to the gh api call by including the --paginate flag to
retrieve all releases across multiple pages before filtering with jq. This
ensures the VERSION variable gets populated correctly even when matching tags
are beyond the first page, preventing the workflow from silently skipping the
matrix job.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6a574403-1036-4123-a42f-d8413fe04d17

📥 Commits

Reviewing files that changed from the base of the PR and between 3ae0c3f and 6feef7c.

📒 Files selected for processing (1)
  • .github/workflows/ci-distro-compat-cua-driver.yml

Comment on lines +82 to +84
VERSION=$(gh api repos/trycua/cua/releases \
--jq '[.[] | select(.tag_name | startswith("cua-driver-rs-v"))] | first | .tag_name | ltrimstr("cua-driver-rs-v")' \
2>/dev/null || echo "")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd /tmp && find . -type f -name "ci-distro-compat-cua-driver.yml" 2>/dev/null | head -5

Repository: trycua/cua

Length of output: 36


🏁 Script executed:

git ls-files | grep -i "ci-distro-compat-cua-driver.yml"

Repository: trycua/cua

Length of output: 104


🏁 Script executed:

cat -n .github/workflows/ci-distro-compat-cua-driver.yml | head -100

Repository: trycua/cua

Length of output: 5197


🏁 Script executed:

cat -n .github/workflows/ci-distro-compat-cua-driver.yml | sed -n '98,150p'

Repository: trycua/cua

Length of output: 3310


🏁 Script executed:

cat -n .github/workflows/ci-distro-compat-cua-driver.yml | tail -80

Repository: trycua/cua

Length of output: 4427


🏁 Script executed:

# Check GitHub CLI releases for trycua/cua to understand release distribution
gh api repos/trycua/cua/releases --jq '.[] | {tag_name, draft}' 2>/dev/null | head -40

Repository: trycua/cua

Length of output: 1545


🏁 Script executed:

# Count total releases to understand pagination risk
gh api repos/trycua/cua/releases --jq 'length' 2>/dev/null

Repository: trycua/cua

Length of output: 57


🏁 Script executed:

# Check if there are more releases beyond page 1 (need to use --paginate to see)
gh api --paginate repos/trycua/cua/releases --jq '.[] | .tag_name' 2>/dev/null | wc -l

Repository: trycua/cua

Length of output: 58


🏁 Script executed:

# Check what the current query actually returns (without pagination)
gh api repos/trycua/cua/releases --jq '[.[] | select(.tag_name | startswith("cua-driver-rs-v"))] | first | .tag_name | ltrimstr("cua-driver-rs-v")' 2>/dev/null

Repository: trycua/cua

Length of output: 60


🏁 Script executed:

# Check if the proposed fix works correctly and would catch more releases
gh api --paginate repos/trycua/cua/releases --jq '.[] | select((.draft | not) and (.tag_name | startswith("cua-driver-rs-v"))) | .tag_name' 2>/dev/null | head -5

Repository: trycua/cua

Length of output: 159


🏁 Script executed:

# Test the proposed fix
VERSION=$(gh api --paginate repos/trycua/cua/releases \
  --jq '.[] | select((.draft | not) and (.tag_name | startswith("cua-driver-rs-v"))) | .tag_name' \
  2>/dev/null | sed -n 's/^cua-driver-rs-v//p' | head -n1)
VERSION="${VERSION:-}"
echo "Proposed fix result: $VERSION"

Repository: trycua/cua

Length of output: 81


🏁 Script executed:

# Verify the proposed fix matches current code output
CURRENT=$(gh api repos/trycua/cua/releases \
  --jq '[.[] | select(.tag_name | startswith("cua-driver-rs-v"))] | first | .tag_name | ltrimstr("cua-driver-rs-v")' \
  2>/dev/null || echo "")
echo "Current code result: $CURRENT"

PROPOSED=$(gh api --paginate repos/trycua/cua/releases \
  --jq '.[] | select((.draft | not) and (.tag_name | startswith("cua-driver-rs-v"))) | .tag_name' \
  2>/dev/null | sed -n 's/^cua-driver-rs-v//p' | head -n1)
PROPOSED="${PROPOSED:-}"
echo "Proposed fix result: $PROPOSED"

if [[ "$CURRENT" == "$PROPOSED" ]]; then
  echo "✓ Results match"
else
  echo "✗ Results differ"
fi

Repository: trycua/cua

Length of output: 124


Release auto-detection can silently fail when matching tags are off page 1.

Line 82 queries only the first /releases page. With 528 total releases in this repo (default 30 per page), future release patterns could push all cua-driver-rs-v* tags beyond page 1, causing VERSION to become empty. The workflow then reports false-green by skipping the matrix (jobs are conditional on version != 'none' and continue-on-error: true masks the silent failure).

Proposed fix
-            VERSION=$(gh api repos/trycua/cua/releases \
-              --jq '[.[] | select(.tag_name | startswith("cua-driver-rs-v"))] | first | .tag_name | ltrimstr("cua-driver-rs-v")' \
-              2>/dev/null || echo "")
+            VERSION=$(gh api --paginate repos/trycua/cua/releases \
+              --jq '.[] | select((.draft | not) and (.tag_name | startswith("cua-driver-rs-v"))) | .tag_name' \
+              2>/dev/null | sed -n 's/^cua-driver-rs-v//p' | head -n1)
+            VERSION="${VERSION:-}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
VERSION=$(gh api repos/trycua/cua/releases \
--jq '[.[] | select(.tag_name | startswith("cua-driver-rs-v"))] | first | .tag_name | ltrimstr("cua-driver-rs-v")' \
2>/dev/null || echo "")
VERSION=$(gh api --paginate repos/trycua/cua/releases \
--jq '.[] | select((.draft | not) and (.tag_name | startswith("cua-driver-rs-v"))) | .tag_name' \
2>/dev/null | sed -n 's/^cua-driver-rs-v//p' | head -n1)
VERSION="${VERSION:-}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci-distro-compat-cua-driver.yml around lines 82 - 84, The
GitHub API query for the cua-driver-rs release version only retrieves the first
page of releases (30 per page by default), but with 528 total releases in the
repository, cua-driver-rs-v* tags could exist on later pages. Add pagination to
the gh api call by including the --paginate flag to retrieve all releases across
multiple pages before filtering with jq. This ensures the VERSION variable gets
populated correctly even when matching tags are beyond the first page,
preventing the workflow from silently skipping the matrix job.

Comment on lines +223 to +229
if [[ $EXIT_CODE -eq 127 || $EXIT_CODE -eq 126 ]]; then
echo "ERROR: cua-driver failed to execute (exit $EXIT_CODE) — likely glibc ABI mismatch"
exit 1
fi
# Treat 0 (all capabilities present) or 1 (capabilities missing but
# doctor ran) as success — both mean the binary loaded correctly.
echo "PASS: doctor ran without ABI error"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd .github/workflows && cat -n ci-distro-compat-cua-driver.yml | sed -n '210,240p'

Repository: trycua/cua

Length of output: 1815


🏁 Script executed:

# Check if there are other test/verification steps in the workflow
rg "EXIT_CODE" .github/workflows/ci-distro-compat-cua-driver.yml

# Check if there are other doctor-related checks elsewhere
rg -i "doctor" .github/workflows/ -A 2 -B 2 | head -80

Repository: trycua/cua

Length of output: 4726


doctor smoke gate accepts non-zero exits outside 126/127 as success, weakening ABI/runtime validation.

The current check on line 223 only rejects exit codes 126 and 127. This allows crash exits like 132 (SIGILL), 134 (SIGABRT), and 139 (SIGSEGV) to pass, even though the test intent (lines 210–216) is to verify the binary loads and exits with a parseable status—not a crash. The comment on lines 227–228 claims success for exits 0 or 1 only, but the code never validates EXIT_CODE is actually one of those values.

Proposed fix
          # Exit codes that indicate glibc/ABI failure (command not found / bad ELF):
          if [[ $EXIT_CODE -eq 127 || $EXIT_CODE -eq 126 ]]; then
            echo "ERROR: cua-driver failed to execute (exit $EXIT_CODE) — likely glibc ABI mismatch"
            exit 1
          fi
-         # Treat 0 (all capabilities present) or 1 (capabilities missing but
-         # doctor ran) as success — both mean the binary loaded correctly.
+         # Treat only 0 (all capabilities present) or 1 (capabilities missing
+         # but doctor ran) as success.
+         if [[ $EXIT_CODE -ne 0 && $EXIT_CODE -ne 1 ]]; then
+           echo "ERROR: cua-driver doctor exited unexpectedly ($EXIT_CODE)"
+           exit 1
+         fi
          echo "PASS: doctor ran without ABI error"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ $EXIT_CODE -eq 127 || $EXIT_CODE -eq 126 ]]; then
echo "ERROR: cua-driver failed to execute (exit $EXIT_CODE) — likely glibc ABI mismatch"
exit 1
fi
# Treat 0 (all capabilities present) or 1 (capabilities missing but
# doctor ran) as success — both mean the binary loaded correctly.
echo "PASS: doctor ran without ABI error"
if [[ $EXIT_CODE -eq 127 || $EXIT_CODE -eq 126 ]]; then
echo "ERROR: cua-driver failed to execute (exit $EXIT_CODE) — likely glibc ABI mismatch"
exit 1
fi
# Treat only 0 (all capabilities present) or 1 (capabilities missing
# but doctor ran) as success.
if [[ $EXIT_CODE -ne 0 && $EXIT_CODE -ne 1 ]]; then
echo "ERROR: cua-driver doctor exited unexpectedly ($EXIT_CODE)"
exit 1
fi
echo "PASS: doctor ran without ABI error"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci-distro-compat-cua-driver.yml around lines 223 - 229,
The exit code validation in the smoke gate test is incomplete. Currently, the
condition starting with `if [[ $EXIT_CODE -eq 127 || $EXIT_CODE -eq 126 ]]` only
rejects those two specific exit codes, but allows other non-zero exits (like
132, 134, 139 from signal terminations) to pass as success. You need to add an
additional validation after the existing check to ensure that only exit codes 0
or 1 are treated as success, explicitly rejecting all other non-zero exit codes.
This will align the code behavior with the stated intent in the comment that
follows.

Rocky Linux 9 ships curl-minimal in the base image which conflicts with
the full curl package. Use --allowerasing to let dnf replace curl-minimal
with the full curl package transparently.
@r33drichards

Copy link
Copy Markdown
Collaborator Author

CI Status Update

All 5 distros passing with cua-driver-rs-v0.5.8 (published 2026-06-21).

Distro glibc Status
debian:12 2.36
ubuntu:22.04 2.35
ubuntu:24.04 2.39
rockylinux:9 2.34
fedora:41 2.40

What was fixed: Added X11 runtime libraries (libx11-6 libxi6 libxtst6 libxext6 on Debian/Ubuntu; libX11 libXi libXtst libXext on RPM distros) to the pkg_install matrix entries. Without them, the dynamically-linked binary fails with exit 127 before main() runs. Also added --allowerasing to the Rocky Linux 9 dnf command to resolve the curl vs curl-minimal conflict.

Workflow run: https://github.com/trycua/cua/actions/runs/27893070447

…nifest typo

- Add libwayland-client0 (deb) and libwayland-client (rpm) to pkg_install
  because the CD workflow links against libwayland-dev (native Wayland
  backend, added in #1910); without the runtime lib the dynamic linker
  fails on any distro that doesn't install it by default.
- Fix typo: 'manifst' -> 'manifest' in doctor smoke-test comment.
- Update comment block to mention Wayland alongside X11 deps.
@r33drichards

Copy link
Copy Markdown
Collaborator Author

✅ Review complete

Review commit 41d213cd pushed:

  • Added Wayland runtime dep (libwayland-client0/libwayland-client) to all 5 distros — cua-driver links against Wayland backend from wayland support #1910
  • Typo fix (manifst → manifest)

Follow-up suggestions noted (arm64 matrix, continue-on-error gate, DEBIAN_FRONTEND).

Ready for merge.

@r33drichards

Copy link
Copy Markdown
Collaborator Author

🏔️ Hillclimb complete

All CI checks are green ✅ — no fixes were needed.

Check Status
debian:12 (glibc 2.36) ✅ pass
ubuntu:22.04 (glibc 2.35) ✅ pass
ubuntu:24.04 (glibc 2.39) ✅ pass
rockylinux:9 (glibc 2.34) ✅ pass
fedora:41 (glibc 2.40) ✅ pass
Distro compat summary ✅ pass
Resolve release version ✅ pass
link-check ✅ pass
release-reminder ✅ pass
Vercel Preview ✅ pass

The new distro-compat smoke test workflow for cua-driver is passing on all target distributions. PR is ready to merge.

@r33drichards
r33drichards merged commit 12832de into main Jun 21, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants