Files
ForgeBucket/CHANGELOG.md
T
2026-05-12 20:32:30 +02:00

16 KiB
Raw Blame History

Changelog

All notable changes to ForgeBucket are documented here.

Format follows Keep a Changelog. Versions follow Semantic Versioning.


Unreleased

Planned — Phase 3E (Observability)

  • Prometheus metrics endpoint GET /metrics
  • Structured internal metrics: pipeline duration, queue depth, deployment frequency, error rates
  • Health check endpoint GET /health returning DB + NATS status
  • Environment cards: live health status via HTTP health check polling
  • Repo page: error rate and deployment frequency sparklines

Planned — Phase 3F (Federation, next)

  • ActivityPub inbox/outbox HTTP handlers
  • HTTP signature verification middleware
  • WebFinger /.well-known/webfinger endpoint
  • Cross-instance pull requests via ActivityPub activities

Planned — Phase 4 (Intelligence + Artifacts)

  • AI failure diagnosis (pipeline failure root-cause analysis via Claude API)
  • AI deployment risk scoring
  • Signed artifacts (Sigstore/Cosign)
  • SBOM generation (CycloneDX/SPDX)
  • OCI container registry
  • Secret scanning (commit-level pattern detection)
  • Dependency vulnerability scanning

0.8.0 — 2026-05-12

Phase 3E complete. Prometheus metrics, structured health checks, and per-repo operational health are operational.

Added — Prometheus Metrics (internal/observability/)

  • GET /metrics — Prometheus text format endpoint (standard root-level path for k8s/Prometheus scraping)
  • GET /health — upgraded from static {"status":"ok"} to a structured liveness response: {"status":"healthy","checks":{"database":"ok","nats":"ok"},"version":"0.8.0"} Returns HTTP 503 when any dependency is degraded
  • internal/observability/metrics.go — metric definitions:
    • forgebucket_http_requests_total{method,path,status} — counter
    • forgebucket_http_request_duration_seconds{method,path} — histogram (Prometheus default buckets)
    • forgebucket_pipeline_runs_total{status} — counter (succeeded/failed/cancelled), pre-initialized to 0
    • forgebucket_deployments_total{status} — counter (pending/success/failure/cancelled), pre-initialized to 0
    • forgebucket_active_pipeline_runs — gauge (in-flight runs)
  • internal/observability/health.goCheck(db, bus) pings PostgreSQL and calls bus.Healthy()
  • HTTP instrumentation middleware inserted after Recoverer, before CORS — records every request
  • Path normalization prevents label cardinality explosion: /repos/alice/myrepo/runs/42/api/v1/repos/:owner/:repo/runs/:id
  • NATS metric watcher subscribes to pipeline.> and deployment.> and increments counters

Added — Per-Repo Operational Health (GET /api/v1/repos/{owner}/{repo}/health)

  • Returns a JSON summary for the repo page operational header:
    • ciPassRate7d — fraction of pipeline runs that succeeded in the last 7 days
    • totalRuns7d — total run count in the last 7 days
    • latestRun — most recent PipelineRun record
    • latestDeployments — one entry per environment showing latest deploy (envName, status, sha, finishedAt)
    • openDriftCount — GitOpsConfigs in drifted state
    • openPRCount — open pull request count

Added — EventBus Healthy() bool

  • Added to the EventBus interface; NATSBus returns nc.IsConnected(); NoOpBus returns true

Changed — Middleware chain

  • observability.Middleware() added between Recoverer and CORS (applies to all requests including /health and /metrics)

0.7.0 — 2026-05-12

Phase 3D complete. Git is now the source of truth for environment deployment state.

Added — GitOps Controller (internal/domain/gitops/)

  • controller.go — starts as a background goroutine; subscribes to push.received, deployment.succeeded, deployment.failed; runs a periodic reconciliation ticker (interval configurable via GITOPS_RECONCILE_INTERVAL); recovers stale syncing configs to drifted on startup
  • drift.goCheckDrift calls git rev-parse via the existing git domain wrapper; handlePush queries all GitOpsConfigs matching the pushed branch and evaluates drift; periodicCheck iterates configs whose SyncInterval has elapsed; publishes environment.drift_detected when drift is found
  • reconciler.goTriggerSync creates a Deployment record and publishes deployment.started (same lifecycle path as manual deployments, TriggeredBy="gitops"); handleDeploymentSucceeded resolves open drift events and marks config synced for both GitOps and manual deployments; handleDeploymentFailed reverts to drifted

Added — GitOps HTTP API (internal/api/handlers/gitops.go)

All routes live under /api/v1/repos/{owner}/{repo}/environments/{envName}/gitops/:

  • GET /gitops — current GitOpsConfig or 404 if not configured
  • PUT /gitops — idempotent upsert (branch, autoSync, syncInterval)
  • DELETE /gitops — remove config without deleting deployments
  • POST /gitops/sync — manual reconciliation trigger; creates deployment record
  • GET /gitops/drift — current sync status: syncStatus, desiredSha, actualSha, isDrifted
  • GET /gitops/drift/history — paginated drift event log (newest first)
  • POST /gitops/drift/{driftID}/acknowledge — acknowledge without syncing

Added — Database Models (migration 013_gitops)

  • GitOpsConfig — links environment to a branch; tracks DesiredSHA, ActualSHA, SyncStatus (unknown/synced/drifted/syncing), AutoSync, SyncInterval, LastCheckedAt
  • GitOpsDriftEvent — append-only drift record: DesiredSHA, ActualSHA, SyncStatus (drifted/synced/acknowledged), DetectedAt, ResolvedAt

Added — Supporting Changes

  • git.RevParse(repoPath, ref) — new function in internal/domain/git/binary.go used by CheckDrift to resolve branch HEAD SHA
  • events.DeploymentEvent + events.DriftEvent types added to internal/events/types.go
  • EnvironmentHandler.publishDeployEvent updated to use shared events.DeploymentEvent so the GitOps controller can unmarshal deployment lifecycle events correctly
  • GITOPS_RECONCILE_INTERVAL env var (default 300s); 0 disables the periodic ticker
  • ArtifactRoot config field + ARTIFACT_ROOT env var

0.6.0 — 2026-05-12

Phase 3C complete. Multi-tenant workspaces and a full secret management hierarchy operational.

Added — Workspaces

  • Workspace model (migration 011): globally unique handle, display name, description, avatarUrl
  • WorkspaceMember model: owner/admin/member roles per workspace
  • Repository workspace_id column (optional; null = personal repo)
  • Full workspace CRUD API: GET/POST /api/v1/workspaces, GET/PATCH/DELETE /api/v1/workspaces/{handle}
  • Workspace member management: list, add, update role, remove
  • GET /api/v1/workspaces/{handle}/repos — repos in workspace
  • Workspace frontend: WorkspacesPage, WorkspacePage, workspace switcher in sidebar header
  • Workspace owner selector in repo create flow

Added — Secret Management (internal/api/handlers/secret.go)

  • Secret model (migration 012): Scope (global/workspace/repo/env), ScopeID, Name, EncryptedValue (AES-256-GCM, never returned by API)
  • Unique constraint on (scope, scope_id, name)
  • CRUD at all scope levels:
    • GET/POST/DELETE /api/v1/admin/secrets (global, admin-only)
    • GET/POST/DELETE /api/v1/workspaces/{handle}/secrets (workspace-scoped)
    • GET/POST/DELETE /api/v1/repos/{owner}/{repo}/secrets (repo-scoped)
    • GET/POST/DELETE /api/v1/repos/{owner}/{repo}/environments/{envName}/secrets (env-scoped)
  • ResolveSecretsForRun(db, repoID, workspaceID, envID, sessionSecret) — hierarchy resolution for CI executor: Env > Repo > Workspace > Global
  • CI executor updated to inject resolved secrets as Docker --env flags
  • RepoSecretsPage — write-only UI, values never displayed after creation
  • Sidebar "Secrets" nav item in repo context

0.5.0 — 2026-05-11

Phases 3A and 3B complete. Environments, deployments, and the operational timeline are operational.

Added — Environments + Deployments (Phase 3A)

  • Environment model (migration 010): repoId, name, URL, protectionRules (JSON)
  • Deployment model: envId, repoId, sha, ref, status lifecycle (pending → in_progress → success/failure/cancelled), triggeredBy, description, runId link
  • CRUD API for environments: GET/POST /environments, GET/PATCH/DELETE /environments/{envName}
  • Deployment API: GET/POST /environments/{envName}/deployments, PATCH /environments/{envName}/deployments/{id}/status
  • NATS events published on status transitions: deployment.started, deployment.succeeded, deployment.failed
  • EnvironmentsPage — environment cards each showing latest deployment status, SHA, actor, and time since deploy; deployment history per env
  • Sidebar "Environments" nav item in repo context
  • Repo page deployment status badges (latest deploy per env at a glance)

Added — Unified Operational Timeline (Phase 3B)

  • GET /api/v1/repos/{owner}/{repo}/timeline — merged chronological feed of commits, pipeline runs, and deployments; default 60 events, max 200
  • RepoTimelinePage at /repos/:owner/:repo/timeline — vertical event feed with type filter tabs (all / commits / runs / deployments)
  • Sidebar "Timeline" nav item between Environments and Settings
  • Answers "what changed before things broke?" without navigating between separate pages

0.4.0 — 2026-05-11

Phase 2C complete. CI results are legible in the UI; the dashboard is an operational command center.

Added — Pipeline Visualization

  • PipelinesPage — cross-repo pipeline runs feed with status filter tabs (all / running / failed / succeeded)
  • RepoPipelinesPage — repo-scoped runs list at /repos/:owner/:repo/pipelines
  • PipelineRunPage — run detail with topological DAG visualization using real PipelineJob[] + needs graph; step log viewer (collapsible per step, ANSI color, auto-scroll with lock toggle)
  • PipelineWaterfall — rewritten to accept live job data instead of static mock stages
  • GET /api/v1/pipelines/runs — cross-repo recent runs for the dashboard

Added — Dashboard CI Command Center

  • Dashboard CI widget replaced "coming soon" with live recent pipeline runs
  • Dashboard recentRuns[] field added to the /api/v1/dashboard response

Added — Command Palette Wiring

  • Pipeline run results surfaced in command palette results
  • "Pipelines" quick-nav action

0.3.0 — 2026-05-11

Phase 2B complete. Full CI/CD execution backend operational.

Added — CI Orchestrator (internal/domain/ci/)

  • DAG-based pipeline orchestrator (orchestrator.go): subscribes to NATS push.received, parses .forgebucket/workflows/*.yml, creates PipelineRun/Job/Step records, advances DAG on job.completed/failed, recovers stale runs on startup
  • Docker executor (executor.go): steps run in isolated containers (docker run --rm), logs stream to DB and NATS via pipeline.log, workspace extracted via git archive
  • Runner manager (runner_manager.go): semaphore-limited (default 4 concurrent), subscribes to job.queued, skips gracefully if Docker is unavailable
  • DAG engine (dag.go): TopoSort, ReadyJobs
  • Workflow parser (parser.go): .forgebucket/workflows/*.yml from git ref, MatchesPushTrigger with glob branch patterns; StringOrSlice YAML unmarshaler

Added — CI API Handlers

  • GET /api/v1/repos/:owner/:repo/pipelines — pipeline definitions
  • GET /api/v1/repos/:owner/:repo/runs — pipeline runs (newest first)
  • GET /api/v1/repos/:owner/:repo/runs/:runID — run detail with job + step tree
  • POST /api/v1/repos/:owner/:repo/runs/:runID/cancel
  • POST /api/v1/repos/:owner/:repo/runs/:runID/jobs/:jobID/retry
  • GET /api/v1/repos/:owner/:repo/runs/:runID/jobs/:jobID/logs — step log chunks
  • GET/POST /api/v1/repos/:owner/:repo/runs/:runID/artifacts
  • GET /api/v1/repos/:owner/:repo/artifacts/:artifactID/download — path-traversal guarded
  • GET/POST /api/v1/admin/runners — runner list + registration (admin-only, bcrypt token)

Added — Database Models (migration 009_ci)

  • Pipeline, PipelineRun, PipelineJob, PipelineStep, PipelineStepLog
  • Runner (name, labels, status, tokenHash, lastSeenAt)
  • Artifact (runId, repoId, name, storagePath, size, contentType)

Changed — Git HTTP handler

  • parseAndCheckBody replaces checkProtectionsFromBody — now also returns parsed refUpdate structs for publishing push.received after each successful receive-pack

0.2.0 — 2026-05-11

Phase 2A complete. Real-time event infrastructure and audit log operational.

Added — NATS Event Bus (internal/events/)

  • EventBus interface: Publish, Subscribe, Close
  • NATSBus: NATS-backed with auto-reconnect; NoOpBus fallback when NATS_URL unset
  • New(url) factory: returns NATSBus or NoOpBus
  • 40+ event subjects in subjects.go covering repo, push, PR, issue, pipeline, job, deployment, environment, and audit namespaces

Added — WebSocket Hub

  • GET /ws — NATS wildcard subscription (>) fans all events to connected clients as JSON
  • { subject, payload } envelope format
  • Goroutine per client with buffered send channel (64 events); slow clients drop events

Added — Audit Log (migration 008_audit_log)

  • AuditLog model: actorId, actorName, method, path, statusCode, ipAddress, userAgent
  • Middleware records every POST/PUT/PATCH/DELETE in the protected route group
  • Writes DB row + publishes audit.event asynchronously (never blocks the response)
  • GET /api/v1/audit — paginated, filterable by actor/method/since (admin-only)

0.1.0 — 2026-05-11

Initial development milestone. Core Git hosting, collaboration, and frontend SPA functional.

Added — Authentication & Security

  • User registration and login with secure session cookies
  • CSRF protection via double-submit cookie pattern (X-CSRF-Token)
  • SSH key management per user
  • OIDC / OAuth2 optional integration
  • Scoped access tokens with optional expiration
  • Repository deploy keys (read-only or read-write)
  • ENV-driven config with fail-fast on missing secrets

Added — Git Hosting

  • Smart HTTP transport (clone, push, pull over HTTP)
  • AGit protocol (refs/for/ push for instant PR creation)
  • Branch management, commit log, diff viewing
  • Git LFS per-repository (configurable file size limits)
  • Branch protection rules (force-push blocking)
  • Repository visibility (public / private)

Added — Collaboration

  • Pull requests (open / merged / closed) with author tracking
  • Issues (open / closed)
  • Reviewer assignment (default reviewer per repo, per-PR overrides)
  • Merge strategy selection per repository (merge / squash / rebase)
  • Branching model configuration (feature / bugfix / release / hotfix prefixes)
  • PR default description templates + excluded-files configuration
  • Webhook system with event filtering (push, pull_request, issue)
  • Repository member RBAC (read / write / admin)

Added — Frontend SPA

  • React 18 + TypeScript + Vite, embedded into Go binary via //go:embed
  • 20 route-level pages covering auth, dashboard, repos, code, PRs, issues, and settings
  • Triple-state sidebar: expanded (320px) / collapsed (56px) / mobile bottom bar
  • Mobile-first responsive design (375px → 1440px)
  • DiffViewer (side-by-side + unified), MobileComment (bottom-sheet), TreeBrowser

Added — Design System

  • Custom semantic token palette in frontend/src/ui/tokens.ts
  • Full dark/light mode via Tailwind CSS v4 @variant dark
  • 8px grid system; 44px minimum touch targets (WCAG 2.5.5)
  • System font stack (Segoe UI, Roboto, sans-serif)

Added — Infrastructure

  • PostgreSQL + XORM with migrations 001007
  • ActivityPub actor data model (FederationActor) — data layer only
  • Docker Compose for local PostgreSQL + NATS
  • Makefile: dev, build, migrate, test, lint, docker-up