Files
ForgeBucket/CHANGELOG.md
T
erangel1 edf3c9824e Phase 3C — Commit Summary
feat: workspaces — collaborative repo namespaces
Backend
- internal/models/workspace.go — Workspace (handle, displayName,
  description, createdBy) + WorkspaceMember (workspaceId, userId,
  username, role: owner/admin/member)
- internal/models/repo.go — added nullable workspace_id column; existing
  user repos unaffected
- internal/models/migrations/011_workspaces.go — syncs both tables +
  adds column to repository
- internal/api/handlers/workspace.go — ListWorkspaces, CreateWorkspace,
  GetWorkspace, UpdateWorkspace, DeleteWorkspace (blocks if repos
  remain), ListRepos, ListMembers, AddMember, UpdateMember, RemoveMember
- internal/api/handlers/repos.go — lookupRepo resolves workspace
  handles; Create accepts workspace field; List includes workspace
  member repos; withOwnerName uses workspace handle for workspace-owned
  repos
- internal/api/handlers/dashboard.go — recentRuns + repo list include
  workspace repos the user is a member of
- internal/api/router.go — /workspaces, /workspaces/:handle/* routes
  Workspace rules enforced:
- Handle globally unique across usernames + workspace handles (409 on
  collision)
- Creator auto-assigned owner role
- Delete blocked if repos exist
- Last owner cannot be demoted/removed
  ---
  feat: secret management hierarchy (Global → Workspace → Repo → Env)
  Backend
- internal/models/secret.go — Secret struct +
  EncryptSecret/DecryptSecret with AES-256-GCM (key = SHA-256 of
  SESSION_SECRET); values never serialised to JSON
- internal/models/migrations/012_secrets.go — syncs secret table
- internal/api/handlers/secret.go — List/Upsert/Delete for all four
  scopes; ResolveSecretsForRun builds merged env map for CI
- internal/domain/ci/executor.go — JobContext.Secrets field; secrets
  injected as --env KEY=VALUE into docker run; buildJobContext calls
  resolveSecrets(Global < Workspace < Repo < Env)
- internal/domain/ci/runner_manager.go — passes cfg.SessionSecret to
  buildJobContext
- internal/api/router.go — /repos/:owner/:repo/secrets,
  /environments/:envName/secrets, /workspaces/:handle/secrets,
  /admin/secrets
  ---
  feat: workspace + secret management UI
  Frontend
- types/api.ts — Workspace, WorkspaceWithMeta, WorkspaceMember,
  SecretListItem types
- api/queries/workspaces.ts — full CRUD hooks + WorkspaceRepo type
- api/queries/secrets.ts — repo/env/workspace secret hooks
- pages/WorkspacesPage.tsx — list + create modal
- pages/WorkspacePage.tsx — workspace dashboard with repo list
- pages/WorkspaceSettingsPage.tsx — general settings, members CRUD,
  workspace secrets, danger zone
- pages/RepoSecretsPage.tsx — repo secrets + per-environment secret
  sections with priority hierarchy callout
- pages/CreateRepoPage.tsx — ?workspace= query param pre-fills owner
  selector; only admin/owner workspaces shown
- components/layout/Sidebar.tsx — "Workspaces" global nav item +
  workspace quick-links; "Secrets" in RepoSubNav; new SecretsIcon,
  WorkspaceIcon
- App.tsx — routes for /workspaces, /workspaces/:handle,
  /workspaces/:handle/settings, /repos/:owner/:repo/secrets
2026-05-11 23:34:46 +02:00

221 lines
12 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]
### In Progress — Phase 3C (Workspaces + Secret management hierarchy)
- `Workspace` model — named collaborative namespace (handle, displayName, description, avatarUrl)
- `WorkspaceMember` model — user membership with owner/admin/member roles
- Repos can be owned by a workspace; URL format stays `/{owner}/{repo}` where owner is a workspace handle or username
- `Secret` model — AES-256-GCM encrypted, scoped to global / workspace / repo / env
- Secret hierarchy resolution in CI executor: Env → Repo → Workspace → Global
- Full CRUD APIs for workspaces, workspace members, secrets at all scope levels
- WorkspacesPage, WorkspacePage, WorkspaceSettingsPage (settings + members)
- Workspace switcher in sidebar header
- Create repo: workspace owner selector
- RepoSecretsPage — write-only secret management per repo and per environment
- Sidebar "Secrets" nav item in repo context
### Completed — Phase 3B (Unified Operational Timeline)
- `GET /api/v1/repos/:owner/:repo/timeline` — merges commits, pipeline runs, and deployments into a single chronological feed
- `RepoTimelinePage` at `/repos/:owner/:repo/timeline` — vertical event feed with type filter tabs
- Sidebar "Timeline" nav item between Environments and Settings
- Event types: commit (SHA, message, author), run (status, ref, duration), deployment (env, status, SHA)
### Completed — Phase 3A (Environment model + deployment tracking)
- `Environment` model per repo (name, URL, protection rules)
- `Deployment` model (sha, ref, status, triggered_by, run_id link)
- Full CRUD API for environments
- Deployment trigger + status update API
- NATS event publishing for `deployment.*` subjects
- `EnvironmentsPage` per repo — environment cards with live deployment status
- Deployment history per environment
- Sidebar "Environments" nav item
- Repo page deployment status badges
### Completed — Phase 2C (CI Legibility)
- `PipelinesPage` — real cross-repo runs feed with status filter tabs
- `RepoPipelinesPage` — repo-scoped runs list at `/repos/:owner/:repo/pipelines`
- `PipelineRunPage` — run detail with topological DAG visualization + step log viewer
- `PipelineWaterfall` — rewritten to accept real `PipelineJob[]` data with `needs` graph
- Dashboard CI widget — live recent runs replacing "coming soon" placeholder
- Command palette — pipeline run results + Pipelines quick-nav
- `GET /api/v1/pipelines/runs` — cross-repo recent runs endpoint
- Dashboard `recentRuns[]` field added
### Planned — Phase 3 (GitOps + Observability + Federation)
- GitOps controller with reconciliation loops
- Environment model + deployment tracking
- Unified operational timeline (commits + deployments + CI failures merged)
- Drift detection and sync status
- Deployment promotion workflows (dev → staging → production)
- Rollback visualization and one-click rollbacks
- Canary and blue/green deployment support
- ActivityPub / ForgeFed federation handlers (inbox, outbox, cross-instance PRs)
- Secret management hierarchy (Global → Org → Repo → Env)
- Observability (Prometheus endpoint, health sparklines)
### Planned — Phase 4
- AI diagnostics (pipeline failure root-cause analysis)
- Signed artifacts (Sigstore/Cosign)
- OCI package registry
- Secret and dependency vulnerability scanning
---
## [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`/`PipelineJob`/`PipelineStep`
records, advances DAG on `job.completed`/`job.failed`, recovers stale runs on startup
- Docker executor (`executor.go`): runs steps in isolated containers (`docker run --rm`),
streams logs to DB and NATS via `pipeline.log` subject, handles `git archive` workspace extraction
- Runner manager (`runner_manager.go`): semaphore-limited concurrent job dispatch (default 4),
subscribes to `job.queued`, calls executor when Docker is available
- DAG engine (`dag.go`): full topological sort (`TopoSort`) and `ReadyJobs` for dependency resolution
- Workflow parser (`parser.go`): reads `.forgebucket/workflows/*.yml` from git ref,
`MatchesPushTrigger` with glob pattern support
- CI types (`types.go`): `WorkflowFile`, `WorkflowJob`, `WorkflowStep`, YAML `StringOrSlice` unmarshaler
### Added — CI API Handlers
- `GET /api/v1/repos/:owner/:repo/pipelines` — list pipeline definitions
- `GET /api/v1/repos/:owner/:repo/runs` — list pipeline runs (most recent first, limit 30)
- `GET /api/v1/repos/:owner/:repo/runs/:runID` — run detail with full job + step tree
- `POST /api/v1/repos/:owner/:repo/runs/:runID/cancel` — cancel queued or running run
- `POST /api/v1/repos/:owner/:repo/runs/:runID/jobs/:jobID/retry` — re-queue failed/cancelled job
- `GET /api/v1/repos/:owner/:repo/runs/:runID/jobs/:jobID/logs` — step-level log chunks
- `GET /api/v1/repos/:owner/:repo/runs/:runID/artifacts` — list artifacts for a run
- `POST /api/v1/repos/:owner/:repo/runs/:runID/artifacts` — upload artifact (multipart, 512 MB max)
- `GET /api/v1/repos/:owner/:repo/artifacts/:artifactID/download` — artifact download with path traversal guard
- `GET /api/v1/admin/runners` — list registered runners (admin-only)
- `POST /api/v1/admin/runners/register` — register a new runner with bcrypt token hashing (admin-only)
### Added — Database Models (migration `009_ci`)
- `Pipeline` — workflow definition record (name, filePath, repoId)
- `PipelineRun` — execution record (triggerRef, triggerSha, triggeredBy, status, startedAt, finishedAt)
- `PipelineJob` — single DAG node (name, image, needs JSON, status, timing)
- `PipelineStep` — single command within a job (seq, runCmd, usesAction, exitCode, timing)
- `PipelineStepLog` — append-only log chunk storage (stepId, chunkIndex, content)
- `Runner` — registered execution backend (name, labels, status, tokenHash, lastSeenAt)
- `Artifact` — build artifact (runId, repoId, name, storagePath, size, contentType)
---
## [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 implementation with auto-reconnect, max-reconnect disabled
- `NoOpBus`: silent fallback when `NATS_URL` is not configured (app fully functional without NATS)
- `New(url)` factory: returns `NATSBus` if URL is set, `NoOpBus` otherwise
- Event subjects defined in `subjects.go`:
- `repo.*` (created, deleted, pushed)
- `push.received`
- `pr.*` (opened, merged, closed)
- `issue.*` (opened, closed)
- `pipeline.*` (queued, started, succeeded, failed, cancelled)
- `job.*` (queued, started, completed, failed), `pipeline.log`
- `deployment.*`, `environment.*` (Phase 3 stubs)
- `audit.event`
### Added — WebSocket Hub (`internal/api/handlers/ws.go`)
- `GET /ws` — upgrades HTTP to WebSocket (nhooyr.io/websocket)
- Subscribes to all NATS subjects on connect, fans events to the client as JSON
- Optional session auth (`auth.Optional` middleware) — works for guests too
- Phase 2B note: per-user event filtering is a planned upgrade
### Added — Audit Log
- `AuditLog` model (migration `008_audit_log`): actor, method, path, statusCode, requestBody, ipAddr, timestamp
- `AuditLog` middleware: records every authenticated request to the DB and publishes `audit.event`
- `GET /api/v1/audit` — paginated audit log query (admin-only, filterable by actor/method/time range)
### Fixed — Local development environment
- `DATABASE_URL` was using Docker-internal hostname `postgres`; corrected to `localhost` for `make dev`
- Added `NATS_URL=nats://localhost:4222` to `.env` (was missing; CI orchestrator requires it)
- `REPO_ROOT` corrected to `/tmp/forgebucket/repos` (Docker path `/var/lib/forgebucket/repos` requires sudo on macOS)
---
## [0.1.0] — 2026-05-11
Initial development milestone. Core Git hosting, collaboration, and frontend SPA are functional.
### Added — Authentication & Security
- User registration and login with secure session cookies
- CSRF protection on all mutating routes via `X-CSRF-Token` header
- Middleware chain: Logger → RealIP → Recoverer → CORS → CSRF → SessionAuth → RBAC → Handler
- SSH key management per user
- OIDC / OAuth2 optional integration (configurable via env)
- Scoped access tokens with optional expiration dates
- Repository deploy keys (read-only or read-write HTTP tokens)
- ENV-driven config with fail-fast validation on missing secrets
### Added — Git Hosting
- Smart HTTP transport (git clone, push, pull over HTTP)
- AGit protocol support (`refs/for/` push for instant PR creation without branch switching)
- Branch management (list, create, delete, default branch configuration)
- Commit log and diff viewing
- Git LFS per-repository (configurable file size limits, locking)
- Branch protection rules (force-push blocking, required reviews)
- Repository visibility (public / private)
### Added — Collaboration
- Pull requests (open / merged / closed states) with author tracking
- Issues (open / closed)
- Reviewer assignment (default reviewer per repo, per-PR reviewer assignment)
- Merge strategy selection per repository (merge commit / squash / rebase)
- Branching model configuration (feature / bugfix / release / hotfix prefixes)
- PR default description templates (per-repo)
- Excluded files from diffs (glob pattern configuration)
- Webhook system with event filtering (push, pull_request, issue)
- Repository member RBAC (read / write / admin roles)
### Added — Frontend SPA
- React 18 + TypeScript + Vite, embedded into Go binary via `//go:embed`
- 20 route-level pages: Login, Register, Dashboard, Repos, CreateRepo, ImportRepo, Repo,
RepoSettings, Blob, Commits, Branches, RepoIssues, RepoPRs, CreatePR, PRDetail, Starred,
PRs (cross-repo), Pipelines (placeholder), Explore, Profile, Settings
- AppShell layout wrapper for all authenticated pages
- Triple-state sidebar: expanded (320px) / collapsed (56px) / mobile bottom bar
- Mobile-first responsive design (375px → 1440px)
- DiffViewer: side-by-side and unified views with syntax highlighting
- MobileComment: bottom-sheet overlay for inline code review on mobile
- TreeBrowser: repository file tree navigation
- PipelineWaterfall: placeholder pipeline visualization component
- Skeleton loading states for perceived performance
### Added — Design System
- Custom semantic token palette in `frontend/src/ui/tokens.ts`
- Full dark/light mode support via Tailwind CSS v4 `@variant dark`
- Brand colors: `#0052CC` (light) / `#3B82F6` (dark)
- 8px grid system (xs: 4px, sm: 8px, md: 16px, lg: 24px, xl: 32px, xxl: 48px)
- 44px minimum touch targets on all interactive elements (WCAG 2.5.5)
- Consistent border radius scale (subtle 38px, full 9999px)
- System font stack (Segoe UI, Roboto, sans-serif)
### Added — Infrastructure
- PostgreSQL + XORM with 7 migration files covering: users, repositories, issues, SSH keys,
access tokens, deploy keys, workflows, and LFS settings
- ActivityPub actor data model (FederationActor with inbox/outbox URLs and RSA key pairs) — data layer only
- Docker Compose setup for local PostgreSQL + NATS
- Makefile targets: dev, build, migrate, test, lint, docker-up
- WebSockets foundation for live logs and notifications
---
[Unreleased]: https://github.com/forgeo/forgebucket/compare/v0.3.0...HEAD
[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