Continuous Deployments for WordPress Using GitHub Actions
Publikováno: 6.4.2020
Continuous Integration (CI) workflows are considered a best practice these days. As in, you work with your version control system (Git), and as you do, CI is doing work for you like running tests, sending notifications, and deploying code. That last part is called Continuous Deployment (CD). But shipping code to a production server often requires paid services. With GitHub Actions, Continuous Deployment is free for everyone. Let’s explore how to set that up.
DevOps is for everyone… Read article “Continuous Deployments for WordPress Using GitHub Actions”
The post Continuous Deployments for WordPress Using GitHub Actions appeared first on CSS-Tricks.
Continuous Integration (CI) workflows are considered a best practice these days. As in, you work with your version control system (Git), and as you do, CI is doing work for you like running tests, sending notifications, and deploying code. That last part is called Continuous Deployment (CD). But shipping code to a production server often requires paid services. With GitHub Actions, Continuous Deployment is free for everyone. Let’s explore how to set that up.
DevOps is for everyone
As a front-end developer, continuous deployment workflows used to be exciting, but mysterious to me. I remember numerous times being scared to touch deployment configurations. I defaulted to the easy route instead — usually having someone else set it up and maintain it, or manual copying and pasting things in a worst-case scenario.
As soon as I understood the basics of rsync, CD finally became tangible to me. With the following GitHub Action workflow, you do not need to be a DevOps specialist; but you’ll still have the tools at hand to set up best practice deployment workflows.
The basics of a Continuous Deployment workflow
So what’s the deal, how does this work? It all starts with CI, which means that you commit code to a shared remote repository, like GitHub, and every push to it will run automated tasks on a remote server. Those tasks could include test and build processes, like linting, concatenation, minification and image optimization, among others.
CD also delivers code to a production website server. That may happen by copying the verified and built code and placing it on the server via FTP, SSH, or by shipping containers to an infrastructure. While every shared hosting package has FTP access, it’s rather unreliable and slow to send many files to a server. And while shipping application containers is a safe way to release complex applications, the infrastructure and setup can be rather complex as well. Deploying code via SSH though is fast, safe and flexible. Plus, it’s supported by many hosting packages.
How to deploy with rsync
An easy and efficient way to ship files to a server via SSH is rsync, a utility tool to sync files between a source and destination folder, drive or computer. It will only synchronize those files which have changed or don’t already exist at the destination. As it became a standard tool on popular Linux distributions, chances are high you don’t even need to install it.
The most basic operation is as easy as calling rsync SRC DEST
to sync files from one directory to another one. However, there are a couple of options you want to consider:
-c
compares file changes by checksum, not modification time-h
outputs numbers in a more human readable format-a
retains file attributes and permissions and recursively copies files and directories-v
shows status output--delete
deletes files from the destination that aren’t found in the source (anymore)--exclude
prevents syncing specified files like the.git
directory andnode_modules
And finally, you want to send the files to a remote server, which makes the full command look like this:
rsync -chav --delete --exclude /.git/ --exclude /node_modules/ ./ ssh-user@example.com:/mydir
You could run that command from your local computer to deploy to any live server. But how cool would it be if it was running in a controlled environment from a clean state? Right, that’s what you’re here for. Let’s move on with that.
Create a GitHub Actions workflow
With GitHub Actions you can configure workflows to run on any GitHub event. While there is a marketplace for GitHub Actions, we don’t need any of them but will build our own workflow.
To get started, go to the “Actions” tab of your repository and click “Set up a workflow yourself.” This will open the workflow editor with a .yaml
template that will be committed to the .github/workflows
directory of your repository.
When saved, the workflow checks out your repo code and runs some echo
commands. name
helps follow the status and results later. run
contains the shell commands you want to run in each step.
Define a deployment trigger
Theoretically, every commit to the master branch should be production-ready. However, reality teaches you that you need to test results on the production server after deployment as well and you need to schedule that. We at bleech consider it a best practice to only deploy on workdays — except Fridays and only before 4:00 pm — to make sure we have time to roll back or fix issues during business hours if anything goes wrong.
An easy way to get manual-level control is to set up a branch just for triggering deployments. That way, you can specifically merge your master branch into it whenever you are ready. Call that branch production, let everyone on your team know pushes to that branch are only allowed from the master branch and tell them to do it like this:
git push origin master:production
Here’s how to change your workflow trigger to only run on pushes to that production
branch:
name: Deployment
on:
push:
branches: [ production ]
Build and verify the theme
I’ll assume you’re using Flynt, our WordPress starter theme, which comes with dependency management via Composer and npm as well as a preconfigured build process. If you’re using a different theme, the build process is likely to be similar, but might need adjustments. And if you’re checking in the built assets to your repository, you can skip all steps except the checkout
command.
For our example, let’s make sure that node is executed in the required version and that dependencies are installed before building:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1.1.0
with:
version: 12.x
- name: Install dependencies
run: |
composer install -o
npm install
- name: Build
run: npm run build
The Flynt build task finally requires, lints, compiles, and transpiles Sass and JavaScript files, then adds revisioning to assets to prevent browser cache issues. If anything in the build step fails, the workflow will stop executing and thus prevents you from deploying a broken release.
Configure server access and destination
For the rsync
command to run successfully, GitHub needs access to SSH into your server. This can be accomplished by:
- Generating a new SSH key (without a passphrase)
- Adding the public key to your
~/.ssh/authorized_keys
on the production server - Adding the private key as a secret with the name
DEPLOY_KEY
to the repository
The sync workflow step needs to save the key to a local file, adjust file permissions and pass the file to the rsync
command. The destination has to point to your WordPress theme directory on the production server. It’s convenient to define it as a variable so you know what to change when reusing the workflow for future projects.
- name: Sync
env:
dest: 'ssh-user@example.com:/mydir/wp-content/themes/mytheme’
run: |
echo "${{secrets.DEPLOY_KEY}}" > deploy_key
chmod 600 ./deploy_key
rsync -chav --delete \
-e 'ssh -i ./deploy_key -o StrictHostKeyChecking=no' \
--exclude /.git/ \
--exclude /.github/ \
--exclude /node_modules/ \
./ ${{env.dest}}
Depending on your project structure, you might want to deploy plugins and other theme related files as well. To accomplish that, change the source and destination to the desired parent directory, make sure to check if the excluded files need an update, and check if any paths in the build process should be adjusted.
Put the pieces together
We’ve covered all necessary steps of the CD process. Now we need to run them in a sequence which should:
- Trigger on each push to the
production
branch - Install dependencies
- Build and verify the code
- Send the result to a server via rsync
The complete GitHub workflow will look like this:
name: Deployment
on:
push:
branches: [ production ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1.1.0
with:
version: 12.x
- name: Install dependencies
run: |
composer install -o
npm install
- name: Build
run: npm run build
- name: Sync
env:
dest: 'ssh-user@example.com:/mydir/wp-content/themes/mytheme’
run: |
echo "${{secrets.DEPLOY_KEY}}" > deploy_key
chmod 600 ./deploy_key
rsync -chav --delete \
-e 'ssh -i ./deploy_key -o StrictHostKeyChecking=no' \
--exclude /.git/ \
--exclude /.github/ \
--exclude /node_modules/ \
./ ${{env.dest}}
To test the workflow, commit the changes, pull them into your local repository and trigger the deployment by pushing your master
branch to the production
branch:
git push origin master:production
You can follow the status of the execution by going to the “Actions” tab in GitHub, then selecting the recent execution and clicking on the “deploy“ job. The green checkmarks indicate that everything went smoothly. If there are any issues, check the logs of the failed step to fix them.
Check the full report on GitHub
Congratulations! You’ve successfully deployed your WordPress theme to a server. The workflow file can easily be reused for future projects, making continuous deployment setups a breeze.
To further refine your deployment process, the following topics are worth considering:
- Caching dependencies to speed up the GitHub workflow
- Activating the WordPress maintenance mode while syncing files
- Clearing the website cache of a plugin (like Cache Enabler) after the deployment
The post Continuous Deployments for WordPress Using GitHub Actions appeared first on CSS-Tricks.