refactor: remove lite variant, fix release workflow

- Remove all lite/full variant logic from frontend, API, shared constants,
  docs, and tests (single unified Docker image only)
- Replace single QEMU multi-arch Docker build with per-architecture native
  builds (amd64 + arm64) and manifest merge to fix disk space exhaustion
- Add disk cleanup step and per-platform build cache scopes
- Switch release trigger from push to workflow_dispatch
- Add GitHub issue templates and PR template
This commit is contained in:
Siddharth Kumar Sah
2026-04-10 17:38:54 +08:00
parent b0083e2b08
commit 958b10cb45
32 changed files with 311 additions and 424 deletions
-8
View File
@@ -23,14 +23,6 @@ import { teamsRoutes } from "./routes/teams.js";
import { registerToolRoutes } from "./routes/tools/index.js";
import { userFileRoutes } from "./routes/user-files.js";
// Warn about deprecated STIRLING_VARIANT env var
if (process.env.STIRLING_VARIANT) {
console.warn(
`WARNING: STIRLING_VARIANT="${process.env.STIRLING_VARIANT}" is set but ignored. ` +
"There is now a single unified image with all features. Remove STIRLING_VARIANT from your environment.",
);
}
// Run before anything else
runMigrations();
console.log("Database initialized");
+1 -5
View File
@@ -6,7 +6,6 @@
* GET /api/v1/settings/:key — Get a specific setting
*/
import { PYTHON_SIDECAR_TOOLS } from "@stirling-image/shared";
import { eq } from "drizzle-orm";
import type { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { db, schema } from "../db/index.js";
@@ -27,10 +26,7 @@ export async function settingsRoutes(app: FastifyInstance): Promise<void> {
settings[row.key] = row.value;
}
const variant = process.env.STIRLING_VARIANT === "lite" ? "lite" : "full";
const variantUnavailableTools = variant === "lite" ? [...PYTHON_SIDECAR_TOOLS] : [];
return reply.send({ settings, variant, variantUnavailableTools });
return reply.send({ settings });
});
// PUT /api/v1/settings — Save settings (admin only)
+3 -21
View File
@@ -1,4 +1,4 @@
import { PYTHON_SIDECAR_TOOLS, TOOLS } from "@stirling-image/shared";
import { TOOLS } from "@stirling-image/shared";
import { eq } from "drizzle-orm";
import type { FastifyInstance } from "fastify";
import { db, schema } from "../../db/index.js";
@@ -69,10 +69,6 @@ export async function registerToolRoutes(app: FastifyInstance): Promise<void> {
// Build skip set
const skipTools = new Set([...disabledTools, ...(enableExperimental ? [] : experimentalToolIds)]);
// In lite mode, register 501 stubs for AI tools instead of real handlers
const isLite = process.env.STIRLING_VARIANT === "lite";
const liteStubTools = new Set<string>(PYTHON_SIDECAR_TOOLS);
const toolRegistrations: Array<{
id: string;
register: (app: FastifyInstance) => void;
@@ -131,7 +127,6 @@ export async function registerToolRoutes(app: FastifyInstance): Promise<void> {
];
let skipped = 0;
let stubbed = 0;
for (const { id, register } of toolRegistrations) {
if (skipTools.has(id)) {
app.log.info(`Skipping disabled/experimental tool: ${id}`);
@@ -139,24 +134,11 @@ export async function registerToolRoutes(app: FastifyInstance): Promise<void> {
continue;
}
if (isLite && liteStubTools.has(id)) {
// Register a 501 stub instead of the real handler
app.post(`/api/v1/tools/${id}`, async (_request, reply) => {
return reply.status(501).send({
statusCode: 501,
error: "Not Available",
message: `The "${id}" tool requires the full image. Pull stirlingimage/stirling-image:latest for all features.`,
});
});
stubbed++;
continue;
}
register(app);
}
const registered = toolRegistrations.length - skipped - stubbed;
const registered = toolRegistrations.length - skipped;
app.log.info(
`Tool routes: ${registered} active, ${stubbed} lite-stubbed, ${skipped} skipped (${toolRegistrations.length} total)`,
`Tool routes: ${registered} active, ${skipped} skipped (${toolRegistrations.length} total)`,
);
}