mirror of
https://github.com/jetkvm/cloud-api.git
synced 2026-05-21 05:20:36 +00:00
fix: keep default release when latest has no compatible SKU artifact
After the getDefaultRelease SKU-compat fix, the default path was graceful but the rollout-upgrade path stayed strict: if a device was in the rollout bucket and the latest release lacked a compatible artifact for the requested SKU, dbReleaseToMetadata still threw and 404'd the whole request — even though responseJson already held a valid default. Short-circuit the upgrade when the latest release has no compatible artifact and update the regression test to assert the default is kept instead of asserting the throw.
This commit is contained in:
+9
-5
@@ -617,26 +617,30 @@ export async function Retrieve(req: Request, res: Response) {
|
||||
|
||||
// Background update checks follow rollout percentages so new releases roll
|
||||
// out gradually. Devices outside the bucket fall back to the default (the
|
||||
// newest 100%-rolled-out release).
|
||||
// newest 100%-rolled-out release). If the latest release lacks a compatible
|
||||
// artifact for this SKU (e.g. a SKU-specific build hasn't shipped yet) we
|
||||
// silently keep the default rather than 404 the whole request.
|
||||
const responseJson = toRelease(
|
||||
dbReleaseToMetadata(defaultAppRelease, query.sku),
|
||||
dbReleaseToMetadata(defaultSystemRelease, query.sku),
|
||||
);
|
||||
|
||||
if (
|
||||
await isDeviceEligibleForLatestRelease(
|
||||
latestAppRelease.artifacts.length > 0 &&
|
||||
(await isDeviceEligibleForLatestRelease(
|
||||
latestAppRelease.rolloutPercentage,
|
||||
query.deviceId,
|
||||
)
|
||||
))
|
||||
) {
|
||||
setAppRelease(responseJson, dbReleaseToMetadata(latestAppRelease, query.sku));
|
||||
}
|
||||
|
||||
if (
|
||||
await isDeviceEligibleForLatestRelease(
|
||||
latestSystemRelease.artifacts.length > 0 &&
|
||||
(await isDeviceEligibleForLatestRelease(
|
||||
latestSystemRelease.rolloutPercentage,
|
||||
query.deviceId,
|
||||
)
|
||||
))
|
||||
) {
|
||||
setSystemRelease(responseJson, dbReleaseToMetadata(latestSystemRelease, query.sku));
|
||||
}
|
||||
|
||||
+20
-11
@@ -489,7 +489,7 @@ describe("Retrieve handler", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("does not fall back when the latest release lacks a compatible artifact", async () => {
|
||||
it("keeps the default when the latest release lacks a compatible artifact for an in-bucket device", async () => {
|
||||
await createDbRelease("app", "3.3.0", 100, [
|
||||
{
|
||||
...releaseArtifact("app", "3.3.0", DEFAULT_SKU),
|
||||
@@ -506,19 +506,28 @@ describe("Retrieve handler", () => {
|
||||
releaseArtifact("system", "3.3.0", DEFAULT_SKU, "system-default-hash"),
|
||||
releaseArtifact("system", "3.3.0", SDMMC_SKU, "system-sdmmc-hash"),
|
||||
]);
|
||||
// system 3.3.1 ships only with the default-SKU artifact — no sdmmc binary.
|
||||
await createDbRelease("system", "3.3.1", 100);
|
||||
|
||||
await expect(
|
||||
Retrieve(
|
||||
createMockRequest({
|
||||
deviceId: "sdmmc-compatible-fallback-device",
|
||||
sku: SDMMC_SKU,
|
||||
}),
|
||||
createMockResponse(),
|
||||
),
|
||||
).rejects.toThrow(
|
||||
'Version 3.3.1 predates SKU support and cannot serve SKU "jetkvm-v2-sdmmc"',
|
||||
// Every device is in-bucket at 100% rollout, so this exercises the
|
||||
// upgrade path. The request must keep the default 3.3.0 system release
|
||||
// rather than 404 because 3.3.1 has no sdmmc binary.
|
||||
const res = createMockResponse();
|
||||
await Retrieve(
|
||||
createMockRequest({
|
||||
deviceId: "sdmmc-compatible-fallback-device",
|
||||
sku: SDMMC_SKU,
|
||||
}),
|
||||
res,
|
||||
);
|
||||
|
||||
expect(jsonBody(res)).toMatchObject({
|
||||
appVersion: "3.3.1",
|
||||
appUrl: artifactUrl("app", "3.3.1"),
|
||||
systemVersion: "3.3.0",
|
||||
systemUrl: artifactUrl("system", "3.3.0", SDMMC_SKU),
|
||||
systemHash: "system-sdmmc-hash",
|
||||
});
|
||||
});
|
||||
|
||||
it("does not discover or create stable releases from S3", async () => {
|
||||
|
||||
Reference in New Issue
Block a user