feat(health): migrate VERSION file to merkwerk integration (#83)

- Replace read_version() with merkwerk.get_health_info()
- Health endpoint now returns content_hash, vcs_info, source tracking
- Add merkwerk_integrated feature flag
- Enhanced startup logs with content-hash and VCS info
- Maintain backward compatibility with version field
- lua51 compatible integration for OpenBSD deployment

Migration from static VERSION file to dynamic merkwerk version tracking.
Health endpoint now provides rich metadata for debugging and monitoring.

Resolves DAW/furt#83
This commit is contained in:
michael 2025-08-19 21:28:22 +02:00
parent 7053af3c0d
commit 00b8a18527
3 changed files with 276 additions and 18 deletions

View file

@ -13,23 +13,29 @@ local AuthRoute = require("src.routes.auth")
-- Load configuration
local config = require("config.server")
-- Read version from VERSION file
local function read_version()
local file, err = io.open("VERSION", "r")
if not file then
print("WARNING: Could not read VERSION file: " .. (err or "unknown error"))
return "?.?.?"
local function get_version_info()
-- Load merkwerk integration
local success, merkwerk = pcall(require, "integrations.lua-api")
if not success then
print("WARNING: merkwerk integration not available, using fallback")
return {
service = "furt-lua",
version = "?.?.?",
content_hash = "unknown",
vcs_info = { type = "none", hash = "", branch = "" },
source = "fallback-no-merkwerk"
}
end
local version = file:read("*line")
file:close()
-- Get merkwerk health info
local health_info = merkwerk.get_health_info()
if not version or version:match("^%s*$") then
print("WARNING: VERSION file is empty or contains only whitespace")
return "?.?.?"
-- Ensure compatibility with old VERSION-only expectations
if not health_info.version then
health_info.version = "?.?.?"
end
return version:match("^%s*(.-)%s*$") -- trim whitespace
return health_info
end
-- HTTP-Server Module
@ -243,10 +249,12 @@ function FurtServer:start()
error("Failed to bind to " .. self.host .. ":" .. self.port)
end
local version = read_version()
local version_info = get_version_info()
print(string.format("Furt HTTP-Server started on %s:%d", self.host, self.port))
print("Version: " .. version)
print("Version: " .. version_info.version .. " (merkwerk)")
print("Content-Hash: " .. (version_info.content_hash or "unknown"))
print("VCS: " .. (version_info.vcs_info and version_info.vcs_info.hash or "none"))
print("API-Key authentication: ENABLED")
print("Rate limiting: ENABLED (60 req/hour per API key, 100 req/hour per IP)")
print("CORS enabled for configured origins")
@ -267,16 +275,20 @@ local server = FurtServer:new()
-- Public routes (no authentication required)
server:add_route("GET", "/health", function(request, server)
local version = read_version()
local version_info = get_version_info()
local response_data = {
status = "healthy",
service = "furt-lua",
version = version,
service = version_info.service or "furt-lua",
version = version_info.version,
content_hash = version_info.content_hash,
vcs_info = version_info.vcs_info,
timestamp = os.time(),
source = version_info.source,
features = {
smtp_configured = config.mail and config.mail.username ~= nil,
auth_enabled = true,
rate_limiting = true
rate_limiting = true,
merkwerk_integrated = version_info.source == "merkwerk"
}
}
return server:create_response(200, response_data, nil, nil, request)