mirror of
https://github.com/Koenkk/zigbee-OTA.git
synced 2026-06-24 10:58:33 +00:00
Add metadata checks for Tuya and Gledopto (#867)
This commit is contained in:
@@ -19,6 +19,10 @@ import {
|
||||
} from "./common.js";
|
||||
import type {ExtraMetas, GHExtraMetas, RepoImageMeta} from "./types.js";
|
||||
|
||||
const GLEDOPTO_MANUFACTURER_CODE = 4687;
|
||||
const TUYA_MANUFACTURER_CODE_1 = 4098;
|
||||
const TUYA_MANUFACTURER_CODE_2 = 4417;
|
||||
|
||||
const EXTRA_METAS_PR_BODY_START_TAG = "```json";
|
||||
const EXTRA_METAS_PR_BODY_END_TAG = "```";
|
||||
|
||||
@@ -26,7 +30,6 @@ function getFileExtraMetas(extraMetas: GHExtraMetas, fileName: string): ExtraMet
|
||||
if (Array.isArray(extraMetas)) {
|
||||
const fileExtraMetas = extraMetas.find((m) => m.fileName === fileName) ?? {};
|
||||
/** @see getValidMetas */
|
||||
// biome-ignore lint/performance/noDelete: <explanation>
|
||||
delete fileExtraMetas.fileName;
|
||||
|
||||
return fileExtraMetas;
|
||||
@@ -36,7 +39,7 @@ function getFileExtraMetas(extraMetas: GHExtraMetas, fileName: string): ExtraMet
|
||||
return extraMetas;
|
||||
}
|
||||
|
||||
async function getPRBody(github: Octokit, core: typeof CoreApi, context: Context): Promise<string | undefined> {
|
||||
async function getPRBody(github: Octokit, _core: typeof CoreApi, context: Context): Promise<string | undefined> {
|
||||
assert(context.payload.pull_request || context.eventName === "push");
|
||||
|
||||
if (context.payload.pull_request) {
|
||||
@@ -119,7 +122,7 @@ export async function processOtaFiles(
|
||||
core.startGroup(filePath);
|
||||
|
||||
const logPrefix = `[${filePath}]`;
|
||||
let failureComment = "";
|
||||
let failureComment: string | undefined;
|
||||
|
||||
try {
|
||||
const firmwareFileName = path.basename(filePath);
|
||||
@@ -145,6 +148,20 @@ export async function processOtaFiles(
|
||||
const [baseMatchIndex, baseMatch] = findMatchImage(parsedImage, baseManifest, fileExtraMetas);
|
||||
const statusToBase = getParsedImageStatus(parsedImage, baseMatch);
|
||||
|
||||
// Manufacturer specific checks
|
||||
if (parsedImage.manufacturerCode === GLEDOPTO_MANUFACTURER_CODE && !fileExtraMetas.modelId) {
|
||||
// Gledopto uses the same imageType for every device, force modelId to be present.
|
||||
// https://github.com/Koenkk/zigbee-OTA/pull/864
|
||||
throw new Error("Gledopto image requires extra `modelId` metadata");
|
||||
}
|
||||
if (
|
||||
(TUYA_MANUFACTURER_CODE_1 === parsedImage.manufacturerCode || TUYA_MANUFACTURER_CODE_2 === parsedImage.manufacturerCode) &&
|
||||
!fileExtraMetas.manufacturerName
|
||||
) {
|
||||
// Tuya uses the same imageType for every device, force manufacturerName to be present.
|
||||
throw new Error("Tuya image requires extra `manufacturerName` metadata");
|
||||
}
|
||||
|
||||
switch (statusToBase) {
|
||||
case ParsedImageStatus.Older: {
|
||||
// if prev doesn't have a match, move to prev
|
||||
|
||||
@@ -11,6 +11,8 @@ import {it} from "vitest";
|
||||
import * as common from "../src/common";
|
||||
import type {ExtraMetas, RepoImageMeta} from "../src/types";
|
||||
|
||||
export const IMAGE_GLEDOPTO = "GL-B-008P_V17A1_OTAV7.ota";
|
||||
export const IMAGE_TUYA = "1662693814-oem_mg21_zg_nh_win_cover_relay_OTA_1.0.7.bin";
|
||||
export const IMAGE_V14_1 = "ZLinky_router_v14.ota";
|
||||
export const IMAGE_V14_2 = "ZLinky_router_v14_limited.ota";
|
||||
export const IMAGE_V13_1 = "ZLinky_router_v13.ota";
|
||||
|
||||
@@ -10,7 +10,9 @@ import type {RepoImageMeta} from "../src/types";
|
||||
import {
|
||||
BASE_IMAGES_TEST_DIR_PATH,
|
||||
getAdjustedContent,
|
||||
IMAGE_GLEDOPTO,
|
||||
IMAGE_INVALID,
|
||||
IMAGE_TUYA,
|
||||
IMAGE_V12_1,
|
||||
IMAGE_V12_1_METAS,
|
||||
IMAGE_V13_1,
|
||||
@@ -626,4 +628,28 @@ Text after end tag`);
|
||||
]);
|
||||
expect(writeManifestSpy).toHaveBeenCalledWith(common.PREV_INDEX_MANIFEST_FILENAME, [IMAGE_V12_1_METAS]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
['"manufacturerName": ["_TZ3000"]', IMAGE_TUYA, undefined],
|
||||
["", IMAGE_TUYA, "Tuya image requires extra `manufacturerName` metadata"],
|
||||
['"modelId": "GL-C-008"', IMAGE_GLEDOPTO, undefined],
|
||||
["", IMAGE_GLEDOPTO, "Gledopto image requires extra `modelId` metadata"],
|
||||
])("manufacturer specific checks", async (body: string, image: string, error: string | undefined) => {
|
||||
filePaths = [useImage(image)];
|
||||
const newContext = withBody(`\`\`\`json
|
||||
{
|
||||
${body}
|
||||
}
|
||||
\`\`\``);
|
||||
|
||||
if (error === undefined) {
|
||||
// @ts-expect-error mock
|
||||
await checkOtaPR(github, core, newContext);
|
||||
} else {
|
||||
await expect(async () => {
|
||||
// @ts-expect-error mock
|
||||
await checkOtaPR(github, core, newContext);
|
||||
}).rejects.toThrow(expect.objectContaining({message: expect.stringContaining(error)}));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
BIN
tests/images/1662693814-oem_mg21_zg_nh_win_cover_relay_OTA_1.0.7.bin
Executable file
BIN
tests/images/1662693814-oem_mg21_zg_nh_win_cover_relay_OTA_1.0.7.bin
Executable file
Binary file not shown.
BIN
tests/images/GL-B-008P_V17A1_OTAV7.ota
Normal file
BIN
tests/images/GL-B-008P_V17A1_OTAV7.ota
Normal file
Binary file not shown.
Reference in New Issue
Block a user