Markdown in GitHub. WordPress as the publishing surface.
Sync Markdown documentation into WordPress Pages as Gutenberg-compatible block content.
- Put the Markdown documentation in
docs/. - Create a WordPress access token.
- Add one of the GitHub Actions workflows below.
- Run it first with
status: draftanddry-run: true.
The complete product and setup documentation lives at docs.press/docs.
You do not have to install the DocsPress theme. An unversioned DocsPress sync works with the site's existing theme and native WordPress blocks.
Install the theme for the complete documentation layout. Install the Blocks plugin for rich DocsPress blocks; it is required when API versioning is enabled.
Run this from the repository that contains your docs/ directory:
npx @wp-playground/cli@3.1.46 start \
--blueprint=https://raw.githubusercontent.com/Automattic/docspress/main/theme/blueprint-local-docs.json \
--mount="$PWD/docs:/wordpress/docspress-source-docs" \
--no-auto-mount \
--resetWordPress Playground imports the Markdown as editable Pages and opens /docs/.
- Default documentation site
- Contextual sidebars
- Versioned API documentation
- Stock WordPress, no DocsPress theme or plugin
The first two examples include the complete DocsPress presentation layer. The stock WordPress example installs neither optional package and shows repository Markdown as editable native Gutenberg blocks.
Create .github/workflows/sync-docs.yml:
name: Publish documentation
on:
push:
branches: [main]
paths:
- "docs/**"
- ".github/workflows/sync-docs.yml"
workflow_dispatch:
permissions:
contents: read
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Automattic/docspress@main
with:
mode: publish
wordpress-site: example.wordpress.com
wordpress-access-token: ${{ secrets.WP_ACCESS_TOKEN }}
docs-dir: docs
root-slug: docs
status: draft
delete-mode: trash
dry-run: trueReview the Actions summary, then set dry-run: false. Publish the Pages only after the draft site looks right.
After one-way publishing is working, use a single reconcile workflow for edits from either side:
name: Reconcile documentation
on:
push:
branches: [main]
paths:
- "docs/**"
- ".github/workflows/sync-docs.yml"
schedule:
- cron: "3/5 * * * *"
workflow_dispatch:
permissions:
contents: write
pull-requests: write
concurrency:
group: docspress-sync
cancel-in-progress: false
jobs:
sync:
if: >-
github.event_name != 'push' ||
!contains(
github.event.head_commit.message,
format('from {0}/docspress/wordpress-sync', github.repository_owner)
)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Automattic/docspress@main
with:
mode: reconcile
wordpress-site: example.wordpress.com
wordpress-access-token: ${{ secrets.WP_ACCESS_TOKEN }}
docs-dir: docs
root-slug: docs
status: publish
delete-mode: trashWordPress-only edits become a rolling Markdown pull request. A true two-sided edit is reported as a conflict instead of overwriting either version.
DocsPress uses a WordPress.com OAuth token stored as the repository secret WP_ACCESS_TOKEN.
- Create an app at WordPress.com Apps.
- Set the redirect URL to
http://localhost:8787/callback. - Authenticate the GitHub CLI with
gh auth login. - Run the token helper from a trusted local terminal:
printf "WordPress.com client secret: "
IFS= read -r -s DOCSPRESS_CLIENT_SECRET
printf "\n"
npx docspress@0.4.1 token \
--client-id YOUR_CLIENT_ID \
--client-secret "$DOCSPRESS_CLIENT_SECRET" \
--site example.wordpress.com \
--repo OWNER/REPO \
--set-secret
unset DOCSPRESS_CLIENT_SECRETThe helper opens WordPress.com for authorization and stores the resulting token without printing it. Confirm only the secret name:
gh secret list --repo OWNER/REPODocsPress can use a REST API key from your host or authentication plugin when it accepts Authorization: Bearer …. Core WordPress does not create this key itself.
Store the key without printing it:
printf "WordPress REST API key: "
IFS= read -r -s WORDPRESS_REST_API_KEY
printf "\n"
printf "%s" "$WORDPRESS_REST_API_KEY" |
gh secret set WP_ACCESS_TOKEN --repo OWNER/REPO
unset WORDPRESS_REST_API_KEYSet wordpress-url to the site origin without /wp-json:
wordpress-url: https://docs.example.com
wordpress-site: docs.example.com
wordpress-access-token: ${{ secrets.WP_ACCESS_TOKEN }}DocsPress calls https://docs.example.com/wp-json/wp/v2/pages. Confirm that the key can read, create, update, and delete Pages before publishing.
For the complete setup, use Authenticate WordPress.
Continue at docs.press/docs for:
