I love GitHub Actions. They are so simple and powerful, allowing you to have your code deployment and source code in one location.
I manage and deploy all of my sites using SSH (because it’s more secure), and over the years, I’ve adopted numerous deployment strategies. I adopted a Git strategy not too long ago where my server would pull down changes from Git, but it’s a flawed approach.
Here is an actual GitHub Actions build file I use for a project. It’s a mixture of Node.js and WordPress. If your needs are not as complicated, your file will resemble a fraction of this.
The first few parts, I think, are reasonably self-explanatory. Give our action file a name. Specify what triggers our build (in our case, a push to the master
branch).
Inside of the jobs section, we get into the filling of our delicious GitHub Actions pie. We specify we want an Ubuntu Linux instance. I am managing my WordPress dependencies using Composer, so I am using the php-actions/composer
action. I also defined I want Node.js version 14 installed (you can change this to suit your version needs).
You probably don’t need libnotify-bin
I needed it for some scripts I was running which write console output.
Because I have Node dependencies inside of my WordPress theme, I cd into the directory and then run npm install
— I have a couple of Aurelia applications inside of this theme which I then install the dependencies for and subsequently build (for deployment).
name: Deploy Prod Apps on: push: branches: - master jobs: deploy: name: Deploy apps to prod runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: php-actions/composer@v6 - name: Install Node.js uses: actions/setup-node@v1 with: node-version: '14.x' - name: Install libnotify run: sudo apt-get install libnotify-bin - name: Install npm dependencies run: cd wp-content/themes/news-theme && npm install - name: Pinning Queue run: cd wp-content/themes/news-theme/platform-apps/pinning-queue && npm install && npm run build - name: Locality Selector run: cd wp-content/themes/news-theme/platform-apps/locality-selector && npm install && npm run build - name: Deploy uses: easingthemes/ssh-deploy@main env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY_PROD }} ARGS: >- -rltgoDzvO --exclude='.git' --exclude='node_modules/' REMOTE_HOST: ${{ secrets.REMOTE_HOST_PROD }} REMOTE_USER: ${{ secrets.REMOTE_USER_PROD }} TARGET: /opt/bitnami/wordpress/
The SSH deployment step
This is the part you probably want to know about (not the other life story nonsense). We create a new build step called “Deploy” and use the easingthemes/ssh-deploy
action. We then pass in some environment variables to this.
- name: Deploy uses: easingthemes/ssh-deploy@main env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY_PROD }} ARGS: >- -rltgoDzvO --exclude='.git' --exclude='node_modules/' REMOTE_HOST: ${{ secrets.REMOTE_HOST_PROD }} REMOTE_USER: ${{ secrets.REMOTE_USER_PROD }} TARGET: /opt/bitnami/wordpress/
The most important value here is SSH_PRIVATE_KEY
this is your private key value, and you mustn’t publicly specify this in your file whatsoever. For actions, it is best practice to use secret values to pass into your GitHub Actions. I will assume you know how to generate SSH keys, register them and then copy the key. This section on the repo will point you in the right direction.
If you get stuck on this step, make sure you’re using your private key and not your public key. Most of the issues you’ll face are related to not providing the correct key value.
Secondly, you must exclude directories that you do not want to be copied. You don’t want to copy your .git directory, and you especially never want to copy a node_modules
directory (have you ever seen how big this folder gets?).
The REMOTE_HOST
value is usually the IP address of your site. The REMOTE_USER is the username you would use when tunnelling
into our server via SSH. The TARGET
is where your files will be copied. You can see I am using a Bitnami WordPress image, so I make sure my files are deployed into the WordPress directory.
Bonus points: Post deploy commands
Sadly, the ssh-deploy
action does not support post deploy commands (the ability to run commands after a deploy is done). I have had to do this on a couple of occasions to fix file and folder permissions.
For post deploy commands, you can use the appleboy/ssh-action
action to do this. It kind of looks similar to that of the above ssh-deploy
.
- name: Post Deploy uses: appleboy/ssh-action@master with: host: ${{ secrets.REMOTE_HOST_PROD }} username: ${{ secrets.REMOTE_USER_PROD }} key: ${{ secrets.SSH_PRIVATE_KEY_PROD }} port: 22 script: | sudo find /opt/bitnami/wordpress/wp-content/mu-plugins -type d -exec chmod 775 {} \; sudo find /opt/bitnami/wordpress/wp-content/plugins -type d -exec chmod 775 {} \; sudo find /opt/bitnami/wordpress/wp-content/themes -type d -exec chmod 775 {} \; sudo find /opt/bitnami/wordpress/wp-content/mu-plugins -type f -exec chmod 664 {} \; sudo find /opt/bitnami/wordpress/wp-content/plugins -type f -exec chmod 664 {} \; sudo find /opt/bitnami/wordpress/wp-content/themes -type f -exec chmod 664 {} \; sudo chmod 664 /opt/bitnami/wordpress/wp-config.php sudo chmod 775 /opt/bitnami/wordpress/wp-content/w3tc-config sudo chmod 775 /opt/bitnami/wordpress/wp-content/cache
Here is a post-deploy build step that ensures all wp-content folders have 775 permission and the files inside are 664. The pipe on the first line allows us to run multiple script commands. If you have one, put it on a single line and don’t use a pipe.