fix: bootstrap registry on first workspace list
This commit is contained in:
@@ -155,6 +155,12 @@ export class WorkspaceRegistry {
|
||||
}
|
||||
|
||||
async list(): Promise<WorkspaceRevision[]> {
|
||||
const active = await this.tryActiveState();
|
||||
if (active) return active.revisions;
|
||||
// A clean installation has no active snapshot until the first registry operation. Keep
|
||||
// this lazy so health/startup remain available when Git is temporarily unreachable, while
|
||||
// still refusing corrupted existing state (tryActiveState throws instead of returning none).
|
||||
await this.bootstrap();
|
||||
return (await this.activeState()).revisions;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,6 +254,21 @@ test("bootstraps a checkout and activates a validated immutable snapshot", async
|
||||
});
|
||||
});
|
||||
|
||||
test("first list lazily bootstraps a clean registry", async () => {
|
||||
const remote = await fixture();
|
||||
const root = join(remote.root, "registry");
|
||||
const registry = new WorkspaceRegistry(config(root, remote.remote));
|
||||
|
||||
await expect(registry.list()).resolves.toEqual([
|
||||
expect.objectContaining({
|
||||
id: "psd-clinical",
|
||||
commit: remote.initialCommit,
|
||||
state: "operational",
|
||||
}),
|
||||
]);
|
||||
expect(existsSync(join(root, "state", "active.json"))).toBe(true);
|
||||
});
|
||||
|
||||
test("publishes create, update, and delete with the configured Git author identity", async () => {
|
||||
const remote = await fixture();
|
||||
const registry = new WorkspaceRegistry(config(join(remote.root, "registry"), remote.remote, {
|
||||
|
||||
@@ -630,6 +630,27 @@ task13_report_server_workspace_failure() {
|
||||
else
|
||||
printf '%s\n' '(empty response)' >&2
|
||||
fi
|
||||
printf '%s\n' '--- sanitized registry integrity probe ---' >&2
|
||||
{
|
||||
task13_compose exec -T core node --input-type=module -e '
|
||||
const { loadConfig } = await import("/app/backend/dist/config.js");
|
||||
const { WorkspaceRegistry } = await import("/app/backend/dist/workspaces/registry.js");
|
||||
const registry = new WorkspaceRegistry(loadConfig(process.env).workspaceRegistry);
|
||||
try {
|
||||
const revisions = await registry.list();
|
||||
for (const revision of revisions) await registry.read(revision.id);
|
||||
console.log(JSON.stringify({ ok: true, revisions: revisions.length }));
|
||||
} catch (error) {
|
||||
console.log(JSON.stringify({
|
||||
ok: false,
|
||||
name: error instanceof Error ? error.name : "UnknownError",
|
||||
code: error && typeof error === "object" && "code" in error ? error.code : "unknown",
|
||||
message: error instanceof Error ? error.message : "Unknown registry failure",
|
||||
}));
|
||||
process.exitCode = 1;
|
||||
}
|
||||
' 2>&1 || printf '%s\n' '(registry integrity probe unavailable)'
|
||||
} | tail -n 20 | task13_sanitize >&2
|
||||
printf '%s\n' '--- sanitized core logs (last 100 lines) ---' >&2
|
||||
{
|
||||
task13_compose logs --no-color --tail 100 core 2>&1 \
|
||||
@@ -1063,6 +1084,11 @@ task13_self_test_server_workspace_diagnostics() {
|
||||
printf '%s\n' \
|
||||
'{"error":"workspace_invalid","detail":"password=fixture-known-secret"}' >"$response"
|
||||
task13_compose() {
|
||||
if [[ "$*" == "exec -T core node --input-type=module -e "* ]]; then
|
||||
printf '%s\n' \
|
||||
'{"name":"WorkspaceRegistryError","code":"workspace_invalid","message":"Workspace snapshot integrity check failed"}'
|
||||
return 0
|
||||
fi
|
||||
[[ "$*" == "logs --no-color --tail 100 core" ]] \
|
||||
|| task13_fail "server diagnostics requested an unexpected Compose command"
|
||||
while [[ "$i" -le 150 ]]; do
|
||||
@@ -1083,6 +1109,8 @@ task13_self_test_server_workspace_diagnostics() {
|
||||
|| task13_fail "server diagnostics omit the unexpected HTTP status"
|
||||
[[ "$output" == *'workspace_invalid'* ]] \
|
||||
|| task13_fail "server diagnostics omit the generic response"
|
||||
[[ "$output" == *'Workspace snapshot integrity check failed'* ]] \
|
||||
|| task13_fail "server diagnostics omit the bounded internal registry reason"
|
||||
[[ "$output" == *'core-log-051'* && "$output" != *'core-log-050'* ]] \
|
||||
|| task13_fail "server diagnostics do not bound core logs to the last 100 lines"
|
||||
count="$(grep -Ec '^core-log-[0-9]{3}' <<<"$output")"
|
||||
|
||||
Reference in New Issue
Block a user