@jskit-ai/jskit-cli 0.2.129 → 0.2.131
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 +6 -5
- package/src/server/cliRuntime/appState.js +5 -2
- package/src/server/cliRuntime/ci/composer.js +171 -0
- package/src/server/cliRuntime/ci/contract.js +218 -0
- package/src/server/cliRuntime/ci/githubWorkflow.js +136 -0
- package/src/server/cliRuntime/ci/managedWorkflow.js +550 -0
- package/src/server/cliRuntime/descriptorValidation.js +11 -0
- package/src/server/cliRuntime/packageRegistries.js +13 -8
- package/src/server/commandHandlers/app.js +4 -0
- package/src/server/commandHandlers/appCommandCatalog.js +20 -1
- package/src/server/commandHandlers/appCommands/syncCi.js +40 -0
- package/src/server/commandHandlers/appCommands/updatePackages.js +9 -1
- package/src/server/commandHandlers/appCommands/verify.js +12 -1
- package/src/server/commandHandlers/health.js +8 -0
- package/src/server/commandHandlers/packageCommands/add.js +28 -0
- package/src/server/commandHandlers/packageCommands/remove.js +13 -0
- package/src/server/core/buildCommandDeps.js +7 -0
- package/src/server/core/createCliRunner.js +16 -0
- package/src/server/index.js +11 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
async function runAppSyncCiCommand(ctx = {}, { appRoot = "", options = {}, stdout }) {
|
|
2
|
+
const {
|
|
3
|
+
createCliError,
|
|
4
|
+
synchronizeAppCiWorkflow
|
|
5
|
+
} = ctx;
|
|
6
|
+
const force = String(options?.inlineOptions?.force || "").trim().toLowerCase() === "true";
|
|
7
|
+
const result = await synchronizeAppCiWorkflow({
|
|
8
|
+
appRoot,
|
|
9
|
+
allowManagedOverwrite: force
|
|
10
|
+
});
|
|
11
|
+
if (!result.applicable) {
|
|
12
|
+
throw createCliError("jskit app sync-ci only works in a JSKIT app root.");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (options.json) {
|
|
16
|
+
stdout.write(`${JSON.stringify({
|
|
17
|
+
path: result.path,
|
|
18
|
+
hash: result.hash,
|
|
19
|
+
changed: result.changed,
|
|
20
|
+
removedLegacyWorkflow: result.removedLegacyWorkflow,
|
|
21
|
+
replacedModifiedWorkflow: result.replacedModifiedWorkflow
|
|
22
|
+
}, null, 2)}\n`);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (result.replacedModifiedWorkflow) {
|
|
27
|
+
stdout.write(`Replaced the modified JSKIT-managed CI workflow: ${result.path}\n`);
|
|
28
|
+
} else if (result.changed) {
|
|
29
|
+
stdout.write(`Synchronized the JSKIT-managed CI workflow: ${result.path}\n`);
|
|
30
|
+
} else {
|
|
31
|
+
stdout.write(`The JSKIT-managed CI workflow is already current: ${result.path}\n`);
|
|
32
|
+
}
|
|
33
|
+
if (result.removedLegacyWorkflow) {
|
|
34
|
+
stdout.write("Removed the superseded .github/workflows/verify.yml scaffold.\n");
|
|
35
|
+
}
|
|
36
|
+
stdout.write(`Recorded content hash: ${result.hash}\n`);
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { runAppSyncCiCommand };
|
|
@@ -32,9 +32,11 @@ function resolveInstallSpecs(packageNames = [], resolveMajorRange) {
|
|
|
32
32
|
async function runAppUpdatePackagesCommand(ctx = {}, { appRoot = "", options = {}, stdout, stderr }) {
|
|
33
33
|
const {
|
|
34
34
|
createCliError,
|
|
35
|
-
loadAppPackageJson
|
|
35
|
+
loadAppPackageJson,
|
|
36
|
+
assertAppManagedCiWorkflowUnmodified
|
|
36
37
|
} = ctx;
|
|
37
38
|
|
|
39
|
+
await assertAppManagedCiWorkflowUnmodified({ appRoot });
|
|
38
40
|
const { packageJson } = await loadAppPackageJson(appRoot);
|
|
39
41
|
const runtimePackages = collectJskitPackageNames(packageJson?.dependencies);
|
|
40
42
|
const devPackages = collectJskitPackageNames(packageJson?.devDependencies);
|
|
@@ -93,6 +95,12 @@ async function runAppUpdatePackagesCommand(ctx = {}, { appRoot = "", options = {
|
|
|
93
95
|
stderr,
|
|
94
96
|
createCliError
|
|
95
97
|
});
|
|
98
|
+
stdout.write("[jskit:update] synchronizing the managed CI workflow.\n");
|
|
99
|
+
await runLocalJskit(appRoot, ["app", "sync-ci"], {
|
|
100
|
+
stdout,
|
|
101
|
+
stderr,
|
|
102
|
+
createCliError
|
|
103
|
+
});
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
stdout.write("[jskit:update] done.\n");
|
|
@@ -8,7 +8,10 @@ const BASELINE_VERIFY_SCRIPTS = Object.freeze([
|
|
|
8
8
|
]);
|
|
9
9
|
|
|
10
10
|
async function runAppVerifyCommand(ctx = {}, { appRoot = "", options = {}, stdout, stderr }) {
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
createCliError,
|
|
13
|
+
validateAppCiWorkflow
|
|
14
|
+
} = ctx;
|
|
12
15
|
const inlineOptions =
|
|
13
16
|
options?.inlineOptions && typeof options.inlineOptions === "object" ? options.inlineOptions : {};
|
|
14
17
|
const against = String(inlineOptions.against || "").trim();
|
|
@@ -17,6 +20,14 @@ async function runAppVerifyCommand(ctx = {}, { appRoot = "", options = {}, stdou
|
|
|
17
20
|
throw createCliError("jskit app verify does not support --dry-run.", { exitCode: 1 });
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
const ciValidation = await validateAppCiWorkflow({ appRoot });
|
|
24
|
+
if (!ciValidation.valid) {
|
|
25
|
+
throw createCliError(
|
|
26
|
+
ciValidation.issues.map((issue) => issue.message).join("\n"),
|
|
27
|
+
{ exitCode: 1 }
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
for (const scriptName of BASELINE_VERIFY_SCRIPTS) {
|
|
21
32
|
runExternalCommand("npm", ["run", "--if-present", scriptName], {
|
|
22
33
|
cwd: appRoot,
|
|
@@ -26,6 +26,7 @@ function createHealthCommands(ctx = {}) {
|
|
|
26
26
|
loadAppLocalPackageRegistry,
|
|
27
27
|
mergePackageRegistries,
|
|
28
28
|
hydratePackageRegistryFromInstalledNodeModules,
|
|
29
|
+
validateManagedCiWorkflow,
|
|
29
30
|
inspectPackageOfferings,
|
|
30
31
|
fileExists,
|
|
31
32
|
normalizeRelativePath,
|
|
@@ -2130,6 +2131,13 @@ function createHealthCommands(ctx = {}) {
|
|
|
2130
2131
|
seedPackageIds: Object.keys(installed)
|
|
2131
2132
|
});
|
|
2132
2133
|
|
|
2134
|
+
const ciValidation = await validateManagedCiWorkflow({
|
|
2135
|
+
appRoot,
|
|
2136
|
+
lock,
|
|
2137
|
+
packageRegistry: combinedPackageRegistry
|
|
2138
|
+
});
|
|
2139
|
+
issues.push(...ciValidation.issues.map((issue) => issue.message));
|
|
2140
|
+
|
|
2133
2141
|
for (const [packageId, lockEntryValue] of Object.entries(installed)) {
|
|
2134
2142
|
const lockEntry = ensureObject(lockEntryValue);
|
|
2135
2143
|
if (!combinedPackageRegistry.has(packageId)) {
|
|
@@ -360,6 +360,9 @@ async function runPackageAddCommand(ctx = {}, { positional, options, cwd, io })
|
|
|
360
360
|
resolvePackageOptions,
|
|
361
361
|
applyPackageInstall,
|
|
362
362
|
adoptAppLocalPackageDependencies,
|
|
363
|
+
assertManagedCiWorkflowUnmodified,
|
|
364
|
+
composeInstalledPackageCi,
|
|
365
|
+
synchronizeManagedCiWorkflow,
|
|
363
366
|
writeJsonFile,
|
|
364
367
|
readFileBufferIfExists,
|
|
365
368
|
runNpmInstall,
|
|
@@ -485,6 +488,10 @@ async function runPackageAddCommand(ctx = {}, { positional, options, cwd, io })
|
|
|
485
488
|
const combinedPackageRegistry = mergePackageRegistries(packageRegistry, appLocalRegistry);
|
|
486
489
|
const { packageJsonPath, packageJson } = await loadAppPackageJson(appRoot);
|
|
487
490
|
const { lockPath, lock } = await loadLockFile(appRoot);
|
|
491
|
+
await assertManagedCiWorkflowUnmodified({
|
|
492
|
+
appRoot,
|
|
493
|
+
lock
|
|
494
|
+
});
|
|
488
495
|
const resolvedTargetPackageId = targetType === "package"
|
|
489
496
|
? await resolvePackageIdFromRegistryOrNodeModules({
|
|
490
497
|
appRoot,
|
|
@@ -556,6 +563,19 @@ async function runPackageAddCommand(ctx = {}, { positional, options, cwd, io })
|
|
|
556
563
|
combinedPackageRegistry,
|
|
557
564
|
`${invocationMode} ${targetType} ${targetId}`
|
|
558
565
|
);
|
|
566
|
+
for (const packageId of plannedInstalledPackageIds) {
|
|
567
|
+
const packageEntry = combinedPackageRegistry.get(packageId);
|
|
568
|
+
if (!packageEntry) {
|
|
569
|
+
throw createCliError(
|
|
570
|
+
`[ci:descriptor-missing] Installed package descriptor not found for ${packageId}. Restore the package in node_modules or the JSKIT catalog before changing installed package requirements.`
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
composeInstalledPackageCi({
|
|
575
|
+
lock,
|
|
576
|
+
packageRegistry: combinedPackageRegistry,
|
|
577
|
+
installedPackageIds: plannedInstalledPackageIds
|
|
578
|
+
});
|
|
559
579
|
|
|
560
580
|
if (targetType === "bundle") {
|
|
561
581
|
validateInlineOptionsForBundle({
|
|
@@ -766,6 +786,14 @@ async function runPackageAddCommand(ctx = {}, { positional, options, cwd, io })
|
|
|
766
786
|
});
|
|
767
787
|
}
|
|
768
788
|
|
|
789
|
+
await synchronizeManagedCiWorkflow({
|
|
790
|
+
appRoot,
|
|
791
|
+
lock,
|
|
792
|
+
packageRegistry: combinedPackageRegistry,
|
|
793
|
+
touchedFiles,
|
|
794
|
+
dryRun: options.dryRun === true
|
|
795
|
+
});
|
|
796
|
+
|
|
769
797
|
const touchedFileList = sortStrings([...touchedFiles]);
|
|
770
798
|
const successLabel = invocationMode === "generate"
|
|
771
799
|
? "Generated with"
|
|
@@ -27,6 +27,8 @@ async function runPackageRemoveCommand(ctx = {}, { positional, options, cwd, io
|
|
|
27
27
|
removeEnvValue,
|
|
28
28
|
writeFile,
|
|
29
29
|
removeManagedViteProxyEntries,
|
|
30
|
+
assertManagedCiWorkflowUnmodified,
|
|
31
|
+
synchronizeManagedCiWorkflow,
|
|
30
32
|
hashBuffer,
|
|
31
33
|
rm,
|
|
32
34
|
writeJsonFile,
|
|
@@ -45,6 +47,10 @@ async function runPackageRemoveCommand(ctx = {}, { positional, options, cwd, io
|
|
|
45
47
|
const combinedPackageRegistry = mergePackageRegistries(packageRegistry, appLocalRegistry);
|
|
46
48
|
const { packageJsonPath, packageJson } = await loadAppPackageJson(appRoot);
|
|
47
49
|
const { lockPath, lock } = await loadLockFile(appRoot);
|
|
50
|
+
await assertManagedCiWorkflowUnmodified({
|
|
51
|
+
appRoot,
|
|
52
|
+
lock
|
|
53
|
+
});
|
|
48
54
|
const installed = ensureObject(lock.installedPackages);
|
|
49
55
|
await hydratePackageRegistryFromInstalledNodeModules({
|
|
50
56
|
appRoot,
|
|
@@ -159,6 +165,13 @@ async function runPackageRemoveCommand(ctx = {}, { positional, options, cwd, io
|
|
|
159
165
|
}
|
|
160
166
|
|
|
161
167
|
delete installed[resolvedTargetId];
|
|
168
|
+
await synchronizeManagedCiWorkflow({
|
|
169
|
+
appRoot,
|
|
170
|
+
lock,
|
|
171
|
+
packageRegistry: combinedPackageRegistry,
|
|
172
|
+
touchedFiles,
|
|
173
|
+
dryRun: options.dryRun === true
|
|
174
|
+
});
|
|
162
175
|
const touchedFileList = sortStrings([...touchedFiles]);
|
|
163
176
|
|
|
164
177
|
if (!options.dryRun) {
|
|
@@ -27,6 +27,13 @@ function createCommandHandlerDeps(deps = {}) {
|
|
|
27
27
|
applyPackageMigrationsOnly: deps.applyPackageMigrationsOnly,
|
|
28
28
|
applyPackagePositioning: deps.applyPackagePositioning,
|
|
29
29
|
adoptAppLocalPackageDependencies: deps.adoptAppLocalPackageDependencies,
|
|
30
|
+
assertAppManagedCiWorkflowUnmodified: deps.assertAppManagedCiWorkflowUnmodified,
|
|
31
|
+
assertManagedCiWorkflowUnmodified: deps.assertManagedCiWorkflowUnmodified,
|
|
32
|
+
composeInstalledPackageCi: deps.composeInstalledPackageCi,
|
|
33
|
+
synchronizeAppCiWorkflow: deps.synchronizeAppCiWorkflow,
|
|
34
|
+
synchronizeManagedCiWorkflow: deps.synchronizeManagedCiWorkflow,
|
|
35
|
+
validateAppCiWorkflow: deps.validateAppCiWorkflow,
|
|
36
|
+
validateManagedCiWorkflow: deps.validateManagedCiWorkflow,
|
|
30
37
|
loadAppPackageJson: deps.loadAppPackageJson,
|
|
31
38
|
resolveLocalPackageId: deps.resolveLocalPackageId,
|
|
32
39
|
createLocalPackageScaffoldFiles: deps.createLocalPackageScaffoldFiles,
|
|
@@ -93,6 +93,15 @@ import {
|
|
|
93
93
|
import {
|
|
94
94
|
removeManagedViteProxyEntries
|
|
95
95
|
} from "../cliRuntime/viteProxy.js";
|
|
96
|
+
import {
|
|
97
|
+
assertAppManagedCiWorkflowUnmodified,
|
|
98
|
+
assertManagedCiWorkflowUnmodified,
|
|
99
|
+
composeInstalledPackageCi,
|
|
100
|
+
synchronizeAppCiWorkflow,
|
|
101
|
+
synchronizeManagedCiWorkflow,
|
|
102
|
+
validateAppCiWorkflow,
|
|
103
|
+
validateManagedCiWorkflow
|
|
104
|
+
} from "../cliRuntime/ci/managedWorkflow.js";
|
|
96
105
|
|
|
97
106
|
const commandHandlers = createCommandHandlers(
|
|
98
107
|
createCommandHandlerDeps({
|
|
@@ -123,6 +132,13 @@ const commandHandlers = createCommandHandlers(
|
|
|
123
132
|
applyPackageMigrationsOnly,
|
|
124
133
|
applyPackagePositioning,
|
|
125
134
|
adoptAppLocalPackageDependencies,
|
|
135
|
+
assertAppManagedCiWorkflowUnmodified,
|
|
136
|
+
assertManagedCiWorkflowUnmodified,
|
|
137
|
+
composeInstalledPackageCi,
|
|
138
|
+
synchronizeAppCiWorkflow,
|
|
139
|
+
synchronizeManagedCiWorkflow,
|
|
140
|
+
validateAppCiWorkflow,
|
|
141
|
+
validateManagedCiWorkflow,
|
|
126
142
|
loadAppPackageJson,
|
|
127
143
|
resolveLocalPackageId,
|
|
128
144
|
createLocalPackageScaffoldFiles,
|
package/src/server/index.js
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
export { runCli } from "./core/createCliRunner.js";
|
|
2
2
|
export * from "./appBlueprint.js";
|
|
3
|
+
export {
|
|
4
|
+
synchronizeAppCiWorkflow,
|
|
5
|
+
validateAppCiWorkflow
|
|
6
|
+
} from "./cliRuntime/ci/managedWorkflow.js";
|
|
7
|
+
export {
|
|
8
|
+
composeCiContributions
|
|
9
|
+
} from "./cliRuntime/ci/composer.js";
|
|
10
|
+
export {
|
|
11
|
+
JSKIT_CI_WORKFLOW_RELATIVE_PATH,
|
|
12
|
+
renderGithubWorkflow
|
|
13
|
+
} from "./cliRuntime/ci/githubWorkflow.js";
|