整理远程模块
TDevOPsCICD / build-image (push) Waiting to run

This commit is contained in:
cheney
2026-06-16 16:40:34 +08:00
parent b46cddc7cf
commit e05ce19eac
14 changed files with 1154 additions and 365 deletions
+70 -40
View File
@@ -1,53 +1,83 @@
const os = require('os');
const fs = require("fs");
const osutil = require("../util/osutil")
const fs = require("fs");
const path = require("path");
const { execFileSync } = require("child_process");
function matchDistName(cur, dists){
const list = []
for (let dist of dists) {
if ( cur.curOS === dist.os && cur.curPlatform === dist.platform) {
list.push( dist )
}
else if ( cur.curOS === dist.os && "cross" === dist.platform) {
list.unshift( dist )
}
else if ( "cross" === dist.os && cur.curPlatform === dist.platform) {
list.unshift( dist )
}
}
return list
function now() {
return new Date().toISOString();
}
function verifyChecksum(filePath, checksum) {
if (!checksum) {
return;
}
const [alg, expected] = checksum.split(":", 2);
if (!alg || !expected) {
return;
}
const crypto = require("crypto");
const actual = crypto.createHash(alg).update(fs.readFileSync(filePath)).digest("hex");
if (actual !== expected) {
throw new Error(`文件校验失败 ${filePath}`);
}
}
module.exports = async function install(remote, id){
const cur = osutil.cur();
if ( ! id ) {
id = "kit"
function unpackArtifact(artifact, localPath, versionDir) {
if (artifact.type !== "archive" || !artifact.unpack) {
return;
}
// 获取本地版本
const localInfo = osutil.choise([
require("../windows/local").getModuleInfo,
require("../linux/local").getModuleInfo,
])( id )
const extractDir = path.resolve(path.dirname(localPath), "_extracted");
fs.mkdirSync(extractDir, { recursive: true });
const format = artifact.archive_format || "zip";
if (format === "zip") {
if (process.platform === "win32") {
const source = localPath.replace(/'/g, "''");
const target = extractDir.replace(/'/g, "''");
execFileSync("powershell.exe", ["-NoProfile", "-Command", `Expand-Archive -Path '${source}' -DestinationPath '${target}' -Force`], { stdio: "inherit" });
} else {
execFileSync("unzip", ["-o", localPath, "-d", extractDir], { stdio: "inherit" });
}
} else if (["tar", "tar.gz", "tgz", "tar.xz"].includes(format)) {
execFileSync("tar", ["-xf", localPath, "-C", extractDir], { stdio: "inherit" });
}
$logger.info("local version", localInfo.version)
artifact.extracted_path = path.relative(versionDir, extractDir).replace(/\\/g, "/");
if (artifact.entry_point) {
artifact.extracted_entry_point = path.posix.join(artifact.extracted_path, artifact.entry_point.replace(/\\/g, "/"));
}
}
// 确认远程版本文件是否存在
const remoteInfo = await remote.wGetModuleInfo(id)
$logger.info("remote latest version", remoteInfo.latest.version)
module.exports = async function install(remote, id) {
const parsed = remote.parseProjectVersion(id || "kit");
const projectId = parsed.projectId;
const project = await remote.getProjectMetadata(projectId);
const version = parsed.version || project.latest_version;
if (!version) {
throw new Error(`远程模块没有可安装版本 ${projectId}`);
}
const dists = matchDistName(cur, remoteInfo.latest.dist)
const dist = dists.pop()
const versionMeta = await remote.getVersionMetadata(projectId, version);
const artifacts = remote.getMatchingArtifacts(versionMeta);
if (artifacts.length < 1) {
throw new Error(`没有匹配当前平台的文件 ${projectId}@${version}`);
}
await remote.wDownload(
"/modules/" + id + "/" + remoteInfo.latest.version + "/" + cur.curOS + "/" + cur.curPlatform + "/" + dist.filename,
localInfo.homeDir + "/" + dist.filename,
)
const root = remote.getLocalModuleRoot(projectId);
const versionDir = path.resolve(root, "versions", version);
fs.mkdirSync(versionDir, { recursive: true });
fs.writeFileSync( localInfo.homeDir + "/version", remoteInfo.latest.version );
for (const artifact of artifacts) {
const localPath = await remote.downloadArtifact(projectId, version, artifact, versionDir);
verifyChecksum(localPath, artifact.checksum || (versionMeta.checksums && versionMeta.checksums[artifact.path]));
unpackArtifact(artifact, localPath, versionDir);
}
$logger.info("当前版本", remoteInfo.latest.version )
const localVersionMeta = Object.assign({}, versionMeta, { installed_at: now(), artifacts });
fs.writeFileSync(path.resolve(versionDir, ".version.json"), JSON.stringify(localVersionMeta, null, 4), "utf-8");
}
const state = remote.getInstallState(projectId);
const action = state.current_version ? "switch" : "install";
await remote.activate(projectId, version, action);
$logger.info(`当前版本 ${projectId}@${version}`);
return version;
};