Releases: a new SKU's first staged release reaches in-bucket devices - #88
Conversation
getDefaultRelease threw when 100% releases existed for the prefix but none shipped a binary for the SKU. Retrieve awaits that fallback before it checks whether the device is in the staged release's bucket, so the first staged release for a new SKU on a shared prefix answered 404 to every device of that SKU. It now returns null, like a prefix with no 100% release at all, and the caller's bucket check decides.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The focused behavior change is consistent with existing rollout handling and has appropriate regression coverage.
Review effort: Balanced
Findings: None
What changed in this PR
Allows in-bucket devices of a new SKU to receive their first staged OTA release when no fully rolled-out compatible release exists.
Changes:
- Returns
nullinstead of prematurely throwing for a missing SKU-compatible fallback. - Adds regression coverage for in-bucket and out-of-bucket devices.
| File | Description |
|---|---|
src/releases.ts |
Defers missing-fallback handling until rollout eligibility is evaluated. |
test/releases.test.ts |
Tests staged releases for a newly introduced SKU. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The first staged release for a new SKU on a shared prefix returned 404 to every device of that SKU, in and out of the bucket. Found by Codex on #87; the code has been on
mainsince #79. It cannot trigger in production today, since every SKU already has a 100% release on its prefix, but it would on the next new SKU.Retrieve(deviceId, sku) latest = getLatestRelease(prefix, sku) fallback = getDefaultRelease(prefix, sku) 100% releases for prefix, filtered to ones with an artifact for sku none at 100% → null - none for this sku → throw 404 # before the bucket check ran + none for this sku → null in bucket and latest has an artifact → latest else fallback, or 404 "not rolled out yet"Note
Medium Risk
Changes stable OTA selection for new SKUs without a 100% artifact; behavior is narrow but affects firmware delivery for future hardware variants.
Overview
Fixes OTA Retrieve so a new SKU whose first builds exist only on a staged release (no 100% artifact for that SKU yet) can still get updates when the device is in the rollout bucket.
getDefaultReleaseno longer throws when the prefix has 100% releases but none include a binary for the requested SKU; it returnsnulllike the “nothing at 100%” case.Retrievecan then choose the latest DB release (including partial rollouts) for in-bucket devices instead of failing early with a misleading 404.Out-of-bucket devices still get 404 with “not rolled out yet” when there is no fallback. A regression test covers SDMMC’s first 1.3.0 @ 50% build vs default jetkvm-v2-only 100% releases.
Reviewed by Cursor Bugbot for commit 55e18c9. Bugbot is set up for automated code reviews on this repo. Configure here.