@celilo/cli 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/module/packaging/build.ts +41 -33
- package/tsconfig.json +20 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celilo/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Celilo — home lab orchestration CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"bin/",
|
|
11
11
|
"src/",
|
|
12
12
|
"drizzle/",
|
|
13
|
-
"schemas/"
|
|
13
|
+
"schemas/",
|
|
14
|
+
"tsconfig.json"
|
|
14
15
|
],
|
|
15
16
|
"keywords": ["celilo", "homelab", "orchestration", "ansible", "terraform"],
|
|
16
17
|
"license": "MIT",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import { existsSync } from 'node:fs';
|
|
2
|
+
import { cpSync, existsSync, mkdtempSync, rmSync } from 'node:fs';
|
|
3
3
|
import { readFile, readdir, unlink, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
4
5
|
import { basename, join, relative } from 'node:path';
|
|
5
6
|
import { create as tarCreate } from 'tar';
|
|
6
7
|
import { parse as parseYaml } from 'yaml';
|
|
@@ -139,9 +140,20 @@ export async function buildModule(options: ModuleBuildOptions): Promise<ModuleBu
|
|
|
139
140
|
return { success: false, error: dirError };
|
|
140
141
|
}
|
|
141
142
|
|
|
143
|
+
// Copy source to a temp directory so the build doesn't pollute the
|
|
144
|
+
// source tree and avoids workspace resolution issues (e.g., a
|
|
145
|
+
// monorepo's root package.json triggering bun workspace linking).
|
|
146
|
+
const buildDir = mkdtempSync(join(tmpdir(), 'celilo-package-'));
|
|
147
|
+
|
|
142
148
|
try {
|
|
149
|
+
console.log('Copying source to build directory...');
|
|
150
|
+
cpSync(sourceDir, buildDir, {
|
|
151
|
+
recursive: true,
|
|
152
|
+
filter: (src) => !shouldExclude(relative(sourceDir, src)),
|
|
153
|
+
});
|
|
154
|
+
|
|
143
155
|
// Read manifest to get module ID
|
|
144
|
-
const manifestPath = join(
|
|
156
|
+
const manifestPath = join(buildDir, 'manifest.yml');
|
|
145
157
|
const manifestContent = await readFile(manifestPath, 'utf-8');
|
|
146
158
|
const idMatch = manifestContent.match(/^id:\s*["']?([a-z0-9-]+)["']?/m);
|
|
147
159
|
if (!idMatch) {
|
|
@@ -161,18 +173,19 @@ export async function buildModule(options: ModuleBuildOptions): Promise<ModuleBu
|
|
|
161
173
|
console.log(`Building module (${manifest.build.command ? 'command' : 'script'})...`);
|
|
162
174
|
try {
|
|
163
175
|
execSync(buildCmd, {
|
|
164
|
-
cwd:
|
|
176
|
+
cwd: buildDir,
|
|
165
177
|
stdio: 'inherit',
|
|
166
178
|
timeout: 300_000,
|
|
167
179
|
});
|
|
168
|
-
} catch {
|
|
169
|
-
|
|
180
|
+
} catch (buildError) {
|
|
181
|
+
const msg = buildError instanceof Error ? buildError.message : String(buildError);
|
|
182
|
+
return { success: false, error: `Auto-build failed: Build exited with code ${msg}` };
|
|
170
183
|
}
|
|
171
184
|
|
|
172
185
|
// Verify artifacts exist
|
|
173
186
|
if (manifest.build.artifacts) {
|
|
174
187
|
const missing = manifest.build.artifacts.filter(
|
|
175
|
-
(a: string) => !existsSync(join(
|
|
188
|
+
(a: string) => !existsSync(join(buildDir, a)),
|
|
176
189
|
);
|
|
177
190
|
if (missing.length > 0) {
|
|
178
191
|
return {
|
|
@@ -184,45 +197,40 @@ export async function buildModule(options: ModuleBuildOptions): Promise<ModuleBu
|
|
|
184
197
|
}
|
|
185
198
|
|
|
186
199
|
// Compute checksums
|
|
187
|
-
const checksumsData = await computeChecksums(
|
|
200
|
+
const checksumsData = await computeChecksums(buildDir);
|
|
188
201
|
const checksumsJson = JSON.stringify(checksumsData, null, 2);
|
|
189
202
|
|
|
190
203
|
// Sign checksums
|
|
191
204
|
const signature = await signChecksums(checksumsJson, masterKeyPath);
|
|
192
205
|
|
|
193
|
-
// Write
|
|
194
|
-
const checksumsPath = join(
|
|
195
|
-
const signaturePath = join(
|
|
206
|
+
// Write checksums.json and signature.sig into build dir
|
|
207
|
+
const checksumsPath = join(buildDir, 'checksums.json');
|
|
208
|
+
const signaturePath = join(buildDir, 'signature.sig');
|
|
196
209
|
await writeFile(checksumsPath, checksumsJson);
|
|
197
210
|
await writeFile(signaturePath, signature);
|
|
198
211
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
};
|
|
215
|
-
} finally {
|
|
216
|
-
// Clean up temporary files
|
|
217
|
-
await Promise.all([
|
|
218
|
-
unlink(checksumsPath).catch(() => {}),
|
|
219
|
-
unlink(signaturePath).catch(() => {}),
|
|
220
|
-
]);
|
|
221
|
-
}
|
|
212
|
+
// Create tarball
|
|
213
|
+
const finalOutputPath = outputPath || join(process.cwd(), `${moduleId}.netapp`);
|
|
214
|
+
await tarCreate(
|
|
215
|
+
{
|
|
216
|
+
file: finalOutputPath,
|
|
217
|
+
cwd: buildDir,
|
|
218
|
+
gzip: true,
|
|
219
|
+
},
|
|
220
|
+
['checksums.json', 'signature.sig', ...Object.keys(checksumsData.files)],
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
success: true,
|
|
225
|
+
packagePath: finalOutputPath,
|
|
226
|
+
};
|
|
222
227
|
} catch (error) {
|
|
223
228
|
return {
|
|
224
229
|
success: false,
|
|
225
230
|
error: `Failed to build module: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
226
231
|
};
|
|
232
|
+
} finally {
|
|
233
|
+
// Clean up temp directory
|
|
234
|
+
rmSync(buildDir, { recursive: true, force: true });
|
|
227
235
|
}
|
|
228
236
|
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ESNext"],
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"types": ["bun-types"],
|
|
14
|
+
"paths": {
|
|
15
|
+
"@/*": ["./src/*"]
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules"]
|
|
20
|
+
}
|