feat: pin the official plugins in the docker image

This commit is contained in:
LukeGus committed 2026-10-05 21:46:16 -05:00
1 parent 853615af09
commit 88d7bc5525
6 files changed
+329 -3

No files matched your search

+57
View File
@@ -9,6 +9,7 @@ import {
loadBundledPlugins,
fetchArtifact,
extractArtifact,
pinsFromIndex,
} from "./lib/bundled-plugins.cjs";
const cleanups: Array<() => void> = [];
@@ -135,3 +136,59 @@ describe("tmxplug entries", () => {
).rejects.toThrow(/is for "other"/);
});
});
describe("pinsFromIndex", () => {
const index = {
plugins: [
{
id: "beta",
versions: [
{
version: "1.1.0",
url: "https://example.test/beta-1.1.0.tmxplug",
sha256: "b".repeat(64),
},
{
version: "1.0.0",
url: "https://example.test/beta-1.0.0.tmxplug",
sha256: SHA,
},
],
},
{
id: "alpha",
versions: [
{
version: "1.0.0",
url: "https://example.test/alpha-1.0.0.tmxplug",
sha256: "c".repeat(64),
},
],
},
],
};
it("pins the newest version of every plugin, sorted by id", () => {
const pins = pinsFromIndex(index, null);
expect(pins.map((pin) => pin.id)).toEqual(["alpha", "beta"]);
expect(pins[1]).toEqual({
id: "beta",
source: "tmxplug",
url: "https://example.test/beta-1.1.0.tmxplug",
sha256: "b".repeat(64),
});
expect(parseBundledPlugins({ plugins: pins }).problems).toEqual([]);
});
it("pins only the ids asked for", () => {
expect(pinsFromIndex(index, ["beta"]).map((pin) => pin.id)).toEqual([
"beta",
]);
});
it("refuses an id the index does not list", () => {
expect(() => pinsFromIndex(index, ["gamma"])).toThrow(
/not in the registry/,
);
});
});
+21
View File
@@ -152,8 +152,29 @@ async function extractArtifact(buffer, outDir, id) {
}
}
/**
* Pins the newest registry version of each wanted plugin. `ids` is the list
* to pin, or null for every plugin in the index.
*/
function pinsFromIndex(index, ids) {
const plugins = Array.isArray(index?.plugins) ? index.plugins : [];
const byId = new Map(plugins.map((plugin) => [plugin.id, plugin]));
const wanted = ids ?? plugins.map((plugin) => plugin.id);
return [...wanted].sort().map((id) => {
const latest = byId.get(id)?.versions?.[0];
if (!latest) throw new Error(`${id} is not in the registry index`);
return {
id,
source: "tmxplug",
url: latest.url,
sha256: latest.sha256,
};
});
}
module.exports = {
parseBundledPlugins,
pinsFromIndex,
loadBundledPlugins,
checkSha256,
fetchArtifact,
+42
View File
@@ -0,0 +1,42 @@
/**
* Points docker/bundled-plugins.json at the newest version of each plugin in
* the official registry index. Run it again after a plugin is released or
* re-released.
*
* node scripts/pin-bundled-plugins.cjs refresh the plugins already listed
* node scripts/pin-bundled-plugins.cjs --all list every plugin in the index
*/
const fs = require("node:fs");
const path = require("node:path");
const {
loadBundledPlugins,
pinsFromIndex,
} = require("./lib/bundled-plugins.cjs");
const INDEX_URL =
"https://raw.githubusercontent.com/Termix-SSH/Termix-Registry/main/official/index.json";
const root = path.resolve(__dirname, "..");
const configPath = path.join(root, "docker", "bundled-plugins.json");
async function main() {
const all = process.argv.includes("--all");
const response = await fetch(INDEX_URL);
if (!response.ok) {
throw new Error(`registry index download failed with ${response.status}`);
}
const index = await response.json();
const ids = all ? null : loadBundledPlugins(root).map((plugin) => plugin.id);
const plugins = pinsFromIndex(index, ids);
fs.writeFileSync(configPath, `${JSON.stringify({ plugins }, null, 2)}\n`);
console.log(
`Pinned ${plugins.length} plugin(s) in docker/bundled-plugins.json`,
);
}
main().catch((error) => {
console.error(error?.message ?? error);
process.exit(1);
});