Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use a GitHub Actions workflow that runs when a designated branch receives a push, validates the theme, and copies only that theme into the WordPress site’s wp-content/themes/<theme-folder>/ directory. Store the SSH private key in GitHub Secrets, protect production with a GitHub Environment, and prevent overlapping deployments with concurrency controls.
What the deployment pipeline does
A safe theme-only pipeline has five stages:
- A commit reaches an environment branch, such as
stagingormain. - GitHub Actions checks out the repository.
- The workflow validates PHP and builds any required CSS or JavaScript.
- An SSH-authenticated deployment step transfers the theme directory to the matching remote directory.
- You review the Actions log and the host’s deployment status, then clear relevant caches if needed.
Keeping the source and destination limited to one theme reduces the chance of changing WordPress core, uploads, plugins, configuration, or unrelated themes.
Prepare the repository and branches
Keep the theme in a predictable directory
Place the deployable theme at a stable path such as wp-content/themes/genesis-child-theme/. Decide whether compiled CSS and JavaScript are committed to Git or generated during the workflow; either approach can work, but the deployment must transfer the files the site actually needs.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsMap branches to environments
Use a staging branch for automatic staging releases and reserve main for production, or choose another mapping that matches your release process. A push trigger starts the workflow only after the commit has reached the selected branch. Add workflow_dispatch when an operator should be able to start a deployment manually.
#1 Best Overall
Create the GitHub Actions workflow
Save a workflow file under .github/workflows/. This skeleton shows the trigger, validation job, deployment boundary, and serialization controls; the host-specific deployment action belongs in the marked deployment step.
name: Deploy WordPress theme
on:
push:
branches:
- staging
- main
workflow_dispatch:
concurrency:
group: wordpress-theme-${{ github.ref }}
cancel-in-progress: false
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate theme
run: |
find wp-content/themes/genesis-child-theme -name '*.php' -print0 |
xargs -0 -n1 php -l
# Run your CSS/JavaScript build here, if the theme requires one.
deploy:
needs: validate
runs-on: ubuntu-latest
environment:
name: ${{ github.ref_name == 'main' && 'production' || 'staging' }}
steps:
- uses: actions/checkout@v4
- name: Deploy the theme
# Add the deployment action or SSH/rsync implementation supplied by your host.
run: echo "Configure the host-specific deployment step here"
The concurrency group keeps two runs for the same branch from deploying at once. Setting cancel-in-progress: false lets an earlier deployment finish instead of being interrupted; choose a different policy only after considering how your host handles partial updates.
Authenticate without exposing credentials
Generate or obtain an SSH key pair accepted by the WordPress host. Store only the private key in a GitHub repository or organization secret, and install the matching public key on the host with the narrowest access it supports. Never commit the private key or print it in a workflow log.
Recommended Free Tools
WP Engine’s documented integration expects the private key in a secret named WPE_SSHG_KEY_PRIVATE and connects through its SSH Gateway. Other hosts and actions use different secret names, connection details, and destination settings.
Configure a host-specific deployment step
WP Engine example
WP Engine documents wpengine/github-action-wpe-site-deploy, an action that uses the WP Engine SSH Gateway and rsync. Configure its source as the repository theme directory, for example wp-content/themes/genesis-child-theme/, and its destination as the corresponding remote theme directory. Follow the action’s current Marketplace documentation for the exact input names and version.
That action supports PHP syntax checking through its PHP_LINT option. If your theme has a front-end build, run that build before the transfer and make clear whether generated files are committed or created in CI.
Other hosts
A different provider may support ordinary SSH and rsync, a maintained GitHub integration, or neither. Confirm all of the following before relying on automatic deployment:
Free tools Windows power users keep installed
One-click scans. No signup required.
- The host permits SSH or its documented deployment method.
- The remote theme path is correct and writable by the deployment account.
- The GitHub-hosted runner can reach the host and its SSH gateway.
- The provider does not require an IP allowlist, private network, or special firewall route that GitHub-hosted runners cannot satisfy.
If the site is reachable only from a private network, use a properly secured self-hosted runner or the provider’s supported alternative. GitHub-hosted runner traffic can originate from a broad range of IP addresses.
Get source and destination paths right
Deploy the contents of the theme directory, not the whole repository. For example, the source should be the repository’s wp-content/themes/genesis-child-theme/ directory and the remote target should be that site’s matching theme directory.
Check trailing-slash behavior before the first production run. WP Engine documents that a trailing slash copies the contents of the selected source directory, while omitting it copies the directory itself and its contents. A path mismatch can create an extra nested theme directory or leave WordPress loading old files.
Handle exclusions and deletion flags carefully
Exclude development-only files and anything outside the theme’s release, such as local environment files, logs, and build caches. Keep uploads, configuration, plugins, and unrelated themes outside the deployment scope.
WP Engine documents a non-destructive default. Its custom FLAGS replace the default flags, and an example containing --delete can remove remote files that no longer exist in the source. Use deletion only when you intentionally want the remote directory to mirror the repository and have verified the consequences.
Best Value
Protect production releases
Create GitHub Environments named staging and production. Environment rules can:
- Restrict which branches are allowed to deploy.
- Scope deployment secrets to the intended environment.
- Require one or more reviewers before a production job proceeds.
- Record deployment status separately from ordinary workflow runs.
A practical arrangement is automatic deployment from staging and a production job on main that pauses for approval. Keep concurrency keyed to the target environment so separate environments do not block one another unnecessarily, while duplicate runs for one environment remain serialized.
Validate before transferring files
PHP syntax
Lint every PHP file in the theme, either with the host action’s PHP_LINT support or a command such as php -l in the validation job. Syntax errors should stop the workflow before any files reach the site.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Front-end output
If the theme uses a CSS or JavaScript build, install its locked dependencies and produce the deployable output before the transfer. Do not assume the host will run Node, package managers, or other build tools unless its documentation says so.
Scope checks
Review the files selected for transfer and confirm that the source directory contains the intended theme, not a parent repository directory. A dry run, where the chosen action supports one, is useful for detecting path and exclusion mistakes before changing production.
Verify and recover after a deployment
- Open the workflow run and inspect the validation and transfer logs.
- Check the host’s deployment history or SSH transfer status.
- Load the site and exercise the changed templates, styles, scripts, menus, and responsive layouts.
- Clear WordPress page or CDN caches when the host or caching layer requires it.
- If the result is wrong, stop further automatic runs, identify the last known-good commit, and redeploy that commit through the same controlled process.
The WP Engine rsync-style example updates files in place. The official material for this workflow does not establish atomic release switching or automatic rollback, so do not promise those capabilities unless your chosen host and deployment design explicitly provide them.
Quick Recap
Common design choices
| Choice | Advantages | Risks or limits |
|---|---|---|
| Theme-only transfer | Limits the blast radius to the custom theme. | Does not deploy plugin, configuration, database, or upload changes. |
| Automatic staging deployment | Quick feedback after a branch push. | A bad commit can reach staging without a human click. |
| Approved production deployment | Reviewers can inspect the commit before release. | Requires an approval step and a configured GitHub Environment. |
| GitHub-hosted runner | No runner maintenance. | May not pass a private-network route or fixed-IP allowlist. |
| Self-hosted runner | Can operate inside a protected network. | Adds runner patching, hardening, and access-management responsibilities. |
Final checklist
- The selected branch represents the intended environment.
- The workflow runs on
pushand, if needed,workflow_dispatch. - The SSH private key is a GitHub secret, never a repository file.
- The public key and remote permissions are configured on the host.
- Validation completes before deployment.
- The source and destination both identify the correct theme directory.
- Trailing-slash behavior is understood.
- Exclusions protect local-only files and unrelated WordPress data.
- Any
--deleteor equivalent flag has been deliberately reviewed. - Production uses environment restrictions, approvals, and suitable concurrency.
- The runner can reach the host.
- Logs, deployment history, site behavior, and caches are checked after release.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →

