4 KiB
4 KiB
Architecture
WP Packages has two primary runtime concerns:
- Build and serve a static Composer repository.
- Provide web/admin interfaces for package browsing and operations.
System Components
- Single binary (
wppackages) provides CLI commands and HTTP server. - SQLite (WAL mode) as the sole runtime data store.
- R2/CDN serves Composer metadata artifacts (
packages.json,p2/). - Caddy reverse proxies app routes to the Go HTTP server.
- systemd manages the
serveprocess and periodic timers.
Build Pipeline Commands
wppackages discover— discovers package slugs (config list or SVN).wppackages update— fetches and stores package metadata from WordPress.org.wppackages build— generates static Composer JSON artifacts.wppackages deploy— promotes a completed build, supports rollback/cleanup.wppackages pipeline— orchestrates discover → update → build → deploy.
Static Repository Storage
- Immutable build directories under
storage/repository/builds/<build-id>/. - Atomic
currentsymlink points to the promoted build.
Web UI
- Public package browser/detail pages via server-rendered Go templates + Tailwind.
- Admin panel at
/adminwith in-app auth (email/password + session).
Module Layout
cmd/wppackages/ CLI entrypoint (Cobra)
internal/
├── config/ env-first loading + optional YAML config
├── db/ SQLite connection, pragmas, Goose migrations
├── wporg/ WordPress.org API + SVN clients
├── packages/ package normalization/storage logic
├── repository/ artifact generation, hashing, integrity validation
├── deploy/ local promote/rollback/cleanup + R2 sync
├── telemetry/ event ingestion, dedupe, rollups
└── http/ stdlib router, handlers, templates, static assets
Data Flow
- Discovery creates/updates shell package records (
type,name,last_committed). - Update fetches full package payloads, normalizes versions, stores to
packages.versions_json. - Build generates:
packages.json(with absolutenotify-batchURL to app domain)- Composer v2 metadata files under
p2/ manifest.jsonwith build metrics and snapshot metadata
- Deploy promotes a complete build by switching the
currentsymlink and optionally syncing to R2. - R2/CDN serves static JSON directly; Caddy proxies dynamic routes to the Go app.
Snapshot Consistency
wppackages updatestamps updated rows withlast_sync_run_id.wppackages buildsnapshotsmax(last_sync_run_id)and only includes rows at or below that value.- This prevents mixed-state builds when updates are running concurrently.
Static Repository Layout
storage/repository/
├── current -> builds/20260313-140000
└── builds/
├── 20260313-140000/
│ ├── packages.json
│ ├── manifest.json
│ └── p2/
└── 20260313-130000/
Public vs Admin Surface
Public
GET /— package browser with search/filter/sort/paginationGET /packages/{type}/{name}— package detailPOST /downloads— Composer notify-batch endpoint (install telemetry)GET /health— status + package totals + last build metadata
Admin
GET /admin/logs— server logs viewer (auth required)
Static Repository Deployment
Two deployment targets:
- R2/CDN (production) —
wppackages deploy --to-r2syncs the build to Cloudflare R2 with appropriateCache-Controlheaders. R2 custom domain + Cloudflare CDN serves the static files. Seedocs/r2-deployment.md. - Local (development) —
wppackages deployupdates thecurrentsymlink only.
Scheduling
Periodic tasks run via systemd timers or cron (no in-process scheduler required):
wppackages pipeline— every 5 minuteswppackages aggregate-installs— hourlywppackages cleanup-sessions— daily
Optional: wppackages serve --with-scheduler for in-process scheduling.