feat: activate workspaces from the root catalog and bootstrap-only publication

This commit is contained in:
2026-08-11 14:49:46 +02:00
parent 86af45acb4
commit 25ec236f1f
10 changed files with 358 additions and 242 deletions
+12 -15
View File
@@ -66,6 +66,7 @@ const SAFE_MESSAGES = {
workspace_not_activatable: "Workspace cannot be activated on this installation.",
workspace_stale: "Workspace revision is stale.",
workspace_conflict: "Workspace changed in the registry.",
workspace_curator_owned: "Workspace descriptor is owned by the curator and must be changed through Git.",
git_unavailable: "Workspace Git service is unavailable.",
git_auth_failed: "Workspace Git authentication failed.",
git_non_fast_forward: "Workspace Git branch has changed.",
@@ -225,7 +226,7 @@ function workspaceErrorCode(error: unknown): keyof typeof SAFE_MESSAGES {
}
function workspaceErrorStatus(code: keyof typeof SAFE_MESSAGES): number {
if (code === "workspace_conflict" || code === "workspace_stale" || code === "git_non_fast_forward") return 409;
if (code === "workspace_conflict" || code === "workspace_curator_owned" || code === "workspace_stale" || code === "git_non_fast_forward") return 409;
if (code === "git_unavailable" || code === "git_auth_failed" || code === "git_push_rejected") return 503;
return 400;
}
@@ -297,20 +298,16 @@ export function workspaceRoutes(app: FastifyInstance, deps: WorkspaceRoutesDeps)
app.get("/workspaces", async (_request, reply) => {
try {
const revisions = await deps.registry.list();
return await Promise.all(revisions.map(async (revision) => {
const { workspace } = await deps.registry.read(revision.id);
return {
id: revision.id,
// Retain the metadata endpoint's selector fields while adding registry summary data.
name: revision.id,
file: `${revision.id}.yaml`,
displayName: workspace.workspace.name,
description: workspace.workspace.description,
language: workspace.workspace.language,
workspace,
revision,
};
const records = await deps.registry.listCatalog();
return records.map((record) => ({
id: record.id,
// Retain the metadata endpoint's selector field while adding catalog metadata.
name: record.id,
file: `${record.id}/workspace.yaml`,
displayName: record.name,
description: record.description,
configurationState: record.configurationState,
...(record.revision ? { revision: record.revision } : {}),
}));
} catch (error) {
return errorReply(reply, error);