Skip to content

Commit

Permalink
Add deploy script
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgibbs committed Mar 28, 2022
1 parent 09dfa73 commit b513931
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 1 deletion.
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM instrumentisto/rsync-ssh:alpine3.13-r4
LABEL "com.github.actions.name"="GitHub Action to deploy WordPress projects to WP Engine"
LABEL "com.github.actions.description"="An action used to deploy code from a GitHub repo to a WP Engine environment of your choosing"
LABEL "com.github.actions.icon"="upload-cloud"
LABEL "com.github.actions.color"="purple"
LABEL "repository"="https://github.com/indigotree/github-action-deploy-to-wpe"
LABEL "maintainer"="Paul Wong-Gibbs <[email protected]>"
RUN apk add bash php
ADD entrypoint.sh /entrypoint.sh
ADD exclude.txt /exclude.txt
ENTRYPOINT ["/entrypoint.sh"]
44 changes: 44 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
MIT License

Copyright (c) 2021-present Indigo Tree Digital Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

--

Based on prior work from https://github.com/wpengine/github-action-wpe-site-deploy
Copyright (c) 2021 WP Engine

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
129 changes: 128 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,128 @@
# wordpress-deploy-checks-for-github-actions
# GitHub Action to deploy WordPress projects to WP Engine

This GitHub Action is used to deploy code from a GitHub repo to a WP Engine environment of your choosing. Deploy a full site directory or a sub-directory of your WordPress install. Other options include performing a PHP Lint, custom rsync flags, clearing cache, and a executing a post-deploy script of your choosing.

## Setup Instructions

Follow along with the [video tutorial here!](https://wpengine-2.wistia.com/medias/crj1lp3qke)

1. **MAIN.YML SETUP**

- Copy the following `main.yml` to `.github/workflows/main.yml` in your root of your local WordPress project/repo, replacing values of `PRD_BRANCH`, `PRD_ENV` for the branch and WPE Environment name of your choice. Optional vars can be specified as well. Consult ["Environment Variable & Secrets"](#environment-variables--secrets) for more available options.

2. **SSH PRIVATE KEY SETUP IN GITHUB**

- [Generate a new SSH key pair](https://wpengine.com/support/ssh-keys-for-shell-access/#Generate_New_SSH_Key) if you have not already done so.

- Add the _SSH Private Key_ to your [Repository Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) or your [Organization Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-an-organization). Save the new secret "Name" as `WPE_SSHG_KEY_PRIVATE`.

**NOTE:** If using a GitHub Organization, adding the SSH key to the Organization Secrets will allow all repos to reference the same SSH key for deploys using the method in the sample `main.yml`. The SSH Key also connects to all installs made available to its WP Engine User. One key can then effectively be used to deploy all projects to their respective sites on WP Engine. Less work. More deploys!

3. **SSH PUBLIC KEY SETUP IN WP ENGINE**

- Add _SSH Public Key_ to WP Engine SSH Gateway Key settings. [This Guide will show you how.](https://wpengine.com/support/ssh-gateway/#Add_SSH_Key)

**NOTE:** This Action DOES NOT utilize WP Engine GitPush or the GitPush SSH keys [found here.](https://wpengine.com/support/git/#Add_SSH_Key_to_User_Portal)

4. Git push your site GitHub repo. The action will do the rest!

View your actions progress and logs by navigating to the "Actions" tab in your repo.

## Example GitHub Action workflow

### Simple main.yml:

```
name: Deploy to WP Engine
on:
push:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: GitHub Action Deploy to WP Engine
uses: wpengine/[email protected]
with:
# Deploy vars
WPE_SSHG_KEY_PRIVATE: ${{ secrets.WPE_SSHG_KEY_PRIVATE }}
# Branches & Environments
PRD_BRANCH: main
PRD_ENV: prodsitehere
```

### Extended main.yml

```
name: Deploy to WP Engine
on:
push:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: GitHub Action Deploy to WP Engine
uses: wpengine/[email protected]
with:
# Deploy vars
WPE_SSHG_KEY_PRIVATE: ${{ secrets.WPE_SSHG_KEY_PRIVATE }}
PHP_LINT: TRUE
FLAGS: -azvr --inplace --delete --exclude=".*" --exclude-from=.deployignore
CACHE_CLEAR: TRUE
TPO_SRC_PATH: "wp-content/themes/genesis-child-theme/"
TPO_PATH: "wp-content/themes/genesis-child-theme/"
# Branches & Environments
PRD_BRANCH: main
PRD_ENV: prodsitehere
STG_BRANCH: feature/stage
STG_ENV: stagesitehere
DEV_BRANCH: feature/dev
DEV_ENV: devsitehere
```

## Environment Variables & Secrets

### Required

| Name | Type | Usage |
| ---------------------- | ------- | ---------------------------------------------------------------------------------- |
| `PRD_BRANCH` | string | Insert the name of the GitHub branch you would like to deploy from, example; main. |
| `PRD_ENV` | string | Insert the name of the WP Engine environment you want to deploy to. |
| `WPE_SSHG_KEY_PRIVATE` | secrets | Private SSH Key for the SSH Gateway and deployment. See below for SSH key usage. |

### Optional

| Name | Type | Usage |
| -------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STG_BRANCH` | string | Insert the name of a staging GitHub branch you would like to deploy from. Note: exclude leading / from branch names. |
| `STG_ENV` | string | Insert the name of the WP Engine Stage environment you want to deploy to. |
| `DEV_BRANCH` | string | Insert the name of a development GitHub branch you would like to deploy from. Note: exclude leading / in branch names. |
| `DEV_ENV` | string | Insert the name of the WP Engine Dev environment you want to deploy to. |
| `PHP_LINT` | bool | Set to TRUE to execute a php lint on your branch pre-deployment. Default is `FALSE`. |
| `FLAGS` | string | Set optional rsync flags such as `--delete` or `--exclude-from`. The example is excluding paths specified in a `.deployignore` file in the root of the repo. This action defaults to a non-destructive deploy using the flags in the example above. |
| `CACHE_CLEAR` | bool | Optionally clear cache post deploy. This takes a few seconds. Default is TRUE. |
| `TPO_SRC_PATH` | string | Optional path to specify a theme, plugin, or other directory source to deploy from. Ex. `"wp-content/themes/genesis-child-theme/"` . Defaults to "." Dir. |
| `TPO_PATH` | string | Optional path to specify a theme, plugin, or other directory destination to deploy to. Ex. `"wp-content/themes/genesis-child-theme/"` . Defaults to WordPress root directory. |

### Further reading

- [Defining environment variables in GitHub Actions](https://docs.github.com/en/actions/reference/environment-variables)
- [Storing secrets in GitHub repositories](https://docs.github.com/en/actions/reference/encrypted-secrets)
- As this script does not restrict files or directories that can be deployed, it is recommended to leverage one of [WP Engine's .gitignore templates.](https://wpengine.com/support/git/#Add_gitignore)

### Legal

Copyright (C) 2021-present, Indigo Tree Digital Ltd.

See the LICENSE file for license information.

Based on prior work from https://github.com/wpengine/github-action-wpe-site-deploy
60 changes: 60 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: "Deploy WordPress projects to WP Engine"
branding:
icon: "upload-cloud"
color: "purple"
description: "Deploy WordPress projects to WP Engine"
inputs:
WPE_SSHG_KEY_PRIVATE:
description: "The private RSA key you will save in the Github Secrets"
required: true
PHP_LINT:
description: "optional php syntax check"
required: false
default: false
FLAGS:
description: "Optional flags for the deployment"
required: true
default: '-azvr --inplace --exclude=".*"'
CACHE_CLEAR:
description: "Optional WPE Clear cache"
required: false
default: true
TPO_SRC_PATH:
description: "An optional source directory to deploy other than the root directory that is being versioned."
default: "."
required: false
TPO_PATH:
description: "An optional destination directory to deploy to other than the WordPress root."
default: ""
required: false
PRD_BRANCH:
description: "Source branch to deploy PRD_ENV"
required: true
default: "PROD_BRANCH_HERE"
PRD_ENV:
description: "Destination to deploy to WPE Prod"
required: true
default: "PROD_ENV_HERE"
STG_BRANCH:
description: "Source branch to deploy STG_ENV"
required: false
default: "STAGE_BRANCH_HERE"
STG_ENV:
description: "Destination to deploy to WPE Stage"
required: false
default: "STAGE_ENV_HERE"
DEV_BRANCH:
description: "Source branch to deploy DEV_ENV"
required: false
default: "DEV_BRANCH_HERE"
DEV_ENV:
description: "Destination to deploy to WPE Dev"
required: false
default: "DEV_ENV_HERE"
SCRIPT:
description: "File containing custom scripts run after the rsync"
required: false

runs:
using: "docker"
image: "Dockerfile"
102 changes: 102 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash -l

set -e

: ${INPUT_WPE_SSHG_KEY_PRIVATE?Required secret not set.}

if [[ $GITHUB_REF =~ ${INPUT_PRD_BRANCH}$ ]]; then
export WPE_ENV_NAME=$INPUT_PRD_ENV;
elif [[ $GITHUB_REF =~ ${INPUT_STG_BRANCH}$ ]]; then
export WPE_ENV_NAME=$INPUT_STG_ENV;
elif [[ $GITHUB_REF =~ ${INPUT_DEV_BRANCH}$ ]]; then
export WPE_ENV_NAME=$INPUT_DEV_ENV;
else
echo "FAILURE: Branch name required." && exit 1;
fi

echo "Deploying $GITHUB_REF to $WPE_ENV_NAME..."

# Deploy Vars
WPE_SSH_HOST="$WPE_ENV_NAME.ssh.wpengine.net"
DIR_PATH="$INPUT_TPO_PATH"
SRC_PATH="$INPUT_TPO_SRC_PATH"

# Set up our user and path
WPE_SSH_USER="$WPE_ENV_NAME"@"$WPE_SSH_HOST"
WPE_FULL_HOST="$WPE_SSH_USER"
WPE_DESTINATION="$WPE_SSH_USER":sites/"$WPE_ENV_NAME"/"$DIR_PATH"


# Setup our SSH Connection & use keys
if [ ! -d ${HOME}/.ssh ]; then
mkdir "${HOME}/.ssh"
SSH_PATH="${HOME}/.ssh"
mkdir "${SSH_PATH}/ctl/"
# Set Key Perms
chmod -R 700 "$SSH_PATH"
else
SSH_PATH="${HOME}/.ssh"
echo "using established SSH KEY path...";
fi

# Copy Secret Keys to container
WPE_SSHG_KEY_PRIVATE_PATH="$SSH_PATH/github_action"
echo "$INPUT_WPE_SSHG_KEY_PRIVATE" > "$WPE_SSHG_KEY_PRIVATE_PATH"
chmod 600 "$WPE_SSHG_KEY_PRIVATE_PATH"

# Establish known hosts
KNOWN_HOSTS_PATH="$SSH_PATH/known_hosts"
ssh-keyscan -t rsa "$WPE_SSH_HOST" >> "$KNOWN_HOSTS_PATH"
chmod 644 "$KNOWN_HOSTS_PATH"

echo "prepping file perms..."
find $SRC_PATH -type d -exec chmod -R 775 {} \;
find $SRC_PATH -type f -exec chmod -R 664 {} \;
echo "file perms set..."

# pre deploy php lint
if [ "${INPUT_PHP_LINT^^}" == "TRUE" ]; then
echo "Begin PHP Linting."
for file in $(find $SRC_PATH/ -name "*.php"); do
php -l $file
status=$?
if [[ $status -ne 0 ]]; then
echo "FAILURE: Linting failed - $file :: $status" && exit 1
fi
done
echo "PHP Lint Successful! No errors detected!"
else
echo "Skipping PHP Linting."
fi

# post deploy script
if [[ -n ${INPUT_SCRIPT} ]]; then
SCRIPT="&& sh ${INPUT_SCRIPT}";
else
SCRIPT=""
fi

# post deploy cache clear
if [ "${INPUT_CACHE_CLEAR^^}" == "TRUE" ]; then
CACHE_CLEAR="&& wp page-cache flush"
elif [ "${INPUT_CACHE_CLEAR^^}" == "FALSE" ]; then
CACHE_CLEAR=""
else echo "CACHE_CLEAR must be TRUE or FALSE only... Cache not cleared..." && exit 1;
fi

# Deploy via SSH
# setup master ssh connection
ssh -nNf -v -i ${WPE_SSHG_KEY_PRIVATE_PATH} -o StrictHostKeyChecking=no -o ControlMaster=yes -o ControlPath="$SSH_PATH/ctl/%C" $WPE_FULL_HOST

echo "!!! MASTER SSH CONNECTION ESTABLISHED !!!"
rsync --rsh="ssh -v -p 22 -i ${WPE_SSHG_KEY_PRIVATE_PATH} -o StrictHostKeyChecking=no -o 'ControlPath=$SSH_PATH/ctl/%C'" $INPUT_FLAGS --exclude-from='/exclude.txt' $SRC_PATH "$WPE_DESTINATION"

# post deploy script and cache clear
if [[ -n ${SCRIPT} || -n ${CACHE_CLEAR} ]]; then
ssh -v -p 22 -i ${WPE_SSHG_KEY_PRIVATE_PATH} -o StrictHostKeyChecking=no -o ControlPath="$SSH_PATH/ctl/%C" $WPE_FULL_HOST "cd sites/${WPE_ENV_NAME} ${SCRIPT} ${CACHE_CLEAR}"
fi

# close master ssh
ssh -O exit -o ControlPath="$SSH_PATH/ctl/%C" $WPE_FULL_HOST

echo "SUCCESS: Your code has been deployed to WP Engine!"
Loading

0 comments on commit b513931

Please sign in to comment.