Skip to content

Add SKU-aware OTA release artifacts#56

Merged
adamshiervani merged 6 commits intodevfrom
fix/ota-release-artifact-sync
Apr 27, 2026
Merged

Add SKU-aware OTA release artifacts#56
adamshiervani merged 6 commits intodevfrom
fix/ota-release-artifact-sync

Conversation

@adamshiervani
Copy link
Copy Markdown
Contributor

@adamshiervani adamshiervani commented Apr 27, 2026

Summary

  • Add ReleaseArtifact persistence with migration backfill so release rollout remains on Release while URL/hash artifacts are selected by compatible SKU.
  • Move stable /releases and stable pinned/version-constrained responses to DB-backed artifact selection; prerelease and recovery/latest redirects continue using S3 where intended.
  • Add an S3-to-DB sync script and a local-vs-production compare script with accepted deviation logging for stable dev/prerelease constraints.

Test plan

  • npm exec prisma generate
  • npm test -- test/releases.test.ts
  • npm run build

Note

High Risk
High risk because it introduces a new ReleaseArtifact table with backfill and rewires stable /releases selection logic (including rollout/default behavior) to be DB-driven and SKU-filtered, which directly affects OTA update delivery. Sync tooling also now controls what stable releases appear in the DB, so data correctness and migration/sync runs are critical.

Overview
Adds SKU-aware release artifacts. Introduces a new Prisma ReleaseArtifact model/table linked to Release, backfilled from existing Release rows and marking legacy artifacts as compatible only with jetkvm-v2.

Changes stable OTA resolution to be DB-backed and SKU-filtered. Stable /releases requests now select URL/hash from ReleaseArtifact rows compatible with the requested sku, apply rollout/default logic using DB data only, and compute optional .sig URLs by probing S3 based on the chosen artifact URLs; prerelease /releases continues to resolve from S3.

Adds operational tooling and updates tests. Adds scripts/sync-releases.ts (and npm run sync-releases) to import stable releases/artifacts from S3 into the DB without mutating existing rows, plus scripts/compare-releases.sh to diff local vs prod release endpoints; tests/seeding are updated to create ReleaseArtifact records and validate the new DB-backed contract, and Vitest parallelism is disabled.

Reviewed by Cursor Bugbot for commit f7775a0. Bugbot is set up for automated code reviews on this repo. Configure here.

Persist OTA artifact URL/hash data separately from rollout state so stable release responses can choose artifacts by compatible SKU while release rollout remains version/type based.
Comment thread src/releases.ts
Ensure stable release selection only considers releases with artifacts compatible with the requested SKU, and tighten tests around the DB-backed OTA contract.
Comment thread test/setup.ts
compatibleSkus: artifactData.compatibleSkus,
},
create: artifactData,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Exported setRollout helper is now unused dead code

Low Severity

The setRollout function was modified in this PR to add ReleaseArtifact creation logic, but its only consumer (releases.test.ts) removed the import in this same commit. A grep for setRollout across the test directory confirms the sole match is the definition in setup.ts. The newly added artifact-upsert code inside it is unreachable dead code.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9cd63a1. Configure here.

@adamshiervani adamshiervani marked this pull request as ready for review April 27, 2026 15:51
Only expose stable signature URLs that actually exist and preserve production's version-first SKU error behavior.
@adamshiervani adamshiervani marked this pull request as draft April 27, 2026 15:51
@adamshiervani adamshiervani marked this pull request as ready for review April 27, 2026 15:57
Pre-SKU artifacts (no skus/ folder) are jetkvm-v2 only. Marking them
compatible with jetkvm-v2-sdmmc would brick devices that received
firmware predating their hardware. Future SKUs must opt in via an
explicit skus/<sku>/ upload.

sync-releases now skips releases already in the DB instead of upserting
them. This prevents routine sync runs from rewriting Release.url/hash
or appending duplicate ReleaseArtifact rows if R2_CDN_URL ever changes.
Backfills and repairs are left to one-off scripts.
The flag is no longer sent by any client. Routine update checks now
always go through the rollout-aware default-and-latest path, which is
what forceUpdate effectively short-circuited to. Removes one query
parameter, one branch in the handler, and the corresponding axis from
the compare-releases sweep.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 57ec20b. Configure here.

Comment thread src/releases.ts
Comment thread src/releases.ts Outdated
getDefaultRelease previously picked the newest 100%-rolled-out release
without checking SKU compatibility. If that release lacked a compatible
artifact, the request 404'd downstream even though older 100%-rolled-out
releases had valid binaries for the SKU. It now filters to releases that
actually ship a compatible artifact before selecting the latest, falling
back to a 404 only when no compatible default exists.

The four DB lookups in the stable rollout-aware path are independent; run
them concurrently so background-check latency drops from ~4 round trips
to ~1.
@adamshiervani adamshiervani merged commit b24a057 into dev Apr 27, 2026
3 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