@quenty/nevermore-cli 4.32.0 → 4.33.0
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/CHANGELOG.md +13 -0
- package/dist/commands/deploy-command/deploy-init-utils.js +1 -1
- package/dist/commands/deploy-command/deploy-init-utils.js.map +1 -1
- package/dist/commands/deploy-command/deploy-init.js +2 -2
- package/dist/commands/deploy-command/deploy-init.js.map +1 -1
- package/dist/commands/init-command/init-package-command.d.ts +2 -0
- package/dist/commands/init-command/init-package-command.d.ts.map +1 -1
- package/dist/commands/init-command/init-package-command.js +36 -2
- package/dist/commands/init-command/init-package-command.js.map +1 -1
- package/dist/utils/job-context/batch-script-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/batch-script-job-context.js +8 -1
- package/dist/utils/job-context/batch-script-job-context.js.map +1 -1
- package/dist/utils/job-context/cloud-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/cloud-job-context.js +17 -1
- package/dist/utils/job-context/cloud-job-context.js.map +1 -1
- package/dist/utils/job-context/job-context.d.ts +4 -0
- package/dist/utils/job-context/job-context.d.ts.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.d.ts +11 -0
- package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.d.ts.map +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.js +11 -2
- package/dist/utils/testing/parsers/batch-log-parser.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/deploy-command/deploy-init-utils.ts +1 -1
- package/src/commands/deploy-command/deploy-init.ts +2 -2
- package/src/commands/init-command/init-package-command.ts +43 -2
- package/src/utils/job-context/batch-script-job-context.ts +10 -1
- package/src/utils/job-context/cloud-job-context.ts +18 -1
- package/src/utils/job-context/job-context.ts +4 -0
- package/src/utils/open-cloud/open-cloud-client.ts +4 -0
- package/src/utils/testing/parsers/batch-log-parser.ts +16 -2
- package/templates/batch-test-runner.luau +8 -8
- package/templates/nevermore-library-package-template/package.json +3 -1
- package/templates/nevermore-library-package-template/src/jest.config.lua +3 -0
- package/templates/nevermore-library-package-template/test/default.project.json +6 -0
- package/templates/nevermore-library-package-template/test/scripts/Server/ServerMain.server.lua +13 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -282,9 +282,18 @@ export class BatchScriptJobContext implements JobContext {
|
|
|
282
282
|
const rawLogs = await this._inner.getLogsAsync(deployment);
|
|
283
283
|
|
|
284
284
|
if (!result.success) {
|
|
285
|
+
const stateInfo = result.taskState ? ` (state: ${result.taskState})` : '';
|
|
285
286
|
OutputHelper.warn(
|
|
286
|
-
|
|
287
|
+
`Batch execution task did not complete successfully${stateInfo} — parsing partial results`
|
|
287
288
|
);
|
|
289
|
+
if (result.errorMessage) {
|
|
290
|
+
OutputHelper.error(result.errorMessage);
|
|
291
|
+
}
|
|
292
|
+
if (!rawLogs || rawLogs.trim().length === 0) {
|
|
293
|
+
OutputHelper.warn(
|
|
294
|
+
'No logs were returned from the execution — the script may not have started'
|
|
295
|
+
);
|
|
296
|
+
}
|
|
288
297
|
OutputHelper.verbose(`Raw batch logs:\n${rawLogs || '(empty)'}`);
|
|
289
298
|
}
|
|
290
299
|
|
|
@@ -112,7 +112,24 @@ export class CloudJobContext extends BaseJobContext {
|
|
|
112
112
|
cloudDeployment.taskPath = task.path;
|
|
113
113
|
cloudDeployment.taskState = completedTask.state;
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
// Surface error details from the Roblox API when the task didn't complete
|
|
116
|
+
let errorMessage: string | undefined;
|
|
117
|
+
if (completedTask.state !== 'COMPLETE') {
|
|
118
|
+
const parts: string[] = [`Task ended with state: ${completedTask.state}`];
|
|
119
|
+
if (completedTask.error?.message) {
|
|
120
|
+
parts.push(`Error: ${completedTask.error.message}`);
|
|
121
|
+
}
|
|
122
|
+
if (completedTask.error?.code) {
|
|
123
|
+
parts.push(`Code: ${completedTask.error.code}`);
|
|
124
|
+
}
|
|
125
|
+
errorMessage = parts.join('. ');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
success: completedTask.state === 'COMPLETE',
|
|
130
|
+
taskState: completedTask.state,
|
|
131
|
+
errorMessage,
|
|
132
|
+
};
|
|
116
133
|
}
|
|
117
134
|
|
|
118
135
|
async getLogsAsync(deployment: Deployment): Promise<string> {
|
|
@@ -24,6 +24,10 @@ export interface ScriptRunResult {
|
|
|
24
24
|
* wall-clock measurement.
|
|
25
25
|
*/
|
|
26
26
|
durationMs?: number;
|
|
27
|
+
/** Final task state (e.g. 'COMPLETE', 'FAILED', 'CANCELLED'). */
|
|
28
|
+
taskState?: string;
|
|
29
|
+
/** Error message from the execution backend, if any. */
|
|
30
|
+
errorMessage?: string;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
/**
|
|
@@ -20,6 +20,10 @@ export interface LuauTask {
|
|
|
20
20
|
| 'FAILED';
|
|
21
21
|
script: string;
|
|
22
22
|
timeout?: string;
|
|
23
|
+
/** Script return value (populated on COMPLETE). */
|
|
24
|
+
output?: { results?: Array<{ value?: string }> };
|
|
25
|
+
/** Error details (populated on FAILED). */
|
|
26
|
+
error?: { code?: string; message?: string };
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
export interface OpenCloudClientOptions {
|
|
@@ -134,10 +134,24 @@ export function parseBatchTestLogs(
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
// ── Warn when the batch produced no recognizable output ──
|
|
138
|
+
|
|
139
|
+
const noOutputAtAll = logSections.size === 0 && summaryResults.size === 0;
|
|
140
|
+
if (noOutputAtAll) {
|
|
141
|
+
OutputHelper.warn(
|
|
142
|
+
`[batch-log-parser] No batch markers or summary found in logs (${lines.length} lines, ${rawLogs.length} chars). ` +
|
|
143
|
+
'The batch script may not have started or produced output.'
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
137
147
|
// ── Pass 3: Combine log sections with summary results ──
|
|
138
148
|
|
|
149
|
+
// When the batch produced zero output, surface the raw error in every
|
|
150
|
+
// package's logs so reporters show the actual failure instead of "(no output)".
|
|
151
|
+
const fallbackLogs = noOutputAtAll ? rawLogs.trim() : '';
|
|
152
|
+
|
|
139
153
|
for (const [packageName, slug] of slugMap) {
|
|
140
|
-
const sectionLogs = logSections.get(slug) ??
|
|
154
|
+
const sectionLogs = logSections.get(slug) ?? fallbackLogs;
|
|
141
155
|
const summarySuccess = summaryResults.get(slug);
|
|
142
156
|
|
|
143
157
|
// The JSON summary (pcall result) is the primary success signal.
|
|
@@ -150,7 +164,7 @@ export function parseBatchTestLogs(
|
|
|
150
164
|
}
|
|
151
165
|
}
|
|
152
166
|
|
|
153
|
-
if (!success) {
|
|
167
|
+
if (!success && !noOutputAtAll) {
|
|
154
168
|
console.error(
|
|
155
169
|
`[batch-log-parser] ${slug}: summarySuccess=${summarySuccess} hasLogs=${
|
|
156
170
|
sectionLogs.length > 0
|
|
@@ -19,7 +19,7 @@ for _, slug in packageSlugs do
|
|
|
19
19
|
if inst then
|
|
20
20
|
scriptSources[slug] = inst.Source
|
|
21
21
|
else
|
|
22
|
-
|
|
22
|
+
warn(`[BatchTest] Failed to find script source for {slug}`)
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -41,8 +41,8 @@ local results: { Result } = {}
|
|
|
41
41
|
for _, slug in packageSlugs do
|
|
42
42
|
local scriptSource = scriptSources[slug]
|
|
43
43
|
if not scriptSource then
|
|
44
|
-
warn(`[BatchTest] No script for {slug}`)
|
|
45
44
|
print("===BATCH_TEST_BEGIN " .. slug .. "===")
|
|
45
|
+
warn(`[BatchTest] {slug}: No test script found for {slug}. Is it tagged with _BatchTest_{slug}?`)
|
|
46
46
|
print("===BATCH_TEST_END " .. slug .. " FAIL 0===")
|
|
47
47
|
table.insert(results, { slug = slug, success = false, durationMs = 0, error = "No test script found" })
|
|
48
48
|
continue
|
|
@@ -93,14 +93,14 @@ for _, slug in packageSlugs do
|
|
|
93
93
|
|
|
94
94
|
-- CLEANUP: restore service state
|
|
95
95
|
allPackages[slug].Parent = nil
|
|
96
|
-
for _,
|
|
97
|
-
if not preWorkspace[
|
|
98
|
-
pcall(
|
|
96
|
+
for _, child in workspace:GetChildren() do
|
|
97
|
+
if not preWorkspace[child] and not child:IsA("Terrain") and not child:IsA("Camera") then
|
|
98
|
+
pcall(child.Destroy, child)
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
|
-
for _,
|
|
102
|
-
if not preRunService[
|
|
103
|
-
pcall(
|
|
101
|
+
for _, child in ReplicatedStorage:GetChildren() do
|
|
102
|
+
if not preRunService[child] then
|
|
103
|
+
pcall(child.Destroy, child)
|
|
104
104
|
end
|
|
105
105
|
end
|
|
106
106
|
-- Destroy injected LoaderLinks (non-archivable, created by LoaderLinkCreator)
|
|
@@ -28,7 +28,9 @@
|
|
|
28
28
|
"Quenty"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@quenty/loader": "workspace:*"
|
|
31
|
+
"@quenty/loader": "workspace:*",
|
|
32
|
+
"@quenty/nevermore-test-runner": "workspace:*",
|
|
33
|
+
"@quentystudios/jest-lua": "3.10.0-quenty.2"
|
|
32
34
|
},
|
|
33
35
|
"publishConfig": {
|
|
34
36
|
"access": "public"
|
package/templates/nevermore-library-package-template/test/scripts/Server/ServerMain.server.lua
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
@class ServerMain
|
|
3
|
+
]]
|
|
4
|
+
local ServerScriptService = game:GetService("ServerScriptService")
|
|
5
|
+
|
|
6
|
+
local root = ServerScriptService.{{packageName}}
|
|
7
|
+
local loader = root:FindFirstChild("LoaderUtils", true).Parent
|
|
8
|
+
local require = require(loader).bootstrapGame(root)
|
|
9
|
+
|
|
10
|
+
local NevermoreTestRunnerUtils = require("NevermoreTestRunnerUtils")
|
|
11
|
+
if NevermoreTestRunnerUtils.runTestsIfNeededAsync(root) then
|
|
12
|
+
return
|
|
13
|
+
end
|