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
6 changes: 6 additions & 0 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Constants for default and fallback values used throughout the adapter creation process
*/

/** The recommended Node.js version to use as a fallback when none is specified */
export const RECOMMENDED_NODE_VERSION_FALLBACK = "20";
14 changes: 12 additions & 2 deletions templates/_github/workflows/test-and-release.yml.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { TemplateFunction } from "../../../src/lib/createAdapter";
import { RECOMMENDED_NODE_VERSION_FALLBACK } from "../../../src/lib/constants";

const templateFunction: TemplateFunction = answers => {

Expand All @@ -14,8 +15,17 @@ const templateFunction: TemplateFunction = answers => {
const useReleaseScript = answers.releaseScript === "yes";
const isGitHub = answers.target === "github";

const ltsNodeVersion = "20.x";
const adapterTestVersions = ["20.x", "22.x", "24.x"];
// Determine the LTS version and test versions based on the minimum Node.js version selected
const minNodeVersion = answers.nodeVersion || RECOMMENDED_NODE_VERSION_FALLBACK;
const ltsNodeVersion = `${minNodeVersion}.x`;

// Filter test versions to only include versions >= the minimum version
const allTestVersions = ["20.x", "22.x", "24.x"];
const minVersionNumber = parseInt(minNodeVersion, 10);
const adapterTestVersions = allTestVersions.filter(version => {
const versionNumber = parseInt(version.split('.')[0], 10);
return versionNumber >= minVersionNumber;
});

const adapterTestOS = ["ubuntu-latest", "windows-latest", "macos-latest"];

Expand Down
3 changes: 2 additions & 1 deletion templates/package.json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { licenses } from "../src/lib/core/licenses";
import { getDefaultAnswer } from "../src/lib/core/questions";
import type { TemplateFunction } from "../src/lib/createAdapter";
import { fetchPackageReferenceVersion, getPackageName } from "../src/lib/packageVersions";
import { RECOMMENDED_NODE_VERSION_FALLBACK } from "../src/lib/constants";

const templateFunction: TemplateFunction = async answers => {

Expand All @@ -23,7 +24,7 @@ const templateFunction: TemplateFunction = async answers => {
const useNyc = answers.tools && answers.tools.indexOf("code coverage") > -1;
const useReleaseScript = answers.releaseScript === "yes";

const minNodeVersion = answers.nodeVersion ?? "20";
const minNodeVersion = answers.nodeVersion ?? RECOMMENDED_NODE_VERSION_FALLBACK;

const dependencyPromises = [
...(isAdapter ? ["@iobroker/adapter-core"] : [])
Expand Down
3 changes: 2 additions & 1 deletion templates/tsconfig.json.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { TemplateFunction } from "../src/lib/createAdapter";
import { RECOMMENDED_NODE_VERSION_FALLBACK } from "../src/lib/constants";

export = (answers => {

const useTypeScript = answers.language === "TypeScript";
const useTypeChecking = answers.tools && answers.tools.indexOf("type checking") > -1;
if (!useTypeScript && !useTypeChecking) return;

const minNodeVersion = answers.nodeVersion ?? "20";
const minNodeVersion = answers.nodeVersion ?? RECOMMENDED_NODE_VERSION_FALLBACK;

let include: string;
let exclude: string;
Expand Down
80 changes: 80 additions & 0 deletions test/create-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,5 +673,85 @@ describe("adapter creation =>", () => {
);
});
});

describe("GitHub Actions workflow Node.js version filtering", () => {
it("should only test supported Node.js versions", async () => {
const testCases = [
{
nodeVersion: "20",
expectedVersions: ["20.x", "22.x", "24.x"],
expectedLts: "20.x",
},
{
nodeVersion: "22",
expectedVersions: ["22.x", "24.x"],
expectedLts: "22.x",
},
{
nodeVersion: "24",
expectedVersions: ["24.x"],
expectedLts: "24.x",
},
];

for (const testCase of testCases) {
const answers: Answers = {
...baseAnswers,
nodeVersion: testCase.nodeVersion as "20" | "22" | "24",
target: "github",
releaseScript: "yes",
};

const files = await createAdapter(answers);
const workflowFile = files.find((f) =>
f.name.endsWith("test-and-release.yml"),
);

if (!workflowFile) {
throw new Error(
`Workflow file not found for Node.js ${testCase.nodeVersion}`,
);
}

const content = workflowFile.content;

// Check that the matrix includes only the expected versions
const matrixMatch = content.match(
/node-version: \[(.*?)\]/,
);
if (!matrixMatch) {
throw new Error(
`Matrix node versions not found for Node.js ${testCase.nodeVersion}`,
);
}

const actualVersions = matrixMatch[1]
.split(", ")
.map((v) => v.trim());
actualVersions.should.deep.equal(
testCase.expectedVersions,
`For Node.js ${testCase.nodeVersion}, expected versions ${testCase.expectedVersions.join(", ")} but got ${actualVersions.join(", ")}`,
);

// Check that the LTS version is correct
const ltsMatches =
content.match(/node-version: '(\d+\.x)'/g) || [];
if (ltsMatches.length === 0) {
throw new Error(
`LTS node version not found for Node.js ${testCase.nodeVersion}`,
);
}

// All LTS references should use the expected version
for (const ltsMatch of ltsMatches) {
const ltsVersion = ltsMatch.match(/'(\d+\.x)'/)?.[1];
ltsVersion.should.equal(
testCase.expectedLts,
`For Node.js ${testCase.nodeVersion}, expected LTS ${testCase.expectedLts} but got ${ltsVersion}`,
);
}
}
});
});
});
});