-
Notifications
You must be signed in to change notification settings - Fork 6
wordpress.org release (SPP-91) #228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+424
−0
Merged
Changes from all commits
Commits
Show all changes
73 commits
Select commit
Hold shift + click to select a range
2588cbc
Create action file, checkout repositories
strangerkir 52ddd8b
Update job name
strangerkir 66aa793
Move env vars to the job level
strangerkir 8b54ab4
Install required tools before synchronizing repos
strangerkir 2f1aa34
Remove extra env var
strangerkir 8a4cf80
Move checking out git to the sync action
strangerkir b777183
Install required tools first
strangerkir 9d0b0ec
Create directory in a safer way
strangerkir 6c74c55
Use rsync to synchronize SVN with git (WIP)
strangerkir ccaba39
Use official stable version of checkout action
strangerkir 9016f32
Remove extra echo - step name already has it
strangerkir f68aa6c
Keep both SVN username and password as secrets
strangerkir 08424a8
Remove extra else
strangerkir 8b76efa
Do not add readme.txt to excludes list
strangerkir 0f86d3d
Temporarily define env vars in an extra step
strangerkir 6e32ff3
Update SVN tracking: add new files and delete removed ones
strangerkir a015e3a
Add test mode input and prepare dry-run step
strangerkir 4136154
Compress svn trunk and upload as an artifact
strangerkir 0a414be
Remove 'custom SVN repository' feature
strangerkir 69322e6
Update comment
strangerkir 66499ec
Make shell fail early on errors
strangerkir 7bdc46b
Update comment - more concise and better example
strangerkir 0df79c1
Rename TEST_MODE to DRY_RUN
strangerkir b7ea83f
Add IDE's directories to exclusions
strangerkir 26def67
Merge branch 'main' into feature/SPP-91-wordpress-org-release
strangerkir 9dc8ad8
Exclude .distignore file itself
strangerkir 1c86daa
Make sure we have right paths when updating trunk
strangerkir 64ab47e
Remove debug code
strangerkir 77c418e
Add TAG input for both Git and SVN
strangerkir 41c9145
Create SVN tag
strangerkir 41ee1d6
Use separate inputs for plugin version and git ref
strangerkir 46c3a73
Only checkout top-level dirs and trunk contents
strangerkir bef91db
Add ssh-key to the checkout action
strangerkir 592dd13
Update comments
strangerkir d748fb5
Update descriptions
strangerkir 66a87ee
Use env var for trunk path
strangerkir e0e4deb
Quote variables
strangerkir 734a42e
Check for deleted files before removing them
strangerkir 484dc7c
Make sure we are only operate on trunk
strangerkir 59830c1
Remove debugging code
strangerkir 1dbefce
Make sure version doesn't exist yet in SVN
strangerkir 1e64f49
Make sure variable is safely limited
strangerkir 5601a6f
Add committing to WordPress.org
strangerkir cd13f1c
Use env: to set env variables at job level
strangerkir 5a65ef0
Fix verifying SVN version doesn't exist
strangerkir f1799b5
Update comments
strangerkir 92d05cd
Use github.workspace instead of runner.workspace
strangerkir 193fdfe
Add missing secret input
strangerkir 9dc4e25
Add comment to clarify intentions
strangerkir 0596f59
Fix and improve comment
strangerkir a6cfc7a
Merge branch 'main' into feature/SPP-91-wordpress-org-release
strangerkir 25fdc5f
Check that versions match in all sources
strangerkir 7372049
Split workflow into two jobs
strangerkir 3618ab4
Only explicitly exclude sensitive files and .svn
strangerkir da3e14c
Remove check for SVN conflicts
strangerkir 7cf7599
Merge branch 'main' into feature/SPP-91-wordpress-org-release
strangerkir 1cc8ec1
Revert "Split workflow into two jobs"
strangerkir cb95e4d
Merge remote-tracking branch 'origin/feature/SPP-91-wordpress-org-rel…
strangerkir 5e930b7
Make creating a tag conditional
strangerkir 02357c2
Remove extra new line
strangerkir d3a463b
Skip version check when updating trunk only
strangerkir 513b778
Remove extra space
strangerkir a9414c5
Add documentation
strangerkir 3c4f149
Merge branch 'main' into feature/SPP-91-wordpress-org-release
strangerkir 3093a63
Update documentation
strangerkir 94a0e03
Update documentation
strangerkir d3bb7a6
Merge remote-tracking branch 'origin/feature/SPP-91-wordpress-org-rel…
strangerkir 42464c4
Update documentation
strangerkir 736ff07
Add plugin slug validation
strangerkir 8b570af
Update documentation
strangerkir 7732f43
Merge branch 'main' into feature/SPP-91-wordpress-org-release
Biont 6b113cc
Merge branch 'main' into feature/SPP-91-wordpress-org-release
Biont 53d0c0c
Merge branch 'main' into feature/SPP-91-wordpress-org-release
strangerkir File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,261 @@ | ||
| # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json | ||
|
|
||
| name: wordpress.org publishing | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| SVN_PLUGIN_SLUG: | ||
| description: "WordPress.org plugin slug (e.g., 'woocommerce')" | ||
| type: string | ||
| required: true | ||
|
|
||
| PLUGIN_VERSION: | ||
| description: "Plugin version to publish (MAJOR.MINOR.PATCH)" | ||
| type: string | ||
| required: true | ||
|
|
||
| GIT_REF: | ||
| description: "Git ref to publish (tag, branch, or commit)" | ||
| type: string | ||
| required: true | ||
|
|
||
| DRY_RUN: | ||
| description: "Create artifact from trunk instead of committing to SVN" | ||
| type: boolean | ||
| default: false | ||
| required: false | ||
|
|
||
| UPDATE_TRUNK_ONLY: | ||
| description: "Only update trunk at wordpress.org, but don't create a new tag (version)" | ||
| type: boolean | ||
| default: true | ||
| required: false | ||
|
|
||
| secrets: | ||
| SVN_USERNAME: | ||
| required: true | ||
|
|
||
| SVN_PASSWORD: | ||
| required: true | ||
|
|
||
| GITHUB_USER_SSH_KEY: | ||
| required: true | ||
|
|
||
| jobs: | ||
| update_svn_from_git: | ||
| env: | ||
| SVN_REPO_PATH: "${{ github.workspace }}/svn_repository" | ||
| SVN_REPO_ROOT: "${{ github.workspace }}/svn_repository/${{ inputs.SVN_PLUGIN_SLUG }}" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Install required tools | ||
| run: | | ||
| sudo apt-get update -y | ||
| sudo apt-get install -y subversion rsync | ||
|
|
||
| - name: Validate plugin slug | ||
| env: | ||
| SVN_PLUGIN_SLUG: ${{ inputs.SVN_PLUGIN_SLUG }} | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| if [[ ! "$SVN_PLUGIN_SLUG" =~ ^[a-z0-9-]+$ ]]; then | ||
| echo "❌ Invalid plugin slug: $SVN_PLUGIN_SLUG" | ||
| echo " WordPress.org slugs may only contain lowercase letters, numbers, and hyphens" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "✅ Valid plugin slug: $SVN_PLUGIN_SLUG" | ||
|
|
||
| - name: Validate versions | ||
| env: | ||
| PLUGIN_VERSION: ${{ inputs.PLUGIN_VERSION }} | ||
| GIT_REF: ${{ inputs.GIT_REF }} | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| if [[ ! "$PLUGIN_VERSION" =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then | ||
| echo "❌ WordPress.org expects version formatted as MAJOR.MINOR.PATCH" | ||
| echo " Three groups of numbers separated by dots" | ||
| echo " Each group: either 0 or digits not starting with 0" | ||
| echo " Received: $PLUGIN_VERSION" | ||
| exit 1 | ||
| fi | ||
|
Biont marked this conversation as resolved.
|
||
|
|
||
| echo "VALIDATED_PLUGIN_VERSION=$PLUGIN_VERSION" >> $GITHUB_ENV | ||
| echo "✅ Valid WordPress.org version: $PLUGIN_VERSION" | ||
|
|
||
| if ! git check-ref-format --allow-onelevel "$GIT_REF"; then | ||
| echo "❌ Invalid Git ref name: $GIT_REF" | ||
| exit 1 | ||
| fi | ||
| # We do not create VALIDATED_GIT_REF env var here because actions/checkout action we are going to use it with cannot take ref from vars anyway. | ||
| # But since it is validated, it is safe to use it directly from user input. | ||
|
|
||
| - name: Checkout git repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ inputs.GIT_REF }} | ||
| ssh-key: ${{ secrets.GITHUB_USER_SSH_KEY }} | ||
|
|
||
| - name: Verify version consistency | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| PLUGIN_FILE=$(find . -maxdepth 1 -type f -name '*.php' -exec grep -l 'Plugin Name:' {} + | head -1) | ||
| if [ -z "$PLUGIN_FILE" ]; then | ||
| echo "❌ No plugin file with 'Plugin Name:' header found" | ||
| exit 1 | ||
| fi | ||
|
|
||
| EXTRACTION_ERROR=0 | ||
|
|
||
| PLUGIN_FILE_VERSION=$(grep -m1 'Version:' "$PLUGIN_FILE" | grep -oP '[\d]+\.[\d]+\.[\d]+') | ||
| if [ -z "$PLUGIN_FILE_VERSION" ]; then | ||
| echo "❌ Could not extract version from $PLUGIN_FILE" | ||
| EXTRACTION_ERROR=1 | ||
| fi | ||
|
|
||
| if [ ! -f readme.txt ]; then | ||
| echo "❌ readme.txt not found" | ||
| EXTRACTION_ERROR=1 | ||
| else | ||
| README_VERSION=$(grep -m1 'Stable tag:' readme.txt | grep -oP '[\d]+\.[\d]+\.[\d]+' || true) | ||
| if [ -z "$README_VERSION" ]; then | ||
| echo "❌ Could not extract 'Stable tag:' from readme.txt" | ||
| EXTRACTION_ERROR=1 | ||
| fi | ||
| fi | ||
|
|
||
| [ "$EXTRACTION_ERROR" = "1" ] && exit 1 | ||
|
|
||
| MISMATCH=0 | ||
|
|
||
| if [ "$VALIDATED_PLUGIN_VERSION" != "$PLUGIN_FILE_VERSION" ]; then | ||
| echo "❌ Input version ($VALIDATED_PLUGIN_VERSION) does not match $PLUGIN_FILE ($PLUGIN_FILE_VERSION)" | ||
| MISMATCH=1 | ||
| fi | ||
| if [ "$VALIDATED_PLUGIN_VERSION" != "$README_VERSION" ]; then | ||
| echo "❌ Input version ($VALIDATED_PLUGIN_VERSION) does not match readme.txt Stable tag ($README_VERSION)" | ||
| MISMATCH=1 | ||
| fi | ||
|
|
||
| [ "$MISMATCH" = "1" ] && exit 1 | ||
|
|
||
| echo "✅ Version $VALIDATED_PLUGIN_VERSION is consistent across inputs, plugin file, and readme.txt" | ||
|
|
||
| - name: Checkout SVN repository | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p "$SVN_REPO_PATH" && cd "$SVN_REPO_PATH" | ||
|
|
||
| # We only do a full checkout of trunk here, leaving other directories empty. | ||
| # Tags directory can take gigabytes for older plugins, and we don't need them for publishing. | ||
|
|
||
| svn checkout "https://plugins.svn.wordpress.org/${{ inputs.SVN_PLUGIN_SLUG }}" --depth immediates | ||
| cd "$SVN_REPO_ROOT" && svn update trunk --set-depth infinity | ||
|
|
||
| - name: Verify version doesn't exist in SVN | ||
| if: inputs.UPDATE_TRUNK_ONLY != true | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| cd "${SVN_REPO_ROOT}/tags" | ||
| svn update --set-depth immediates | ||
|
|
||
| if [ -d "$VALIDATED_PLUGIN_VERSION" ]; then | ||
| echo "❌ Version $VALIDATED_PLUGIN_VERSION already exists in WordPress.org!" | ||
| echo " Check: https://plugins.svn.wordpress.org/${{ inputs.SVN_PLUGIN_SLUG }}/tags/" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "✅ Version $VALIDATED_PLUGIN_VERSION is available" | ||
|
|
||
| - name: Synchronize SVN repository with Git | ||
| working-directory: ${{ github.workspace }} #Make sure we are in the right place before start sync | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| touch .distignore # Ensure file exists so --exclude-from doesn't fail | ||
|
|
||
| rsync -rc \ | ||
| --delete \ | ||
| --delete-excluded \ | ||
| --exclude='.git' \ | ||
| --exclude='.svn' \ | ||
| --exclude='auth.json' \ | ||
| --exclude='.npmrc' \ | ||
| --exclude='.env' \ | ||
| --exclude='.env.*' \ | ||
| --exclude='.distignore' \ | ||
| --exclude-from='.distignore' \ | ||
|
strangerkir marked this conversation as resolved.
|
||
| ./ "$SVN_REPO_ROOT/trunk/" | ||
|
|
||
| - name: Update SVN tracking | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| cd "${SVN_REPO_ROOT}/trunk" | ||
| svn add . --force | ||
|
|
||
| #Only run if there's anything to delete | ||
| if svn status | grep -q '^!'; then | ||
| svn status | grep '^!' | cut -c9- | while IFS= read -r file; do | ||
| svn delete "$file@" # @ suffix handles files with @ in name | ||
| done | ||
| fi | ||
|
|
||
| - name: Commit changes to SVN repository | ||
| if: inputs.DRY_RUN != true | ||
| env: | ||
| SVN_USERNAME: ${{ secrets.SVN_USERNAME }} | ||
| SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| [ -d "$SVN_REPO_ROOT" ] || { echo "❌ SVN_REPO_ROOT not found"; exit 1; } | ||
| cd "$SVN_REPO_ROOT" | ||
|
|
||
| svn status trunk | grep -q '^[ADMR!~]' || { echo "❌ No changes in trunk"; exit 1; } | ||
|
|
||
| # WordPress.org SVN doesn't support SSH keys or tokens. | ||
| # Keeping credentials as step-level env vars with --no-auth-cache is the best available option. | ||
| echo '🚀 Committing...' | ||
|
|
||
| svn commit trunk \ | ||
| --username "$SVN_USERNAME" \ | ||
| --password "$SVN_PASSWORD" \ | ||
| --no-auth-cache \ | ||
| --non-interactive \ | ||
| -m "Update trunk to version ${VALIDATED_PLUGIN_VERSION}" | ||
|
|
||
| - name: Create a new tag | ||
| if: inputs.UPDATE_TRUNK_ONLY == false && inputs.DRY_RUN != true | ||
| env: | ||
| SVN_USERNAME: ${{ secrets.SVN_USERNAME }} | ||
| SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| echo "🚀 Publishing version ${VALIDATED_PLUGIN_VERSION}" | ||
|
|
||
| svn copy \ | ||
| "https://plugins.svn.wordpress.org/${{ inputs.SVN_PLUGIN_SLUG }}/trunk" \ | ||
| "https://plugins.svn.wordpress.org/${{ inputs.SVN_PLUGIN_SLUG }}/tags/${VALIDATED_PLUGIN_VERSION}" \ | ||
| --username "$SVN_USERNAME" \ | ||
| --password "$SVN_PASSWORD" \ | ||
| --no-auth-cache \ | ||
| --non-interactive \ | ||
| -m "Tagging version ${VALIDATED_PLUGIN_VERSION}" | ||
|
|
||
| echo "✅ Version ${VALIDATED_PLUGIN_VERSION} was published to WordPress.org" | ||
|
|
||
| - name: Compress and upload trunk contents as an artifact | ||
| if: inputs.DRY_RUN == true | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: ${{ inputs.SVN_PLUGIN_SLUG }} | ||
| path: ${{ env.SVN_REPO_ROOT }}/trunk | ||
| include-hidden-files: true | ||
| compression-level: 1 #Minimal compression - we don't want to waste resources for this | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.