WP Manifestindependent plugin directory
manifest / updates / wp-theme-deploy

WP Theme Deploy

WordPress plugin for Github repo configuration for theme deploy

by Amir Sandila, South Digital · github.com/amirmureed/wp-theme-deploy · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/amirmureed/wp-theme-deploy/archive/refs/heads/main.zip

Deploy WordPress themes from a GitHub repository with encrypted credentials, automatic backups, one-click restore, health checks and webhooks.

WP Theme Deploy pulls a theme from GitHub and installs it into wp-content/themes — no FTP, no Git or SSH on the server. It downloads the branch/tag as a zip over the GitHub API, finds the theme inside the repository, backs up whatever is currently in the theme folder, swaps in the new code and verifies the site still responds.

Contents

Features

Authentication methods

Method Notes
None Public repositories
Personal access token Classic or fine-grained
GitHub App The site gets its own identity with least-privilege, auto-rotating installation tokens
OAuth "Sign in with GitHub" web flow, with automatic token refresh

All secrets are encrypted at rest (libsodium, or OpenSSL AES-256-GCM) with a key derived from your wp-config.php salts or a dedicated GHTD_ENCRYPTION_KEY. Secrets can also be supplied as constants so they never touch the database. GitHub Enterprise Server is supported.

Finding the theme

The repository can be the theme, or contain it in a subfolder (for example wp-content/themes/my-theme).

Scan repository downloads the code and lists every folder that has a style.css with a Theme Name: header plus index.php or templates/index.html. Folders that only have functions.php are shown as incomplete. When exactly one valid theme exists it is selected automatically; otherwise you choose which one to deploy and which theme folder it belongs to.

Safety

  • Backups — every deploy moves the existing theme folder into wp-content/ghtd-backups/<theme>/<id>/ before replacing it (fast, same-filesystem rename).
  • Maintenance mode is enabled while the active theme is swapped.
  • Health check — after deploying the active theme, the plugin requests the home page, the admin context (admin-ajax.php) and any extra URLs you list; on a 5xx or fatal error it restores the backup automatically.
  • Watchdog — for a configurable window after the deploy (default 30 minutes) every request is watched. A fatal PHP error that involves the theme — on any page, in the dashboard, or caused by a conflict with another plugin — triggers an automatic rollback and an email. The broken version is kept as a "failed-deploy" backup for inspection.
  • Emergency restore link — a secret URL, handled before WordPress loads the theme, that lists backups and restores one even when the site and dashboard show a critical error.
  • Locking — only one deploy/restore runs at a time (database lock).
  • Backup management — backups can be restored, downloaded as zip, or deleted from the Backups tab; a retention limit prunes old ones.
  • History — every action is logged on the History tab with who, what, which commit and how long.
  • Notifications — optional email on failure or on every run.
  • Honours DISALLOW_FILE_MODS.

Requirements

  • WordPress 6.2 or later (tested up to 7.1)
  • PHP 7.4 or later

Installation

  1. Upload the wp-theme-deploy folder to wp-content/plugins/ and activate it.
  2. Open Theme Deploy → Settings, paste the repository URL, choose an authentication method and save.
  3. On the Deploy tab click Test connection, then Scan repository, pick the theme (if asked) and the target folder, and click Back up & deploy.

Automation

Push-to-deploy webhook

Point a GitHub webhook at:

https://example.com/wp-json/ghtd/v1/webhook

Requests are verified with an HMAC-SHA256 secret, and deploys run in the background. Both JSON and GitHub's default form-encoded content type are accepted.

WP-CLI

wp ghtd status|test|scan|deploy|backup|history|confirm|rescue-url|unlock

Hooks

Actions

  • ghtd_before_deploy
  • ghtd_after_deploy
  • ghtd_after_restore
  • ghtd_history_added
  • ghtd_watchdog_rollback

Filters

  • ghtd_exclude_patterns
  • ghtd_webhook_should_deploy
  • ghtd_webhook_force_async
  • ghtd_capability
  • ghtd_backup_dir
  • ghtd_work_dir
  • ghtd_health_check_targets
  • ghtd_health_check_timeout
  • ghtd_download_timeout
  • ghtd_notification_recipients

FAQ

Which token permissions do I need?
  • Classic PAT: repo (private) or none (public).
  • Fine-grained PAT: repository access to the repo with Contents: Read-only (Metadata is added automatically).
  • GitHub App: Contents: Read-only, installed on the repository.
A deploy broke the site and I cannot reach the dashboard. How do I restore?

In order of convenience:

  1. The watchdog normally restores the previous version by itself within seconds of the first fatal error.

  2. Open the emergency restore link from Settings → Safety (also included in failure emails) and click Restore.

  3. Over SSH:

    wp --skip-themes ghtd backup list
    wp --skip-themes ghtd backup restore <id> --slug=<theme> --yes
  4. With SFTP, copy wp-content/ghtd-backups/<theme>/<id>/files/ over the theme folder.

WordPress' own recovery-mode email link also lets you into the dashboard with the theme paused.

Where are backups stored?

wp-content/ghtd-backups/<theme-folder>/<backup-id>/files/ with a manifest.json next to it. The folder is protected from web access with .htaccess, web.config and index.php.

Does it run a build step?

No. Commit compiled assets, or build them in GitHub Actions and deploy a tag/branch that contains the built files.

I rotated my wp-config.php salts and now the token cannot be decrypted.

That is expected: the encryption key is derived from the salts unless GHTD_ENCRYPTION_KEY is defined. Re-enter the secret in Settings.

Can I keep secrets out of the database?

Yes. Define any of these in wp-config.php:

define( 'GHTD_GITHUB_TOKEN', '...' );
define( 'GHTD_GITHUB_APP_PRIVATE_KEY_FILE', '/path/to/private-key.pem' );
define( 'GHTD_OAUTH_CLIENT_SECRET', '...' );
define( 'GHTD_WEBHOOK_SECRET', '...' );

Changelog

1.2.0

  • Renamed to WP Theme Deploy (folder wp-theme-deploy). Settings, backups, history, webhook URL and emergency link are unchanged.
  • Webhook accepts GitHub's default form-encoded content type as well as JSON.
  • Guard against two copies of the plugin being active at once.

1.1.0

  • Post-deploy watchdog: automatic rollback when the deployed theme causes a fatal error on any request during a configurable window.
  • Emergency restore link that works while the site is down.
  • Health check now also probes the admin context and user-defined URLs.
  • wp ghtd confirm and wp ghtd rescue-url.
  • Health check now bypasses the plugin's own maintenance window (it previously saw the 503 maintenance page and rolled back good deploys of the active theme) and reports the exact PHP error, file, line and stack trace.
  • Fixed progress spinner that stayed visible.

1.0.0

  • Complete rewrite. Multiple auth methods (PAT, GitHub App, OAuth), encrypted secrets, repository scanning with theme detection, atomic swap with backups, restore/download/delete, retention, maintenance mode, health check with automatic rollback, history, email notifications, webhook push-to-deploy, WP-CLI commands, GitHub Enterprise Server support, migration from 0.1.0 settings.

0.1.0

  • Initial MVP.

License

GPLv2 or later

Built by Amir Sandila at South Digital.