Automatic Deployment via good ol' FTP
Tags: actionshackathon, javascript, vue, git
Published: 2020-09-03 08:55:33

Since their release, GitHub actions are on my long-term todo list for increasing automation of my workflows. Thanks to [DEVs GitHub Actions Hackathon](https://dev.to/devteam/announcing-the-github-actions-hackathon-on-dev-3ljn), I'm finally tackling this topic.

I'm not really sure if it's a thing to be ashamed of today, but I'm still pushing build files of most of my personal open source projects manually via good ol' FTP to my server. Maybe I just don't wanted to give up too much control over the files that I push to production. Or after doing web development for more than 15 years now, I was just too lazy to change something 😅

However, I found an awesome GitHub action to publish files automatically via FTP to my server on build.

## My Workflow

It's the [FTP-Deploy-Action](https://github.com/SamKirkland/FTP-Deploy-Action) by Sam Kirkland which utilizes [Git-ftp](https://github.com/git-ftp/git-ftp). I'm mostly creating Vue.js applications with the Vue CLI - so my normal workflow always looked like this:

1. ➕ Make code changes (e.g. fixing an important security issue)
2. 🔨 Test code changes
3. ✅ Commit these changes to the repository
4. 🔁 Create new build files optimized for production using `vue-cli-service build`
5. ❌ Delete old build files from production server
6. ⏫ Upload new build files to production server

Especially the last two points always bothered me, because most of the time I was pushing some smaller changes that only affected a few files and I still deleted and reuploaded the whole application. And this is, where Git-ftp really pays off: <mark>It can upload only those files, that changed since the last upload!</mark> This is extremely useful, especially for projects with a lot of files. A few of my PHP projects e.g. use Git Submodules and uploading the whole project on each build would take an incredible amount of time. So my new workflow now looks like this:

1. ➕ Make code changes (e.g. fixing an important security issue)
2. 🔨 Test code changes
3. ✅ Commit these changes to the repository
4. 🔁 Create new build files optimized for production using `vue-cli-service build`
5. Lean back and let the GitHub FTP-Deploy-Action do the rest

## Submission Category

✅ DIY Deployments

## Configuration

[Note]: # (Our markdown editor supports pretty embeds. Try this syntax: `{% github link_to_your_repo %}` to share a GitHub repository)

So, how can you set up this FTP-Deploy-Action? You simply have to create a configuration file called `ftp-deploy.yaml` under `your-repo/.github/workflows/`. This is what my configuration looks like:

```yml
on:
  push:
    paths:
      - 'dist/*'
name: FTP Deploy
jobs:
  FTP-Deploy-Action:
    name: FTP-Deploy-Action
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2.1.0
      with:
        fetch-depth: 2
    - name: FTP-Deploy-Action
      uses: SamKirkland/FTP-Deploy-Action@master
      with:
        ftp-server: ${{ secrets.ftp_server }}
        ftp-username: ${{ secrets.ftp_username }}
        ftp-password: ${{ secrets.ftp_password }}
        local-dir: dist/
```

I'm going to explain every part in the following for you to understand, how this works 💡

<table><tr><th>Lines</th><th>Explanation</th></tr>
<tr><td>1—4</td><td><code>on: push: paths:</code><br />Only start this action, when changes where pushed to the `dist/` directory (this is the default build folder for Vue CLI)</td></tr>
<tr><td>5</td><td><code>name:</code><br />The name of your GitHub action which is shown in the repositories action tab on GitHub.</td></tr>
<tr><td>6—15</td><td><code>jobs: FTP-Deploy-Action: ...</code><br />This is the default configuration for this action, accourding to <a href="https://github.com/SamKirkland/FTP-Deploy-Action/blob/master/README.md" target="_blank">its documentation</a>.</td></tr>
<tr><td>16</td><td><code>with:</code><br />This section allows for further required or optional configuration of the action.</td></tr>
<tr><td>17—19</td><td><code>ftp-server: | ftp-username: | ftp-password:</code><br />Obviously GitHub needs to know your FTP access data like server url, username and password. Even more obviously, you don't want to store these data in this configuration file rather than as <a href="https://docs.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets" target="_blank">encrypted secrets</a>. The port number is appended to the url, if you need it. Also you can specify the security protocol (see security hint below), e.g.:<br><code>ftps://your.ftp-server.com:21</code></td></tr>
<tr><td>20</td><td><code>local-dir:</code><br />This makes sure, that not the whole repository, but only (in my case) the `dist/` directory gets uploaded, where my build files live.</td></tr>
</table>

**Bonus**: If you want to explicitly exclude some files from being uploaded, you can create a `.git-ftp-ignore` file in the root of your repository, which works the same way as a `.gitignore` file.

## Additional Resources / Info

Here are the repositories of the GitHub action and `git-ftp`:

{% github SamKirkland/FTP-Deploy-Action no-readme %}
{% github git-ftp/git-ftp no-readme %}

## Security hint

FTP itself transfers files unencrypted. Therefore it's highly recommended to use FTPS (FTP with TLS) or SFTP (SSH file transfer), which are both supported by `git-ftp`. Thanks to @lampewebdev for his comment on this topic.

## Wrap it up

So we saw that it's fairly simple to let GitHub deploy you build files automatically via FTP. You just need to create one configuration file and set a few repository secrets.

Let me know, if you also deploy via FTP and this is useful for your own workflows.

---

*Edited: 4th September 2020 (add server url example and security hint)*
*Published: 3rd September 2020*
*Title image: https://codepen.io/devmount/full/qBZPpEM*