Shared CI action for "putting" plugins or themes to various "press" sites (classicpress/wordpress)
- Shell 94.4%
- Dockerfile 5.6%
|
|
||
|---|---|---|
| action.yml | ||
| AGENTS.md | ||
| Dockerfile | ||
| entrypoint.sh | ||
| README.md | ||
| remote-activate.sh | ||
Pressput
A shared CI action that deploys plugins or themes to ClassicPress and WordPress sites running in Docker on our internal servers.
What it does
- Rsyncs your build output to the target theme/plugin directory on the server
- Activates the theme/plugin via
wp-cli(run as a sidecar container on the appropriate Docker network)
Setup
Forgejo
Set these as repository or organization secrets/variables:
SERVER_IP(variable) — server IP/hostnameCI_USER_SSH_KEY(secret) — SSH private key forci-deploy-user
Docker host
The target server must have:
- A
ci-deploy-useraccount with the matching public key in~/.ssh/authorized_keys ci-deploy-userin thedockergroup (to rundockercommands without sudo)- Write access for
ci-deploy-userto the targetwp-content/themes/andwp-content/plugins/directories (groupwww-datawith setgid bit is the typical setup) - Sites organized as
/opt/sites/<stack>/<site_name>/site_data/with WP/CP installed, and a Docker network nameddb-<site_name>connecting the site container to its database
Usage
# .forgejo/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: debian-13
steps:
- uses: actions/checkout@v4
# build steps here — npm install, npm run build, composer install, etc.
- uses: https://git.ouzelsoftware.com/sitetender/pressput@v1.0.0
with:
host: ${{ vars.SERVER_IP }}
ssh_key: ${{ secrets.CI_USER_SSH_KEY }}
src: ./dist
destinations: |
/opt/sites/classicpress/sitetender/site_data:theme:sitetender-theme
Inputs
| Input | Required | Description |
|---|---|---|
host |
yes | Server IP or hostname |
ssh_key |
yes | SSH private key for ci-deploy-user |
src |
no | Path to source directory in the repo to rsync. Default: . |
destinations |
yes | Newline-separated list of deploy targets in the format wp_root:type:slug (see below) |
destinations format
Each line is wp_root:type:slug:
wp_root— absolute path to the WP/CP root on the server (e.g.,/opt/sites/classicpress/sitetender/site_data). The Docker network is derived from this path: it must bedb-<parent-dir-name>. For/opt/sites/classicpress/sitetender/site_data, the network isdb-sitetender.type—themeorpluginslug— directory name underwp-content/themes/orwp-content/plugins/
The action computes the rsync target as <wp_root>/wp-content/<type>s/<slug> and runs wp <type> activate <slug> after copying.
Examples
Deploy a theme to one site:
destinations: |
/opt/sites/classicpress/sitetender/site_data:theme:sitetender-theme
Roll out the same plugin to multiple sites:
destinations: |
/opt/sites/classicpress/site1/site_data:plugin:ouzel-analytics
/opt/sites/classicpress/site2/site_data:plugin:ouzel-analytics
/opt/sites/classicpress/site3/site_data:plugin:ouzel-analytics
Versioning
Tag releases as vMAJOR.MINOR.PATCH. Pin to a specific tag in your workflows:
- uses: https://git.ouzelsoftware.com/sitetender/pressput@v1.0.0
Avoid @main — the Forgejo Actions runner caches action checkouts by ref, and floating refs can serve stale code.