Skip to content

chore(ci): extract reusable e2e/test workflows + release pretest gate#1887

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
senamakel:chore/reusable-ci-workflows
May 16, 2026
Merged

chore(ci): extract reusable e2e/test workflows + release pretest gate#1887
senamakel merged 2 commits into
tinyhumansai:mainfrom
senamakel:chore/reusable-ci-workflows

Conversation

@senamakel
Copy link
Copy Markdown
Member

@senamakel senamakel commented May 16, 2026

Summary

  • Extract e2e.yml and test.yml into workflow_call reusables (e2e-reusable.yml, test-reusable.yml) so PR/push and release runs share one recipe.
  • PR/push: Linux E2E smoke + mega-flow + unit + rust suites (all required). macOS/Windows E2E and full spec suite are opt-in via workflow_dispatch.
  • Release-staging and release-production now gate build-desktop/build-docker on a pretest-tests + pretest-e2e pass across all three target OSes with the full spec suite — no signed bundles get built unless every unit/rust/E2E suite is green on the build ref.
  • Aggressive caching everywhere: pnpm store, Swatinem rust target dirs, CEF runtime download (key shape matches build-desktop.yml so a release build and an E2E run on the same SHA share one ~400MB download), Appium global install, sccache for Rust tests.
  • cleanup-failed-staging and cleanup-failed-release were extended to also tear down the just-pushed tag when pretest fails; release-production additionally guards the release-delete and Docker-cleanup steps so they're skipped when there's nothing to clean up.

Problem

The previous setup ran the E2E recipe inline inside e2e.yml (3 near-identical jobs) and bolted the test pipeline onto every PR via test.yml. The two release workflows then started build-desktop immediately after prepare-build, with no test gate at all — a busted commit on main could produce four signed Tauri bundles + a staging tag + (on production) a draft GH Release before anyone noticed unit tests failed.

That meant:

  1. Bulky e2e.yml duplicated across three jobs, painful to evolve.
  2. No mechanical guarantee that release bundles were built against passing tests.
  3. CEF runtime cache (~400MB) re-downloaded for E2E jobs because the cache key didn't match build-desktop.yml.

Solution

Split the recipe into two reusable workflows and have both PR/push runs and release runs call them, with different inputs:

  • PRs/push call e2e-reusable.yml with run_linux: true only and full: false (smoke + mega-flow). Test-reusable runs the existing unit/rust matrix. Both required.
  • release-staging.yml and release-production.yml insert a pretest-tests + pretest-e2e job between prepare-build and the build matrix, calling the reusables with all three platforms and full: true. build-desktop/build-docker/create-release only proceed if pretest is green.
  • CEF cache keys (cef-<target>-<hashFiles(Cargo.toml)>) intentionally mirror the keys in build-desktop.yml so warm caches survive across workflows on the same commit.

The workflow_dispatch form of e2e.yml keeps the existing "run the full suite on demand" escape hatch via opt-in checkboxes for macOS/Windows/full.

Submission Checklist

  • N/A: CI-config-only change; no application code paths added or changed
  • N/A: CI-config-only change, no coverage delta
  • N/A: behaviour-only change (no feature rows added/removed/renamed)
  • N/A: no feature IDs touched by this change
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • N/A: workflow-only change, no release-cut surface touched
  • N/A: no linked issue — internal CI cleanup

Impact

  • CI runtime: PRs are unchanged in scope but Linux E2E is now blocking (was continue-on-error: true); flaky CEF/Xvfb runs will fail PRs instead of being silently informational. If the container CEF flake returns, re-add continue-on-error: true on the e2e-linux job in e2e-reusable.yml.
  • Release runtime: staging and production cuts now run unit + rust + full E2E on Linux/macOS/Windows before the build matrix starts. This adds ~30–90 min to the wall clock of a release cut (in exchange for never producing un-tested signed bundles).
  • Caching: shared CEF cache key with build-desktop.yml should cut CEF download time to zero on release runs after the first warm hit per Cargo.toml change.
  • No production runtime behavior change — workflows only.

Related

  • Closes:
  • Follow-up PR(s)/TODOs:

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: chore/reusable-ci-workflows
  • Commit SHA: c6a2b67

Validation Run

  • pnpm --filter openhuman-app format:check (ran via pre-push hook, green)
  • pnpm typecheck (ran via pre-push hook, green)
  • Focused tests: N/A: workflow YAML only, parsed with yaml.safe_load on all six files
  • Rust fmt/check (if changed): pre-push hook ran cargo check --manifest-path Cargo.toml and app/src-tauri/Cargo.toml, both green
  • Tauri fmt/check (if changed): same as above

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Release cuts gate on full test+E2E pass before any signed build runs.
  • User-visible effect: None at runtime. Operators will see new pretest-tests and pretest-e2e jobs in release-staging / release-production runs.

Parity Contract

  • Legacy behavior preserved: PR/push test/E2E coverage matches the prior test.yml + e2e.yml Linux smoke + mega-flow. macOS/Windows E2E remain dispatch-only on PR runs.
  • Guard/fallback/dispatch parity checks: cleanup-failed-* extended for the new pretest-failure path (deletes orphaned tag; guards the release-delete and Docker-cleanup steps so they're skipped when nothing was created).

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this one
  • Resolution: N/A

Summary by CodeRabbit

  • Chores
    • Reorganized CI to use reusable test and E2E workflows for more consistent, maintainable runs.
    • Release workflows now require pretest gates (unit, Rust, full E2E) to pass before creating releases.
    • E2E pipeline gained flexible platform selection (Linux/macOS/Windows) and full vs smoke-run options.
    • Test workflow delegation centralizes coverage and Rust test runs and uploads test artifacts for debugging.

Review Change Stack

Split the desktop E2E and test pipelines into `workflow_call` reusable
workflows (`e2e-reusable.yml`, `test-reusable.yml`) so the same recipe
runs on PR/push and at release time without duplication. PR/push runs
Linux-only smoke E2E (required) plus the existing unit + rust suites.

Both release workflows (`release-staging.yml`, `release-production.yml`)
now gate `build-desktop`/`build-docker` on a single `pretest-tests` +
`pretest-e2e` pass across all three target OSes with the full spec
suite — no signed bundles get built unless unit, rust, and E2E are all
green on the build ref. `cleanup-failed-*` was extended to tear down the
just-pushed tag when pretest fails (release-production additionally
guards the release-delete + Docker-cleanup steps so they're skipped when
there is nothing to clean up).

Caching covers pnpm store, Swatinem rust target dirs (root + tauri),
CEF runtime download (keyed to match build-desktop.yml so a release
build and an E2E run on the same commit share a single download),
Appium global install, and sccache for Rust tests.
@senamakel senamakel requested a review from a team May 16, 2026 03:09
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 03c72c57-b6ab-44db-91b9-27cf51789c74

📥 Commits

Reviewing files that changed from the base of the PR and between c6a2b67 and 01c8c4d.

📒 Files selected for processing (4)
  • .github/workflows/e2e-reusable.yml
  • .github/workflows/release-production.yml
  • .github/workflows/release-staging.yml
  • .github/workflows/test-reusable.yml
🚧 Files skipped from review as they are similar to previous changes (4)
  • .github/workflows/release-production.yml
  • .github/workflows/release-staging.yml
  • .github/workflows/test-reusable.yml
  • .github/workflows/e2e-reusable.yml

📝 Walkthrough

Walkthrough

This PR adds reusable GitHub Actions for tests and E2E, updates main test/E2E workflows to delegate to those reusables, and introduces pretest gates in production and staging release workflows that must pass before builds/releases proceed.

Changes

Workflow reusability and pretest gates

Layer / File(s) Summary
Test reusable workflow
.github/workflows/test-reusable.yml
Defines three conditionally-enabled test jobs: frontend Vitest coverage with pnpm caching, Rust core crate tests with sccache, and Rust Tauri shell tests with CEF distribution caching; each configurable via boolean run_unit, run_rust_core, and run_rust_tauri inputs.
Test main workflow simplification
.github/workflows/test.yml
Condenses inlined unit/Rust/E2E test definitions into a single delegating test job that calls the reusable workflow; retains existing triggers (push to main, pull_request, workflow_dispatch) and concurrency behavior.
E2E reusable workflow
.github/workflows/e2e-reusable.yml
Defines Linux (with xvfb-run in container), macOS (with ad-hoc codesign), and Windows E2E jobs with OS-specific toolchain setup, caching for pnpm/Rust/CEF/Appium, Appium driver handling, app build, conditional smoke+mega-flow vs full-suite runs, and artifact upload; exposed via workflow_call inputs ref, run_linux, run_macos, run_windows, and full.
E2E main workflow simplification
.github/workflows/e2e.yml
Replaces three separate OS-specific job implementations with a single delegating e2e job that calls the reusable workflow; adds push to main trigger and converts workflow_dispatch inputs to boolean run_macos, run_windows, and full flags.
Release workflow pretest gates
.github/workflows/release-production.yml, .github/workflows/release-staging.yml
Both release workflows gain pretest phases (pretest-tests, pretest-e2e) that run reusable test and full E2E jobs against the resolved ref before build/release creation; build and release jobs now depend on pretest completion, and cleanup logic was updated for pretest failure/cancel paths and conditional Docker cleanup.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I hopped through YAML, tidy and spry,
Reusable jobs now leap and fly,
Tests gate the release before we try,
A rabbit's CI song — hi-fi! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: extracting reusable CI workflows for E2E and tests, plus adding a pretest gate to release workflows.
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.

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


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/test-reusable.yml (1)

92-95: 💤 Low value

Consider adding timeout-minutes to unit-tests and rust-tauri-tests jobs.

The rust-core-tests job specifies timeout-minutes: 20, but the other two jobs lack timeouts. Adding consistent timeouts prevents runaway jobs from consuming resources indefinitely.

🔧 Suggested diff for rust-tauri-tests
 rust-tauri-tests:
   if: inputs.run_rust_tauri
   name: Rust Tauri Shell Tests
   runs-on: ubuntu-22.04
+  timeout-minutes: 20
   container:
🤖 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/test-reusable.yml around lines 92 - 95, The unit-tests and
rust-tauri-tests jobs are missing job-level timeouts; add a timeout-minutes
setting (match the rust-core-tests value, e.g., timeout-minutes: 20) inside each
job definition for "unit-tests" and "rust-tauri-tests" so the GitHub Actions
runner will cancel runaway jobs; update the YAML under the job keys unit-tests
and rust-tauri-tests to include timeout-minutes: 20.
🤖 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/e2e-reusable.yml:
- Around line 296-322: Add a Windows cache step after the "Cache CEF binary
distribution" step to persist the Appium/npm global install so the subsequent
"Install Appium and chromium driver" step doesn't reinstall each run: use
actions/cache@v5 and cache the Windows npm global and cache directories (e.g.,
paths under %APPDATA%\npm and %USERPROFILE%\.npm or the equivalent runner
variables) with a key that includes the runner OS and a repo manifest hash
(similar to the existing CEF/Appium caches) and appropriate restore-keys so the
"Install Appium and chromium driver" block can rely on the restored cache.

In @.github/workflows/release-production.yml:
- Around line 308-320: The pretest jobs are checking out the wrong commit
because test-reusable.yml and e2e-reusable.yml lack a ref input and their
actions/checkout@v5 steps don't use a ref; add an inputs.ref parameter to both
reusable workflows, update their checkout steps to use ref: ${{ inputs.ref }},
and then update the pretest job invocations (pretest-tests and pretest-e2e) to
pass the produced build_ref via with: ref: ${{
needs.prepare-build.outputs.build_ref }} so the reusable workflows check out the
exact tag/SHA from prepare-build.

---

Nitpick comments:
In @.github/workflows/test-reusable.yml:
- Around line 92-95: The unit-tests and rust-tauri-tests jobs are missing
job-level timeouts; add a timeout-minutes setting (match the rust-core-tests
value, e.g., timeout-minutes: 20) inside each job definition for "unit-tests"
and "rust-tauri-tests" so the GitHub Actions runner will cancel runaway jobs;
update the YAML under the job keys unit-tests and rust-tauri-tests to include
timeout-minutes: 20.
🪄 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: 0d0851e7-ccb0-4619-8b42-6e0cdd5bc31e

📥 Commits

Reviewing files that changed from the base of the PR and between 7968f3c and c6a2b67.

📒 Files selected for processing (6)
  • .github/workflows/e2e-reusable.yml
  • .github/workflows/e2e.yml
  • .github/workflows/release-production.yml
  • .github/workflows/release-staging.yml
  • .github/workflows/test-reusable.yml
  • .github/workflows/test.yml

Comment thread .github/workflows/e2e-reusable.yml
Comment thread .github/workflows/release-production.yml
@senamakel senamakel self-assigned this May 16, 2026
Address CodeRabbit review on PR tinyhumansai#1887:

- Add a `ref` input to `test-reusable.yml` and `e2e-reusable.yml` and
  wire it through every `actions/checkout@v5` step in those workflows.
  Previously the pretest gate ran on whatever ref happened to trigger
  the release workflow (main HEAD), not the bumped commit the build
  matrix would actually consume. After this, both release workflows
  pass `needs.prepare-build.outputs.build_ref` (the freshly-pushed
  staging / production tag) so pretest validates byte-for-byte what
  build-desktop will check out.
- Add the missing Appium global-install cache step to the Windows e2e
  job, matching the Linux and macOS jobs.
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.

1 participant