Automate Your WordPress Blog : Publishing Markdown Posts via GitHub Actions
If you are a developer or technical writer, you likely prefer writing content in Markdown inside your favorite code editor (like VS Code) rather than using the standard WordPress block editor. What if you could write your posts in a Git repository and have them automatically pushed to your WordPress site as drafts every time you hit git push?
In this comprehensive guide, we will walk through the exact technical implementation of setting up a fully automated pipeline using GitHub Actions, Python, and the WordPress REST API.
Architecture Overview
The automated workflow relies on three core components:
1. GitHub Repository: Stores your Markdown files and GitHub Actions workflow configuration.
2. GitHub Actions Runner: Detects changes to your repository, spins up a Python environment, and executes the deployment script.
3. WordPress REST API: Receives the payload (title, content, and metadata) and securely creates a new draft post on your website using basic authentication or application passwords.
Step 1: Setting up WordPress Authentication
By default, WordPress blocks standard login credentials over the REST API for security. To let your GitHub script authenticate securely, you have two options:
* Option A (Recommended): Generate an Application Password from your WordPress User Profile (Users > Profile > Application Passwords).
* Option B: Install a plugin like REST API Basic Authentication if your environment restricts application passwords.
Save your WordPress URL, Username, and Password/Application Password; you will need them in the next step.
Step 2: Configuring GitHub Secrets
To keep your credentials secure, never hardcode them into your scripts. Instead, store them as GitHub Secrets.
- Go to your GitHub repository and click on Settings.
- Navigate to Secrets and variables > Actions.
- Click New repository secret and add the following three secrets:
WP_URL: Your website base URL (e.g.,https://yourdomain.com)WP_USER: Your WordPress administrator or author usernameWP_PASSWORD: Your application password or standard password
Step 3: Creating the Python Publisher Script
Create a folder named scripts in your repository and add a file named publish.py. This script parses your Markdown file’s frontmatter (title) and content, converts the markdown body into HTML, and sends a POST request to the WordPress REST API.
Create scripts/publish.py:
“`python
import os
import sys
import frontmatter
import markdown
import requests
Load environment variables
WP_URL = os.environ.get(“WP_URL”)
WP_USER = os.environ.get(“WP_USER”)
WP_PASSWORD = os.environ.get(“WP_PASSWORD”)
if not all([WP_URL, WP_USER, WP_PASSWORD]):
print(“Error: Missing WordPress environment variables.”)
sys.exit(1)
Get filename from command line argument passed by GitHub Actions
filename = sys.argv[1]
Parse markdown file with frontmatter
post = frontmatter.load(filename)
title = post.get(“title”, “Untitled Post”)
markdown_content = post.content
Convert Markdown content to HTML for WordPress
html_content = markdown.markdown(markdown_content)
Prepare WordPress REST API endpoint
posts_url = f”{WP_URL}/wp-json/wp/v2/posts”
post_data = {
“title”: title,
“content”: html_content,
“status”: “draft”, # Publishes as a draft safely for review
}
Send request to WordPress
response = requests.post(
posts_url, auth=(WP_USER, WP_PASSWORD), json=post_data
)
if response.status_code == 201:
print(f”Success! Draft created for: ‘{title}’”)
else:
print(f”Failed to create draft: {response.status_code} – {response.text}”)
sys.exit(1)
“`
Step 4: Setting up the GitHub Actions Workflow
Next, configure the CI/CD pipeline. Create a directory named .github/workflows/ and add a file named deploy.yml.
This workflow triggers automatically whenever a Markdown file inside the posts/ folder is pushed, tracks which file changed, installs dependencies, and executes your Python script.
Create .github/workflows/deploy.yml:
“`yaml
name: Deploy Blog Post to WordPress
on:
push:
paths:
– ‘posts/*.md’
jobs:
publish:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: pip install requests python-frontmatter markdown
- name: Publish modified posts
env:
WP_URL: ${{ secrets.WP_URL }}
WP_USER: ${{ secrets.WP_USER }}
WP_PASSWORD: ${{ secrets.WP_PASSWORD }}
run: |
# Automatically detect changed markdown files in the push
FILES=$(git diff-tree --no-commit-id --name-only -r ${{ github.sha }} | grep '^posts/.*\.md$')
for file in $FILES; do
if [ -f "$file" ]; then
echo "Processing $file..."
python scripts/publish.py "$file"
fi
done
“`
Step 5: Writing and Publishing Your First Post
With the pipeline completely set up, writing a new blog post is as simple as creating a file in your posts/ directory.
Create posts/my-first-automated-post.md:
Commit and push your files to GitHub:
bash
git add .
git commit -m "Add automated workflow and first markdown post"
git push origin main
Head over to your GitHub repository’s Actions tab to watch your script run successfully, then log into your WordPress dashboard under Posts > Drafts to see your newly generated post waiting for review!!




Leave a Reply