Skip to content

Run CI in parallel lanes and gate desktop releases on the upgrade test - #219

Merged
SunkenInTime merged 4 commits into
icarus-cloudfrom
ci-parallel-lanes
Sep 28, 2026
Merged

SunkenInTime merged 4 commits into
icarus-cloudfrom
ci-parallel-lanes

Conversation

@SunkenInTime

@SunkenInTime SunkenInTime commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Problem
A CI run took about 27 minutes to go green on every PR, whatever it changed. Agents wait on it between loops, so it sets the pace of all our work.

On the latest icarus-cloud run, the Windows validate job ran every step one after another:

  • Windows build: 9.0 min
  • flutter test: 5.2 min
  • Rust bridge tests: 3.3 min
  • installer, then upgrade and rollback test: about 2 min
  • everything else: about 4 min

The Linux job (13 min) ran in parallel but repeated analyze, codegen, the full test suite, and the Rust tests. Nothing cancelled a run once a newer push made it pointless: we had 140 runs in the last 7 days.

Separately, the upgrade/rollback test only ever ran in CI, against an unsigned build of a PR. release-desktop.yml never ran it, so the installer players actually download was never checked.

What changes in CI

  • Always on, in parallel on Linux: analyze (plus the web binding and wall height checks), test split into 2 shards, and web (the beta's build flags).

  • Lanes picked from the files a PR changes (a changes job reads gh pr diff --name-only):

    Lane Runs when a PR changes
    convex: tsc, Convex tests, contract preview convex/, root npm/tsconfig/vitest files
    presence-worker presence/
    client-contract: gauntlet, codegen, drift convex/, tool/, lib/collab/
    native-bridge: cargo tests third_party/
    windows-build, windows-test, linux-build lib/migrations/, *.g.dart, installer/, scripts/, the library probe test
  • Every lane runs for manual runs, PRs into main, PRs that change .github/, and PRs whose file list can't be read.

  • Pushes to main/icarus-cloud run every lane except the desktop ones. The release covers those, below.

  • A newer push to a PR cancels its older run.

  • The Windows work is two parallel jobs: windows-build (build, installer, upgrade/rollback) and windows-test (the suite on Windows).

  • Rust dependencies are cached. The desktop builds cache cargokit's compiled Rust dependencies with Swatinem/rust-cache.

  • One shared setup action. The Flutter setup that was copied into each job is now .github/actions/setup-flutter. Its setup-dart problem matcher is off, because it can't find its file inside a composite action.

What changes in the release

  • release-desktop.yml runs Test Public Upgrade And Rollback on the signed installer, after "Verify Authenticode Signatures" and before "Stage Desktop Release".
  • The test installs 3.2.3 and imports a historical .ica, then upgrades to the release and rolls back, checking the library at each step. If it fails, nothing is staged or published.
  • It adds about 2 minutes to a release.

What we give up

  • A PR that changes native code (windows/, linux/, third_party/), pubspec, or lib/main.dart no longer builds the desktop app before merge. A break there first shows up at release, and the release stops before publishing.
  • Dart-only PRs no longer run the suite on Windows. Only one test checks the platform (hive_store_launch_test.dart).

Measured on this PR (CI changes run every lane, first run with a cold Rust cache):

Before After
Dart-only PR (analyze, 2 test shards, web) ~27 min 3m48s
Server PR (+ convex, client-contract) ~27 min ~3m50s (convex 1m13s, client-contract 2m24s)
Every lane ~27 min 13m38s (windows-build: 8.7 min build + 2.2 min upgrade test)

Verification

🤖 Generated with Claude Code

RetriggerConfidence Score: 4/5

Not safe to merge until fork PRs can check contract-script changes without the repository preview key.

Findings

  1. P1 Fork contract checks fail ▶

Summary

The PR splits CI into file-selected checks and adds an upgrade-and-rollback gate before desktop releases are staged. The latest selector change makes fork PRs that edit either Convex contract script fail the Convex check before the scripts run.

Reviews (2) · Last reviewed commit: "Run the Convex lane when its contract sc..."

CI took about 27 minutes because one Windows job ran every step in order,
and the Linux job repeated analyze, tests, and the Rust tests. Now analyze,
two test shards, and the web build run on Linux for every change, in
parallel. The Convex, presence, client-contract, Rust bridge, and desktop
build lanes run only when a PR touches their files. Pushes, PRs into main,
and PRs that change CI still run every lane. A newer push to a PR cancels
its older run, and the desktop builds cache cargokit's compiled Rust
dependencies.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: ad053edf-f45d-4b2d-bffe-bcd832558004

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

It registers a matcher file relative to the calling action's folder, which
does not exist in a composite action, and failed every Flutter job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
The upgrade and rollback test only ran in CI, against an unsigned build of a
PR. The release itself never ran it, so the installer players download was
never checked. It now runs in the release on the signed installer, after the
signatures are verified and before anything is staged or published.

With the release as the gate, CI builds the desktop app and runs the test
only for PRs that touch Hive (migrations, generated adapters), the installer,
the release scripts, or the test itself, and no longer after every merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SunkenInTime SunkenInTime changed the title Run CI in parallel lanes picked from the files a PR changes Run CI in parallel lanes and gate desktop releases on the upgrade test Sep 28, 2026
Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
@greptile-apps

greptile-apps Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Comments Outside Diff

These findings sit on lines the diff does not cover, so they could not be posted inline. Each one leaves this list once its file changes.

  • P1 Contract-script-only fork PRs fail the Convex key guard ▶

    • Bug
      • A fork pull_request into icarus-cloud changing only tool/snapshot_convex_contract.mjs or tool/audit_convex_contract.mjs now selects the Convex job. Fork PRs cannot receive the repository preview deploy key, so the job fails before running the contract scripts, regardless of their validity.
    • Cause
      • .github/workflows/ci.yml line 80 added those files to the Convex lane selector, while that lane requires CONVEX_PREVIEW_DEPLOY_KEY without a fork-safe path.
    • Fix
      • Provide a fork-safe validation path for these changes that does not require the preview key; retain secret-dependent preview deployment only for trusted runs.

The snapshot and audit scripts in tool/ run only in the Convex lane, against
its fresh preview, so a PR changing just those scripts skipped the checks
they define.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SunkenInTime

Copy link
Copy Markdown
Owner Author

Fixed the contract-script gap in 93ae5c0 and replied on the other three threads: they describe trade-offs the maintainer chose when the upgrade/rollback test moved into the release. @greptileai

Comment thread .github/workflows/ci.yml
fi
}
# The contract scripts in tool/ run in this lane, against its preview.
lane convex '^(convex/|package(-lock)?\.json$|tsconfig\.json$|vitest\.config|tool/(snapshot|audit)_convex_contract\.mjs$)'

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.

P1 Fork contract checks fail

If a fork PR targeting icarus-cloud changes only tool/snapshot_convex_contract.mjs or tool/audit_convex_contract.mjs, this selector starts the Convex job. Fork PRs cannot access CONVEX_PREVIEW_DEPLOY_KEY, so the job fails at its key check before running either script, even when the changes are correct. Provide a fork-safe way to check these edits.

Artifacts

Authored fork PR workflow replay

  • The Python harness extracts and executes the workflow’s selector and key guard using a synthetic file listing and empty fork-secret context, without accessing secrets.

Previous workflow skips the Convex lane

  • Running the replay against d217bcf with a snapshot-script-only fork PR selected the contract lane but not Convex.

Current workflow fails the preview-key guard

  • Running the same replay against HEAD selected Convex and produced exit code 1 from its key guard before contract comparison.

Routing diff and audit-script fork replay

  • The executed diff shows the line 80 addition, and the audit-script-only replay shows the same key-guard failure.

View artifacts

T-Rex Ran code and verified through T-Rex

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Pre-existing, and narrower after this PR: before it, the contract job ran on every PR, so every fork PR failed at the same key check. Now only fork PRs touching Convex or these two scripts reach it. Fork PRs are rare here (1 in the last 100), and a maintainer re-running the checks from a branch covers them, so a fork-safe path stays out of scope.

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.

The narrowing is a real improvement, and I agree fork PRs are uncommon. However, a maintainer re-run does not cover this case: GitHub re-runs a pull_request workflow with the privileges of the original fork-triggered run, so repository secrets remain unavailable. The Convex job will still stop at Require Convex preview deploy key before either contract script runs.

That makes this a deliberate CI policy trade-off rather than a covered path: affected fork PRs cannot get a passing required check unless the change is tested from a trusted branch or the workflow is redesigned with a fork-safe contract-check path. If fork PRs are explicitly out of scope, I’m fine treating this as accepted risk; the original concern remains technically valid.

@SunkenInTime
SunkenInTime merged commit 7a8c1cf into icarus-cloud Sep 28, 2026
14 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.

1 participant