Skip to content

Commit 87fb796

Browse files
authored
Merge pull request #22 from WebDecoy/chore/release-flow
chore: bring release flow into the canonical repo (#1)
2 parents d3f6769 + a5bc834 commit 87fb796

4 files changed

Lines changed: 193 additions & 0 deletions

File tree

RELEASING.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Releasing the WebDecoy WordPress plugin
2+
3+
**This repository (`WebDecoy/wordpress-plugin`) is the canonical home of the
4+
plugin.** Releases are cut here. The copy under `php-sdk/wordpress/` in the app
5+
monorepo is a deprecated mirror — do not develop or release from it.
6+
7+
## 1. Bump the version
8+
9+
Update the version string in **all** of these:
10+
11+
1. `webdecoy.php` — the `Version:` header and the `WEBDECOY_VERSION` constant
12+
2. `readme.txt``Stable tag:` and the changelog section
13+
3. `changelog.txt` — add the new version entry at the top
14+
15+
The SDK `User-Agent` derives from `WEBDECOY_VERSION` automatically — nothing to
16+
bump there.
17+
18+
## 2. Build + prepare CDN metadata
19+
20+
```bash
21+
./release.sh <version> # e.g. ./release.sh 2.2.0
22+
```
23+
24+
This runs `build.sh`, produces `dist/webdecoy-<version>.zip`, and regenerates
25+
`cdn-files/update-info.json` with the ZIP's SHA-256 (the self-hosted updater
26+
rejects a package whose hash doesn't match). `cdn-files/update-info.json` is
27+
git-ignored on purpose — it's a per-build artifact, uploaded to the CDN rather
28+
than committed. `cdn-files/plugin-info.json` (the "View details" metadata) is
29+
tracked; bump its `version`/`download_url`/changelog when they change.
30+
31+
## 3. Upload to the CDN
32+
33+
The plugin ZIP and CDN JSON are hosted on Cloudflare R2
34+
(`webdecoy-cdn-assets` bucket, served at `https://cdn.webdecoy.com/wordpress/`):
35+
36+
```bash
37+
npx wrangler r2 object put webdecoy-cdn-assets/wordpress/webdecoy-<version>.zip \
38+
--file=./dist/webdecoy-<version>.zip --remote
39+
npx wrangler r2 object put webdecoy-cdn-assets/wordpress/update-info.json \
40+
--file=./cdn-files/update-info.json --remote
41+
npx wrangler r2 object put webdecoy-cdn-assets/wordpress/plugin-info.json \
42+
--file=./cdn-files/plugin-info.json --remote
43+
```
44+
45+
Self-hosted auto-updates are gated behind the `WEBDECOY_SELF_HOSTED` constant
46+
and read `update-info.json` from the CDN — so the CDN's `update-info.json` must
47+
always point at a ZIP that actually exists there with a matching SHA-256.
48+
49+
## 4. Tag
50+
51+
```bash
52+
git tag -a v<version> -m "v<version> — <summary>"
53+
git push origin v<version>
54+
```

cdn-files/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# update-info.json is generated by release.sh (it embeds the built ZIP's
2+
# SHA-256, which changes every build). Only the plugin-info.json template is
3+
# tracked; the release artifact is uploaded to the CDN, not committed.
4+
update-info.json

cdn-files/plugin-info.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "WebDecoy Bot Detection",
3+
"slug": "webdecoy",
4+
"version": "2.1.0",
5+
"author": "<a href=\"https://webdecoy.com\">WebDecoy</a>",
6+
"author_profile": "https://webdecoy.com",
7+
"requires": "5.6",
8+
"tested": "6.7",
9+
"requires_php": "7.4",
10+
"download_url": "https://cdn.webdecoy.com/wordpress/webdecoy-2.1.0.zip",
11+
"sections": {
12+
"description": "<p>WebDecoy provides enterprise-grade bot detection and fraud protection for WordPress websites. Unlike simple CAPTCHA solutions, WebDecoy uses a layered defense approach that analyzes visitors from multiple angles — including deterministic tripwires that catch scanners with zero false positives.</p><h4>Key Features</h4><ul><li>Deterministic tripwires (hidden honeypot paths) — zero-false-positive bot blocking</li><li>Server-side and client-side bot detection</li><li>Invisible proof-of-work challenge (no external CAPTCHA service)</li><li>Comment, login, and registration spam protection</li><li>WooCommerce carding attack prevention</li><li>60+ good bots automatically allowed</li><li>AI crawler detection and blocking</li><li>Optional WebDecoy Cloud: centralized dashboard and rotation-proof device lockouts</li></ul>",
13+
"installation": "<ol><li>Upload the plugin files to <code>/wp-content/plugins/webdecoy</code></li><li>Activate the plugin through the Plugins menu</li><li>Tripwires and local protection are active out of the box — no API key required</li><li>Optionally go to WebDecoy &gt; Settings &gt; WebDecoy Cloud to connect for centralized monitoring and enforcement</li></ol>",
14+
"changelog": "<h4>2.1.0</h4><ul><li>JS execution verification to catch non-JS HTTP scrapers</li><li>Challenge token meta tag on page serve; automatic page-serve reporting</li></ul><h4>2.0.0</h4><ul><li>All detection and protection now works locally — no API key required</li><li>Invisible proof-of-work challenge system (SHA-256, no external service)</li><li>Behavioral scoring, statistics page, enhanced detections page</li></ul><h4>1.3.0</h4><ul><li>Bulk IP blocking/unblocking; enhanced good bot detection (60+ bots)</li></ul>",
15+
"faq": "<h4>Does WebDecoy slow down my site?</h4><p>No. WebDecoy adds negligible latency; tripwire checks are a fast path lookup and clearance minting is idle-deferred.</p><h4>Will it block search engines?</h4><p>No. WebDecoy automatically allows 60+ known good bots including all major search engines, and tripwires only fire on hidden paths no legitimate crawler follows.</p>"
16+
},
17+
"icons": {
18+
"1x": "https://cdn.webdecoy.com/wordpress/assets/icon-128x128.png",
19+
"2x": "https://cdn.webdecoy.com/wordpress/assets/icon-256x256.png"
20+
},
21+
"banners": {
22+
"low": "https://cdn.webdecoy.com/wordpress/assets/banner-772x250.png",
23+
"high": "https://cdn.webdecoy.com/wordpress/assets/banner-1544x500.png"
24+
}
25+
}

release.sh

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/bin/bash
2+
#
3+
# WebDecoy WordPress Plugin Release Script
4+
#
5+
# Builds the plugin and prepares CDN files for deployment.
6+
#
7+
# Usage: ./release.sh <version>
8+
# Example: ./release.sh 1.0.1
9+
#
10+
11+
set -e
12+
13+
VERSION="$1"
14+
15+
if [ -z "$VERSION" ]; then
16+
echo "Usage: ./release.sh <version>"
17+
echo "Example: ./release.sh 1.0.1"
18+
exit 1
19+
fi
20+
21+
echo "🚀 Releasing WebDecoy WordPress Plugin v${VERSION}"
22+
echo "================================================"
23+
24+
# Build the plugin
25+
./build.sh "$VERSION"
26+
27+
# Compute the SHA-256 of the built ZIP. The self-hosted updater REQUIRES this
28+
# checksum in update-info.json and refuses to install a package whose hash does
29+
# not match (prevents installing a tampered ZIP). build.sh also writes a
30+
# dist/<zip>.sha256 file; we recompute here so release.sh is self-contained.
31+
ZIP_PATH="./dist/webdecoy-${VERSION}.zip"
32+
if [ ! -f "$ZIP_PATH" ]; then
33+
echo "❌ Build artifact not found: ${ZIP_PATH}"
34+
exit 1
35+
fi
36+
SHA256="$(shasum -a 256 "$ZIP_PATH" | awk '{print $1}')"
37+
if ! printf '%s' "$SHA256" | grep -Eq '^[a-f0-9]{64}$'; then
38+
echo "❌ Failed to compute a valid SHA-256 for ${ZIP_PATH}"
39+
exit 1
40+
fi
41+
echo "🔐 Package SHA-256: ${SHA256}"
42+
43+
# Update CDN files
44+
echo "📝 Updating CDN metadata files..."
45+
46+
CDN_DIR="./cdn-files"
47+
mkdir -p "$CDN_DIR"
48+
49+
# Update update-info.json
50+
# NOTE: "sha256" MUST be present and match the ZIP, or self-hosted auto-updates
51+
# will be rejected by the plugin's upgrader_pre_download integrity check.
52+
cat > "${CDN_DIR}/update-info.json" << EOF
53+
{
54+
"version": "${VERSION}",
55+
"download_url": "https://cdn.webdecoy.com/wordpress/webdecoy-${VERSION}.zip",
56+
"sha256": "${SHA256}",
57+
"details_url": "https://webdecoy.com/wordpress/changelog",
58+
"tested": "6.7",
59+
"requires_php": "7.4",
60+
"icons": {
61+
"1x": "https://cdn.webdecoy.com/wordpress/assets/icon-128x128.png",
62+
"2x": "https://cdn.webdecoy.com/wordpress/assets/icon-256x256.png"
63+
},
64+
"banners": {
65+
"low": "https://cdn.webdecoy.com/wordpress/assets/banner-772x250.png",
66+
"high": "https://cdn.webdecoy.com/wordpress/assets/banner-1544x500.png"
67+
}
68+
}
69+
EOF
70+
71+
echo "✅ Wrote update-info.json with sha256=${SHA256}"
72+
73+
# Update version in plugin-info.json
74+
sed -i '' "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" "${CDN_DIR}/plugin-info.json"
75+
sed -i '' "s|webdecoy-.*\.zip|webdecoy-${VERSION}.zip|g" "${CDN_DIR}/plugin-info.json"
76+
77+
echo ""
78+
echo "✅ Release v${VERSION} prepared!"
79+
echo "================================================"
80+
echo ""
81+
echo "Files to upload to CDN (https://cdn.webdecoy.com/wordpress/):"
82+
echo ""
83+
echo " dist/webdecoy-${VERSION}.zip"
84+
echo " cdn-files/update-info.json"
85+
echo " cdn-files/plugin-info.json"
86+
echo ""
87+
echo "CDN Directory Structure:"
88+
echo ""
89+
echo " cdn.webdecoy.com/"
90+
echo " └── wordpress/"
91+
echo " ├── webdecoy-${VERSION}.zip"
92+
echo " ├── update-info.json"
93+
echo " ├── plugin-info.json"
94+
echo " └── assets/"
95+
echo " ├── icon-128x128.png"
96+
echo " ├── icon-256x256.png"
97+
echo " ├── banner-772x250.png"
98+
echo " └── banner-1544x500.png"
99+
echo ""
100+
echo "Upload commands (adjust for your CDN):"
101+
echo ""
102+
echo " # AWS S3"
103+
echo " aws s3 cp dist/webdecoy-${VERSION}.zip s3://cdn-bucket/wordpress/"
104+
echo " aws s3 cp cdn-files/update-info.json s3://cdn-bucket/wordpress/"
105+
echo " aws s3 cp cdn-files/plugin-info.json s3://cdn-bucket/wordpress/"
106+
echo ""
107+
echo " # Generic SCP"
108+
echo " scp dist/webdecoy-${VERSION}.zip user@cdn.webdecoy.com:/var/www/wordpress/"
109+
echo " scp cdn-files/*.json user@cdn.webdecoy.com:/var/www/wordpress/"
110+
echo ""

0 commit comments

Comments
 (0)