Releasing Plugins
Every WordPress plugin in this monorepo ships via the same GitHub Actions workflow:
.github/workflows/release-plugins.yml.
Tag pattern → release. No manual zipping, no panel uploads.
Tag conventions
Section titled “Tag conventions”| Tag format | Plugin family | Plugin directory |
|---|---|---|
swft-checkout-v<X.Y.Z> | Swft Checkout | plugin/ |
swft-wallet-v<X.Y.Z> | Swft Wallet | plugin-wallet/ |
swft-lottery-compat-v<X.Y.Z> | Swft Lottery Compat | plugin-lottery-compat/ |
swft-<slug>-v<X.Y.Z> | other Swft plugins | plugin-<slug>/ |
fp-prize-portal-v<X.Y.Z> | FP Prize Portal | Lottery Ecosystem/Current Plugins/fp-prize-portal/ |
fp-instant-win-terrawallet-cu-sync-v<X.Y.Z> | FP Instant Win Sync | Lottery Ecosystem/Current Plugins/fp-instant-win-terrawallet-cu-sync/ |
fp-addons-v<X.Y.Z> | FP Add-ons | Lottery Ecosystem/Current Plugins/fp-addons/ |
fp-<slug>-v<X.Y.Z> | other FP plugins | Lottery Ecosystem/Current Plugins/fp-<slug>/ |
Version segment must be three dot-separated numbers (2.5.2, not 2.5 and not 2.5.2-rc1) so Plugin Update Checker can compare it.
Release flow
Section titled “Release flow”-
Bump the plugin’s version in BOTH the file header and any
define( '*_VERSION', ... )constant. The values must match — the WP admin UI reads the header, but the plugin’s update checker reads the constant. -
Commit the bump (any message; the commit doesn’t have to mention “release”):
Terminal window git add path/to/plugin/git commit -m "fix(fp-prize-portal): v2.5.2 — ..."git push -
Tag the commit and push the tag:
Terminal window git tag fp-prize-portal-v2.5.2git push origin fp-prize-portal-v2.5.2 -
CI takes over:
- Workflow
Release Plugintriggers on the tag - Resolves the plugin directory by parsing the tag prefix
- Stages the plugin as
<slug>/(canonical WP folder name) - For
fp-*tags only: downloads pinned Plugin Update Checker (PUC_VERSIONenv in the workflow) and vendors it into<slug>/lib/plugin-update-checker/ - Builds
<slug>.zipwith the dev cruft excluded - Creates a GitHub Release named e.g.
fp-prize-portal v2.5.2with the zip attached
- Workflow
-
Verify at
https://github.com/BuiltByGo/swft-app/releases— the new release should appear within ~30 seconds with the zip asset.
Installing on staging
Section titled “Installing on staging”# Replace the URL with the asset URL from the release pagewp plugin install \ https://github.com/BuiltByGo/swft-app/releases/download/fp-prize-portal-v2.5.2/fp-prize-portal.zip \ --activate --force--force overwrites an existing install (the WP “Replace current with uploaded” prompt). Skip it on first install.
Auto-updates on production
Section titled “Auto-updates on production”Once a plugin has been installed from a GitHub Release (so the bundled Plugin Update Checker is present), subsequent releases on this repo will appear in WP admin → Dashboard → Updates within ~12 hours, or instantly if the merchant clicks “Check Again.”
To force a check immediately:
wp eval 'delete_site_transient("update_plugins");'wp plugin update fp-prize-portal # or fp-addons, etc.Yanking a release
Section titled “Yanking a release”If a release is broken:
- Delete the release on GitHub (web UI → release → Delete) — this removes the asset and the Update URI lookup will roll back to the previous release.
- Delete the tag locally + on origin:
Terminal window git tag -d fp-prize-portal-v2.5.2git push origin :refs/tags/fp-prize-portal-v2.5.2 - Bump the version (e.g. v2.5.3) with the fix and tag again. Don’t re-use the deleted version number — sites that managed to update before you yanked won’t pick up a re-tagged v2.5.2.
Plugin Update Checker details
Section titled “Plugin Update Checker details”PUC v5 is bundled into fp-* zips at build time (PUC_VERSION env in the workflow controls the pinned version; currently v5.5). Each FP plugin’s main file loads PUC behind a file_exists guard, so:
- Source installs (cloning the repo into
wp-content/plugins/for dev) → no PUC, no auto-updates, plugin works manually. - Release zip installs (the standard path) → PUC loaded, WP detects new tags via GitHub Releases API.
Each plugin’s PUC config restricts release matching to its own tag prefix so a swft-wallet tag never offers an update to fp-prize-portal. The pattern is /^<slug>-v(\d+\.\d+\.\d+)$/i matched against tag names, plus an asset filename filter /^<slug>\.zip$/i.
To bump PUC version globally: edit PUC_VERSION in the workflow, tag any FP plugin, verify the resulting zip’s lib/plugin-update-checker/ matches the new pinned version.
When a release fails
Section titled “When a release fails”The workflow logs are at Actions → Release Plugin → <tag name>.
Common failure modes:
| Symptom | Cause | Fix |
|---|---|---|
ERROR: directory 'X' not found for slug 'Y' | Tag prefix doesn’t match an existing plugin dir | Check the tag — typo, or the dir hasn’t been added to the resolver in release-plugins.yml |
curl: (22) The requested URL returned error: 404 during PUC vendor | PUC_VERSION env points at a tag that doesn’t exist on YahnisElsts/plugin-update-checker | Check upstream, update PUC_VERSION |
| Zip built but release not created | GITHUB_TOKEN missing contents: write permission | Verify the workflow has permissions: contents: write |
| Release created but PUC doesn’t detect it on Mercury | Tag format mismatch with setReleaseVersionFilter() regex | Confirm tag is exactly <slug>-v<X.Y.Z> (no -rc1, no two-segment versions) |