Skip to content
Draft
Changes from 21 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
2588cbc
Create action file, checkout repositories
strangerkir Feb 19, 2026
52ddd8b
Update job name
strangerkir Feb 20, 2026
66aa793
Move env vars to the job level
strangerkir Feb 20, 2026
8b54ab4
Install required tools before synchronizing repos
strangerkir Feb 20, 2026
2f1aa34
Remove extra env var
strangerkir Feb 20, 2026
8a4cf80
Move checking out git to the sync action
strangerkir Feb 20, 2026
b777183
Install required tools first
strangerkir Feb 20, 2026
9d0b0ec
Create directory in a safer way
strangerkir Feb 20, 2026
6c74c55
Use rsync to synchronize SVN with git (WIP)
strangerkir Feb 20, 2026
ccaba39
Use official stable version of checkout action
strangerkir Feb 20, 2026
9016f32
Remove extra echo - step name already has it
strangerkir Feb 20, 2026
f68aa6c
Keep both SVN username and password as secrets
strangerkir Feb 20, 2026
08424a8
Remove extra else
strangerkir Mar 2, 2026
8b76efa
Do not add readme.txt to excludes list
strangerkir Mar 2, 2026
0f86d3d
Temporarily define env vars in an extra step
strangerkir Mar 2, 2026
6e32ff3
Update SVN tracking: add new files and delete removed ones
strangerkir Mar 2, 2026
a015e3a
Add test mode input and prepare dry-run step
strangerkir Mar 2, 2026
4136154
Compress svn trunk and upload as an artifact
strangerkir Mar 3, 2026
0a414be
Remove 'custom SVN repository' feature
strangerkir Mar 3, 2026
69322e6
Update comment
strangerkir Mar 3, 2026
66499ec
Make shell fail early on errors
strangerkir Mar 3, 2026
7bdc46b
Update comment - more concise and better example
strangerkir Mar 4, 2026
0df79c1
Rename TEST_MODE to DRY_RUN
strangerkir Mar 4, 2026
b7ea83f
Add IDE's directories to exclusions
strangerkir Mar 4, 2026
26def67
Merge branch 'main' into feature/SPP-91-wordpress-org-release
strangerkir Mar 4, 2026
9dc8ad8
Exclude .distignore file itself
strangerkir Mar 4, 2026
1c86daa
Make sure we have right paths when updating trunk
strangerkir Mar 4, 2026
64ab47e
Remove debug code
strangerkir Mar 5, 2026
77c418e
Add TAG input for both Git and SVN
strangerkir Mar 5, 2026
41c9145
Create SVN tag
strangerkir Mar 5, 2026
41ee1d6
Use separate inputs for plugin version and git ref
strangerkir Mar 11, 2026
46c3a73
Only checkout top-level dirs and trunk contents
strangerkir Mar 12, 2026
bef91db
Add ssh-key to the checkout action
strangerkir Mar 12, 2026
592dd13
Update comments
strangerkir Mar 12, 2026
d748fb5
Update descriptions
strangerkir Mar 12, 2026
66a87ee
Use env var for trunk path
strangerkir Mar 12, 2026
e0e4deb
Quote variables
strangerkir Mar 12, 2026
734a42e
Check for deleted files before removing them
strangerkir Mar 12, 2026
484dc7c
Make sure we are only operate on trunk
strangerkir Mar 12, 2026
59830c1
Remove debugging code
strangerkir Mar 12, 2026
1dbefce
Make sure version doesn't exist yet in SVN
strangerkir Mar 12, 2026
1e64f49
Make sure variable is safely limited
strangerkir Mar 12, 2026
5601a6f
Add committing to WordPress.org
strangerkir Mar 12, 2026
cd13f1c
Use env: to set env variables at job level
strangerkir Mar 12, 2026
5a65ef0
Fix verifying SVN version doesn't exist
strangerkir Mar 12, 2026
f1799b5
Update comments
strangerkir Mar 12, 2026
92d05cd
Use github.workspace instead of runner.workspace
strangerkir Mar 12, 2026
193fdfe
Add missing secret input
strangerkir Mar 12, 2026
9dc4e25
Add comment to clarify intentions
strangerkir Mar 12, 2026
0596f59
Fix and improve comment
strangerkir Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions .github/workflows/wordpress-org-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json

name: wordpress.org publishing

on:
workflow_call:
inputs:
SVN_PLUGIN_SLUG:
description: "Plugin slug in the SVN repository. E.g. if plugin URL is https://wordpress.org/plugins/payoneer-checkout, slug is payoneer-checkout."
type: string
required: true

TEST_MODE:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note

I would rename this to DRY_RUN.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done

description: "In test mode no commit to the SVN repository happens. Instead, files from trunk are provided as an artifact."
type: boolean
default: false
required: false

secrets:
SVN_USERNAME:
required: true

SVN_PASSWORD:
required: true

jobs:
update_svn_from_git:
# TODO: Set env vars here and remove an extra step.
# This works in real GH Actions but act doesn't support runner context at job level, so we had to create an extra step
# Desired format:
# env:
# SVN_REPO_PATH: "${{ runner.workspace }}/svn_repository"
# SVN_REPO_ROOT: "${{ runner.workspace }}/svn_repository/${{ inputs.SVN_PLUGIN_SLUG }}"
runs-on: ubuntu-latest
steps:
#TODO: remove this step (see the comment above for details)
- name: Configure paths
run: |

Check failure on line 38 in .github/workflows/wordpress-org-release.yml

View workflow job for this annotation

GitHub Actions / actionlint

property "workspace" is not defined in object type {arch: string; debug: string; environment: string; name: string; os: string; temp: string; tool_cache: string}

Check failure on line 38 in .github/workflows/wordpress-org-release.yml

View workflow job for this annotation

GitHub Actions / actionlint

property "workspace" is not defined in object type {arch: string; debug: string; environment: string; name: string; os: string; temp: string; tool_cache: string}
echo "SVN_REPO_PATH=${{ runner.workspace }}/svn_repository" >> $GITHUB_ENV
echo "SVN_REPO_ROOT=${{ runner.workspace }}/svn_repository/${{ inputs.SVN_PLUGIN_SLUG }}" >> $GITHUB_ENV

- name: Install required tools
run: |
sudo apt-get update -y
sudo apt-get install -y subversion rsync

- name: Checkout git repository
uses: actions/checkout@v4

- name: Checkout SVN repository
run: |
set -euo pipefail
mkdir -p $SVN_REPO_PATH && cd $SVN_REPO_PATH
svn checkout "https://plugins.svn.wordpress.org/${{ inputs.SVN_PLUGIN_SLUG }}"

- name: Synchronize SVN repository with Git
run: |
set -euo pipefail

touch .distignore

rsync -rc \
--delete \
--delete-excluded \
--exclude='.git' \
--exclude='.svn' \
--exclude='auth.json' \
--exclude='.env' \
--exclude='.env.*' \
--exclude='composer.json' \
--exclude='composer.lock' \
--exclude='package.json' \
--exclude='package-lock.json' \
--exclude='yarn.lock' \
--exclude='node_modules' \
--exclude='.github' \
--exclude='.ddev' \
--exclude-from='.distignore' \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question:
If we are already respecting .distignore do we even need to exclude other files on top of it?

And again: If we are intending to sync production artifacts from a build branch anyway, should we even dabble with bespoke exclude lists in the first place?
The expectation should be that everything that is present in the artifact should also be synced to SVN - since the build process already applied the .distignore.

Or are you explicitly aiming to support "simple" plugin publishing workflows directly off a dev branch? Is this something we need?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming we don't know when/how this reusable workflow will be used. Not all projects use Build and Distribute yet, so this workflow should work on dev branches, too.

The exclusions provide sensible defaults (.git, node_modules, auth.json) that are universally unwanted on wordpress.org. Projects can extend this via .distignore for their specific needs (note: the file is optional, so branches after build-and-distribute work fine).

What's the intended scope? I'd keep it as it is, but I'm open to removing exclusions if you are sure they are pointless.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this is less about build&distribute in particular and more about the question if this workflow should be about publishing or about postprocessing and publishing

My gut reaction what that "whatever lands here is intentionally in that state": If the release artifact wants to include the composer.json, why is our workflow gatekeeping that?


That said, I could be sacrificing security for ontologic purity. A pragmatic safety net against erroneously pushing sensitive stuff is hard to really argue against.

suggestion:

Perhaps though, a .distignore is really all we need?
Test if the file exists (instead of creating an empty one).
Remove it after applying.

I would like others to weigh in on this as well. For me it's not a blocker, but I do see room for improvements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking a bit, I agree that excluding files like composer.json is probably too much. How about the middle ground like this:

  • exclude from .distignore if it exists;
  • exclude .env and auth.json because of security
  • remove the rest of the exclusions

?

"$GITHUB_WORKSPACE/" "$SVN_REPO_ROOT/trunk/"

- name: Update SVN tracking
run: |
set -euo pipefail

cd $SVN_REPO_ROOT
svn add . --force
svn status | grep '^!' | cut -c9- | while IFS= read -r file; do
svn delete "$file@" # @ suffix handles files with @ in name
done

- name: Commit changes to SVN repository
if: inputs.TEST_MODE != true
run: | #TODO: do SVN commit here
echo 'Committing...'

- name: Compress and upload trunk contents as an artifact
if: inputs.TEST_MODE == true
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.SVN_PLUGIN_SLUG }}
path: ${{ runner.workspace }}/svn_repository/${{ inputs.SVN_PLUGIN_SLUG }}/trunk
include-hidden-files: true
compression-level: 1
Loading