返回 CodeWhale
prepare-local-release-assets.js
根目录 / scripts / release / prepare-local-release-assets.js
1 #!/usr/bin/env node
2
3 const crypto = require("crypto");
4 const fs = require("fs/promises");
5 const path = require("path");
6
7 const {
8 allReleaseAssetNames,
9 BUNDLE_ASSET_NAMES,
10 BUNDLE_CHECKSUM_MANIFEST,
11 CHECKSUM_MANIFEST,
12 detectBinaryNames,
13 } = require("../../npm/codewhale/scripts/artifacts");
14
15 const WINDOWS_LAUNCHER = "codewhale.bat";
16 const WINDOWS_CLI_ASSET = "codewhale-windows-x64.exe";
17
18 async function sha256(filePath) {
19 const content = await fs.readFile(filePath);
20 return crypto.createHash("sha256").update(content).digest("hex");
21 }
22
23 async function main() {
24 const prepareAllAssets =
25 process.env.DEEPSEEK_TUI_PREPARE_ALL_ASSETS === "1" ||
26 process.env.DEEPSEEK_PREPARE_ALL_ASSETS === "1";
27 const outputDir = path.resolve(
28 process.argv[2] || path.join("target", "npm-release-assets"),
29 );
30 const buildDir = path.resolve(
31 process.argv[3] || path.join("target", "release"),
32 );
33 const { codewhale, tui, codew } = detectBinaryNames();
34 const isWindows = process.platform === "win32";
35
36 const assets = [
37 {
38 source: path.join(buildDir, isWindows ? "codewhale.exe" : "codewhale"),
39 target: codewhale,
40 },
41 {
42 source: path.join(buildDir, isWindows ? "codew.exe" : "codew"),
43 target: codew,
44 },
45 {
46 source: path.join(buildDir, isWindows ? "codewhale-tui.exe" : "codewhale-tui"),
47 target: tui,
48 },
49 ];
50
51 if (prepareAllAssets) {
52 for (const assetName of allReleaseAssetNames()) {
53 if (
54 assetName === WINDOWS_LAUNCHER ||
55 assetName === CHECKSUM_MANIFEST ||
56 assetName === BUNDLE_CHECKSUM_MANIFEST
57 ) {
58 continue;
59 }
60 if (assets.some((asset) => asset.target === assetName)) {
61 continue;
62 }
63 assets.push({
64 source: assetName.startsWith("codewhale-tui")
65 ? path.join(buildDir, isWindows ? "codewhale-tui.exe" : "codewhale-tui")
66 : assetName.startsWith("codew-")
67 ? path.join(buildDir, isWindows ? "codew.exe" : "codew")
68 : path.join(buildDir, isWindows ? "codewhale.exe" : "codewhale"),
69 target: assetName,
70 });
71 }
72 }
73
74 await fs.mkdir(outputDir, { recursive: true });
75
76 const manifestLines = [];
77 for (const asset of assets) {
78 const outputPath = path.join(outputDir, asset.target);
79 await fs.copyFile(asset.source, outputPath);
80 manifestLines.push(`${await sha256(outputPath)} ${asset.target}`);
81 }
82
83 if (assets.some((asset) => asset.target === WINDOWS_CLI_ASSET)) {
84 const batContent = [
85 "@echo off",
86 "where wt >nul 2>nul",
87 "set NO_ANIMATIONS=1",
88 'if "%ERRORLEVEL%"=="0" (',
89 ' wt --title Codewhale cmd /k "%~dp0codewhale-windows-x64.exe"',
90 ") else (",
91 ' "%~dp0codewhale-windows-x64.exe"',
92 ")",
93 "",
94 ].join("\r\n");
95 const batPath = path.join(outputDir, WINDOWS_LAUNCHER);
96 await fs.writeFile(batPath, batContent, "utf8");
97 const batHash = await sha256(batPath);
98 manifestLines.push(`${batHash} ${WINDOWS_LAUNCHER}`);
99 console.log(`Generated ${batPath}`);
100 }
101
102 if (prepareAllAssets) {
103 const bundleManifestLines = [];
104 for (const assetName of BUNDLE_ASSET_NAMES) {
105 const assetPath = path.join(outputDir, assetName);
106 bundleManifestLines.push(`${await sha256(assetPath)} ${assetName}`);
107 }
108 bundleManifestLines.sort();
109 const bundleManifestPath = path.join(outputDir, BUNDLE_CHECKSUM_MANIFEST);
110 await fs.writeFile(
111 bundleManifestPath,
112 `${bundleManifestLines.join("\n")}\n`,
113 "utf8",
114 );
115 manifestLines.push(
116 `${await sha256(bundleManifestPath)} ${BUNDLE_CHECKSUM_MANIFEST}`,
117 );
118 console.log(`Wrote bundle checksum manifest ${bundleManifestPath}`);
119 }
120
121 manifestLines.sort();
122 const manifestPath = path.join(outputDir, CHECKSUM_MANIFEST);
123 await fs.writeFile(manifestPath, `${manifestLines.join("\n")}\n`, "utf8");
124
125 const preparedCount = prepareAllAssets
126 ? allReleaseAssetNames().length
127 : assets.length + 1;
128 console.log(`Prepared ${preparedCount} assets in ${outputDir}`);
129 console.log(`Wrote checksum manifest ${manifestPath}`);
130 }
131
132 main().catch((error) => {
133 console.error("Failed to prepare local release assets:", error.message);
134 process.exit(1);
135 });
136
136 lines JAVASCRIPT