├── .editorconfig ├── .gitattributes ├── Dockerfile ├── LICENSE ├── README.md ├── action.yml └── entrypoint.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | *.md text eol=lf 3 | *.sh text eol=lf 4 | *.yml text eol=lf 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stable-slim 2 | 3 | RUN apt-get update \ 4 | && apt-get install -y subversion rsync git \ 5 | && apt-get clean -y \ 6 | && rm -rf /var/lib/apt/lists/* 7 | 8 | COPY entrypoint.sh /entrypoint.sh 9 | 10 | RUN chmod +x /entrypoint.sh 11 | 12 | ENTRYPOINT ["/entrypoint.sh"] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 nK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WordPress Plugin SVN Deploy 2 | 3 | This Action commits the contents of your Git tag to the WordPress.org plugin repository using the same tag name. It can exclude files as defined in `.distignore`, and moves anything from a `.wordpress-org` subdirectory to the top-level `assets` directory in Subversion (plugin banners, icons, and screenshots). 4 | 5 | The code forked from and slightly simplified for our own needs. Also added `SOURCE_DIR` variable support. 6 | 7 | ## Configuration 8 | 9 | ### Required secrets 10 | 11 | * `SVN_USERNAME` 12 | * `SVN_PASSWORD` 13 | 14 | [Secrets are set in your repository settings](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets). They cannot be viewed once stored. 15 | 16 | ### Optional environment variables 17 | 18 | * `SLUG` - defaults to the repository name, customizable in case your WordPress repository has a different slug or is capitalized differently. 19 | * `VERSION` - defaults to the tag name; do not recommend setting this except for testing purposes. 20 | * `SOURCE_DIR` - defaults to `/` root directory of your repository. If you use custom build directory, it will be useful to customize to something like this `build/`. 21 | * `ASSETS_DIR` - defaults to `.wordpress-org`, customizable for other locations of WordPress.org plugin repository-specific assets that belong in the top-level `assets` directory (the one on the same level as `trunk`). 22 | 23 | ## Excluding files from deployment 24 | 25 | If there are files or directories to be excluded from deployment, such as tests or editor config files, they can be specified in either a `.distignore` file using the `export-ignore` directive. If a `.distignore` file is present, it will be used. 26 | 27 | `.distignore` is useful particularly when there are built files that are in `.gitignore`, and is a file that is used in [WP-CLI](https://wp-cli.org/). For modern plugin setups with a build step and no built files committed to the repository, this is the way forward. 28 | 29 | ### Sample baseline files 30 | 31 | #### `.distignore` 32 | 33 | **Notes:** `.distignore` is for files to be ignored **only**. This comes from its current expected syntax in WP-CLI's [`wp dist-archive` command](https://github.com/wp-cli/dist-archive-command/). 34 | 35 | ``` 36 | /.wordpress-org 37 | /.git 38 | /.github 39 | /node_modules 40 | .distignore 41 | .gitignore 42 | ``` 43 | 44 | ## Example Workflow File 45 | 46 | ```yml 47 | name: Deploy to WordPress.org 48 | on: 49 | push: 50 | tags: 51 | - "v*" 52 | pull_request: 53 | tags: 54 | - "v*" 55 | 56 | jobs: 57 | deploy: 58 | runs-on: ubuntu-latest 59 | steps: 60 | - uses: actions/checkout@master 61 | 62 | - name: Build 63 | run: | 64 | npm install 65 | npm run build 66 | 67 | - name: WordPress Plugin Deploy 68 | uses: nk-o/action-wordpress-plugin-deploy@master 69 | env: 70 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} 71 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }} 72 | SOURCE_DIR: dist/ 73 | SLUG: my-plugin-name 74 | ``` 75 | 76 | ## Thanks to 77 | 78 | This action is based on 10up action, so we need to thank [for code](https://github.com/10up/action-wordpress-plugin-deploy/) to these guys 79 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'WordPress Plugin SVN Deploy' 2 | description: 'Deploy to the WordPress Plugin Repository' 3 | author: 'nK' 4 | runs: 5 | using: 'docker' 6 | image: 'Dockerfile' 7 | branding: 8 | icon: 'upload-cloud' 9 | color: 'blue' 10 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Note that this does not use pipefail 4 | # because if the grep later doesn't match any deleted files, 5 | # which is likely the majority case, 6 | # it does not exit with a 0, and I only care about the final exit. 7 | set -eo 8 | 9 | # Ensure SVN username and password are set 10 | # IMPORTANT: while secrets are encrypted and not viewable in the GitHub UI, 11 | # they are by necessity provided as plaintext in the context of the Action, 12 | # so do not echo or use debug mode unless you want your secrets exposed! 13 | if [[ -z "$SVN_USERNAME" ]]; then 14 | echo "Set the SVN_USERNAME secret" 15 | exit 1 16 | fi 17 | 18 | if [[ -z "$SVN_PASSWORD" ]]; then 19 | echo "Set the SVN_PASSWORD secret" 20 | exit 1 21 | fi 22 | 23 | # Allow some ENV variables to be customized 24 | if [[ -z "$SLUG" ]]; then 25 | SLUG=${GITHUB_REPOSITORY#*/} 26 | fi 27 | echo "ℹ︎ SLUG is $SLUG" 28 | 29 | # Does it even make sense for VERSION to be editable in a workflow definition? 30 | if [[ -z "$VERSION" ]]; then 31 | VERSION="${GITHUB_REF#refs/tags/}" 32 | VERSION="${VERSION#v}" 33 | fi 34 | if [[ -z "$VERSION" ]]; then 35 | echo "Wrong VERSION" 36 | exit 1 37 | fi 38 | echo "ℹ︎ VERSION is $VERSION" 39 | 40 | if [[ -z "$ASSETS_DIR" ]]; then 41 | ASSETS_DIR=".wordpress-org" 42 | fi 43 | echo "ℹ︎ ASSETS_DIR is $ASSETS_DIR" 44 | 45 | # By default we use root directory to upload on SVN 46 | # But sometimes we need to upload files from `build` directory 47 | if [[ -z "$SOURCE_DIR" ]]; then 48 | SOURCE_DIR="" 49 | else 50 | echo "ℹ︎ Using custom directory to upload from - $SOURCE_DIR" 51 | fi 52 | 53 | SVN_URL="https://plugins.svn.wordpress.org/${SLUG}/" 54 | SVN_DIR="${HOME}/svn-${SLUG}" 55 | 56 | # Checkout just trunk and assets for efficiency 57 | # Tagging will be handled on the SVN level 58 | echo "➤ Checking out .org repository..." 59 | svn checkout --depth immediates "$SVN_URL" "$SVN_DIR" 60 | cd "$SVN_DIR" 61 | svn update --set-depth infinity assets 62 | svn update --set-depth infinity trunk 63 | 64 | echo "➤ Copying files..." 65 | # Copy from current branch to /trunk, excluding dotorg assets 66 | # The --delete flag will delete anything in destination that no longer exists in source 67 | if [[ -e "$GITHUB_WORKSPACE/.distignore" ]]; then 68 | echo "ℹ︎ Using .distignore" 69 | rsync -rc --exclude-from="$GITHUB_WORKSPACE/.distignore" "$GITHUB_WORKSPACE/$SOURCE_DIR" trunk/ --delete --delete-excluded 70 | else 71 | rsync -rc "$GITHUB_WORKSPACE/$SOURCE_DIR" trunk/ --delete --delete-excluded 72 | fi 73 | 74 | # Copy dotorg assets to /assets 75 | if [[ -d "$GITHUB_WORKSPACE/$ASSETS_DIR/" ]]; then 76 | rsync -rc "$GITHUB_WORKSPACE/$ASSETS_DIR/" assets/ --delete 77 | else 78 | echo "ℹ︎ No assets directory found; skipping..." 79 | fi 80 | 81 | # Add everything and commit to SVN 82 | # The force flag ensures we recurse into subdirectories even if they are already added 83 | # Suppress stdout in favor of svn status later for readability 84 | echo "➤ Preparing files..." 85 | svn add . --force > /dev/null 86 | 87 | # SVN delete all deleted files 88 | # Also suppress stdout here 89 | svn status | grep '^\!' | sed 's/! *//' | xargs -I% svn rm %@ > /dev/null 90 | 91 | # Copy tag locally to make this a single commit 92 | echo "➤ Copying tag..." 93 | svn cp "trunk" "tags/$VERSION" 94 | 95 | # Fix screenshots getting force downloaded when clicking them 96 | # https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/ 97 | svn propset svn:mime-type image/png assets/*.png || true 98 | svn propset svn:mime-type image/jpeg assets/*.jpg || true 99 | 100 | svn status 101 | 102 | echo "➤ Committing files..." 103 | svn commit -m "Update to version $VERSION from GitHub" --no-auth-cache --non-interactive --username "$SVN_USERNAME" --password "$SVN_PASSWORD" 104 | 105 | echo "✓ Plugin deployed!" 106 | --------------------------------------------------------------------------------