
ReleaseWP
A minimal WordPress plugin that receives changelog updates from GitHub via REST API and automatically publishes them as WordPress posts.
What It Does
ReleaseWP creates a REST API endpoint on your WordPress site that accepts changelog content in Markdown format. When triggered (typically via GitHub Actions), it:
- Receives a title and Markdown content via POST request
- Converts the Markdown to HTML using Parsedown
- Sanitizes the content for security
- Creates a new WordPress post with your configured post type
- Returns success/error status
Perfect for: Automatically publishing release notes, changelogs, or version updates from your GitHub repository to your WordPress site.
Requirements
- WordPress 5.0 or higher
- PHP 7.0 or higher
- WordPress user with
edit_postscapability
Installation
- Upload the
releasewpfolder to/wp-content/plugins/ - Activate the plugin through the ‘Plugins’ menu in WordPress
- Go to Settings → ReleaseWP to configure:
- Target Post Type: Select which post type to use (defaults to standard Posts)
- Title Template: Format post titles using
%version%placeholder (defaults to “Version %version%”)
GitHub Integration Setup
Step 1: Create WordPress Application Password
- Log into your WordPress admin dashboard
- Go to Users → Profile
- Scroll to Application Passwords section
- Enter a name (e.g., “GitHub Actions”)
- Click Add New Application Password
- Copy the generated password (you won’t be able to see it again)
Step 2: Configure GitHub Secrets
In your GitHub repository:
- Go to Settings → Secrets and variables → Actions
- Click New repository secret
- Add two secrets:WP_API_ENDPOINT
https://your-wordpress-site.com/wp-json/releasewp/v1/post-updateWP_API_TOKENyour-username:your-application-password(Replace with your WordPress username and the application password from Step 1)
Step 3: Create GitHub Action Workflow
Create .github/workflows/update-wordpress.yml in your repository:
name: Update WordPress with Changelog
on:
workflow_dispatch:
inputs:
version:
description: 'Changelog Version'
required: true
default: '1.0.0'
jobs:
updateWordPress:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Install jq
run: sudo apt-get install jq
- name: Extract Specific Changelog Block
run: |
VERSION_HEADER="## [${{ github.event.inputs.version }}]"
VERSION_HEADER_ESCAPED=$(printf '%s\n' "$VERSION_HEADER" | sed -e 's/[]\/$*.^[]/\\&/g')
lines_under_version_header=$(awk "/$VERSION_HEADER_ESCAPED/"' {p=1; next} p && /^## \[/ {p=0} p' CHANGELOG.md)
echo "$lines_under_version_header" > specific-changelog.md
- name: Convert Extracted Changelog to JSON
run: |
VERSION="${{ github.event.inputs.version }}"
# Send just the version number - WordPress will format the title
jq -Rs --arg version "$VERSION" '{title: $version, content: .}' specific-changelog.md > changelog.json
- name: Update WordPress
env:
WP_API_ENDPOINT: ${{ secrets.WP_API_ENDPOINT }}
WP_API_TOKEN: ${{ secrets.WP_API_TOKEN }}
run: |
echo "Updating WordPress..."
curl -X POST $WP_API_ENDPOINT \
-H "Authorization: Bearer $WP_API_TOKEN" \
-H "Content-Type: application/json" \
--data @changelog.json
Step 4: Format Your CHANGELOG.md
Your CHANGELOG.md should follow this format:
# Changelog ## [1.2.0] - 2024-01-15 ### Added - New feature X - Enhancement Y ### Fixed - Bug fix Z ## [1.1.0] - 2024-01-01 ### Changed - Updated something
Plugin Configuration
After installation, configure the plugin:
Plugin Configuration
After installation, configure the plugin in Settings → ReleaseWP:
- Target Post Type: Select which post type to create (Posts, Pages, or any custom post type)
- Title Template: Customize how post titles are formatted
- Use
%version%as a placeholder for the version number from GitHub - Default:
Version %version%(e.g., “Version 1.2.0”) - Examples:
MyPlugin %version% is here!→ “MyPlugin 1.2.0 is here!”%version% Release Notes→ “1.2.0 Release Notes”What's New in %version%→ “What’s New in 1.2.0”
- Use
- Click Save Settings
The GitHub Action will send just the version number (e.g., “1.2.0”), and WordPress will format it according to your template.
Manual Trigger (Recommended)
- Go to your GitHub repository
- Click Actions tab
- Select “Update WordPress with Changelog” workflow
- Click Run workflow
- Enter the version number (e.g.,
1.2.0) - Click Run workflow
The workflow will extract that version’s changelog and post it to WordPress.
Automatic Trigger on Release
To trigger automatically when creating a GitHub release, modify the workflow’s on: section:
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Changelog Version'
required: true
API Endpoint Documentation
POST /wp-json/releasewp/v1/post-update
Authentication: Bearer token (WordPress application password)
Request Body:
{
"title": "Release v1.2.0",
"content": "## Changes\n- Feature added\n- Bug fixed"
}
Response:
200 OK:"Post Created"500 Internal Server Error:"Error creating post"
Testing
Test your endpoint with cURL:
curl -X POST https://your-site.com/wp-json/releasewp/v1/post-update \
-H "Authorization: Bearer username:application_password" \
-H "Content-Type: application/json" \
-d '{"title":"Test Release","content":"## Test\n- Item 1\n- Item 2"}'
Customization
Change Post Type
Edit line 47 in releasewp.php:
'post_type' => 'your_custom_type',
Change Post Status
To publish as draft instead:
'post_status' => 'draft',
Add Custom Fields
After line 48, add:
$post_id = wp_insert_post( $new_post );
if ( ! is_wp_error( $post_id ) ) {
update_post_meta( $post_id, 'version_number', $version );
}
Troubleshooting
403 Forbidden Error
- Check your application password is correct
- Verify the WordPress user has
edit_postscapability
404 Not Found
- Ensure the plugin is activated
- Verify the endpoint URL matches:
/wp-json/releasewp/v1/post-update
500 Internal Server Error
- Check if the
updatecustom post type exists - Review WordPress error logs
Post Not Appearing
- Verify the
updatepost type is registered and visible in admin - Check if posts are being created as drafts instead of published
Security
- All content is sanitized using
wp_kses_post()andwp_strip_all_tags() - Requires WordPress authentication (application passwords)
- Only users with
edit_postscapability can create posts - Markdown is converted server-side to prevent XSS attacks
License
This plugin is provided as-is for integration between GitHub and WordPress.
