mirror of
https://github.com/tale/headplane.git
synced 2026-10-25 22:20:30 +00:00
feat: start some cleanup
This commit is contained in:
@@ -121,7 +121,7 @@ jobs:
|
||||
TAG: ${{ github.ref_name }}
|
||||
LATEST: ${{ needs.channel.outputs.latest }}
|
||||
run: |
|
||||
node --disable-warning=ExperimentalWarning scripts/release.ts notes "$TAG" > "$RUNNER_TEMP/notes.md"
|
||||
node scripts/release.ts notes "$TAG" > "$RUNNER_TEMP/notes.md"
|
||||
if [[ "$TAG" == *-* ]]; then
|
||||
gh release create "$TAG" --title "$TAG" --notes-file "$RUNNER_TEMP/notes.md" --prerelease
|
||||
else
|
||||
|
||||
+26
-29
@@ -3,7 +3,7 @@ import pino from "pino";
|
||||
type Category = "server" | "config" | "agent" | "api" | "auth" | "sse";
|
||||
type Level = "info" | "warn" | "error" | "debug";
|
||||
|
||||
export interface Logger extends Record<
|
||||
interface Logger extends Record<
|
||||
Level,
|
||||
(category: Category, message: string, ...args: unknown[]) => void
|
||||
> {
|
||||
@@ -11,41 +11,38 @@ export interface Logger extends Record<
|
||||
}
|
||||
|
||||
const DEBUG_VALUES = new Set(["1", "true", "yes", "on"]);
|
||||
export default createLogger(process.env, defaultDestination());
|
||||
const debugEnabled = DEBUG_VALUES.has(process.env.HEADPLANE_DEBUG_LOG?.trim().toLowerCase() ?? "");
|
||||
|
||||
export function createLogger(env: NodeJS.ProcessEnv, destination: pino.DestinationStream): Logger {
|
||||
const debugEnabled = DEBUG_VALUES.has(env.HEADPLANE_DEBUG_LOG?.trim().toLowerCase() ?? "");
|
||||
const root = pino(
|
||||
{
|
||||
level: debugEnabled ? "debug" : "info",
|
||||
timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
|
||||
formatters: {
|
||||
level: (label: string) => ({ level: label }),
|
||||
},
|
||||
const root = pino(
|
||||
{
|
||||
level: debugEnabled ? "debug" : "info",
|
||||
timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
|
||||
formatters: {
|
||||
level: (label: string) => ({ level: label }),
|
||||
},
|
||||
destination,
|
||||
);
|
||||
},
|
||||
destination(),
|
||||
);
|
||||
|
||||
const at =
|
||||
(level: Level) =>
|
||||
(category: Category, message: string, ...args: unknown[]) =>
|
||||
root[level]({ component: category }, message, ...args);
|
||||
const at =
|
||||
(level: Level) =>
|
||||
(category: Category, message: string, ...args: unknown[]) =>
|
||||
root[level]({ component: category }, message, ...args);
|
||||
|
||||
return {
|
||||
debugEnabled,
|
||||
info: at("info"),
|
||||
warn: at("warn"),
|
||||
error: at("error"),
|
||||
debug: at("debug"),
|
||||
};
|
||||
}
|
||||
export default {
|
||||
debugEnabled,
|
||||
info: at("info"),
|
||||
warn: at("warn"),
|
||||
error: at("error"),
|
||||
debug: at("debug"),
|
||||
} satisfies Logger;
|
||||
|
||||
function defaultDestination(): pino.DestinationStream {
|
||||
function destination(): pino.DestinationStream {
|
||||
if (process.env.NODE_ENV === "test") {
|
||||
return { write: (line) => console.log(line.trimEnd()) };
|
||||
}
|
||||
|
||||
const destination = pino.destination({ dest: 1, sync: false });
|
||||
process.on("exit", () => destination.flushSync());
|
||||
return destination;
|
||||
const stream = pino.destination({ dest: 1, sync: false });
|
||||
process.on("exit", () => stream.flushSync());
|
||||
return stream;
|
||||
}
|
||||
|
||||
+3
-4
@@ -14,13 +14,13 @@
|
||||
"pretypecheck": "cn build -q --content 'app/**/*.{ts,tsx}' --css app/tailwind.css -o app/utils/cn-tables.ts",
|
||||
"typecheck": "react-router typegen && tsc",
|
||||
"test:unit": "vitest run --project unit",
|
||||
"test:integration": "vitest run --project integration --project integration:agent",
|
||||
"harness": "node --disable-warning=ExperimentalWarning --import tsx tests/harness/cli.ts",
|
||||
"test:integration": "vitest run --project integration:*",
|
||||
"harness": "node tests/harness/launch.ts",
|
||||
"docs:dev": "cd docs && react-router dev",
|
||||
"docs:build": "cd docs && react-router build && node scripts/finish-build.ts",
|
||||
"lint": "oxlint",
|
||||
"format": "oxfmt",
|
||||
"release": "node --disable-warning=ExperimentalWarning scripts/release.ts"
|
||||
"release": "node scripts/release.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@base-ui/react": "^1.9.0",
|
||||
@@ -76,7 +76,6 @@
|
||||
"tailwindcss": "^4.3.3",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"testcontainers": "^12.2.1",
|
||||
"tsx": "^4.23.15",
|
||||
"typescript": "7.0.2",
|
||||
"vite": "^8.3.4",
|
||||
"vitest": "^5.0.4"
|
||||
|
||||
Generated
+2
-3
@@ -175,9 +175,6 @@ importers:
|
||||
testcontainers:
|
||||
specifier: ^12.2.1
|
||||
version: 12.2.1
|
||||
tsx:
|
||||
specifier: ^4.23.15
|
||||
version: 4.23.15
|
||||
typescript:
|
||||
specifier: 7.0.2
|
||||
version: 7.0.2
|
||||
@@ -6349,6 +6346,7 @@ snapshots:
|
||||
'@esbuild/win32-arm64': 0.28.2
|
||||
'@esbuild/win32-ia32': 0.28.2
|
||||
'@esbuild/win32-x64': 0.28.2
|
||||
optional: true
|
||||
|
||||
escalade@3.2.0: {}
|
||||
|
||||
@@ -8413,6 +8411,7 @@ snapshots:
|
||||
esbuild: 0.28.2
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
optional: true
|
||||
|
||||
tunnel-agent@0.6.0:
|
||||
dependencies:
|
||||
|
||||
@@ -9,15 +9,10 @@ import { parseArgs } from "node:util";
|
||||
|
||||
import { stringify } from "yaml";
|
||||
|
||||
// Headplane's modules expect the build-time globals Vite defines.
|
||||
Object.assign(globalThis, { __VERSION__: "harness", __PREFIX__: "/admin" });
|
||||
|
||||
const { HARNESS_LABEL } = await import("./constants");
|
||||
const { applyScenario } = await import("./scenario");
|
||||
const { createTailnet } = await import("./tailnet");
|
||||
const { HEADSCALE_VERSIONS, LATEST_HEADSCALE } = await import("./versions");
|
||||
type Scenario = import("./scenario").Scenario;
|
||||
type HeadscaleVersion = import("./versions").HeadscaleVersion;
|
||||
import { HARNESS_LABEL } from "./constants";
|
||||
import { applyScenario, type Scenario } from "./scenario";
|
||||
import { createTailnet } from "./tailnet";
|
||||
import { HEADSCALE_VERSIONS, type HeadscaleVersion, LATEST_HEADSCALE } from "./versions";
|
||||
|
||||
const scenariosDir = join(import.meta.dirname, "scenarios");
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { createServer, createServerModuleRunner } from "vite";
|
||||
|
||||
const server = await createServer({
|
||||
configFile: "vitest.config.ts",
|
||||
logLevel: "error",
|
||||
appType: "custom",
|
||||
server: { middlewareMode: true, hmr: false, watch: null },
|
||||
});
|
||||
|
||||
await createServerModuleRunner(server.environments.ssr).import("/tests/harness/cli.ts");
|
||||
@@ -1,52 +0,0 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { createLogger } from "~/utils/log";
|
||||
|
||||
function capture(env: NodeJS.ProcessEnv) {
|
||||
const lines: Record<string, unknown>[] = [];
|
||||
const log = createLogger(env, { write: (line) => lines.push(JSON.parse(line)) });
|
||||
return { log, lines };
|
||||
}
|
||||
|
||||
describe("structured logger", () => {
|
||||
test("writes JSON log entries", () => {
|
||||
const { log, lines } = capture({});
|
||||
|
||||
log.info("server", "Listening on %s://%s:%s", "http", "127.0.0.1", 3000);
|
||||
|
||||
expect(lines).toEqual([
|
||||
expect.objectContaining({
|
||||
level: "info",
|
||||
component: "server",
|
||||
msg: "Listening on http://127.0.0.1:3000",
|
||||
timestamp: expect.any(String),
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
test.for([{}, { HEADPLANE_DEBUG_LOG: "false" }, { HEADPLANE_DEBUG_LOG: "nope" }])(
|
||||
"drops debug entries without HEADPLANE_DEBUG_LOG (%o)",
|
||||
(env) => {
|
||||
const { log, lines } = capture(env);
|
||||
|
||||
log.debug("api", "GET %s", "/v1/node");
|
||||
|
||||
expect(log.debugEnabled).toBe(false);
|
||||
expect(lines).toEqual([]);
|
||||
},
|
||||
);
|
||||
|
||||
test.for(["1", "true", " YES ", "on"])(
|
||||
"writes debug entries for HEADPLANE_DEBUG_LOG=%s",
|
||||
(value) => {
|
||||
const { log, lines } = capture({ HEADPLANE_DEBUG_LOG: value });
|
||||
|
||||
log.debug("api", "GET %s", "/v1/node");
|
||||
|
||||
expect(log.debugEnabled).toBe(true);
|
||||
expect(lines).toEqual([
|
||||
expect.objectContaining({ level: "debug", component: "api", msg: "GET /v1/node" }),
|
||||
]);
|
||||
},
|
||||
);
|
||||
});
|
||||
+1
-2
@@ -29,7 +29,7 @@ export default defineConfig({
|
||||
{
|
||||
extends: true,
|
||||
test: {
|
||||
name: "integration",
|
||||
name: "integration:app",
|
||||
include: ["tests/integration/**/*.test.ts"],
|
||||
exclude: ["node_modules/**", "build/**", "tests/integration/agent/**"],
|
||||
testTimeout: 120_000,
|
||||
@@ -49,7 +49,6 @@ export default defineConfig({
|
||||
],
|
||||
environment: "node",
|
||||
silent: "passed-only",
|
||||
execArgv: ["--disable-warning=ExperimentalWarning"],
|
||||
exclude: ["node_modules/**", "build/**"],
|
||||
},
|
||||
resolve: {
|
||||
|
||||
Reference in New Issue
Block a user