diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 294c52e7..05eeb4b7 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -89,7 +89,7 @@ jobs:
run: bash bin/build-plugins.sh
- name: Inspect Push MD plugin zip
- run: bin/inspect-push-md-zip.sh dist/plugins/push-md.zip
+ run: bash bin/inspect-push-md-zip.sh dist/plugins/push-md.zip
- name: Upload Push MD release asset
env:
@@ -98,6 +98,37 @@ jobs:
gh --version
gh release upload "$RELEASE_TAG" dist/plugins/push-md.zip --clobber
+ - name: Deploy Push MD to WordPress.org SVN
+ env:
+ WPORG_PLUGIN_SLUG: push-md
+ WPORG_USERNAME: ${{ secrets.WPORG_USERNAME }}
+ WPORG_PASSWORD: ${{ secrets.WPORG_PASSWORD }}
+ shell: bash
+ run: |
+ set -euo pipefail
+
+ if [ "${{ github.event.release.prerelease }}" = "true" ]; then
+ echo "Skipping WordPress.org SVN deploy for prerelease $RELEASE_TAG."
+ exit 0
+ fi
+
+ if [[ "${{ steps.release.outputs.version }}" == *-* ]]; then
+ echo "Skipping WordPress.org SVN deploy for non-stable release version ${{ steps.release.outputs.version }}."
+ exit 0
+ fi
+
+ if [ -z "$WPORG_USERNAME" ] || [ -z "$WPORG_PASSWORD" ]; then
+ echo "Skipping WordPress.org SVN deploy because WPORG_USERNAME or WPORG_PASSWORD is not configured."
+ exit 0
+ fi
+
+ if ! command -v svn >/dev/null 2>&1; then
+ sudo apt-get update
+ sudo apt-get install -y subversion
+ fi
+
+ bin/deploy-push-md-wporg-svn.sh dist/plugins/push-md.zip
+
# Temporarily disabled legacy release flow. Restore these sections when the
# repository release process should publish Composer packages, PHARs, examples,
# and the older plugin zips again.
diff --git a/bin/deploy-push-md-wporg-svn.sh b/bin/deploy-push-md-wporg-svn.sh
new file mode 100755
index 00000000..ae1a4734
--- /dev/null
+++ b/bin/deploy-push-md-wporg-svn.sh
@@ -0,0 +1,194 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
+
+ZIP_PATH="${1:-$PROJECT_DIR/dist/plugins/push-md.zip}"
+PLUGIN_SLUG="${WPORG_PLUGIN_SLUG:-push-md}"
+SVN_URL="${WPORG_SVN_URL:-https://plugins.svn.wordpress.org/$PLUGIN_SLUG/}"
+COMMIT_MESSAGE="${WPORG_COMMIT_MESSAGE:-}"
+DRY_RUN="${WPORG_DRY_RUN:-0}"
+SVN_DIR="${WPORG_SVN_DIR:-}"
+USERNAME="${WPORG_USERNAME:-}"
+PASSWORD="${WPORG_PASSWORD:-}"
+
+TEMP_SVN_DIR=""
+TEMP_EXTRACT_DIR=""
+
+usage() {
+ cat <
git clone https://pushmd.blog/wp-json/git/v1/md.git my-site
The public remote is pullable for a first look. Pushes need the plugin on your own authenticated WordPress site.
+The public remote is pullable for a first look. Pushes need Push MD installed from WordPress.org on your own authenticated WordPress site.
diff --git a/plugins/push-md/readme.txt b/plugins/push-md/readme.txt index 3b570c00..ed085f57 100644 --- a/plugins/push-md/readme.txt +++ b/plugins/push-md/readme.txt @@ -1,4 +1,4 @@ -=== Push MD === +=== Push MD - Git Sync for WordPress Content === Contributors: artpi, zieladam Tags: git, markdown, content, workflow Requires at least: 6.9 @@ -8,80 +8,93 @@ Stable tag: 0.6.7 License: GPL-2.0-or-later License URI: https://www.gnu.org/licenses/gpl-2.0.html -Edit WordPress content with Git, Markdown and block files, reviewable diffs, and safe pushes. +Use Git to edit WordPress content with agents and local tools. Pull WP-Admin changes, push Markdown updates, and keep WordPress in charge. == Description == -Push MD makes a WordPress site available as a Git remote for supported content. Authenticated users can run familiar Git commands such as `clone`, `pull`, and `push` against a WordPress REST API endpoint, then edit content locally in Markdown-friendly tools or coding-agent workspaces. +Push MD makes WordPress available as a Git remote for supported content. Posts and pages can be cloned as readable Markdown, edited in a local editor or coding-agent workspace, committed, and pushed back through WordPress. -WordPress remains the source of truth. Push MD stores the Git object data it needs in WordPress database tables, exports the current WordPress state into a repository tree, and imports pushed changes back through WordPress post APIs. +WordPress stays in charge. Push MD reads and writes through WordPress APIs, checks the current user's capabilities, creates WordPress revisions for accepted content changes, and rejects stale pushes before they can overwrite newer WP-Admin edits. -The result is a static-site-generator-like workflow for a dynamic WordPress site: content can be cloned, diffed, edited, committed, and reviewed as files, while WordPress still handles publishing, previews, permissions, revisions, the editor, and the front end. +This gives Markdown-first teams and coding agents a Git-shaped workflow without moving the source of truth out of WordPress. -= Common use cases = +**Beta:** Push MD is an early release for experimentation. Try it on a staging site first and keep your normal WordPress backups in place. -* Edit posts and pages in a local editor, Markdown vault, or coding-agent workspace. -* Review content changes with normal Git diffs before they are applied to WordPress. -* Pull recent WP-Admin edits before local work and use normal Git conflict handling. -* Let an authenticated coding agent pull current site content, make a scoped edit, commit it, and push it back. -* Work with block theme templates, template parts, navigation posts, and Global Styles as files when those WordPress entities are available. -* Pull site content into automation workflows without exporting the whole database or copying plugin/theme code. += What you can do = + +* Clone supported WordPress content with a normal Git client. +* Edit posts and pages as Markdown. +* Review changes with standard Git diffs before pushing. +* Pull WP-Admin edits before continuing local work. +* Let authenticated coding agents work in an ordinary checkout. +* Keep WordPress roles, revisions, previews, publishing, and rendering in the loop. +* Work with block theme files, Global Styles, and Gutenberg Guidelines when available. = How it works = -The Git endpoint is: +The Git endpoint on a site with Push MD active is: `/wp-json/git/v1/md.git` The repository branch is `trunk`. Push MD accepts pushes to `trunk` only. -Users authenticate through WordPress REST authentication. The built-in Application Passwords feature is the usual Git-over-HTTPS option when it is available, and other REST authentication plugins can work if they authenticate the request as a WordPress user. +Users authenticate through WordPress REST authentication. The built-in WordPress Application Passwords feature is the usual Git-over-HTTPS option, and other REST authentication plugins can work when they authenticate the request as a WordPress user before Push MD's permission checks run. -A local clone can contain files such as: +A checkout can include: * `post/{slug}.md` for posts. * `page/{slug}.md` and `page/{parent}/{child}.md` for pages. * `wp_template/{slug}.html` and `wp_template/{theme}/{slug}.html` for templates. * `wp_template_part/{theme}/{slug}.html` for template parts. * `wp_navigation/{slug}.html` for navigation posts. -* `wp_theme/{theme}/theme.json` as read-only theme context. +* `wp_theme/{theme}/theme.json` as read-only context. * `wp_global_styles/{theme}.json` for editable Global Styles overlays. * `wp_guideline/skills/{slug}/SKILL.md` for Gutenberg Guidelines skills and Push MD's built-in agent skills. * `AGENTS.md`, `CLAUDE.md`, `.agents/skills`, and `.claude/skills` for agent guidance when available. -Markdown files use a small front matter contract: `title`, `date`, `status`, and optional `description`. Identity comes from the file path, so `id`, `slug`, `type`, and unknown front matter fields are rejected. +Markdown files use a small front matter contract: `title`, `date`, `status`, and optional `description`. File paths identify content. Structural block files use raw Gutenberg block markup with no front matter so they can round-trip through WordPress without being forced into Markdown. -Push MD's built-in agent skills are generated only when Gutenberg Guidelines are enabled and no matching Guideline exists. Edit the canonical `wp_guideline/skills/{slug}/SKILL.md` file; generated aliases such as `AGENTS.md` and `.agents/skills` remain read-only. - = Safety model = -Push MD is designed to fail closed. Before applying a push, it validates and plans all changed files across the pushed range. If any file or later commit is unsafe, the whole push is rejected before WordPress content is changed. +Push MD is designed to fail closed. Before applying a push, it validates the changed files across the pushed range. If any file or later commit is unsafe, the whole push is rejected before WordPress content is changed. -Push validation rejects stale remote state, unsupported paths, path traversal, non-canonical slugs, unsupported file modes, user-authored symlinks, generated symlink edits, NUL bytes, malformed front matter, unsupported front matter fields, malformed Gutenberg block markup, invalid Global Styles JSON, edits to read-only theme JSON, and unsafe page hierarchy changes. +Push validation rejects stale remote state, unsupported paths, path traversal, malformed front matter, invalid block markup, invalid Global Styles JSON, and edits to read-only theme JSON. Deleted post and page files move the matching WordPress content to trash instead of permanently deleting it. Re-adding the same path restores the trashed object instead of creating a duplicate. -Template, template part, navigation, and Global Styles deletes or renames are rejected until reset semantics are explicit. Theme JSON files are exported only as read-only context. +Template, template part, navigation, and Global Styles deletes or renames are rejected until reset semantics are explicit. -Pushed updates go through WordPress permissions and post APIs, so users can only change content their WordPress account is allowed to edit. Existing WP-Admin workflows can continue alongside Git-based edits. += Try a read-only demo = -= What this is not = +You can clone the public read-only demo remote before installing Push MD: -Push MD is not a full database backup, theme deployment tool, plugin sync tool, media-library mirror, or arbitrary custom post type exporter. It exposes supported content entities only. PHP code, plugins, theme source, uploads, and arbitrary database tables are outside the current release scope. +`git clone https://pushmd.blog/wp-json/git/v1/md.git my-site` + +That demo lets you inspect the file tree and Markdown shape. Pushes require Push MD on your own authenticated WordPress site. == Installation == -1. Upload the plugin files to the `wp-content/plugins/push-md` directory. +1. Upload the plugin files to the `wp-content/plugins/push-md` directory, or install Push MD from the WordPress Plugin Directory. 2. Activate the plugin through the Plugins screen in WordPress. -3. Open Tools > Push MD to monitor the initial import. +3. Open Tools > Push MD and wait for the initial import to finish. +4. Create a WordPress Application Password for your user if you want to use Git over HTTPS. +5. Clone your site's endpoint, replacing `example.com` with your site URL: + +`git clone https://example.com/wp-json/git/v1/md.git my-site` + +Use the `trunk` branch for pulls and pushes. == Frequently Asked Questions == += Is WordPress still the source of truth? = + +Yes. Your WordPress database remains authoritative. Git clients read and write through Push MD, so there is no separate content repository to reconcile. + = Which content types are exported? = -Posts, pages, supported block theme templates, template parts, navigation posts, read-only theme JSON context, Global Styles overlays, Gutenberg Guidelines when available, and Push MD's built-in agent guidance. +Posts, pages, supported block theme templates, template parts, navigation posts, read-only theme JSON context, Global Styles overlays, Gutenberg Guidelines when available, and built-in agent guidance. = Which branch should I use? = @@ -93,35 +106,33 @@ Users must be authenticated and allowed to read the exported repository. Users w = Who can push changes? = -Push MD checks permissions for each changed object. Updating or trashing existing content requires permission to edit or delete that specific post. Creating new files requires permission to create that post type, and publishing, scheduling, or making content private requires the relevant WordPress capability. - -= Can I change a post or page slug in front matter? = +Push MD checks permissions for each changed object. Updating, trashing, creating, publishing, scheduling, or making content private requires the matching WordPress capability. -No. File paths are the identity model. Push MD rejects `id`, `slug`, `type`, and unknown front matter fields. Rename or move files only when the corresponding path operation is supported and safe. += What happens when someone edits in WP-Admin? = -= Can I still edit content in WP-Admin? = +WP-Admin edits become Git-visible on pull. If a local checkout is stale, Push MD rejects the push before writing over newer WordPress content. -Yes. WordPress remains the source of truth. Pull before editing locally to pick up recent WP-Admin changes, and Push MD will reject stale pushes that could overwrite newer WordPress edits. += Do pushes create revisions? = -= Does Push MD enable Application Passwords? = +Yes. Accepted content updates go through WordPress post APIs and create normal WordPress revisions. -No. Push MD does not enable or force any authentication method. It works with WordPress users that are already authenticated for REST requests and have the required capabilities. += How do agent skills become available? = -The built-in WordPress Application Passwords feature is the default way to use Git over HTTPS when it is available on the site. Other REST authentication plugins may also work if they authenticate the request as a WordPress user before Push MD's permission checks run. +Push MD stores agent skills as WordPress Guidelines. Today, that means the site needs the Gutenberg plugin installed and active, with the Guidelines experiment enabled from the Gutenberg Experiments page. After that, skills appear in the checkout under `wp_guideline/skills/{slug}/SKILL.md`, with generated aliases such as `AGENTS.md` for agent discovery. -= Does Push MD require Composer or a PHAR archive? = += Is this a static site generator? = -No. Push MD includes the readable PHP Toolkit runtime files it needs under `php-toolkit/` in the plugin package. The plugin does not install Composer dependencies on the site and does not load an opaque PHAR archive. +No. Push MD gives you the local-file workflow people like in static site generators, while WordPress still handles previews, rendering, publishing, roles, and revisions. -= Does this sync my site to GitHub or another Git host? = += Does Push MD sync my site to GitHub or another Git host? = No. Push MD makes WordPress itself behave like a Git remote for supported content. You can add GitHub, GitLab, Bitbucket, or another host as a separate remote in your local clone if your workflow needs that. -= Does this export plugin or theme source code? = += Does Push MD export plugin or theme source code? = No. The checkout is scoped to supported WordPress content. Theme-provided files such as `wp_theme/{theme}/theme.json` may appear as read-only context, but Push MD does not deploy theme or plugin code. -= Does this export media files? = += Does Push MD export media files? = No. Media mirroring is planned future work. The current release does not mirror uploads or import attachment binaries. @@ -129,7 +140,7 @@ No. Media mirroring is planned future work. The current release does not mirror No. Push MD does not send content to GitHub, Automattic, WordPress.org, or any other third-party service. It exposes a Git endpoint on the WordPress site where the plugin is installed, and authenticated users connect directly to that site's REST API. -Because Push MD represents supported WordPress content as Git history, authorized clones can include posts, pages, templates, navigation posts, Global Styles, Guidelines, and their prior Git revisions. Private, draft, pending, and future content may appear in the Git repository when the authenticated user is allowed to read the full export. Treat clone URLs, Application Passwords, and local clones as sensitive site access. +Authorized clones can include supported content and prior Git revisions. Private, draft, pending, and future content may appear when the authenticated user is allowed to read the full export. Treat clone URLs, Application Passwords, and local clones as sensitive site access. = What happens when I uninstall Push MD? = @@ -139,6 +150,6 @@ The removed tables contain Push MD's derived Git repository history. Reinstallin == Changelog == -= 0.5.0 = += 0.6.7 = -Initial release. +Initial WordPress.org release.