693 lines
25 KiB
Markdown
693 lines
25 KiB
Markdown
# Plugin Update Workflow
|
|
|
|
**Last Updated:** January 20, 2026
|
|
**Version:** 1.8.4
|
|
**Status:** Production
|
|
**Scope:** How to release plugin updates and what happens automatically vs manually
|
|
|
|
---
|
|
|
|
## 🎯 Quick Start: Simplified Release Process
|
|
|
|
The plugin release process has been **simplified** to require only 3 fields:
|
|
|
|
1. **Version** (e.g., 1.3.3)
|
|
2. **Changelog** (what's new)
|
|
3. **Status** (draft → released)
|
|
|
|
All other fields are either:
|
|
- ✅ Auto-filled from previous version
|
|
- ✅ Auto-generated on release (file path, size, checksum)
|
|
- ✅ Auto-calculated (version code)
|
|
|
|
**Release in 3 clicks:**
|
|
```
|
|
Django Admin → Add Plugin Version → Enter 3 fields → Save → Change status to 'released'
|
|
```
|
|
|
|
---
|
|
|
|
## Recent Release History (v1.7.0)
|
|
|
|
### WordPress Plugin Progression
|
|
|
|
| Version | Date | Type | Key Changes |
|
|
|---------|------|------|-------------|
|
|
| 1.5.1 | Jan 10, 2026 | Minor | Admin UI consolidation: 6→3 pages (Dashboard, Settings, Logs), header alignment fixes |
|
|
| 1.5.0 | Jan 10, 2026 | Minor | Authentication simplification: Site.wp_api_key as single source of truth |
|
|
| 1.3.3 | Jan 10, 2026 | Patch | Template design: Square image grid fixes, landscape image positioning, direct border-radius/shadow on images without captions |
|
|
| 1.3.2 | Jan 9, 2026 | Patch | Template fixes in app and plugin, image layout improvements |
|
|
| 1.3.1 | Jan 9, 2026 | Patch | WordPress plugin versioning updates |
|
|
| 1.3.0 | Jan 8, 2026 | Minor | Initial distribution system release, automated updates |
|
|
|
|
### Distribution System Status
|
|
|
|
- ✅ Automated ZIP generation: Operational
|
|
- ✅ Checksum calculation: MD5 + SHA256
|
|
- ✅ WordPress auto-update: Active
|
|
- ✅ Health checks: Implemented
|
|
- ✅ Installation tracking: Complete
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Update Workflow Overview](#1-update-workflow-overview)
|
|
2. [What Happens Automatically](#2-what-happens-automatically)
|
|
3. [What Requires Manual Action](#3-what-requires-manual-action)
|
|
4. [Step-by-Step: Releasing a New Version](#4-step-by-step-releasing-a-new-version)
|
|
5. [Post-Update Verification Checklist](#5-post-update-verification-checklist)
|
|
6. [Version Numbering](#6-version-numbering)
|
|
7. [Rollback Procedure](#7-rollback-procedure)
|
|
8. [Emergency Updates](#8-emergency-updates)
|
|
9. [Recent Updates & Lessons Learned](#9-recent-updates--lessons-learned)
|
|
|
|
---
|
|
|
|
## 1. Update Workflow Overview
|
|
|
|
### The Big Picture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ Plugin Update Lifecycle │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌──────────────┐ │
|
|
│ │ 1. DEVELOP │ Make changes to plugin source code │
|
|
│ │ ↓ │ Location: /plugins/wordpress/source/igny8-wp-bridge/ │
|
|
│ └──────────────┘ │
|
|
│ │
|
|
│ ┌──────────────┐ │
|
|
│ │ 2. VERSION │ Update version in PHP header + constant │
|
|
│ │ ↓ │ File: igny8-bridge.php │
|
|
│ └──────────────┘ │
|
|
│ │
|
|
│ ┌──────────────┐ │
|
|
│ │ 3. RELEASE │ Create PluginVersion in Django admin │
|
|
│ │ ↓ │ Set status = "released" or "update_ready" │
|
|
│ └──────────────┘ │
|
|
│ │
|
|
│ ┌──────────────┐ │
|
|
│ │ 4. AUTO-BUILD│ ✅ AUTOMATIC: ZIP created, checksums calculated │
|
|
│ │ ↓ │ Signal handler builds package on status change │
|
|
│ └──────────────┘ │
|
|
│ │
|
|
│ ┌──────────────┐ │
|
|
│ │ 5. VERIFY │ Test download, check contents, verify endpoints │
|
|
│ │ ↓ │ See verification checklist below │
|
|
│ └──────────────┘ │
|
|
│ │
|
|
│ ┌──────────────┐ │
|
|
│ │ 6. AVAILABLE │ WordPress sites can now see and install update │
|
|
│ │ │ Users update via WP admin or auto-update │
|
|
│ └──────────────┘ │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 2. What Happens Automatically
|
|
|
|
When you change a `PluginVersion` status to `released` or `update_ready`, the following happens **automatically** via Django signals:
|
|
|
|
### ✅ Automatic Actions
|
|
|
|
| Action | Details |
|
|
|--------|---------|
|
|
| **ZIP Creation** | Source files packaged into distribution ZIP |
|
|
| **Version Update** | Version number updated in PHP files inside ZIP |
|
|
| **File Cleanup** | Tests, .git, __pycache__, .bak files removed from ZIP |
|
|
| **Checksum Calculation** | SHA256 hash generated |
|
|
| **File Size Recording** | Byte count stored in database |
|
|
| **File Path Update** | `file_path` field populated |
|
|
| **Released Date** | `released_at` timestamp set |
|
|
| **Symlink Update** | `*-latest.zip` symlink updated |
|
|
|
|
### How It Works (Signal Handler)
|
|
|
|
```python
|
|
# backend/igny8_core/plugins/signals.py
|
|
|
|
@receiver(pre_save, sender=PluginVersion)
|
|
def auto_build_plugin_on_release(sender, instance, **kwargs):
|
|
"""
|
|
Triggered when PluginVersion.status changes to:
|
|
- 'released'
|
|
- 'update_ready'
|
|
|
|
Actions:
|
|
1. Calls create_plugin_zip() utility
|
|
2. Updates instance.file_path
|
|
3. Updates instance.file_size
|
|
4. Updates instance.checksum
|
|
5. Sets instance.released_at
|
|
"""
|
|
```
|
|
|
|
### What WordPress Sites See
|
|
|
|
Once released, the `check-update` API returns:
|
|
|
|
```json
|
|
{
|
|
"update_available": true,
|
|
"latest_version": "1.2.0",
|
|
"download_url": "https://api.igny8.com/api/plugins/igny8-wp-bridge/download/",
|
|
"changelog": "Your changelog here"
|
|
}
|
|
```
|
|
|
|
WordPress will show "Update Available" in:
|
|
- Plugins page
|
|
- Dashboard → Updates
|
|
- Admin bar (if enabled)
|
|
|
|
---
|
|
|
|
## 3. What Requires Manual Action
|
|
|
|
### ❌ Manual Steps Required
|
|
|
|
| Action | When | How |
|
|
|--------|------|-----|
|
|
| **Update Source Version** | Before release | Edit `igny8-bridge.php` header |
|
|
| **Create PluginVersion Record** | Each release | Django admin: just enter version, changelog, status |
|
|
| **Verify After Release** | After status change | Run verification checklist |
|
|
| **Mark Old Version Deprecated** | After successful release | Change old version status |
|
|
|
|
**Note:** The form is simplified - most fields auto-fill from previous version or are auto-generated.
|
|
|
|
### Source Version Update Locations
|
|
|
|
When releasing a new version, update these in the source:
|
|
|
|
**File:** `/plugins/wordpress/source/igny8-wp-bridge/igny8-bridge.php`
|
|
|
|
```php
|
|
/**
|
|
* Plugin Name: IGNY8 WordPress Bridge
|
|
* Version: 1.2.0 ← UPDATE THIS
|
|
*/
|
|
|
|
define('IGNY8_BRIDGE_VERSION', '1.2.0'); ← AND THIS
|
|
```
|
|
|
|
**Note:** The ZIP build process also updates these, but it's good practice to keep source in sync.
|
|
|
|
---
|
|
|
|
## 4. Step-by-Step: Releasing a New Version
|
|
|
|
### The Simplified Process
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ Simplified Version Release (3 Required Fields) │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Django Admin → Add Plugin Version │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
│ │ Plugin: [IGNY8 WordPress Bridge ▼] ← Select plugin │ │
|
|
│ │ Version: [1.2.0] ← New version │ │
|
|
│ │ Status: [draft ▼] ← Start as draft │ │
|
|
│ │ Changelog: [Bug fixes and improvements] ← What's new │ │
|
|
│ │ │ │
|
|
│ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ │
|
|
│ │ Everything below is AUTO-FILLED or AUTO-GENERATED: │ │
|
|
│ │ │ │
|
|
│ │ Min API Version: 1.0 (from previous version) │ │
|
|
│ │ Min PHP Version: 7.4 (from previous version) │ │
|
|
│ │ File Path: (empty) → Auto-generated on release │ │
|
|
│ │ File Size: (empty) → Auto-calculated on release │ │
|
|
│ │ Checksum: (empty) → Auto-calculated on release │ │
|
|
│ │ Version Code: (empty) → Auto-calculated from version │ │
|
|
│ └────────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ Click [Save] → Status changes to 'released' → ZIP builds automatically │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Step 1: Make Code Changes
|
|
|
|
```bash
|
|
cd /data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/
|
|
|
|
# Make your changes to PHP files
|
|
# Test locally if possible
|
|
```
|
|
|
|
### Step 2: Update Version Number
|
|
|
|
Edit `igny8-bridge.php`:
|
|
|
|
```php
|
|
/**
|
|
* Plugin Name: IGNY8 WordPress Bridge
|
|
* Version: 1.2.0 ← New version
|
|
*/
|
|
|
|
define('IGNY8_BRIDGE_VERSION', '1.2.0'); ← Match here
|
|
```
|
|
|
|
### Step 3: Create PluginVersion in Django Admin
|
|
|
|
1. Go to: `https://api.igny8.com/backend/`
|
|
2. Navigate to: **Plugin Distribution** → **Plugin Versions**
|
|
3. Click **Add Plugin Version**
|
|
4. Fill in **ONLY** these required fields:
|
|
- **Plugin:** IGNY8 WordPress Bridge
|
|
- **Version:** 1.2.0
|
|
- **Status:** draft (initially)
|
|
- **Changelog:** Describe changes
|
|
5. Click **Save**
|
|
|
|
**Note:** All other fields are auto-filled:
|
|
- `min_api_version`, `min_platform_version`, `min_php_version` → Copied from previous version
|
|
- `file_path`, `file_size`, `checksum` → Auto-generated when you release
|
|
- `version_code` → Auto-calculated from version number
|
|
|
|
### Step 4: Release the Version
|
|
|
|
**Option A: Release via Status Change**
|
|
|
|
1. Edit the PluginVersion you just created
|
|
2. Change **Status** to `released`
|
|
3. Click **Save**
|
|
|
|
**Option B: Release via Bulk Action**
|
|
|
|
1. Select the version(s) in the list
|
|
2. Choose **Actions** → **✅ Release selected versions**
|
|
3. Click **Go**
|
|
|
|
**What happens:** Signal triggers auto-build → ZIP created → database updated with file info
|
|
|
|
**Note:** You can also use the action **📢 Mark as update ready** to immediately notify WordPress sites.
|
|
|
|
### Step 5: Verify Release
|
|
|
|
Run the [verification checklist](#5-post-update-verification-checklist) below.
|
|
|
|
### Step 6: Deprecate Old Version (Optional)
|
|
|
|
1. Find the previous version in Django admin
|
|
2. Change **Status** to `deprecated`
|
|
3. Save
|
|
|
|
---
|
|
|
|
## 5. Post-Update Verification Checklist
|
|
|
|
### Quick Verification Script
|
|
|
|
Run this single command to verify everything:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Complete Plugin Release Verification Script
|
|
# Usage: Save as verify-plugin.sh and run: bash verify-plugin.sh 1.1.2
|
|
|
|
VERSION=${1:-"latest"}
|
|
PLUGIN_SLUG="igny8-wp-bridge"
|
|
|
|
echo "=========================================="
|
|
echo "Plugin Release Verification: v${VERSION}"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
# 1. Check ZIP file exists
|
|
echo "1. Checking ZIP file..."
|
|
if [ "$VERSION" = "latest" ]; then
|
|
ls -lh /data/app/igny8/plugins/wordpress/dist/${PLUGIN_SLUG}-latest.zip 2>/dev/null && echo " ✓ Latest ZIP exists" || echo " ✗ Latest ZIP not found"
|
|
else
|
|
ls -lh /data/app/igny8/plugins/wordpress/dist/${PLUGIN_SLUG}-v${VERSION}.zip 2>/dev/null && echo " ✓ ZIP v${VERSION} exists" || echo " ✗ ZIP v${VERSION} not found"
|
|
fi
|
|
echo ""
|
|
|
|
# 2. Check symlink
|
|
echo "2. Checking symlink..."
|
|
ls -la /data/app/igny8/plugins/wordpress/dist/${PLUGIN_SLUG}-latest.zip | grep -q "^l" && echo " ✓ Symlink valid" || echo " ✗ Symlink missing"
|
|
echo ""
|
|
|
|
# 3. Test download endpoint
|
|
echo "3. Testing download endpoint..."
|
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://api.igny8.com/api/plugins/${PLUGIN_SLUG}/download/)
|
|
FILE_SIZE=$(curl -s -o /dev/null -w "%{size_download}" https://api.igny8.com/api/plugins/${PLUGIN_SLUG}/download/)
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
echo " ✓ Download works: ${HTTP_CODE} - ${FILE_SIZE} bytes ($(( FILE_SIZE / 1024 )) KB)"
|
|
else
|
|
echo " ✗ Download failed: HTTP ${HTTP_CODE}"
|
|
fi
|
|
echo ""
|
|
|
|
# 4. Test check-update endpoint
|
|
echo "4. Testing check-update endpoint..."
|
|
UPDATE_RESPONSE=$(curl -s "https://api.igny8.com/api/plugins/${PLUGIN_SLUG}/check-update/?current_version=1.0.0")
|
|
LATEST_VERSION=$(echo "$UPDATE_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('latest_version', 'N/A'))" 2>/dev/null)
|
|
if [ -n "$LATEST_VERSION" ] && [ "$LATEST_VERSION" != "N/A" ]; then
|
|
echo " ✓ Check-update works: Latest version = $LATEST_VERSION"
|
|
else
|
|
echo " ✗ Check-update failed"
|
|
fi
|
|
echo ""
|
|
|
|
# 5. Test info endpoint
|
|
echo "5. Testing info endpoint..."
|
|
INFO_RESPONSE=$(curl -s "https://api.igny8.com/api/plugins/${PLUGIN_SLUG}/info/")
|
|
PLUGIN_NAME=$(echo "$INFO_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('name', 'N/A'))" 2>/dev/null)
|
|
if [ -n "$PLUGIN_NAME" ] && [ "$PLUGIN_NAME" != "N/A" ]; then
|
|
echo " ✓ Info endpoint works: $PLUGIN_NAME"
|
|
else
|
|
echo " ✗ Info endpoint failed"
|
|
fi
|
|
echo ""
|
|
|
|
# 6. Verify version in ZIP
|
|
echo "6. Verifying version in ZIP..."
|
|
if [ "$VERSION" != "latest" ]; then
|
|
ZIP_VERSION=$(unzip -p /data/app/igny8/plugins/wordpress/dist/${PLUGIN_SLUG}-v${VERSION}.zip ${PLUGIN_SLUG}/igny8-bridge.php 2>/dev/null | grep -E "Version:" | head -1 | awk '{print $3}')
|
|
if [ "$ZIP_VERSION" = "$VERSION" ]; then
|
|
echo " ✓ ZIP version matches: $ZIP_VERSION"
|
|
else
|
|
echo " ✗ ZIP version mismatch: expected $VERSION, got $ZIP_VERSION"
|
|
fi
|
|
else
|
|
echo " - Skipped (use specific version to check)"
|
|
fi
|
|
echo ""
|
|
|
|
# 7. Verify API URL
|
|
echo "7. Verifying API URL in ZIP..."
|
|
API_COUNT=$(unzip -p /data/app/igny8/plugins/wordpress/dist/${PLUGIN_SLUG}-latest.zip ${PLUGIN_SLUG}/igny8-bridge.php 2>/dev/null | grep -c "api.igny8.com")
|
|
if [ "$API_COUNT" -gt 0 ]; then
|
|
echo " ✓ API URL correct: api.igny8.com found (${API_COUNT} occurrences)"
|
|
else
|
|
echo " ✗ API URL incorrect: api.igny8.com not found"
|
|
fi
|
|
echo ""
|
|
|
|
# 8. Check database
|
|
echo "8. Checking database..."
|
|
docker exec igny8_backend python manage.py shell -c "
|
|
from igny8_core.plugins.models import Plugin, PluginVersion
|
|
try:
|
|
p = Plugin.objects.get(slug='${PLUGIN_SLUG}')
|
|
v = p.get_latest_version()
|
|
if v:
|
|
print(f' ✓ Latest version: {v.version}')
|
|
print(f' ✓ Status: {v.status}')
|
|
print(f' ✓ File: {v.file_path}')
|
|
print(f' ✓ Size: {v.file_size:,} bytes ({v.file_size/1024:.1f} KB)')
|
|
print(f' ✓ Checksum: {v.checksum[:32]}...')
|
|
else:
|
|
print(' ✗ No released version found')
|
|
except Exception as e:
|
|
print(f' ✗ Error: {e}')
|
|
" 2>/dev/null | grep -E "✓|✗"
|
|
echo ""
|
|
|
|
echo "=========================================="
|
|
echo "Verification Complete"
|
|
echo "=========================================="
|
|
```
|
|
|
|
**Quick run (copy-paste):**
|
|
|
|
```bash
|
|
# Verify latest version
|
|
curl -s "https://api.igny8.com/api/plugins/igny8-wp-bridge/info/" | python3 -m json.tool && \
|
|
curl -s "https://api.igny8.com/api/plugins/igny8-wp-bridge/check-update/?current_version=1.0.0" | python3 -m json.tool && \
|
|
ls -lh /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-latest.zip && \
|
|
echo "✓ All endpoints working"
|
|
```
|
|
|
|
### Database Verification
|
|
|
|
```bash
|
|
# Check database has correct values
|
|
docker exec igny8_backend python manage.py shell -c "
|
|
from igny8_core.plugins.models import Plugin, PluginVersion
|
|
p = Plugin.objects.get(slug='igny8-wp-bridge')
|
|
v = p.get_latest_version()
|
|
print(f'Version: {v.version}')
|
|
print(f'Status: {v.status}')
|
|
print(f'File path: {v.file_path}')
|
|
print(f'File size: {v.file_size}')
|
|
print(f'Checksum: {v.checksum[:32]}...')
|
|
print(f'Released at: {v.released_at}')
|
|
"
|
|
```
|
|
|
|
### Expected Results
|
|
|
|
| Check | Expected |
|
|
|-------|----------|
|
|
| Download returns | 200 status, ~150-200KB |
|
|
| check-update shows | `"latest_version": "1.2.0"` |
|
|
| info shows | `"version": "1.2.0"` |
|
|
| ZIP version header | `Version: 1.2.0` |
|
|
| API URL | `api.igny8.com` (NOT app.igny8.com) |
|
|
|
|
### WordPress Verification (If Possible)
|
|
|
|
1. Go to a test WordPress site with plugin installed
|
|
2. Navigate to **Dashboard** → **Updates** → **Check Again**
|
|
3. Verify "IGNY8 WordPress Bridge" shows update available
|
|
4. Click "View version details" → verify changelog appears
|
|
5. Click "Update Now" → verify update completes successfully
|
|
|
|
---
|
|
|
|
## 6. Version Numbering
|
|
|
|
### Semantic Versioning
|
|
|
|
Format: `MAJOR.MINOR.PATCH` (e.g., 1.2.3)
|
|
|
|
| Part | When to Increment |
|
|
|------|-------------------|
|
|
| **MAJOR** | Breaking changes, incompatible API changes |
|
|
| **MINOR** | New features, backwards compatible |
|
|
| **PATCH** | Bug fixes, minor improvements |
|
|
|
|
### Version Code Calculation
|
|
|
|
Used for numeric comparison in database:
|
|
|
|
```
|
|
1.0.0 → 10000
|
|
1.0.1 → 10001
|
|
1.2.0 → 10200
|
|
1.2.3 → 10203
|
|
2.0.0 → 20000
|
|
```
|
|
|
|
Formula: `(MAJOR * 10000) + (MINOR * 100) + PATCH`
|
|
|
|
---
|
|
|
|
## 7. Rollback Procedure
|
|
|
|
### If Update Causes Issues
|
|
|
|
**Option 1: Quick Rollback via Database**
|
|
|
|
```bash
|
|
# Make old version the "latest" by changing status
|
|
docker exec igny8_backend python manage.py shell -c "
|
|
from igny8_core.plugins.models import PluginVersion
|
|
|
|
# Demote new version
|
|
new = PluginVersion.objects.get(plugin__slug='igny8-wp-bridge', version='1.2.0')
|
|
new.status = 'deprecated'
|
|
new.save()
|
|
|
|
# Promote old version back
|
|
old = PluginVersion.objects.get(plugin__slug='igny8-wp-bridge', version='1.1.1')
|
|
old.status = 'released'
|
|
old.save()
|
|
|
|
print('Rollback complete')
|
|
"
|
|
```
|
|
|
|
**Option 2: Keep Old ZIP Files**
|
|
|
|
Old ZIP files are preserved in `dist/`. To serve an old version:
|
|
|
|
```bash
|
|
# Update symlink to point to old version
|
|
cd /data/app/igny8/plugins/wordpress/dist/
|
|
ln -sf igny8-wp-bridge-v1.1.1.zip igny8-wp-bridge-latest.zip
|
|
```
|
|
|
|
### Retention Policy
|
|
|
|
Keep at least 3 previous version ZIPs for emergency rollback:
|
|
- Current release
|
|
- Previous release
|
|
- One before that
|
|
|
|
---
|
|
|
|
## 8. Emergency Updates
|
|
|
|
### For Critical Security Fixes
|
|
|
|
1. **Set `force_update = True`** on the new PluginVersion
|
|
2. This flag signals WordPress sites that update is mandatory
|
|
3. Sites with auto-updates enabled will update immediately
|
|
|
|
### Emergency Release Checklist
|
|
|
|
```bash
|
|
# 1. Make the fix in source
|
|
cd /data/app/igny8/plugins/wordpress/source/igny8-wp-bridge/
|
|
# ... make changes ...
|
|
|
|
# 2. Update version (use PATCH increment)
|
|
# Edit igny8-bridge.php
|
|
|
|
# 3. Create version in Django admin with:
|
|
# - Status: update_ready
|
|
# - Force Update: ✓ (checked)
|
|
# - Changelog: "SECURITY: [description]"
|
|
|
|
# 4. Verify immediately
|
|
curl https://api.igny8.com/api/plugins/igny8-wp-bridge/check-update/?current_version=1.0.0
|
|
|
|
# Response should include:
|
|
# "force_update": true
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Recent Updates & Lessons Learned
|
|
|
|
### v1.3.3 Release (Jan 10, 2026)
|
|
|
|
**Changes:**
|
|
- Fixed square image grid layout (side-by-side display)
|
|
- Fixed landscape image positioning in sections 4+
|
|
- Removed card wrapper for images without captions
|
|
- Applied border-radius/shadow directly to images
|
|
- Landscape images now appear after first paragraph
|
|
|
|
**Process:**
|
|
- Source code updated in plugin templates and CSS
|
|
- Version bumped in `igny8-bridge.php` (header + constant)
|
|
- Django admin: Created v1.3.3 with changelog
|
|
- Status changed to "released" → ZIP auto-generated
|
|
- Verified download endpoint and file contents
|
|
- Template changes tested on staging WordPress site
|
|
|
|
**Lessons:**
|
|
- CSS changes require thorough cross-browser testing
|
|
- Image layout fixes need responsive design verification
|
|
- Template changes should be tested with multiple content types
|
|
|
|
### v1.3.2 Release (Jan 9, 2026)
|
|
|
|
**Changes:**
|
|
- Template rendering improvements
|
|
- Image layout enhancements
|
|
- Content section fixes
|
|
|
|
**Process:**
|
|
- Standard release workflow
|
|
- Auto-build successful
|
|
- No rollback needed
|
|
|
|
### v1.3.0 Release (Jan 8, 2026)
|
|
|
|
**Changes:**
|
|
- Initial distribution system implementation
|
|
- WordPress auto-update mechanism
|
|
- Base template system
|
|
|
|
**Process:**
|
|
- Major release with new infrastructure
|
|
- Extensive testing required
|
|
- First use of automated packaging
|
|
|
|
### Distribution System Milestones
|
|
|
|
**v1.7.0 Infrastructure:**
|
|
- ✅ Complete plugin distribution system
|
|
- ✅ Multi-platform support architecture
|
|
- ✅ Automated versioning and packaging
|
|
- ✅ Security features (checksums, signed URLs)
|
|
- ✅ Monitoring and analytics
|
|
|
|
**Best Practices Established:**
|
|
1. Always test download endpoint after release
|
|
2. Verify ZIP contents match source
|
|
3. Check version number in extracted files
|
|
4. Test update notification in WordPress
|
|
5. Monitor download analytics
|
|
|
|
**Common Issues Resolved:**
|
|
- ZIP generation timing → Now synchronous in signals
|
|
- Checksum mismatches → Auto-calculated reliably
|
|
- Version comparison → Semantic versioning logic fixed
|
|
- File size tracking → Automatic and accurate
|
|
|
|
---
|
|
|
|
## Quick Reference Card
|
|
|
|
### Release New Version (Simplified)
|
|
|
|
```
|
|
1. Edit source code in /plugins/wordpress/source/igny8-wp-bridge/
|
|
2. Update version in igny8-bridge.php (header + constant)
|
|
3. Django Admin → Add Plugin Version:
|
|
- Plugin: IGNY8 WordPress Bridge
|
|
- Version: 1.3.3 (or next version)
|
|
- Changelog: Describe changes
|
|
- Status: draft
|
|
- (All other fields auto-fill)
|
|
4. Change status to "released" (or use bulk action) → Auto-build triggers
|
|
5. Run verification checklist
|
|
6. Optionally: Mark old version as deprecated
|
|
```
|
|
|
|
**Admin Bulk Actions:**
|
|
- **✅ Release selected versions** - Builds ZIP and marks as released
|
|
- **📢 Mark as update ready** - Notifies WordPress sites
|
|
- **🗑️ Mark as deprecated** - Deprecates old versions
|
|
|
|
### Verification Commands
|
|
|
|
```bash
|
|
# Test all endpoints
|
|
curl -I https://api.igny8.com/api/plugins/igny8-wp-bridge/download/
|
|
curl https://api.igny8.com/api/plugins/igny8-wp-bridge/check-update/?current_version=1.0.0
|
|
curl https://api.igny8.com/api/plugins/igny8-wp-bridge/info/
|
|
|
|
# Check ZIP contents
|
|
unzip -l /data/app/igny8/plugins/wordpress/dist/igny8-wp-bridge-v*.zip | head -20
|
|
```
|
|
|
|
### Emergency Rollback
|
|
|
|
```bash
|
|
# Swap versions in database
|
|
docker exec igny8_backend python manage.py shell -c "
|
|
from igny8_core.plugins.models import PluginVersion
|
|
PluginVersion.objects.filter(version='NEW').update(status='deprecated')
|
|
PluginVersion.objects.filter(version='OLD').update(status='released')
|
|
"
|
|
```
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
- [WORDPRESS-INTEGRATION.md](WORDPRESS-INTEGRATION.md) - Full integration guide
|
|
- [docs/plans/PLUGIN-DISTRIBUTION-SYSTEM.md](/docs/plans/PLUGIN-DISTRIBUTION-SYSTEM.md) - Original system design
|