Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/releases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,10 @@ function dbReleaseToMetadata(release: DbRelease, sku: string): ReleaseMetadata {
}

/**
* Newest fully rolled out release for the prefix, or null when no release
* has reached 100% yet (a prefix whose first release is still staged).
* Newest fully rolled out release that ships a binary for the SKU, or null
* when there is none: the prefix's first release is still staged, or the SKU
* is new and its first build has not reached 100% yet. The caller decides
* whether the device is in the staged release's bucket before it needs this.
*/
async function getDefaultRelease(prefix: string, sku: string): Promise<DbRelease | null> {
const rolledOutReleases = await prisma.release.findMany({
Expand All @@ -447,9 +449,7 @@ async function getDefaultRelease(prefix: string, sku: string): Promise<DbRelease
const compatibleReleases = rolledOutReleases.filter(r => r.artifacts.length > 0);

if (compatibleReleases.length === 0) {
throw new NotFoundError(
`No default ${prefix} release available for SKU "${sku}"`,
);
return null;
}

const latestVersion = semver.maxSatisfying(
Expand Down
15 changes: 15 additions & 0 deletions test/releases.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,21 @@ describe("Retrieve handler", () => {
Retrieve(createMockRequest({ deviceId: "late-adopter" }), createMockResponse()),
).rejects.toThrow(/No (app|system) release is rolled out yet for SKU "jetkvm-v2"/);
});

it("serves the first staged release for a new SKU when no 100% release ships it", async () => {
// The seeded 100% releases carry jetkvm-v2 only. The first SDMMC build
// is staged at 50%: early-adopter (bucket 8) is in, late-adopter (95) out.
await createDbRelease("app", "1.3.0", 50, [releaseArtifact("app", "1.3.0", SDMMC_SKU)]);
await createDbRelease("system", "1.3.0", 50, [releaseArtifact("system", "1.3.0", SDMMC_SKU)]);

const inBucket = createMockResponse();
await Retrieve(createMockRequest({ deviceId: "early-adopter", sku: SDMMC_SKU }), inBucket);
expect(jsonBody(inBucket)).toMatchObject({ appVersion: "1.3.0", systemVersion: "1.3.0" });

await expect(
Retrieve(createMockRequest({ deviceId: "late-adopter", sku: SDMMC_SKU }), createMockResponse()),
).rejects.toThrow(/No (app|system) release is rolled out yet for SKU "jetkvm-v2-sdmmc"/);
});
});

describe("signature URL handling", () => {
Expand Down
Loading