diff --git a/.air.toml b/.air.toml index 27e9aae..00dd14b 100644 --- a/.air.toml +++ b/.air.toml @@ -1,6 +1,6 @@ [build] cmd = "make build" - full_bin = "ADMIN_ALLOW_CIDR= ./wpcomposer dev --addr :8080" + full_bin = "ADMIN_ALLOW_CIDR= ./wppackages dev --addr :8080" exclude_dir = ["storage", "bin", "test", "docs", ".git"] include_ext = ["go", "html", "css", "tmpl"] kill_delay = "1s" diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 2047b41..23eebc1 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -37,9 +37,9 @@ jobs: { "repositories": [ { - "name": "wp-composer", + "name": "wp-packages", "type": "composer", - "url": "https://repo.wp-composer.com", + "url": "https://repo.wp-packages.org", "only": ["wp-plugin/*", "wp-theme/*"] } ], diff --git a/.gitignore b/.gitignore index e6e59be..ef6b839 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/wpcomposer +/wppackages /bin/ internal/http/static/assets/styles/app.css storage/ diff --git a/CLAUDE.md b/CLAUDE.md index c340f19..66c20e2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ -# WP Composer +# WP Packages -Go + SQLite single binary (`wpcomposer`) for CLI + HTTP. Server-rendered templates + Tailwind. Composer metadata served from R2/CDN. See `docs/` for details. +Go + SQLite single binary (`wppackages`) for CLI + HTTP. Server-rendered templates + Tailwind. Composer metadata served from R2/CDN. See `docs/` for details. ## Dev diff --git a/Makefile b/Makefile index 3e77e43..d8f8813 100644 --- a/Makefile +++ b/Makefile @@ -26,11 +26,11 @@ tailwind: tailwind-install # Build the binary build: tailwind - go build -o wpcomposer ./cmd/wpcomposer + go build -o wppackages ./cmd/wppackages # Install to $GOPATH/bin install: - go install ./cmd/wpcomposer + go install ./cmd/wppackages # Live-reload dev server (migrations, seed data, serve) dev: tailwind-install @@ -55,14 +55,14 @@ lint: db-restore: @eval $$(ansible-vault view --vault-password-file deploy/ansible/.vault_pass $(VAULT_FILE) | yq -r \ '"export LITESTREAM_BUCKET=\(.vault_r2_litestream_bucket) R2_ENDPOINT=\(.vault_r2_endpoint) R2_ACCESS_KEY_ID=\(.vault_r2_access_key_id) R2_SECRET_ACCESS_KEY=\(.vault_r2_secret_access_key)"') && \ - export DB_PATH=./storage/wpcomposer.db && \ + export DB_PATH=./storage/wppackages.db && \ echo "LITESTREAM_BUCKET=$$LITESTREAM_BUCKET" && \ echo "R2_ENDPOINT=$$R2_ENDPOINT" && \ echo "R2_ACCESS_KEY_ID=$$R2_ACCESS_KEY_ID" && \ echo "R2_SECRET_ACCESS_KEY=$$R2_SECRET_ACCESS_KEY" && \ - go run ./cmd/wpcomposer db restore --force + go run ./cmd/wppackages db restore --force # Remove build artifacts clean: - rm -f wpcomposer + rm -f wppackages rm -rf storage/ diff --git a/README.md b/README.md index 9ab9865..778902b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# WP Composer +# WP Packages -[![Build status](https://img.shields.io/github/actions/workflow/status/roots/wp-composer/ci.yml?branch=main&style=flat-square)](https://github.com/roots/wp-composer/actions) +[![Build status](https://img.shields.io/github/actions/workflow/status/roots/wp-packages/ci.yml?branch=main&style=flat-square)](https://github.com/roots/wp-packages/actions) [![Follow Roots](https://img.shields.io/badge/follow%20@rootswp-1da1f2?logo=twitter&logoColor=ffffff&message=&style=flat-square)](https://twitter.com/rootswp) [![Sponsor Roots](https://img.shields.io/badge/sponsor%20roots-525ddc?logo=github&style=flat-square&logoColor=ffffff&message=)](https://github.com/sponsors/roots) @@ -29,9 +29,9 @@ Add the repository to your `composer.json`: { "repositories": [ { - "name": "wp-composer", + "name": "wp-packages", "type": "composer", - "url": "https://repo.wp-composer.com", + "url": "https://repo.wp-packages.org", "only": ["wp-plugin/*", "wp-theme/*"] } ], @@ -63,7 +63,7 @@ Add the repository to your `composer.json`: ### Roots WordPress Packages -WP Composer is built by [Roots](https://roots.io) and is the recommended repository for use alongside the Roots WordPress packaging ecosystem: +WP Packages is built by [Roots](https://roots.io) and is the recommended repository for use alongside the Roots WordPress packaging ecosystem: | Package | Description | |---|---| @@ -72,15 +72,15 @@ WP Composer is built by [Roots](https://roots.io) and is the recommended reposit | [`roots/wordpress-no-content`](https://github.com/roots/wordpress-no-content) | Minimal WordPress build (core only) | | [`roots/bedrock`](https://github.com/roots/bedrock) | WordPress boilerplate with Composer, better config, and improved structure | -A typical [Bedrock](https://roots.io/bedrock/) project uses `roots/wordpress` for WordPress core and WP Composer for plugins and themes: +A typical [Bedrock](https://roots.io/bedrock/) project uses `roots/wordpress` for WordPress core and WP Packages for plugins and themes: ```json { "repositories": [ { - "name": "wp-composer", + "name": "wp-packages", "type": "composer", - "url": "https://repo.wp-composer.com", + "url": "https://repo.wp-packages.org", "only": ["wp-plugin/*", "wp-theme/*"] } ], @@ -116,7 +116,7 @@ A typical [Bedrock](https://roots.io/bedrock/) project uses `roots/wordpress` fo Or use the [migration script](scripts/migrate-from-wpackagist.sh) to automatically update your `composer.json`: ```sh -curl -sO https://raw.githubusercontent.com/roots/wp-composer/main/scripts/migrate-from-wpackagist.sh && bash migrate-from-wpackagist.sh +curl -sO https://raw.githubusercontent.com/roots/wp-packages/main/scripts/migrate-from-wpackagist.sh && bash migrate-from-wpackagist.sh ``` ## Community diff --git a/benchmarks/README.md b/benchmarks/README.md index 226ea97..b649fa1 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,6 +1,6 @@ -# WP Composer Benchmarks +# WP Packages Benchmarks -Comparative benchmarks: WP Composer vs WPackagist. +Comparative benchmarks: WP Packages vs WPackagist. ## Prerequisites diff --git a/benchmarks/freshness.sh b/benchmarks/freshness.sh index 9b2a4f3..27fbf02 100755 --- a/benchmarks/freshness.sh +++ b/benchmarks/freshness.sh @@ -3,7 +3,7 @@ # Benchmark: Version freshness — compare available versions between repos # # For a set of popular plugins, fetches the version list from both -# WP Composer and WPackagist and compares: +# WP Packages and WPackagist and compares: # - Latest version available # - Total version count # - Missing versions in either repo @@ -16,7 +16,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" RESULTS_DIR="${SCRIPT_DIR}/results" mkdir -p "$RESULTS_DIR" -WPC_BASE="https://repo.wp-composer.com" +WPC_BASE="https://repo.wp-packages.org" WPKG_BASE="https://wpackagist.org" PLUGIN_COUNT=20 @@ -82,7 +82,7 @@ get_packages_json() { # ── Helpers ─────────────────────────────────────────────────────── -# Fetch version list via p2 metadata-url (WP Composer) +# Fetch version list via p2 metadata-url (WP Packages) get_versions_p2() { local base="$1" local package="$2" @@ -255,7 +255,7 @@ wpc_current=$(awk -F',' 'NR>1 && $7=="yes" {n++} END {print n+0}' "$CSV") wpkg_current=$(awk -F',' 'NR>1 && $8=="yes" {n++} END {print n+0}' "$CSV") total=${#PLUGINS[@]} -echo " WP Composer: ${wpc_current}/${total} plugins have latest version" +echo " WP Packages: ${wpc_current}/${total} plugins have latest version" echo " WPackagist: ${wpkg_current}/${total} plugins have latest version" echo "" echo "Raw CSV: ${CSV}" diff --git a/benchmarks/metadata.sh b/benchmarks/metadata.sh index b9b503d..fe60e4d 100755 --- a/benchmarks/metadata.sh +++ b/benchmarks/metadata.sh @@ -3,7 +3,7 @@ # Benchmark: Repository metadata — sizes, TTFB, transfer times # # Compares packages.json, provider files, and p2 metadata endpoints -# between WP Composer and WPackagist. +# between WP Packages and WPackagist. # # Usage: ./benchmarks/metadata.sh [--runs N] # @@ -14,7 +14,7 @@ RESULTS_DIR="${SCRIPT_DIR}/results" mkdir -p "$RESULTS_DIR" RUNS=5 -WPC_BASE="https://repo.wp-composer.com" +WPC_BASE="https://repo.wp-packages.org" WPKG_BASE="https://wpackagist.org" while [[ $# -gt 0 ]]; do @@ -119,7 +119,7 @@ echo "label,url,size_bytes,ttfb_avg,ttfb_min,ttfb_max,total_avg,total_min,total_ # Root packages.json echo "── packages.json ──" -measure_url "wp-composer/packages.json" "${WPC_BASE}/packages.json" +measure_url "wp-packages/packages.json" "${WPC_BASE}/packages.json" measure_url "wpackagist/packages.json" "${WPKG_BASE}/packages.json" # p2 metadata for specific packages @@ -133,9 +133,9 @@ for plugin in "${SAMPLE_PLUGINS[@]}"; do wpkg_p2=$(resolve_p2_url "$WPKG_BASE" "wpackagist-plugin/${plugin}" 2>/dev/null || echo "") if [[ -n "$wpc_p2" ]]; then - measure_url "wp-composer/p2/${plugin}" "$wpc_p2" + measure_url "wp-packages/p2/${plugin}" "$wpc_p2" else - printf " %-45s No p2 metadata-url\n" "wp-composer/p2/${plugin}" + printf " %-45s No p2 metadata-url\n" "wp-packages/p2/${plugin}" fi if [[ -n "$wpkg_p2" ]]; then @@ -149,7 +149,7 @@ done echo "" echo "── Cache headers ──" -echo " wp-composer/packages.json:" +echo " wp-packages/packages.json:" curl -sI "${WPC_BASE}/packages.json" 2>/dev/null | grep -iE '^(cache-control|cdn-cache|cf-cache|x-cache|age):' | sed 's/^/ /' || echo " (none)" echo " wpackagist/packages.json:" diff --git a/benchmarks/resolve.sh b/benchmarks/resolve.sh index 479f58e..09e60b1 100755 --- a/benchmarks/resolve.sh +++ b/benchmarks/resolve.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Benchmark: Composer resolve times — WP Composer vs WPackagist +# Benchmark: Composer resolve times — WP Packages vs WPackagist # # Measures cold (no cache) and warm (cached) composer update times # across small/medium/large dependency sets. @@ -15,7 +15,7 @@ mkdir -p "$RESULTS_DIR" RUNS=5 SIZE="all" -WPC_URL="https://repo.wp-composer.com" +WPC_URL="https://repo.wp-packages.org" WPKG_URL="https://wpackagist.org" while [[ $# -gt 0 ]]; do @@ -171,7 +171,7 @@ run_size() { echo "" echo "── ${size_label} (${#plugins[@]} plugins) ──" - run_benchmark "wp-composer-${size_label}" "$WPC_URL" "wp-plugin" "${plugins[@]}" + run_benchmark "wp-packages-${size_label}" "$WPC_URL" "wp-plugin" "${plugins[@]}" run_benchmark "wpackagist-${size_label}" "$WPKG_URL" "wpackagist-plugin" "${plugins[@]}" } diff --git a/cmd/wpcomposer/cmd/admin.go b/cmd/wppackages/cmd/admin.go similarity index 98% rename from cmd/wpcomposer/cmd/admin.go rename to cmd/wppackages/cmd/admin.go index 885cfdb..ecfd14a 100644 --- a/cmd/wpcomposer/cmd/admin.go +++ b/cmd/wppackages/cmd/admin.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "github.com/roots/wp-composer/internal/auth" + "github.com/roots/wp-packages/internal/auth" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/aggregate_installs.go b/cmd/wppackages/cmd/aggregate_installs.go similarity index 92% rename from cmd/wpcomposer/cmd/aggregate_installs.go rename to cmd/wppackages/cmd/aggregate_installs.go index 665b289..e4c0ae5 100644 --- a/cmd/wpcomposer/cmd/aggregate_installs.go +++ b/cmd/wppackages/cmd/aggregate_installs.go @@ -1,7 +1,7 @@ package cmd import ( - "github.com/roots/wp-composer/internal/telemetry" + "github.com/roots/wp-packages/internal/telemetry" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/build.go b/cmd/wppackages/cmd/build.go similarity index 98% rename from cmd/wpcomposer/cmd/build.go rename to cmd/wppackages/cmd/build.go index 8289812..717ad14 100644 --- a/cmd/wpcomposer/cmd/build.go +++ b/cmd/wppackages/cmd/build.go @@ -5,7 +5,7 @@ import ( "path/filepath" "time" - "github.com/roots/wp-composer/internal/repository" + "github.com/roots/wp-packages/internal/repository" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/cleanup_sessions.go b/cmd/wppackages/cmd/cleanup_sessions.go similarity index 91% rename from cmd/wpcomposer/cmd/cleanup_sessions.go rename to cmd/wppackages/cmd/cleanup_sessions.go index f9f6d3c..a6d19cd 100644 --- a/cmd/wpcomposer/cmd/cleanup_sessions.go +++ b/cmd/wppackages/cmd/cleanup_sessions.go @@ -1,7 +1,7 @@ package cmd import ( - "github.com/roots/wp-composer/internal/auth" + "github.com/roots/wp-packages/internal/auth" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/db.go b/cmd/wppackages/cmd/db.go similarity index 96% rename from cmd/wpcomposer/cmd/db.go rename to cmd/wppackages/cmd/db.go index 9b68033..d29cce1 100644 --- a/cmd/wpcomposer/cmd/db.go +++ b/cmd/wppackages/cmd/db.go @@ -5,8 +5,8 @@ import ( "os" "os/exec" - "github.com/roots/wp-composer/internal/config" - "github.com/roots/wp-composer/internal/db" + "github.com/roots/wp-packages/internal/config" + "github.com/roots/wp-packages/internal/db" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/deploy.go b/cmd/wppackages/cmd/deploy.go similarity index 98% rename from cmd/wpcomposer/cmd/deploy.go rename to cmd/wppackages/cmd/deploy.go index 606fe38..9aaabc0 100644 --- a/cmd/wpcomposer/cmd/deploy.go +++ b/cmd/wppackages/cmd/deploy.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/roots/wp-composer/internal/deploy" + "github.com/roots/wp-packages/internal/deploy" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/dev.go b/cmd/wppackages/cmd/dev.go similarity index 92% rename from cmd/wpcomposer/cmd/dev.go rename to cmd/wppackages/cmd/dev.go index 1fe006a..784a457 100644 --- a/cmd/wpcomposer/cmd/dev.go +++ b/cmd/wppackages/cmd/dev.go @@ -9,14 +9,14 @@ import ( "github.com/spf13/cobra" "golang.org/x/sync/errgroup" - wpcomposergo "github.com/roots/wp-composer" - "github.com/roots/wp-composer/internal/auth" - "github.com/roots/wp-composer/internal/db" - "github.com/roots/wp-composer/internal/deploy" - apphttp "github.com/roots/wp-composer/internal/http" - "github.com/roots/wp-composer/internal/packages" - "github.com/roots/wp-composer/internal/repository" - "github.com/roots/wp-composer/internal/wporg" + wppackagesgo "github.com/roots/wp-packages" + "github.com/roots/wp-packages/internal/auth" + "github.com/roots/wp-packages/internal/db" + "github.com/roots/wp-packages/internal/deploy" + apphttp "github.com/roots/wp-packages/internal/http" + "github.com/roots/wp-packages/internal/packages" + "github.com/roots/wp-packages/internal/repository" + "github.com/roots/wp-packages/internal/wporg" ) var devCmd = &cobra.Command{ @@ -42,7 +42,7 @@ func runDev(cmd *cobra.Command, args []string) error { // 1. Migrations application.Logger.Info("dev: running migrations") - if err := db.Migrate(application.DB, wpcomposergo.Migrations); err != nil { + if err := db.Migrate(application.DB, wppackagesgo.Migrations); err != nil { return fmt.Errorf("migrations: %w", err) } diff --git a/cmd/wpcomposer/cmd/discover.go b/cmd/wppackages/cmd/discover.go similarity index 98% rename from cmd/wpcomposer/cmd/discover.go rename to cmd/wppackages/cmd/discover.go index 3c202f3..f5047d6 100644 --- a/cmd/wpcomposer/cmd/discover.go +++ b/cmd/wppackages/cmd/discover.go @@ -9,8 +9,8 @@ import ( "github.com/spf13/cobra" "golang.org/x/sync/errgroup" - "github.com/roots/wp-composer/internal/packages" - "github.com/roots/wp-composer/internal/wporg" + "github.com/roots/wp-packages/internal/packages" + "github.com/roots/wp-packages/internal/wporg" ) var discoverCmd = &cobra.Command{ diff --git a/cmd/wpcomposer/cmd/generate_og.go b/cmd/wppackages/cmd/generate_og.go similarity index 94% rename from cmd/wpcomposer/cmd/generate_og.go rename to cmd/wppackages/cmd/generate_og.go index 38f08c2..8dcd8b7 100644 --- a/cmd/wpcomposer/cmd/generate_og.go +++ b/cmd/wppackages/cmd/generate_og.go @@ -1,7 +1,7 @@ package cmd import ( - "github.com/roots/wp-composer/internal/og" + "github.com/roots/wp-packages/internal/og" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/migrate.go b/cmd/wppackages/cmd/migrate.go similarity index 92% rename from cmd/wpcomposer/cmd/migrate.go rename to cmd/wppackages/cmd/migrate.go index 1c057a6..5d51436 100644 --- a/cmd/wpcomposer/cmd/migrate.go +++ b/cmd/wppackages/cmd/migrate.go @@ -3,7 +3,7 @@ package cmd import ( "embed" - "github.com/roots/wp-composer/internal/db" + "github.com/roots/wp-packages/internal/db" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/pipeline.go b/cmd/wppackages/cmd/pipeline.go similarity index 99% rename from cmd/wpcomposer/cmd/pipeline.go rename to cmd/wppackages/cmd/pipeline.go index 80b95a8..7ac5d2a 100644 --- a/cmd/wpcomposer/cmd/pipeline.go +++ b/cmd/wppackages/cmd/pipeline.go @@ -10,7 +10,7 @@ import ( "syscall" "time" - "github.com/roots/wp-composer/internal/deploy" + "github.com/roots/wp-packages/internal/deploy" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/pipeline_lock_test.go b/cmd/wppackages/cmd/pipeline_lock_test.go similarity index 100% rename from cmd/wpcomposer/cmd/pipeline_lock_test.go rename to cmd/wppackages/cmd/pipeline_lock_test.go diff --git a/cmd/wpcomposer/cmd/root.go b/cmd/wppackages/cmd/root.go similarity index 85% rename from cmd/wpcomposer/cmd/root.go rename to cmd/wppackages/cmd/root.go index 0620034..da681f4 100644 --- a/cmd/wpcomposer/cmd/root.go +++ b/cmd/wppackages/cmd/root.go @@ -3,8 +3,8 @@ package cmd import ( "fmt" - "github.com/roots/wp-composer/internal/app" - "github.com/roots/wp-composer/internal/config" + "github.com/roots/wp-packages/internal/app" + "github.com/roots/wp-packages/internal/config" "github.com/spf13/cobra" ) @@ -17,8 +17,8 @@ var ( ) var rootCmd = &cobra.Command{ - Use: "wpcomposer", - Short: "WP Composer - Composer repository for WordPress packages", + Use: "wppackages", + Short: "WP Packages - Composer repository for WordPress packages", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { if cmd.Annotations["requires_app"] != "true" { return nil @@ -56,7 +56,7 @@ func Execute() error { func init() { rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file path") - rootCmd.PersistentFlags().StringVar(&dbPath, "db", "", "database path (default ./storage/wpcomposer.db)") + rootCmd.PersistentFlags().StringVar(&dbPath, "db", "", "database path (default ./storage/wppackages.db)") rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "", "log level (debug, info, warn, error)") } diff --git a/cmd/wpcomposer/cmd/serve.go b/cmd/wppackages/cmd/serve.go similarity index 89% rename from cmd/wpcomposer/cmd/serve.go rename to cmd/wppackages/cmd/serve.go index 0a303d4..e353c7a 100644 --- a/cmd/wpcomposer/cmd/serve.go +++ b/cmd/wppackages/cmd/serve.go @@ -1,7 +1,7 @@ package cmd import ( - apphttp "github.com/roots/wp-composer/internal/http" + apphttp "github.com/roots/wp-packages/internal/http" "github.com/spf13/cobra" ) diff --git a/cmd/wpcomposer/cmd/update.go b/cmd/wppackages/cmd/update.go similarity index 98% rename from cmd/wpcomposer/cmd/update.go rename to cmd/wppackages/cmd/update.go index 0e9e228..8974dc8 100644 --- a/cmd/wpcomposer/cmd/update.go +++ b/cmd/wppackages/cmd/update.go @@ -9,8 +9,8 @@ import ( "github.com/spf13/cobra" "golang.org/x/sync/errgroup" - "github.com/roots/wp-composer/internal/packages" - "github.com/roots/wp-composer/internal/wporg" + "github.com/roots/wp-packages/internal/packages" + "github.com/roots/wp-packages/internal/wporg" ) var updateCmd = &cobra.Command{ diff --git a/cmd/wpcomposer/main.go b/cmd/wppackages/main.go similarity index 51% rename from cmd/wpcomposer/main.go rename to cmd/wppackages/main.go index 51a71bc..5e15f82 100644 --- a/cmd/wpcomposer/main.go +++ b/cmd/wppackages/main.go @@ -4,12 +4,12 @@ import ( "fmt" "os" - wpcomposergo "github.com/roots/wp-composer" - "github.com/roots/wp-composer/cmd/wpcomposer/cmd" + wppackagesgo "github.com/roots/wp-packages" + "github.com/roots/wp-packages/cmd/wppackages/cmd" ) func main() { - cmd.Migrations = wpcomposergo.Migrations + cmd.Migrations = wppackagesgo.Migrations if err := cmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) diff --git a/deploy/ansible/deploy.yml b/deploy/ansible/deploy.yml index 7253a15..1099f6c 100644 --- a/deploy/ansible/deploy.yml +++ b/deploy/ansible/deploy.yml @@ -1,5 +1,5 @@ --- -- name: Deploy WP Composer (Go) +- name: Deploy WP Packages (Go) hosts: all become: true tasks: diff --git a/deploy/ansible/group_vars/production/main.yml b/deploy/ansible/group_vars/production/main.yml index 5f51948..c5f606b 100644 --- a/deploy/ansible/group_vars/production/main.yml +++ b/deploy/ansible/group_vars/production/main.yml @@ -1,7 +1,7 @@ # Application -app_name: wp-composer -app_domain: wp-composer.com -app_root: /srv/wp-composer +app_name: wp-packages +app_domain: wp-packages.org +app_root: /srv/wp-packages app_env: production app_debug: "false" app_url: "https://{{ app_domain }}" @@ -14,20 +14,20 @@ users: - qwp6t # Go binary -go_binary_name: wpcomposer +go_binary_name: wppackages go_listen_addr: "127.0.0.1:8080" go_upstream_addr: "127.0.0.1:8080" go_log_level: info # SQLite -db_path: "{{ app_root }}/shared/storage/wpcomposer.db" +db_path: "{{ app_root }}/shared/storage/wppackages.db" # Caddy caddy_email: "team@roots.io" # R2 -wp_composer_deploy_r2: "true" -r2_cdn_public_url: "https://cdn.wp-composer.com" +wp_packages_deploy_r2: "true" +r2_cdn_public_url: "https://cdn.wp-packages.org" # Litestream litestream_version: "0.5.10" diff --git a/deploy/ansible/inventory/hosts/production.example.yml b/deploy/ansible/inventory/hosts/production.example.yml index 959ecc1..9d2ba46 100644 --- a/deploy/ansible/inventory/hosts/production.example.yml +++ b/deploy/ansible/inventory/hosts/production.example.yml @@ -1,6 +1,6 @@ all: hosts: - wp-composer: + wp-packages: ansible_host: your.server.ip.or.hostname ansible_user: deploy ansible_python_interpreter: /usr/bin/python3 diff --git a/deploy/ansible/provision.yml b/deploy/ansible/provision.yml index 1a3217c..02b2128 100644 --- a/deploy/ansible/provision.yml +++ b/deploy/ansible/provision.yml @@ -1,9 +1,9 @@ --- -- name: Provision WP Composer (Go) +- name: Provision WP Packages (Go) hosts: all become: true roles: - server - caddy - - wpcomposer + - wppackages - app diff --git a/deploy/ansible/roles/app/tasks/deploy.yml b/deploy/ansible/roles/app/tasks/deploy.yml index cd61fa7..2e8e29b 100644 --- a/deploy/ansible/roles/app/tasks/deploy.yml +++ b/deploy/ansible/roles/app/tasks/deploy.yml @@ -27,11 +27,11 @@ become: false shell: > cd {{ playbook_dir }}/../.. && - GOOS=linux GOARCH=amd64 go build -o /tmp/wpcomposer-deploy-{{ release_id }} ./cmd/wpcomposer + GOOS=linux GOARCH=amd64 go build -o /tmp/wppackages-deploy-{{ release_id }} ./cmd/wppackages - name: Upload binary copy: - src: "/tmp/wpcomposer-deploy-{{ release_id }}" + src: "/tmp/wppackages-deploy-{{ release_id }}" dest: "{{ release_path }}/{{ go_binary_name }}" owner: deploy group: www-data @@ -70,16 +70,16 @@ ln -sfn {{ release_path }} {{ app_root }}/current.tmp mv -T {{ app_root }}/current.tmp {{ app_root }}/current -- name: Check if wpcomposer service exists +- name: Check if wppackages service exists stat: - path: /etc/systemd/system/wpcomposer.service - register: wpcomposer_service + path: /etc/systemd/system/wppackages.service + register: wppackages_service -- name: Restart wpcomposer service +- name: Restart wppackages service service: - name: wpcomposer + name: wppackages state: restarted - when: wpcomposer_service.stat.exists + when: wppackages_service.stat.exists - name: Clean up old releases shell: | @@ -90,5 +90,5 @@ delegate_to: localhost become: false file: - path: "/tmp/wpcomposer-deploy-{{ release_id }}" + path: "/tmp/wppackages-deploy-{{ release_id }}" state: absent diff --git a/deploy/ansible/roles/app/tasks/main.yml b/deploy/ansible/roles/app/tasks/main.yml index 12bfcd7..dfc6783 100644 --- a/deploy/ansible/roles/app/tasks/main.yml +++ b/deploy/ansible/roles/app/tasks/main.yml @@ -25,7 +25,7 @@ - name: Deploy logrotate config template: src: logrotate.j2 - dest: /etc/logrotate.d/wp-composer + dest: /etc/logrotate.d/wp-packages owner: root group: root mode: "0644" diff --git a/deploy/ansible/roles/app/templates/env.j2 b/deploy/ansible/roles/app/templates/env.j2 index 0c01f62..90454fd 100644 --- a/deploy/ansible/roles/app/templates/env.j2 +++ b/deploy/ansible/roles/app/templates/env.j2 @@ -9,7 +9,7 @@ SESSION_LIFETIME_MINUTES={{ session_lifetime_minutes }} SEEDS_FILE={{ seeds_file }} -WP_COMPOSER_DEPLOY_R2={{ wp_composer_deploy_r2 }} +WP_PACKAGES_DEPLOY_R2={{ wp_packages_deploy_r2 }} R2_ACCESS_KEY_ID={{ vault_r2_access_key_id }} R2_SECRET_ACCESS_KEY={{ vault_r2_secret_access_key }} R2_BUCKET={{ vault_r2_bucket }} diff --git a/deploy/ansible/roles/wpcomposer/handlers/main.yml b/deploy/ansible/roles/wppackages/handlers/main.yml similarity index 66% rename from deploy/ansible/roles/wpcomposer/handlers/main.yml rename to deploy/ansible/roles/wppackages/handlers/main.yml index 2835cd4..f958815 100644 --- a/deploy/ansible/roles/wpcomposer/handlers/main.yml +++ b/deploy/ansible/roles/wppackages/handlers/main.yml @@ -3,7 +3,7 @@ systemd: daemon_reload: yes -- name: Restart wpcomposer +- name: Restart wppackages service: - name: wpcomposer + name: wppackages state: restarted diff --git a/deploy/ansible/roles/wpcomposer/tasks/main.yml b/deploy/ansible/roles/wppackages/tasks/main.yml similarity index 57% rename from deploy/ansible/roles/wpcomposer/tasks/main.yml rename to deploy/ansible/roles/wppackages/tasks/main.yml index ef0f90a..ef2cda1 100644 --- a/deploy/ansible/roles/wpcomposer/tasks/main.yml +++ b/deploy/ansible/roles/wppackages/tasks/main.yml @@ -7,16 +7,16 @@ group: www-data mode: "0640" -- name: Remove legacy wpcomposer socket unit +- name: Remove legacy wppackages socket unit file: - path: /etc/systemd/system/wpcomposer.socket + path: /etc/systemd/system/wppackages.socket state: absent notify: Reload systemd -- name: Deploy wpcomposer service +- name: Deploy wppackages service template: - src: wpcomposer.service.j2 - dest: /etc/systemd/system/wpcomposer.service + src: wppackages.service.j2 + dest: /etc/systemd/system/wppackages.service owner: root group: root mode: "0644" @@ -24,8 +24,8 @@ - name: Deploy pipeline timer template: - src: wpcomposer-pipeline.service.j2 - dest: /etc/systemd/system/wpcomposer-pipeline.service + src: wppackages-pipeline.service.j2 + dest: /etc/systemd/system/wppackages-pipeline.service owner: root group: root mode: "0644" @@ -33,8 +33,8 @@ - name: Deploy pipeline timer unit template: - src: wpcomposer-pipeline.timer.j2 - dest: /etc/systemd/system/wpcomposer-pipeline.timer + src: wppackages-pipeline.timer.j2 + dest: /etc/systemd/system/wppackages-pipeline.timer owner: root group: root mode: "0644" @@ -42,8 +42,8 @@ - name: Deploy aggregate-installs timer template: - src: wpcomposer-aggregate.service.j2 - dest: /etc/systemd/system/wpcomposer-aggregate.service + src: wppackages-aggregate.service.j2 + dest: /etc/systemd/system/wppackages-aggregate.service owner: root group: root mode: "0644" @@ -51,8 +51,8 @@ - name: Deploy aggregate-installs timer unit template: - src: wpcomposer-aggregate.timer.j2 - dest: /etc/systemd/system/wpcomposer-aggregate.timer + src: wppackages-aggregate.timer.j2 + dest: /etc/systemd/system/wppackages-aggregate.timer owner: root group: root mode: "0644" @@ -60,8 +60,8 @@ - name: Deploy cleanup-sessions timer template: - src: wpcomposer-cleanup.service.j2 - dest: /etc/systemd/system/wpcomposer-cleanup.service + src: wppackages-cleanup.service.j2 + dest: /etc/systemd/system/wppackages-cleanup.service owner: root group: root mode: "0644" @@ -69,8 +69,8 @@ - name: Deploy cleanup-sessions timer unit template: - src: wpcomposer-cleanup.timer.j2 - dest: /etc/systemd/system/wpcomposer-cleanup.timer + src: wppackages-cleanup.timer.j2 + dest: /etc/systemd/system/wppackages-cleanup.timer owner: root group: root mode: "0644" @@ -78,8 +78,8 @@ - name: Deploy generate-og timer template: - src: wpcomposer-generate-og.service.j2 - dest: /etc/systemd/system/wpcomposer-generate-og.service + src: wppackages-generate-og.service.j2 + dest: /etc/systemd/system/wppackages-generate-og.service owner: root group: root mode: "0644" @@ -87,8 +87,8 @@ - name: Deploy generate-og timer unit template: - src: wpcomposer-generate-og.timer.j2 - dest: /etc/systemd/system/wpcomposer-generate-og.timer + src: wppackages-generate-og.timer.j2 + dest: /etc/systemd/system/wppackages-generate-og.timer owner: root group: root mode: "0644" @@ -97,9 +97,9 @@ - name: Flush handlers meta: flush_handlers -- name: Enable and start wpcomposer service +- name: Enable and start wppackages service service: - name: wpcomposer + name: wppackages state: started enabled: yes @@ -109,7 +109,7 @@ state: started enabled: yes loop: - - wpcomposer-pipeline.timer - - wpcomposer-aggregate.timer - - wpcomposer-cleanup.timer - - wpcomposer-generate-og.timer + - wppackages-pipeline.timer + - wppackages-aggregate.timer + - wppackages-cleanup.timer + - wppackages-generate-og.timer diff --git a/deploy/ansible/roles/wpcomposer/templates/litestream.yml.j2 b/deploy/ansible/roles/wppackages/templates/litestream.yml.j2 similarity index 100% rename from deploy/ansible/roles/wpcomposer/templates/litestream.yml.j2 rename to deploy/ansible/roles/wppackages/templates/litestream.yml.j2 diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-aggregate.service.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-aggregate.service.j2 similarity index 88% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-aggregate.service.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-aggregate.service.j2 index c1f6222..5c70678 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-aggregate.service.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-aggregate.service.j2 @@ -1,5 +1,5 @@ [Unit] -Description=WP Composer Aggregate Install Metrics +Description=WP Packages Aggregate Install Metrics [Service] Type=oneshot diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-aggregate.timer.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-aggregate.timer.j2 similarity index 66% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-aggregate.timer.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-aggregate.timer.j2 index dad5018..adc8f1f 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-aggregate.timer.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-aggregate.timer.j2 @@ -1,5 +1,5 @@ [Unit] -Description=Run WP Composer install aggregation hourly +Description=Run WP Packages install aggregation hourly [Timer] OnCalendar=hourly diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-cleanup.service.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-cleanup.service.j2 similarity index 88% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-cleanup.service.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-cleanup.service.j2 index 7211684..3141c79 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-cleanup.service.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-cleanup.service.j2 @@ -1,5 +1,5 @@ [Unit] -Description=WP Composer Cleanup Expired Sessions +Description=WP Packages Cleanup Expired Sessions [Service] Type=oneshot diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-cleanup.timer.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-cleanup.timer.j2 similarity index 68% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-cleanup.timer.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-cleanup.timer.j2 index 08461c1..103a236 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-cleanup.timer.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-cleanup.timer.j2 @@ -1,5 +1,5 @@ [Unit] -Description=Run WP Composer session cleanup daily +Description=Run WP Packages session cleanup daily [Timer] OnCalendar=daily diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-generate-og.service.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-generate-og.service.j2 similarity index 89% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-generate-og.service.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-generate-og.service.j2 index 0cbbb39..09dbc42 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-generate-og.service.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-generate-og.service.j2 @@ -1,5 +1,5 @@ [Unit] -Description=WP Composer Generate OG Images +Description=WP Packages Generate OG Images [Service] Type=oneshot diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-generate-og.timer.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-generate-og.timer.j2 similarity index 63% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-generate-og.timer.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-generate-og.timer.j2 index 252927d..b780609 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-generate-og.timer.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-generate-og.timer.j2 @@ -1,5 +1,5 @@ [Unit] -Description=Run WP Composer OG image generation daily +Description=Run WP Packages OG image generation daily [Timer] OnCalendar=*-*-* 03:00:00 diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-pipeline.service.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-pipeline.service.j2 similarity index 85% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-pipeline.service.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-pipeline.service.j2 index 1d29543..fbca756 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-pipeline.service.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-pipeline.service.j2 @@ -1,5 +1,5 @@ [Unit] -Description=WP Composer Pipeline (discover + update + build + deploy) +Description=WP Packages Pipeline (discover + update + build + deploy) [Service] Type=oneshot diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-pipeline.timer.j2 b/deploy/ansible/roles/wppackages/templates/wppackages-pipeline.timer.j2 similarity index 66% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer-pipeline.timer.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages-pipeline.timer.j2 index eaf9bcb..d1c99e2 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer-pipeline.timer.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages-pipeline.timer.j2 @@ -1,5 +1,5 @@ [Unit] -Description=Run WP Composer pipeline every 5 minutes +Description=Run WP Packages pipeline every 5 minutes [Timer] OnCalendar=*:0/5 diff --git a/deploy/ansible/roles/wpcomposer/templates/wpcomposer.service.j2 b/deploy/ansible/roles/wppackages/templates/wppackages.service.j2 similarity index 70% rename from deploy/ansible/roles/wpcomposer/templates/wpcomposer.service.j2 rename to deploy/ansible/roles/wppackages/templates/wppackages.service.j2 index efe1f86..771dac0 100644 --- a/deploy/ansible/roles/wpcomposer/templates/wpcomposer.service.j2 +++ b/deploy/ansible/roles/wppackages/templates/wppackages.service.j2 @@ -1,5 +1,5 @@ [Unit] -Description=WP Composer +Description=WP Packages After=network.target [Service] @@ -10,8 +10,8 @@ WorkingDirectory={{ app_root }}/current ExecStart=/usr/bin/litestream replicate -config {{ app_root }}/shared/litestream.yml -exec "{{ app_root }}/current/{{ go_binary_name }} serve --db {{ db_path }}" Restart=always RestartSec=1s -StandardOutput=append:{{ app_root }}/shared/storage/logs/wpcomposer.log -StandardError=append:{{ app_root }}/shared/storage/logs/wpcomposer.log +StandardOutput=append:{{ app_root }}/shared/storage/logs/wppackages.log +StandardError=append:{{ app_root }}/shared/storage/logs/wppackages.log EnvironmentFile={{ app_root }}/shared/.env [Install] diff --git a/docs/admin-access.md b/docs/admin-access.md index 9ff91d6..dc7662e 100644 --- a/docs/admin-access.md +++ b/docs/admin-access.md @@ -11,19 +11,19 @@ Admin access is protected by in-app authentication. Email/password login and adm ### Create initial admin user ```bash -echo 'secure-password' | wpcomposer admin create --email admin@example.com --name "Admin" --password-stdin +echo 'secure-password' | wppackages admin create --email admin@example.com --name "Admin" --password-stdin ``` ### Promote existing user to admin ```bash -wpcomposer admin promote --email user@example.com +wppackages admin promote --email user@example.com ``` ### Reset admin password ```bash -echo 'new-password' | wpcomposer admin reset-password --email admin@example.com --password-stdin +echo 'new-password' | wppackages admin reset-password --email admin@example.com --password-stdin ``` ## Login/Logout @@ -38,7 +38,7 @@ echo 'new-password' | wpcomposer admin reset-password --email admin@example.com Expired sessions accumulate in the `sessions` table. Clean them periodically: ```bash -wpcomposer cleanup-sessions +wppackages cleanup-sessions ``` Run via systemd timer or cron (daily recommended). @@ -52,7 +52,7 @@ If locked out of the admin panel: ssh deploy@your-server # Reset the password -echo 'new-password' | wpcomposer admin reset-password --email admin@example.com --password-stdin +echo 'new-password' | wppackages admin reset-password --email admin@example.com --password-stdin ``` No database access or application restart required. diff --git a/docs/architecture.md b/docs/architecture.md index 6e1dbaf..b496735 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,13 +1,13 @@ # Architecture -WP Composer has two primary runtime concerns: +WP Packages has two primary runtime concerns: 1. Build and serve a static Composer repository. 2. Provide web/admin interfaces for package browsing and operations. ## System Components -- **Single binary** (`wpcomposer`) provides CLI commands and HTTP server. +- **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. @@ -15,11 +15,11 @@ WP Composer has two primary runtime concerns: ### Build Pipeline Commands -- `wpcomposer discover` — discovers package slugs (config list or SVN). -- `wpcomposer update` — fetches and stores package metadata from WordPress.org. -- `wpcomposer build` — generates static Composer JSON artifacts. -- `wpcomposer deploy` — promotes a completed build, supports rollback/cleanup. -- `wpcomposer pipeline` — orchestrates discover → update → build → deploy. +- `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 @@ -34,7 +34,7 @@ WP Composer has two primary runtime concerns: ## Module Layout ``` -cmd/wpcomposer/ CLI entrypoint (Cobra) +cmd/wppackages/ CLI entrypoint (Cobra) internal/ ├── config/ env-first loading + optional YAML config ├── db/ SQLite connection, pragmas, Goose migrations @@ -59,8 +59,8 @@ internal/ ## Snapshot Consistency -- `wpcomposer update` stamps updated rows with `last_sync_run_id`. -- `wpcomposer build` snapshots `max(last_sync_run_id)` and only includes rows at or below that value. +- `wppackages update` stamps updated rows with `last_sync_run_id`. +- `wppackages build` snapshots `max(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 @@ -97,15 +97,15 @@ storage/repository/ Two deployment targets: -- **R2/CDN (production)** — `wpcomposer deploy --to-r2` syncs the build to Cloudflare R2 with appropriate `Cache-Control` headers. R2 custom domain + Cloudflare CDN serves the static files. See `docs/r2-deployment.md`. -- **Local (development)** — `wpcomposer deploy` updates the `current` symlink only. +- **R2/CDN (production)** — `wppackages deploy --to-r2` syncs the build to Cloudflare R2 with appropriate `Cache-Control` headers. R2 custom domain + Cloudflare CDN serves the static files. See `docs/r2-deployment.md`. +- **Local (development)** — `wppackages deploy` updates the `current` symlink only. ## Scheduling Periodic tasks run via systemd timers or cron (no in-process scheduler required): -- `wpcomposer pipeline` — every 5 minutes -- `wpcomposer aggregate-installs` — hourly -- `wpcomposer cleanup-sessions` — daily +- `wppackages pipeline` — every 5 minutes +- `wppackages aggregate-installs` — hourly +- `wppackages cleanup-sessions` — daily -Optional: `wpcomposer serve --with-scheduler` for in-process scheduling. \ No newline at end of file +Optional: `wppackages serve --with-scheduler` for in-process scheduling. \ No newline at end of file diff --git a/docs/development.md b/docs/development.md index b22c412..b897da5 100644 --- a/docs/development.md +++ b/docs/development.md @@ -23,35 +23,35 @@ This builds the binary, runs migrations, creates an admin user (`admin@localhost make build # Run migrations -./wpcomposer migrate +./wppackages migrate # Create admin user -echo 'your-password' | ./wpcomposer admin create \ +echo 'your-password' | ./wppackages admin create \ --email admin@example.com \ --name "Admin" \ --password-stdin # Start server -./wpcomposer serve +./wppackages serve ``` ## Commands | Command | Purpose | |---------|---------| -| `wpcomposer dev` | Bootstrap and start dev server (all-in-one) | -| `wpcomposer serve` | Start HTTP server | -| `wpcomposer migrate` | Apply database migrations | -| `wpcomposer discover` | Discover package slugs from WordPress.org | -| `wpcomposer update` | Fetch/store package metadata | -| `wpcomposer build` | Generate Composer repository artifacts | -| `wpcomposer deploy` | Promote build (local symlink and/or R2 sync) | -| `wpcomposer pipeline` | Run full discover → update → build → deploy | -| `wpcomposer aggregate-installs` | Recompute install counters | -| `wpcomposer cleanup-sessions` | Remove expired admin sessions | -| `wpcomposer admin create` | Create admin user | -| `wpcomposer admin promote` | Grant admin role to existing user | -| `wpcomposer admin reset-password` | Reset user password | +| `wppackages dev` | Bootstrap and start dev server (all-in-one) | +| `wppackages serve` | Start HTTP server | +| `wppackages migrate` | Apply database migrations | +| `wppackages discover` | Discover package slugs from WordPress.org | +| `wppackages update` | Fetch/store package metadata | +| `wppackages build` | Generate Composer repository artifacts | +| `wppackages deploy` | Promote build (local symlink and/or R2 sync) | +| `wppackages pipeline` | Run full discover → update → build → deploy | +| `wppackages aggregate-installs` | Recompute install counters | +| `wppackages cleanup-sessions` | Remove expired admin sessions | +| `wppackages admin create` | Create admin user | +| `wppackages admin promote` | Grant admin role to existing user | +| `wppackages admin reset-password` | Reset user password | All commands accept `--config`, `--db`, and `--log-level` flags. See [`operations.md`](operations.md) for usage details. @@ -62,7 +62,7 @@ Env-first with optional YAML config file (env overrides YAML). | Variable | Default | Purpose | |----------|---------|---------| | `APP_URL` | — | App domain for `notify-batch` URL | -| `DB_PATH` | `./storage/wpcomposer.db` | SQLite database path | +| `DB_PATH` | `./storage/wppackages.db` | SQLite database path | | `WP_COMPOSER_DEPLOY_R2` | `false` | Enable R2 deploy | | `R2_ACCESS_KEY_ID` | — | R2 credentials | | `R2_SECRET_ACCESS_KEY` | — | R2 credentials | diff --git a/docs/operations.md b/docs/operations.md index 4175a14..b353587 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -1,14 +1,14 @@ # Operations -Day-to-day operation of WP Composer in production-like environments. +Day-to-day operation of WP Packages in production-like environments. ## Prerequisites - Ubuntu 24.04 LTS server -- Go binary (`wpcomposer`) deployed to the server -- SQLite database at configured path (default `./storage/wpcomposer.db`) +- Go binary (`wppackages`) deployed to the server +- SQLite database at configured path (default `./storage/wppackages.db`) - Caddy configured as reverse proxy for app routes -- systemd service for `wpcomposer serve` +- systemd service for `wppackages serve` - systemd timers or cron for periodic commands All prerequisites are automated via Ansible. See [Server Provisioning](#server-provisioning) below. @@ -18,7 +18,7 @@ All prerequisites are automated via Ansible. See [Server Provisioning](#server-p ### Migrate ```bash -wpcomposer migrate +wppackages migrate ``` Apply pending database migrations. Run this before first use and after upgrades. @@ -26,8 +26,8 @@ Apply pending database migrations. Run this before first use and after upgrades. ### Discover ```bash -wpcomposer discover --source=svn -wpcomposer discover --source=config --type=plugin --limit=100 +wppackages discover --source=svn +wppackages discover --source=config --type=plugin --limit=100 ``` - `--source=svn` for full WordPress.org directory discovery. @@ -38,9 +38,9 @@ wpcomposer discover --source=config --type=plugin --limit=100 ### Update ```bash -wpcomposer update -wpcomposer update --type=plugin --name=akismet --force -wpcomposer update --include-inactive +wppackages update +wppackages update --type=plugin --name=akismet --force +wppackages update --include-inactive ``` - Fetches full package payloads from WordPress.org and normalizes versions. @@ -51,9 +51,9 @@ wpcomposer update --include-inactive ### Build ```bash -wpcomposer build -wpcomposer build --force -wpcomposer build --package=wp-plugin/akismet +wppackages build +wppackages build --force +wppackages build --package=wp-plugin/akismet ``` - Generates build artifacts (`p2/` files, `packages.json`, `manifest.json`). @@ -63,13 +63,13 @@ wpcomposer build --package=wp-plugin/akismet ### Deploy ```bash -wpcomposer deploy -wpcomposer deploy 20260313-140000 -wpcomposer deploy --rollback -wpcomposer deploy --rollback=20260313-130000 -wpcomposer deploy --to-r2 -wpcomposer deploy --cleanup -wpcomposer deploy --cleanup --retain 10 +wppackages deploy +wppackages deploy 20260313-140000 +wppackages deploy --rollback +wppackages deploy --rollback=20260313-130000 +wppackages deploy --to-r2 +wppackages deploy --cleanup +wppackages deploy --cleanup --retain 10 ``` - Validates build artifacts before any sync or promotion. @@ -81,10 +81,10 @@ wpcomposer deploy --cleanup --retain 10 ### Full Pipeline ```bash -wpcomposer pipeline -wpcomposer pipeline --skip-discover -wpcomposer pipeline --skip-deploy -wpcomposer pipeline --discover-source=config +wppackages pipeline +wppackages pipeline --skip-discover +wppackages pipeline --skip-deploy +wppackages pipeline --discover-source=config ``` Runs discover → update → build → deploy sequentially, stopping on failure. After a successful deploy, automatically cleans up old local builds (keeps 5 most recent). Cleanup is best-effort — failures are logged as warnings but do not fail the pipeline. @@ -92,15 +92,15 @@ Runs discover → update → build → deploy sequentially, stopping on failure. ### Aggregate Installs ```bash -wpcomposer aggregate-installs +wppackages aggregate-installs ``` -Recomputes `wp_composer_installs_total`, `wp_composer_installs_30d`, and `last_installed_at` on all packages. +Recomputes `wp_packages_installs_total`, `wp_packages_installs_30d`, and `last_installed_at` on all packages. ### Cleanup Sessions ```bash -wpcomposer cleanup-sessions +wppackages cleanup-sessions ``` Deletes expired rows from the `sessions` table. @@ -111,19 +111,19 @@ Configure via systemd timers or cron: | Command | Schedule | Notes | |---------|----------|-------| -| `wpcomposer pipeline` | Every 5 minutes | Main data refresh cycle | -| `wpcomposer aggregate-installs` | Hourly | Telemetry counter rollups | -| `wpcomposer cleanup-sessions` | Daily | Expired session cleanup | -| `wpcomposer generate-og` | Daily | Regenerate OG images where install counts changed | +| `wppackages pipeline` | Every 5 minutes | Main data refresh cycle | +| `wppackages aggregate-installs` | Hourly | Telemetry counter rollups | +| `wppackages cleanup-sessions` | Daily | Expired session cleanup | +| `wppackages generate-og` | Daily | Regenerate OG images where install counts changed | -Alternatively, run `wpcomposer serve --with-scheduler` to handle scheduling in-process. +Alternatively, run `wppackages serve --with-scheduler` to handle scheduling in-process. ## Global Flags All commands accept: - `--config ` — optional config file path -- `--db ` — database path (default `./storage/wpcomposer.db`) +- `--db ` — database path (default `./storage/wppackages.db`) - `--log-level info|debug|warn|error` — log verbosity ## Key Environment Variables @@ -144,7 +144,7 @@ All commands accept: ### Create initial admin user ```bash -echo 'secure-password' | wpcomposer admin create --email admin@example.com --name "Admin" --password-stdin +echo 'secure-password' | wppackages admin create --email admin@example.com --name "Admin" --password-stdin ``` `--password-stdin` is required. Password must be piped via stdin to avoid shell history exposure. @@ -152,13 +152,13 @@ echo 'secure-password' | wpcomposer admin create --email admin@example.com --nam ### Promote existing user to admin ```bash -wpcomposer admin promote --email user@example.com +wppackages admin promote --email user@example.com ``` ### Reset admin password ```bash -echo 'new-password' | wpcomposer admin reset-password --email admin@example.com --password-stdin +echo 'new-password' | wppackages admin reset-password --email admin@example.com --password-stdin ``` ## Admin Access Model @@ -273,14 +273,14 @@ gh secret set PROD_SSH_PRIVATE_KEY --env production < /path/to/private/key ## Litestream (SQLite Backup to R2) -[Litestream](https://litestream.io/) continuously replicates the SQLite database to R2 by streaming WAL changes. In production it wraps `wpcomposer serve` as a sidecar process — if the child dies, Litestream exits and systemd restarts both. +[Litestream](https://litestream.io/) continuously replicates the SQLite database to R2 by streaming WAL changes. In production it wraps `wppackages serve` as a sidecar process — if the child dies, Litestream exits and systemd restarts both. ### How it works The systemd service runs: ``` -litestream replicate -config /srv/wp-composer/shared/litestream.yml -exec "wpcomposer serve ..." +litestream replicate -config /srv/wp-packages/shared/litestream.yml -exec "wppackages serve ..." ``` WAL segments are uploaded to R2 continuously. A full snapshot is taken every 24 hours (Litestream default). @@ -296,7 +296,7 @@ make db-restore Or directly: ```bash -wpcomposer db restore --force +wppackages db restore --force ``` Requires `litestream` in PATH (`brew install litestream` on macOS) and the following env vars set: @@ -320,10 +320,10 @@ litestream snapshots -config litestream.yml SQLite in WAL mode supports safe file-level backups: ```bash -sqlite3 /path/to/wpcomposer.db ".backup '/path/to/backup.db'" +sqlite3 /path/to/wppackages.db ".backup '/path/to/backup.db'" ``` -Or use filesystem snapshots. The WAL file (`wpcomposer.db-wal`) must be included in any backup. +Or use filesystem snapshots. The WAL file (`wppackages.db-wal`) must be included in any backup. ### Runtime Settings @@ -342,19 +342,19 @@ PRAGMA busy_timeout=5000; - Re-run with `--force`, inspect build output and manifest. 2. **Bad promotion:** - - Use `wpcomposer deploy --rollback` or rollback to an explicit build ID. + - Use `wppackages deploy --rollback` or rollback to an explicit build ID. 3. **R2 sync failed mid-upload:** - Local symlink was not updated, so local state is consistent. - - Re-run `wpcomposer deploy --to-r2` to retry. + - Re-run `wppackages deploy --to-r2` to retry. 4. **Telemetry counters stale:** - - Run `wpcomposer aggregate-installs` manually. + - Run `wppackages aggregate-installs` manually. 5. **Expired sessions accumulating:** - - Run `wpcomposer cleanup-sessions` manually or verify the timer/cron is active. + - Run `wppackages cleanup-sessions` manually or verify the timer/cron is active. 6. **Database locked errors:** - - Verify WAL mode is active: `sqlite3 wpcomposer.db "PRAGMA journal_mode;"` + - Verify WAL mode is active: `sqlite3 wppackages.db "PRAGMA journal_mode;"` - Check `busy_timeout` is set. - - Ensure only one `wpcomposer serve` process is running. + - Ensure only one `wppackages serve` process is running. diff --git a/docs/r2-deployment.md b/docs/r2-deployment.md index c985506..b72bbb6 100644 --- a/docs/r2-deployment.md +++ b/docs/r2-deployment.md @@ -1,6 +1,6 @@ # R2 Deployment -WP Composer deploys built repository artifacts to Cloudflare R2 for serving via CDN. Builds are generated locally (fast filesystem I/O), then synced to R2 on deploy. +WP Packages deploys built repository artifacts to Cloudflare R2 for serving via CDN. Builds are generated locally (fast filesystem I/O), then synced to R2 on deploy. ## Deploy Model @@ -17,7 +17,7 @@ The deploy diffs the current build against the previous build locally. Mutable ` ## Prerequisites 1. A Cloudflare account with R2 enabled. -2. An R2 bucket created for the repository (e.g., `wp-composer-repo`). +2. An R2 bucket created for the repository (e.g., `wp-packages-repo`). 3. An R2 API token with read/write access to the bucket. 4. AWS CLI v2 installed (for manual operations and debugging). @@ -25,7 +25,7 @@ The deploy diffs the current build against the previous build locally. Mutable ` ### Create the bucket -In the Cloudflare dashboard: **R2 > Create bucket**. Pick a name (e.g., `wp-composer-repo`), choose a location hint close to your server. +In the Cloudflare dashboard: **R2 > Create bucket**. Pick a name (e.g., `wp-packages-repo`), choose a location hint close to your server. ### Create API credentials @@ -37,7 +37,7 @@ Save the **Access Key ID** and **Secret Access Key**. ### Connect a custom domain (recommended) -**R2 > your bucket > Settings > Custom Domains > Connect Domain**. This gives you a URL like `https://repo.wp-composer.com` backed by Cloudflare's CDN. +**R2 > your bucket > Settings > Custom Domains > Connect Domain**. This gives you a URL like `https://repo.wp-packages.org` backed by Cloudflare's CDN. Without a custom domain, R2 provides a `.r2.dev` URL, but it has rate limits and no caching. @@ -47,18 +47,18 @@ Without a custom domain, R2 provides a `.r2.dev` URL, but it has rate limits and # R2 credentials R2_ACCESS_KEY_ID=your-access-key-id R2_SECRET_ACCESS_KEY=your-secret-access-key -R2_BUCKET=wp-composer-repo +R2_BUCKET=wp-packages-repo R2_ENDPOINT=https://.r2.cloudflarestorage.com # Enable R2 deploy -WP_COMPOSER_DEPLOY_R2=true +WP_PACKAGES_DEPLOY_R2=true ``` Find your account ID in the Cloudflare dashboard under **R2 > Overview**. ## How Deploy Works -When deploying to R2 (`wpcomposer deploy --to-r2`): +When deploying to R2 (`wppackages deploy --to-r2`): 1. Validates the build (packages.json and manifest.json must exist). 2. Uploads `p2/` files in parallel — skips unchanged files (byte-compared against previous build). Each upload retries up to 3 times with exponential backoff. @@ -103,13 +103,13 @@ Enter: ### Verify access ```bash -aws s3 ls s3://wp-composer-repo/ --profile r2 --endpoint-url https://.r2.cloudflarestorage.com +aws s3 ls s3://wp-packages-repo/ --profile r2 --endpoint-url https://.r2.cloudflarestorage.com ``` ### List bucket contents ```bash -aws s3 ls s3://wp-composer-repo/p2/ --profile r2 --endpoint-url https://.r2.cloudflarestorage.com +aws s3 ls s3://wp-packages-repo/p2/ --profile r2 --endpoint-url https://.r2.cloudflarestorage.com ``` ### Cleanup legacy R2 objects @@ -122,26 +122,26 @@ After dropping Composer v1 support, the following R2 prefixes are orphaned and c Use the AWS CLI to delete these when ready: ```bash -aws s3 rm s3://wp-composer-repo/p/ --recursive --profile r2 --endpoint-url https://.r2.cloudflarestorage.com -aws s3 rm s3://wp-composer-repo/releases/ --recursive --profile r2 --endpoint-url https://.r2.cloudflarestorage.com +aws s3 rm s3://wp-packages-repo/p/ --recursive --profile r2 --endpoint-url https://.r2.cloudflarestorage.com +aws s3 rm s3://wp-packages-repo/releases/ --recursive --profile r2 --endpoint-url https://.r2.cloudflarestorage.com ``` -Local build cleanup is handled by `wpcomposer deploy --cleanup`. +Local build cleanup is handled by `wppackages deploy --cleanup`. ## Rollback Rollback deploys the target build to R2 — it diffs the target build's `p2/` files against the currently deployed build and uploads only changed files: ```bash -wpcomposer deploy --rollback --to-r2 -wpcomposer deploy --rollback=20260313-130000 --to-r2 +wppackages deploy --rollback --to-r2 +wppackages deploy --rollback=20260313-130000 --to-r2 ``` Rollback takes roughly the same time as a normal deploy (proportional to the number of changed files). ## Local-Only Mode -When `WP_COMPOSER_DEPLOY_R2` is unset or `false`, deploy only updates the local `current` symlink. Use this for development or when serving directly from the local filesystem. +When `WP_PACKAGES_DEPLOY_R2` is unset or `false`, deploy only updates the local `current` symlink. Use this for development or when serving directly from the local filesystem. ## Monitoring @@ -149,8 +149,8 @@ After deploy, verify the bucket: ```bash # Check root packages.json has metadata-url -curl -s https://repo.wp-composer.com/packages.json | jq '.["metadata-url"]' +curl -s https://repo.wp-packages.org/packages.json | jq '.["metadata-url"]' # Check a specific package -curl -s https://repo.wp-composer.com/p2/wp-plugin/akismet.json | head -c 200 +curl -s https://repo.wp-packages.org/p2/wp-plugin/akismet.json | head -c 200 ``` diff --git a/docs/telemetry.md b/docs/telemetry.md index 7c17fc6..b5d3902 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -4,7 +4,7 @@ Install telemetry records installs via Composer's `notify-batch` mechanism. ## Goal -- Count installs initiated through WP Composer package metadata. +- Count installs initiated through WP Packages package metadata. - No impact on download latency (notification is sent after install). - Avoid counting rapid duplicate retries from the same client. @@ -83,15 +83,15 @@ dedupe_hash = sha256(ip_hash + package_id + version + user_agent_hash) Periodic command (run hourly via systemd timer or cron): ```bash -wpcomposer aggregate-installs +wppackages aggregate-installs ``` Rollups written to `packages`: | Column | Description | |--------|-------------| -| `wp_composer_installs_total` | All-time install count | -| `wp_composer_installs_30d` | Installs in the last 30 days | +| `wp_packages_installs_total` | All-time install count | +| `wp_packages_installs_30d` | Installs in the last 30 days | | `last_installed_at` | Timestamp of most recent install | ## UI Integration @@ -99,7 +99,7 @@ Rollups written to `packages`: Public browser and detail pages expose: - WordPress.org download count (from package metadata). -- WP Composer install counters (when non-zero). +- WP Packages install counters (when non-zero). - Sort by Composer installs. ## Operational Notes diff --git a/go.mod b/go.mod index 60a3419..39f720a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/roots/wp-composer +module github.com/roots/wp-packages go 1.26.1 diff --git a/internal/app/app.go b/internal/app/app.go index 6e044f9..7808b8f 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -9,9 +9,9 @@ import ( "time" "github.com/getsentry/sentry-go" - "github.com/roots/wp-composer/internal/config" - "github.com/roots/wp-composer/internal/db" - "github.com/roots/wp-composer/internal/packagist" + "github.com/roots/wp-packages/internal/config" + "github.com/roots/wp-packages/internal/db" + "github.com/roots/wp-packages/internal/packagist" ) type App struct { diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 804667c..2aff3ab 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -5,7 +5,7 @@ import ( "database/sql" "testing" - "github.com/roots/wp-composer/internal/db" + "github.com/roots/wp-packages/internal/db" ) func setupTestDB(t *testing.T) *sql.DB { diff --git a/internal/config/config.go b/internal/config/config.go index e3c9122..65794f6 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -70,7 +70,7 @@ func defaults() *Config { return &Config{ Env: "local", LogLevel: "info", - DB: DBConfig{Path: "./storage/wpcomposer.db"}, + DB: DBConfig{Path: "./storage/wppackages.db"}, Server: ServerConfig{ Addr: ":8080", }, diff --git a/internal/db/migrate_test.go b/internal/db/migrate_test.go index 2da39e9..9860fdd 100644 --- a/internal/db/migrate_test.go +++ b/internal/db/migrate_test.go @@ -4,7 +4,7 @@ import ( "database/sql" "testing" - wpcomposergo "github.com/roots/wp-composer" + wppackagesgo "github.com/roots/wp-packages" ) func TestMigrateCreatesPackageStatsAndFTS(t *testing.T) { @@ -15,7 +15,7 @@ func TestMigrateCreatesPackageStatsAndFTS(t *testing.T) { } t.Cleanup(func() { _ = database.Close() }) - if err := Migrate(database, wpcomposergo.Migrations); err != nil { + if err := Migrate(database, wppackagesgo.Migrations); err != nil { t.Fatalf("running migrations: %v", err) } diff --git a/internal/deploy/r2.go b/internal/deploy/r2.go index 795cba7..0119a3c 100644 --- a/internal/deploy/r2.go +++ b/internal/deploy/r2.go @@ -17,7 +17,7 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" - "github.com/roots/wp-composer/internal/config" + "github.com/roots/wp-packages/internal/config" ) const ( diff --git a/internal/http/admin_auth.go b/internal/http/admin_auth.go index 4a6aa6b..ee9c162 100644 --- a/internal/http/admin_auth.go +++ b/internal/http/admin_auth.go @@ -5,8 +5,8 @@ import ( "net/http" "time" - "github.com/roots/wp-composer/internal/app" - "github.com/roots/wp-composer/internal/auth" + "github.com/roots/wp-packages/internal/app" + "github.com/roots/wp-packages/internal/auth" ) func handleLoginPage(a *app.App) http.HandlerFunc { @@ -117,7 +117,7 @@ func loginHTML(errMsg string) string { errorBlock = `

` + html.EscapeString(errMsg) + `

` } return ` -Admin Login — WP Composer +Admin Login — WP Packages