📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const crypto = require("crypto");
|
||||
const fs = require("fs");
|
||||
const https = require("https");
|
||||
const path = require("path");
|
||||
const { spawnSync } = require("child_process");
|
||||
|
||||
const { findProjectRoot } = require("../lib/project-root");
|
||||
|
||||
function platformKey(platform = process.platform, arch = process.arch) {
|
||||
const osName = { darwin: "darwin", linux: "linux" }[platform];
|
||||
const archName = { x64: "amd64", arm64: "arm64" }[arch];
|
||||
if (!osName || !archName) {
|
||||
throw new Error(`Unsupported actionlint platform: ${platform}/${arch}`);
|
||||
}
|
||||
return `${osName}-${archName}`;
|
||||
}
|
||||
|
||||
function sha256(filePath) {
|
||||
return crypto.createHash("sha256").update(fs.readFileSync(filePath)).digest("hex");
|
||||
}
|
||||
|
||||
function download(url, destination, redirects = 5) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = https.get(url, { headers: { "user-agent": "agentic-awesome-skills-actionlint" } }, (response) => {
|
||||
if ([301, 302, 303, 307, 308].includes(response.statusCode) && response.headers.location) {
|
||||
response.resume();
|
||||
if (redirects <= 0) {
|
||||
reject(new Error(`Too many redirects downloading ${url}`));
|
||||
return;
|
||||
}
|
||||
download(response.headers.location, destination, redirects - 1).then(resolve, reject);
|
||||
return;
|
||||
}
|
||||
if (response.statusCode !== 200) {
|
||||
response.resume();
|
||||
reject(new Error(`Download failed (${response.statusCode}) for ${url}`));
|
||||
return;
|
||||
}
|
||||
const stream = fs.createWriteStream(destination, { mode: 0o600 });
|
||||
response.pipe(stream);
|
||||
stream.on("finish", () => stream.close(resolve));
|
||||
stream.on("error", reject);
|
||||
});
|
||||
request.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
function run(command, args, cwd) {
|
||||
const result = spawnSync(command, args, { cwd, stdio: "inherit" });
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`${command} ${args.join(" ")} failed with status ${result.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureActionlint(projectRoot) {
|
||||
const config = JSON.parse(
|
||||
fs.readFileSync(path.join(projectRoot, "tools", "config", "actionlint.json"), "utf8"),
|
||||
);
|
||||
const key = platformKey();
|
||||
const expectedHash = config.artifacts[key];
|
||||
if (!/^[a-f0-9]{64}$/.test(String(expectedHash || ""))) {
|
||||
throw new Error(`Missing SHA-256 for actionlint platform ${key}`);
|
||||
}
|
||||
|
||||
const [osName, archName] = key.split("-");
|
||||
const cacheDir = path.join(projectRoot, ".tmp", "actionlint", config.version, key);
|
||||
const binaryPath = path.join(cacheDir, "actionlint");
|
||||
const archiveName = `actionlint_${config.version}_${osName}_${archName}.tar.gz`;
|
||||
const archivePath = path.join(cacheDir, archiveName);
|
||||
fs.mkdirSync(cacheDir, { recursive: true });
|
||||
|
||||
if (!fs.existsSync(archivePath) || sha256(archivePath) !== expectedHash) {
|
||||
fs.rmSync(archivePath, { force: true });
|
||||
const url = `https://github.com/rhysd/actionlint/releases/download/v${config.version}/${archiveName}`;
|
||||
console.log(`[actionlint] Downloading pinned v${config.version} for ${key}`);
|
||||
await download(url, archivePath);
|
||||
}
|
||||
const actualHash = sha256(archivePath);
|
||||
if (actualHash !== expectedHash) {
|
||||
fs.rmSync(archivePath, { force: true });
|
||||
throw new Error(`actionlint checksum mismatch: expected ${expectedHash}, got ${actualHash}`);
|
||||
}
|
||||
|
||||
// Always recreate the executable from the verified archive so a stale or
|
||||
// tampered cache entry cannot become the verifier.
|
||||
fs.rmSync(binaryPath, { force: true });
|
||||
run("tar", ["-xzf", archivePath, "-C", cacheDir, "actionlint"], projectRoot);
|
||||
fs.chmodSync(binaryPath, 0o755);
|
||||
|
||||
return binaryPath;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const projectRoot = findProjectRoot(__dirname);
|
||||
const binary = await ensureActionlint(projectRoot);
|
||||
run(binary, ["-color"], projectRoot);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main().catch((error) => {
|
||||
console.error(`[actionlint] ${error.message}`);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { download, ensureActionlint, platformKey, sha256 };
|
||||
Reference in New Issue
Block a user