Skip to content

fix(ci): poll for E2E completion in release gate#252

Merged
FSM1 merged 10 commits into
mainfrom
fix/release-gate-wait-for-e2e
Mar 3, 2026
Merged

fix(ci): poll for E2E completion in release gate#252
FSM1 merged 10 commits into
mainfrom
fix/release-gate-wait-for-e2e

Conversation

@FSM1

@FSM1 FSM1 commented Mar 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • The release-please PR opens before E2E tests finish on the same main push, causing the release gate to immediately fail with "no run found"
  • Now polls every 30s (up to 15 min for web, 20 min for desktop) for E2E runs to complete before checking the result
  • Added timeout-minutes: 40 job safety net to accommodate both polling phases
  • Desktop E2E only gates when desktop-related files changed since last release
  • Consolidated cargo check + test into single jobs per platform to eliminate duplicate runner setup
  • Removed push trigger from CI workflow (redundant — CI already runs on PRs, and E2E workflows handle post-merge verification)
  • Removed claude-code.yml workflow (no longer needed)

Test plan

  • Next release-please PR should show the gate waiting for E2E instead of failing immediately

🤖 Generated with Claude Code

…mmediately

The release-please PR opens before E2E tests finish on main, causing
the release gate to fail with "no run found". Now polls every 30s
(up to 15 min) for the E2E run to complete before checking the result.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: b1058120b65d
@coderabbitai

coderabbitai Bot commented Mar 2, 2026

Copy link
Copy Markdown

Walkthrough

Adds a release-gate job that detects desktop-related changes since the last non-staging tag and replaces one-shot E2E checks with polling logic for Web and Desktop E2E runs; gates Desktop E2E on detected desktop changes and accepts a recent successful run if no HEAD run exists.

Changes

Cohort / File(s) Summary
Release gate workflow
​.github/workflows/release-gate.yml
Adds "Detect Changes Since Last Release" job exposing desktop and prev_tag; replaces immediate E2E conclusion checks with polling for Web E2E on main and gated Desktop E2E (poll HEAD run, or accept recent successful SHA in prev_tag..HEAD); adds Skip Desktop E2E and Summary steps; introduces timeout/interval/max-attempts parameters.
CI workflow gating
​.github/workflows/ci.yml
Removes push trigger and push-specific conditionals; standardizes job gates to rely on needs.changes.outputs.src / needs.changes.outputs.desktop; renames/adjusts several cargo check/test jobs and Codecov steps to align with change-detection outputs.
Desktop E2E workflow
​.github/workflows/e2e-desktop.yml
Changes trigger from workflow_run to push/workflow_dispatch; simplifies checkout/ref handling and path-filter base/head usage; conditions simplified to run only when needs.changes.outputs.desktop == 'true'.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor ReleaseGate as Release Gate Workflow
    participant GitHubAPI as GitHub API
    participant WebE2E as Web E2E (main)
    participant DesktopE2E as Desktop E2E (HEAD / recent)
    Note over ReleaseGate,GitHubAPI: Detect changes since last non-staging tag
    ReleaseGate->>GitHubAPI: get latest non-staging tag (prev_tag)
    ReleaseGate->>GitHubAPI: diff prev_tag..HEAD against DESKTOP_PATTERNS
    GitHubAPI-->>ReleaseGate: desktop=true/false, prev_tag
    alt desktop == false
        ReleaseGate->>ReleaseGate: skip Desktop E2E (Summary)
    else desktop == true
        Note over ReleaseGate,WebE2E: Poll Web E2E run for main
        ReleaseGate->>GitHubAPI: query e2e runs on main (repeat until conclusion or timeout)
        GitHubAPI-->>ReleaseGate: status/conclusion
        alt Web E2E success
            Note over ReleaseGate,DesktopE2E: Poll Desktop E2E for HEAD
            ReleaseGate->>GitHubAPI: query Desktop E2E runs for HEAD (repeat)
            GitHubAPI-->>ReleaseGate: run exists? status/conclusion/sha
            alt Desktop HEAD run found and success
                ReleaseGate->>ReleaseGate: pass Desktop gate
            else no HEAD run
                ReleaseGate->>GitHubAPI: list successful Desktop runs in prev_tag..HEAD
                GitHubAPI-->>ReleaseGate: successful SHAs
                alt recent successful SHA found
                    ReleaseGate->>ReleaseGate: accept recent success, pass gate
                else
                    ReleaseGate->>ReleaseGate: error (no suitable Desktop E2E)
                end
            end
        else Web E2E failure or timeout
            ReleaseGate->>ReleaseGate: error (Web E2E gate failed)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: implementing polling for E2E completion in the release gate workflow, which is the core objective addressed across modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/release-gate-wait-for-e2e

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

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/release-gate.yml (1)

55-69: Desktop E2E could face the same race condition.

The Desktop E2E check doesn't implement polling. If the Desktop workflow is still running when this check executes, DESKTOP_CONCLUSION will be empty (since conclusion is null for in-progress runs), and it will be treated as "no run for this commit (skipped)" rather than waiting for the result.

Per the comment "block only if it ran and failed," this appears intentional — Desktop E2E is an optional gate. However, if Desktop E2E is running and later fails, this gate would incorrectly pass.

If Desktop E2E should be a hard gate when it runs, consider adding similar polling logic. If the current "fail-fast only" behavior is intentional, a clarifying comment would help future maintainers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release-gate.yml around lines 55 - 69, The Desktop E2E
gate reads DESKTOP_CONCLUSION from gh run list and treats an in-progress run
(conclusion null) as "skipped", which can miss a later failure; update the block
that queries e2e-desktop.yml for MAIN_SHA (variable DESKTOP_CONCLUSION) to
implement the same polling/retry logic used elsewhere: loop/retry gh run list
until conclusion is non-empty or a timeout/attempts limit is reached, then fail
if DESKTOP_CONCLUSION != "success", otherwise report passed; alternatively, if
the current fail-only-if-already-finished behavior is intended, add a clarifying
comment above the DESKTOP_CONCLUSION logic documenting that in-progress runs are
considered “skipped” by design.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/release-gate.yml:
- Around line 55-69: The Desktop E2E gate reads DESKTOP_CONCLUSION from gh run
list and treats an in-progress run (conclusion null) as "skipped", which can
miss a later failure; update the block that queries e2e-desktop.yml for MAIN_SHA
(variable DESKTOP_CONCLUSION) to implement the same polling/retry logic used
elsewhere: loop/retry gh run list until conclusion is non-empty or a
timeout/attempts limit is reached, then fail if DESKTOP_CONCLUSION != "success",
otherwise report passed; alternatively, if the current
fail-only-if-already-finished behavior is intended, add a clarifying comment
above the DESKTOP_CONCLUSION logic documenting that in-progress runs are
considered “skipped” by design.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef90514 and 11f963e.

📒 Files selected for processing (1)
  • .github/workflows/release-gate.yml

FSM1 and others added 2 commits March 3, 2026 00:40
Instead of checking whether the latest main commit has a desktop E2E
run, diff changed files between the previous release tag and HEAD
against desktop-related path patterns (mirrored from e2e-desktop.yml).
Only require desktop E2E to pass when desktop code actually changed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 0a98db514e8d
- Remove `push` trigger from CI (already ran on PR)
- Desktop E2E triggers directly on push to main with change detection
  instead of chaining off CI via workflow_run
- Release gate detects desktop changes across the full release range
  (last tag..HEAD), not just the HEAD commit
- When desktop changes detected, finds any successful desktop E2E run
  within the release range (not necessarily at HEAD)
- If a desktop E2E run exists for HEAD, polls until it completes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 2b30c684b7fc

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/release-gate.yml (1)

169-170: Minor: Consider handling API pagination for large commit ranges.

The /compare endpoint returns up to 250 commits by default. If the release range spans more commits, some SHAs may be missing from RANGE_COMMITS, potentially causing a false negative when searching for a successful Desktop E2E run.

For very long release cycles, you may need to paginate or use git rev-list locally instead:

RANGE_COMMITS=$(git rev-list "${PREV_TAG}..${MAIN_SHA}")

This requires the repo to be checked out in this job (currently it's not).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release-gate.yml around lines 169 - 170, The RANGE_COMMITS
assignment uses gh api "repos/.../compare/${PREV_TAG}...${MAIN_SHA}" which can
return at most 250 commits and may miss SHAs; update the workflow to handle
large ranges by either (A) checking out the repo in this job (add
actions/checkout@v3) and replace the gh api call with a local git rev-list
"${PREV_TAG}..${MAIN_SHA}" to enumerate all SHAs, or (B) implement proper
pagination against the /compare endpoint (looping on gh api with page parameters
until no more commits) and aggregate commits into RANGE_COMMITS; ensure you
update the variable assignment that references RANGE_COMMITS accordingly and
keep the existing logic that searches for the Desktop E2E run unchanged.
.github/workflows/e2e-desktop.yml (1)

27-43: Consider extracting desktop path patterns to a shared location.

The desktop path patterns are duplicated between this file and release-gate.yml (lines 41-56). If these patterns diverge, the release gate could incorrectly skip or require Desktop E2E verification.

One option is to extract the patterns to a reusable composite action or a shared config file that both workflows reference, reducing maintenance burden and preventing drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/e2e-desktop.yml around lines 27 - 43, The desktop path
pattern list under the "filters: | desktop:" block is duplicated between this
workflow and release-gate.yml and should be centralized to avoid drift; extract
the path patterns into a single reusable source (either a composite action or a
shared YAML/JSON config that exports the array) and update both e2e-desktop.yml
and release-gate.yml to reference that single source instead of inline lists;
ensure the symbol you change is the "filters: | desktop:" block in both
workflows and verify the workflows still expand the same pattern set (and run
CI) after switching to the shared reference.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release-gate.yml:
- Line 78: The workflow's job timeout (timeout-minutes) is too low for the
combined Desktop E2E and Web E2E polling windows; update either the timeout or
the Desktop E2E polling constants so both checks can complete. Specifically,
either increase timeout-minutes from 20 to a value that accommodates Web E2E
plus Desktop E2E polling, or reduce Desktop E2E MAX_ATTEMPTS and/or
POLL_INTERVAL (the variables referenced in the Desktop E2E polling loop) so its
total wait time plus the Web E2E polling fits within the existing timeout;
ensure any change keeps both polling loops' total durations within the job
timeout to avoid premature job termination.

---

Nitpick comments:
In @.github/workflows/e2e-desktop.yml:
- Around line 27-43: The desktop path pattern list under the "filters: |
desktop:" block is duplicated between this workflow and release-gate.yml and
should be centralized to avoid drift; extract the path patterns into a single
reusable source (either a composite action or a shared YAML/JSON config that
exports the array) and update both e2e-desktop.yml and release-gate.yml to
reference that single source instead of inline lists; ensure the symbol you
change is the "filters: | desktop:" block in both workflows and verify the
workflows still expand the same pattern set (and run CI) after switching to the
shared reference.

In @.github/workflows/release-gate.yml:
- Around line 169-170: The RANGE_COMMITS assignment uses gh api
"repos/.../compare/${PREV_TAG}...${MAIN_SHA}" which can return at most 250
commits and may miss SHAs; update the workflow to handle large ranges by either
(A) checking out the repo in this job (add actions/checkout@v3) and replace the
gh api call with a local git rev-list "${PREV_TAG}..${MAIN_SHA}" to enumerate
all SHAs, or (B) implement proper pagination against the /compare endpoint
(looping on gh api with page parameters until no more commits) and aggregate
commits into RANGE_COMMITS; ensure you update the variable assignment that
references RANGE_COMMITS accordingly and keep the existing logic that searches
for the Desktop E2E run unchanged.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11f963e and eacdb8c.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • .github/workflows/e2e-desktop.yml
  • .github/workflows/release-gate.yml

Comment thread .github/workflows/release-gate.yml Outdated
Web E2E polls up to 15min + Desktop E2E polls up to 20min = 35min max.
The 20min job timeout was too low for both phases to complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 7f3f99d856db

Copilot AI 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.

Pull request overview

This PR updates GitHub Actions workflows to make the release gate more reliable by waiting for the main branch E2E workflows to finish (instead of failing when the run hasn’t appeared yet), and by adjusting when Desktop E2E and CI run.

Changes:

  • Add a “detect changes since last release” job and use it to conditionally enforce Desktop E2E in the release gate.
  • Poll for Web E2E completion (up to ~15 minutes) before checking conclusions, and add a job timeout safety net.
  • Change Desktop E2E to run on push to main (instead of workflow_run), and remove push-to-main CI runs (PR-only CI).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
.github/workflows/release-gate.yml Adds polling + desktop-change detection to avoid “no run found” race; gates Desktop E2E only when needed.
.github/workflows/e2e-desktop.yml Switches Desktop E2E trigger to push on main, aligning it with release-gate expectations.
.github/workflows/ci.yml Makes CI PR-only and simplifies conditional execution based on the paths-filter outputs.

Comment thread .github/workflows/release-gate.yml
Comment thread .github/workflows/release-gate.yml
Comment thread .github/workflows/release-gate.yml Outdated
Comment thread .github/workflows/release-gate.yml Outdated
- Use `// empty` in jq to prevent null conclusions from breaking
  poll loops (null is output as "null" string, not empty)
- Use `grep -Fq` for fixed-string matching in change detection
  (dots in patterns like `vite.config.` are regex wildcards)
- Find the most recent desktop E2E run in the release range and
  check its conclusion, rather than accepting any successful run
  (prevents stale success from masking a later failure)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: f1e3905e60a0

Copilot AI 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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Merge the separate cargo-check-{os} and cargo-test-{os} jobs into
unified cargo-{os} jobs that run check then test sequentially. This
eliminates duplicate runner provisioning, checkout, dependency
installation, and cache restore across 3 platforms — saving several
minutes of CI wall time per run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 584cc9d7ce70

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment thread .github/workflows/release-gate.yml
Comment thread .github/workflows/release-gate.yml
Comment thread .github/workflows/release-gate.yml
FSM1 and others added 2 commits March 3, 2026 01:22
- Short-circuit with clear error when no previous release tag exists
  and no Desktop E2E run is available for HEAD
- Filter fallback Desktop E2E query to only completed runs so
  in-progress runs with null conclusion don't cause false failures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: fa055bb71ff8

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/release-gate.yml:
- Around line 129-133: The gh run list invocation that sets HEAD_STATUS (the
command assigning HEAD_STATUS using --workflow=e2e-desktop.yml ... --limit=5)
uses too small a --limit, causing valid runs for MAIN_SHA to be missed during
high activity; update all gh run list calls that target the e2e-desktop workflow
(the HEAD_STATUS assignment and the analogous commands around lines referenced)
to use a much larger --limit (e.g., 50 or 100) consistently to ensure the query
window covers recent activity and avoid false "no run found" results.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eacdb8c and f9c17d9.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • .github/workflows/release-gate.yml

Comment thread .github/workflows/release-gate.yml
@codecov

codecov Bot commented Mar 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 46.31%. Comparing base (ef90514) to head (fa926d9).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #252   +/-   ##
=======================================
  Coverage   46.31%   46.31%           
=======================================
  Files         106      106           
  Lines        8266     8266           
  Branches      591      591           
=======================================
  Hits         3828     3828           
  Misses       4271     4271           
  Partials      167      167           
Flag Coverage Δ
api 83.86% <ø> (ø)
crypto 83.86% <ø> (ø)
desktop 25.45% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Bump --limit from 5/20 to 50 on gh run list queries for
e2e-desktop.yml to avoid missing valid runs during periods
of high workflow activity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 8e251b5e10a6

Copilot AI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread .github/workflows/e2e-desktop.yml
Comment thread .github/workflows/ci.yml
HEAD~1 only diffs the last commit, missing changes from earlier
commits in multi-commit pushes. github.event.before captures the
full push range correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 9519b3358eb6
@FSM1 FSM1 enabled auto-merge (squash) March 3, 2026 00:44
@FSM1 FSM1 merged commit 308619f into main Mar 3, 2026
15 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