Files
ForgeBucket/CHANGELOG.md
T

285 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
All notable changes to ForgeBucket are documented here.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
---
## [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)
- 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.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.go``CheckDrift` 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.go``TriggerSync` 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 `300`s); `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
---
[Unreleased]: https://github.com/forgeo/forgebucket/compare/v0.7.0...HEAD
[0.7.0]: https://github.com/forgeo/forgebucket/compare/v0.6.0...v0.7.0
[0.6.0]: https://github.com/forgeo/forgebucket/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/forgeo/forgebucket/compare/v0.4.0...v0.5.0
[0.4.0]: https://github.com/forgeo/forgebucket/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/forgeo/forgebucket/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/forgeo/forgebucket/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/forgeo/forgebucket/releases/tag/v0.1.0