Setup Continuous Deployment with GitHub Actions (on a shared server) 4 (4)

Continuous Deployment with GitHub Actions

By on Tue Oct 26 in Continuous Delivery, FTP Deploy, GitHub Actions


Some time ago I had the need to implement a Continuous Deployment with Github Actions for a personal project. At the enterprise level, and working in a team, I used different services such as Team City. TeamCity is a CI/CD solution that allows maximum flexibility for all types of workflows and development practices.

Instead, working on my local machine, and as a solo developer, initially all I did was upload the changed files to the server, via FTP. Dinosaur style!

Some notes:

  • I use Docker for my local development because in this way I am able to replicate the same production environment;
  • Then Github allows me to track my changes made to the code, and work in isolation using feature branches;
  • To complete the picture, the personal project is based on Laravel 6, and is hosted on a shared server.

Production deployment with Github Actions

At some point, I always find it interesting to learn how to use new services. No matter how personal the project is, and as few as the changes are. Github Actions was what I needed because I was already using Github, and also because it’s a free tool.

The Actions help automate tasks such as deployment during the development lifecycle of your software. GitHub Actions are event-driven, which means that you can execute a series of commands after a specific event has occurred. For example, whenever someone creates a pull request for a repository, you can automatically run a test script. In the same way, as we are focused in this article, we can run an automatic deployment.

Let’s see now how to configure Github Actions.

How to configure Github Actions for automatic deployment via FTP

If you are in my situation, that is working a shared server, you can follow my configuration. You will result by configuring automatic deployment via FTP. That means that every time a Pull Request is approve, and the feature branch is merged with the master branch (or main branch), the deploy will start.

On the Github marketplace, in the Actions section, we can find a free tool for us: FTP Deploy. This tool is used to automate the deployment of websites and web apps.

We can say that there are two pre-requisites to meet:
– have FTP access to your server. If your server requires SSH access, then this is not the right tool for you;
– your project on Github must reflect the exact structure of the project on the server, so it’s not possible to use this configuration. If, for example, you have saved on Github also the Docker infrastructure with your project inside, your Docker will not exist on the server because you are working on a shared server.

The Workflows file

First of all, we need to create a new directory within our project, called .github, and within that, create another one called workflows. At this point we can create a new file called main.yml inside /.github/workflows/ and paste this code inside the newly created file:

# This is a basic workflow to help you get started with Actions

name: 🚀 Automatic YOUR-PROJECT Deploy on pull_request

      - master
      - main
    types: [closed]

  # Allows you to run this workflow manually from the Actions tab

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
    name: 🎉 Deploy
    runs-on: ubuntu-latest
    - name: 🚚 Get latest code
      uses: actions/checkout@v2

    - name: 📂 Sync files
      uses: SamKirkland/[email protected]
        server: YOUR-PROJECT-FTP-HOST
        password: ${{ secrets.FTP_PASSWORD }}
        server-dir: YOUR-PROJECT-FTP-DIRECTORY

Now, change all the placeholders with your personal values: YOUR-PROJECT, YOUR-PROJECT-FTP-HOST, YOUR-PROJECT-FTP-USERNAME, YOUR-PROJECT-FTP-DIRECTORY.

Then you have to add a key to the secrets section of your project. To add a secret password you must click on the Settings tab of the project and select the Secrets item, on the left menu. Then add a new secret string for the password by clicking on the top right “New repository secret”. Use FTP_PASSWORD as the name for the value, and digit the password of your FTP server in the text area corresponding to the value of our new secret string.

Save, and now add the new file /.github/workflows/main.yml – using git – and do a commit and push to save the new file to the remote repository:

git add .
git commit -m "Added github actions workflow"
git push

In this case, it is possible to work on the main branch, master or main.

First synchronization

At this point, let’s go back to our Github repository and click on the Actions tab. On the left, under “All workflows”, we should find our new workflow, and clicking on it will take us to the workflow summary page. We will be able to see how many times it has been executed (zero times for now).

For this first time let’s run it manually so that the workflow will synchronize the project. Two files will be created:

  • .ftp-deploy-sync-state.json
  • .gitattributes

The first is an index file that will tell the workflow which files are contained within your project and is used to keep track of which files have been synchronized in the most recent deployment. If you delete this file you will need to perform another synchronization.

In the second file, you save any and all information needed for the workflow.

If you have a WordPress project the first run will take a long time to finish, even up to an hour, because there are thousands of files in such a project.

Pull request and automatic deploy

Once the synchronization is finished, we can test our new Action to check our Continuous Deployment system with GitHub Actions.

Let’s create a new branch, called autodeploy:

git checkout -b autodeploy

Now let’s open the README file of the project, and add the following line to the bottom of the file:

Automatic YOUR-PROJECT deployed on pull_request with FTP Deploy and Github Action.

Replace the placeholder YOUR-PROJECT with the name of the project in question.

Then we can add the file to the repository by issuing a commit and push command:

git add .\readme.html
git commit -m "Readme updated"
git push --set-upstream origin autodeploy

Now let’s go to Github and create a pull request:

Setup continuous deployment - Github Actions compare and pull request
Setup continuous deployment – Github Actions compare and pull request

Once created, we can click on Merge pull request and Confirm merge to merge our feature branch autodeploy with the master (or main) branch. We can then click on Delete branch because we don’t need autodeploy anymore. You can also delete the branch locally, here are the commands to use in the terminal:

git checkout master
git pull
git branch -d autodeploy

We moved to the master branch, updated it with the latest changes due to the merge, and deleted the feature branch autodeploy locally.

Go back to our Github repository and click on the Actions tab, we’ll see that our workflows Readme updated has been executed as it has a green checkmark!

Setup continuous Deployment - Github actions workflow run successfully
Setup continuous deployment – Github actions workflow run successfully

We can check the Readme file, via browser or downloading via FTP, and see that the new line we inserted was added (automatically). The best part is that it was possible without our manual intervention of uploading the file via FTP.


Thanks to the implementation of this Continuous Deployment with GitHub Actions and FTP Deploy, from now on we we will be able to update our online project automatically.

Instead, after having made our changes locally, in isolation within a feature branch, we’ll just have to create a pull request and when it will be closed, the changes will be automatically uploaded to the server. Definitely a nice time saver.

If you found this article interesting, rate it by clicking on the stars. Do the same if, even better, it helped you with your workflow! If you have any doubts or questions, drop me a message by the contact form.

Good work!