{"id":47351465,"url":"https://github.com/builtmighty/builtmighty-site-backup","last_synced_at":"2026-03-18T00:01:49.778Z","repository":{"id":343324822,"uuid":"1174792703","full_name":"builtmighty/builtmighty-site-backup","owner":"builtmighty","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-16T16:32:49.000Z","size":6892,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-17T03:54:32.131Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/builtmighty.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-06T21:07:37.000Z","updated_at":"2026-03-16T16:31:37.000Z","dependencies_parsed_at":"2026-03-18T00:01:05.416Z","dependency_job_id":null,"html_url":"https://github.com/builtmighty/builtmighty-site-backup","commit_stats":null,"previous_names":["builtmighty/builtmighty-site-backup"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/builtmighty/builtmighty-site-backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtmighty%2Fbuiltmighty-site-backup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtmighty%2Fbuiltmighty-site-backup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtmighty%2Fbuiltmighty-site-backup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtmighty%2Fbuiltmighty-site-backup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/builtmighty","download_url":"https://codeload.github.com/builtmighty/builtmighty-site-backup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtmighty%2Fbuiltmighty-site-backup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30636636,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T23:56:54.546Z","status":"ssl_error","status_checked_at":"2026-03-17T23:56:28.952Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-18T00:00:49.545Z","updated_at":"2026-03-18T00:01:49.770Z","avatar_url":"https://github.com/builtmighty.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Built Mighty Site Backup\n\nA WordPress plugin that automates site backups to DigitalOcean Spaces. Designed for the Built Mighty team, it supports scheduled and on-demand backups of both the database and file system, with built-in integration for the staged-loader Codespace pipeline.\n\n[![Download ZIP](https://img.shields.io/badge/Download-ZIP-blue?style=for-the-badge)](https://github.com/builtmighty/builtmighty-site-backup/releases/latest/download/builtmighty-site-backup.zip)\n\n## Install via WP-CLI\n\n```bash\nwp plugin install https://github.com/builtmighty/builtmighty-site-backup/releases/latest/download/builtmighty-site-backup.zip --activate\n```\n\n## Requirements\n\n- WordPress 6.0+\n- PHP 8.1+\n\n## Features\n\n- **Full, Database, or Files-only backups** — choose what to back up\n- **Scheduled backups** — daily, twice daily, or weekly via WP-Cron\n- **DigitalOcean Spaces storage** — multipart uploads with retry and resume\n- **Retention management** — automatically prunes old backups beyond a configurable limit\n- **Backup history** — logs every backup with status, sizes, and errors\n- **Email notifications** — alerts on backup failure\n- **Codespace integration** — REST API endpoint for the bootstrap pipeline\n- **WP-CLI support** — full command-line interface\n- **Multisite compatible** — settings stored at the network level\n- **Cancel in-progress backups** — stop a running backup from the admin UI or WP-CLI\n- **Developer filters** — tune batch size, part size, concurrency, and gzip levels via `add_filter()`\n- **Action hooks** — fire custom code before/after each backup step, on completion, or on failure\n- **Access-controlled settings** — settings page restricted to authorized `@builtmighty.com` accounts\n\n## Installation\n\n1. Upload the plugin to `wp-content/plugins/builtmighty-site-backup`.\n2. Run `composer install` from the plugin directory.\n3. Activate the plugin in WordPress (or Network Activate on multisite).\n4. Go to **Settings \u003e Site Backup** and configure your DigitalOcean Spaces credentials.\n\n## Configuration\n\nAll settings are managed from the admin settings page.\n\n| Setting | Description |\n|---|---|\n| **Spaces Access Key** | DigitalOcean Spaces access key |\n| **Spaces Secret Key** | Secret key (encrypted at rest with AES-256-CBC) |\n| **Spaces Endpoint** | e.g. `nyc3.digitaloceanspaces.com` |\n| **Spaces Bucket** | Bucket name |\n| **Client Path** | Path prefix within the bucket |\n| **Hosting Provider** | Pressable or Generic |\n| **Schedule Frequency** | Daily, Twice Daily, or Weekly |\n| **Schedule Time** | Time of day (HH:MM) |\n| **Retention Count** | Number of backups to keep (1–365, default 7) |\n| **File Exclusions** | Additional patterns to exclude (one per line) |\n| **Notify on Failure** | Send email alerts when a backup fails |\n| **Notification Email** | Custom recipient (defaults to site admin) |\n\n### Default File Exclusions\n\nThe following paths are always excluded from file backups:\n\n- `wp-content/uploads`\n- `wp-content/cache`\n- `wp-content/upgrade`\n- `wp-content/backups`\n- `wp-content/backup-db`\n- `.git`\n- `node_modules`\n\n## WP-CLI Commands\n\n```bash\n# Run a backup (synchronous by default)\nwp bm-backup run [--type=\u003cfull|db|files\u003e] [--async]\n\n# Check backup status\nwp bm-backup status\n\n# List backups stored on Spaces\nwp bm-backup list [--type=\u003call|db|files\u003e]\n\n# Manually trigger retention cleanup\nwp bm-backup prune\n\n# Test the Spaces connection\nwp bm-backup test\n```\n\n## Developer Hooks \u0026 Filters\n\n### Filters\n\n| Filter | Default | Description |\n|--------|---------|-------------|\n| `bm_backup_db_batch_size` | `1000` | Rows per paginated DB export query |\n| `bm_backup_db_gzip_level` | `6` | Gzip compression level for DB dump |\n| `bm_backup_files_gzip_level` | `6` | Gzip compression level for file archive |\n| `bm_backup_upload_part_size` | `10485760` | Multipart upload part size in bytes (10 MB) |\n| `bm_backup_upload_concurrency` | `5` | Concurrent upload parts |\n| `bm_backup_upload_max_retries` | `3` | Max upload retries per part |\n| `bm_backup_admin_domains` | `['builtmighty.com']` | Email domains permitted to access the settings page |\n\n### Action Hooks\n\n| Hook | Args | Description |\n|------|------|-------------|\n| `bm_backup_before_start` | `$state` | Fires at the top of the start step |\n| `bm_backup_after_start` | `$state` | Fires after the start step |\n| `bm_backup_before_export_db` | `$state` | Fires before DB export |\n| `bm_backup_after_export_db` | `$state, $db_path` | Fires after DB export |\n| `bm_backup_before_archive_files` | `$state` | Fires before file archive |\n| `bm_backup_after_archive_files` | `$state, $files_path` | Fires after file archive |\n| `bm_backup_before_upload` | `$state, $type` | Fires before each upload step |\n| `bm_backup_after_upload` | `$state, $type, $remote_key` | Fires after each upload step |\n| `bm_backup_completed` | `$state` | Fires when backup completes successfully |\n| `bm_backup_failed` | `$state, $error` | Fires when backup fails |\n\n## REST API\n\n### Codespace Config\n\n```\nGET /wp-json/bm-backup/v1/codespace-config\nAuthorization: Bearer \u003capi-key\u003e\n```\n\nReturns encrypted credentials and backup configuration for the Codespace bootstrap pipeline. HTTPS only, rate-limited to 10 requests per 60 seconds per IP.\n\nA **Bootstrap Key** (available on the settings page) combines the site URL and API key into a single Base64-encoded secret for Codespace setup.\n\n## How It Works\n\nBackups are executed as a chain of background steps via Action Scheduler:\n\n1. **Start** — initialize backup, create log entry\n2. **Export Database** — stream a gzipped SQL dump using primary-key pagination\n3. **Archive Files** — create a `tar.gz` archive (shell `tar` preferred, PharData fallback)\n4. **Upload Database** — multipart upload to Spaces (10 MB parts, 5 concurrent)\n5. **Upload Files** — multipart upload to Spaces\n6. **Cleanup** — run retention policy, delete temp files, mark complete\n\nEach step runs independently to avoid timeout issues on resource-constrained hosts.\n\n## Security\n\n- Secret keys encrypted with AES-256-CBC using WordPress salts\n- Optional `BM_BACKUP_SECRET` constant in `wp-config.php` adds a second pepper to AES-256-CBC key derivation\n- Credential fields are write-only — values never appear in page source or form fields\n- Settings page restricted to authorized email domains (default: `@builtmighty.com`)\n- REST API protected with Bearer token authentication\n- HTTPS enforced on API endpoints\n- Rate limiting on API access\n- Nonce verification on all AJAX requests\n- Capability checks (`manage_options` / `manage_network_options`)\n- Prepared statements for all database queries\n- Temp files created with 0600 permissions\n\n## Dependencies\n\nManaged via Composer:\n\n- [aws/aws-sdk-php](https://github.com/aws/aws-sdk-php) ^3.300\n- [woocommerce/action-scheduler](https://github.com/woocommerce/action-scheduler) ^3.9\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuiltmighty%2Fbuiltmighty-site-backup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuiltmighty%2Fbuiltmighty-site-backup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuiltmighty%2Fbuiltmighty-site-backup/lists"}