Automate Your WordPress Blog

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.

  1. Go to your GitHub repository and click on Settings.
  2. Navigate to Secrets and variables > Actions.
  3. Click New repository secret and add the following three secrets:
  4. WP_URL: Your website base URL (e.g., https://yourdomain.com)
  5. WP_USER: Your WordPress administrator or author username
  6. WP_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!!

Omkar Pasalkar Avatar

Leave a Reply

Your email address will not be published. Required fields are marked *

[contact-form-7 id=”f245613″ title=”Newsletter”]