Github Actions to Deploy via FTPS

  • Git / Version Control
  • PHP
  • WordPress

As a developer I personally dislike pushing files up to production sites with FTP. Having to either upload the whole folder when only a few files have changed, or navigate to each changed file in the folder structure to select and push each – oh my, the tediousness of it all!

OK, I know, there are ways to synchronize the files. FileZilla does a nice job with comparison of each side, and will even hide the files on both sides if they are the same. CyberDuck will go one step further and actually look at the whole project and then move only changed filed up. But all that takes time.

This is until I found Github Actions and FTP-Deploy-Action by Sam Kirkland – you can see hid project here: github.com/…/FTP-Deploy-Action

What is needed?

First you will need a Github account. The free level is good as this gives you access to both Private Repositories and GitHub Actions. If you have an account, just log in and if not then you can create one.

Second you will need to have a local repository, hopefully set up so the code that is contained is being run on a local web server. Since I’m primarily a WordPress Developer I typically use LocalWP but I also have MAMP Pro installed. I would recommend either, but MAMP Pro is a little more technical whereas LocalWP is intended to allow spinning up of WordPress sites to be super simple and fast.

Next you need Git installed, and whilst you can just command line everything and Git GUI is recommended. I use SourceTree by Atlassian.

Setup Github Actions

In your Github account, click on the “Actions” tab in the main navigation and then click on the “Add workflow” button. Here you well be able to search for or see other workflows that are available, but we just want to set up a blank workflow. You should see an option near the top for this.

This will open the YML editor for the workflow with the default name of “main.yml” – this is all great, leave it. Now start to build out the content of the YML file. Here we will need to refer to https://github.com/SamKirkland/FTP-Deploy-Action which is the code the workflow uses.

The following is what I have set up:

on:
  push:
    branches:    
      - main

jobs:
  FTP-Deploy-Action:
    name: FTP-Deploy-Action
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@main
    
    - name: Use Node.js 16
      uses: actions/setup-node@v2
      with:
        node-version: '16'
        
    - name: Build Project
      run: |
        npm install
        npm run build --if-present
        
    - name: List output files
      run: ls
      
    - name: FTP-Deploy-Action
      uses: SamKirkland/[email protected]
      with:
        server: ${{ secrets.FTP_SERVER }}
        username: ${{ secrets.FTP_USERNAME }}
        password: ${{ secrets.FTP_PASSWORD }}
        local-dir: ./public/
        server-dir: public_html/
        protocol: ftps

Here I am also taking advantage of the “Actions secrets and variables” feature in the repo settings, allowing me to have my {{ secrets.FTP_SERVER }} {{ secrets.FTP_USERNAME }} and {{ secrets.FTP_PASSWORD }} stored in a secure way external from may workflow file. I do this in case I need to share the workflow, but do not have to worry about exposing my FTP credentials.

What is in (or not in) my repository?

There are some practices I subscribe to designed to keep the size of my repository as small as possible. There is no need to have WordPress Core commited to the repo, the same with plugins and themes that are readily available in the WordPress Plugin or Theme libraries. As such, it is really just my code, my themes, my plugins, that I commit, and thus deploy in the workflow. This makes the time spent pushing the repository and well as the workflow duration much shorter.

Here is what my project .gitignore looks like:

# LocalWP
/sql
/public/local-xdebuginfo.php

# Core
#
# Note: if you want to stage/commit WP core files
# you can delete this whole section/until Configuration.
/public/wp-admin/
/public/wp-content/index.php
/public/wp-content/languages
/public/wp-content/plugins/index.php
/public/wp-content/themes/index.php
/public/wp-includes/
/public/index.php
/public/license.txt
/public/readme.html
/public/wp-*.php
/public/xmlrpc.php

# htaccess
/public/.htaccess

# Configuration
/public/wp-config.php

# themes
/public/wp-content/themes/twenty*/

# plugins
/public/wp-content/plugins/

# Uploads
/public/wp-content/uploads/
/public/wp-content/updraft/

# Log files
*.log

I have some specific settings here, since my repo is at the /app folder of my LocalWP site folder. At this level in the file system there is an /sql folder where LocalWP stores MySQL backups, and I also have X-debug turned on in LocalWP. My paths also have /public as this is the folder in LocalWP folder structure that equates to the public root of my local website – this maps to my /public_html folder in my live website.

I exclude the WordPress Core, and all plugins (in this project) and any /twenty prefixed theme. If you want to then not ignore a path, you can start the line with a ! bang (exclamation point), but in this project I’m not needing this.

How to change code and deploy to your website

Once you have everything set up, you can simply make code changes in your theme locally, test in your browser running the code in the LocalWP site, and then commit to the Git repository. You can then push the branch to the origin remote which will trigger the Actions workflow. After the workflow completes, the pushed code will be on the website and you can refresh the live site to see the changes.

This is simply awesome (dawesome!) as you have historic log (Git) for your changes, automated deployment (Actions workflow), and a simple and clear pipeline to go from local code development to to live website functionality.

Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.