feat: build and publish the gateway image via Forgejo Actions

- Dockerfile: multi-stage, distroless nonroot, CGO_ENABLED=0 static, commit
  SHA stamped via VERSION build arg.
- .forgejo/workflows/ci.yaml: Forgejo reads .forgejo/, not .github/, and the
  runner declares only the "docker" label. Verify job on every push; image
  build and push gated to main.
- Drop .github/workflows/ci.yml — this remote is Forgejo, so it never ran.
- deployment.yaml: image from the Forgejo registry, forgejo-registry pull
  secret, runAsUser 65532 to match distroless nonroot.
- kustomization.yaml: pin the tag in one place. Promoting a build is a
  one-line newTag bump, never :latest.
This commit is contained in:
Story Crater Bot
2026-08-19 21:48:11 -07:00
parent 058f11cf2b
commit b0ce2fb67c
8 changed files with 1527 additions and 84 deletions
+17 -3
View File
@@ -13,15 +13,29 @@ import (
)
// RouteRequest determines which upstream should handle the request.
// For /v1/* routes, it uses body-based dispatch (reads JSON to find "model" field).
// For other routes, it returns the single configured route.
// For /v1/chat/completions, it uses body-based dispatch (reads JSON to find "model" field).
// For other routes, it looks up by path prefix.
func (h *Handler) RouteRequest(r *http.Request) (*Route, error) {
// For /v1/chat/completions, use body-based dispatch
if r.URL.Path == "/v1/chat/completions" && r.Method == "POST" {
return h.routeByModel(r)
}
// For other paths, return the first (and usually only) route
// For other paths, try to find a matching route by path
// Look for exact path match or path prefix match
for _, route := range h.routes {
// Check if route's pathRewrite matches request path
if route.Upstream.PathRewrite != "" && route.Upstream.PathRewrite == r.URL.Path {
return route, nil
}
}
// If no routes configured, return error
if len(h.routes) == 0 {
return nil, fmt.Errorf("no routes configured")
}
// Return the first configured route as fallback
for _, route := range h.routes {
return route, nil
}