Automate deploying websites and more with this GitHub action
Usage Example
Place the following in Your_Project/.github/workflows/main.yml
on: push
name: Publish Website
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@3.1.1
with:
ftp-server: ftp://ftp.samkirkland.com/
ftp-username: myFtpUserName
ftp-password: ${{ secrets.FTP_PASSWORD }}
Setup Steps
- Select the repository you want to add the action to
- Select the
Actions
tab - Select
Blank workflow file
orSet up a workflow yourself
, if you don't see these options manually create a yaml fileYour_Project/.github/workflows/main.yml
- Paste the example above into your yaml file and save
- Now you need to add a key to the
secrets
section in your project. To add asecret
go to theSettings
tab in your project then selectSecrets
. Add a newSecret
forftp-password
- Update your yaml file settings
Note: Only tracked files will be published by default. If you want to publish files that don't exist in github (example: files generated during the action run) you must add those files/folders to .git-ftp-include
Migrating from v2? See the migration guide
Settings
Keys can be added directly to your .yml config file or referenced from your project Secrets
storage.
To add a secret
go to the Settings
tab in your project then select Secrets
.
I recommend you store your ftp-password
as a secret.
Key Name | Required? | Example | Default | Description |
---|---|---|---|---|
ftp-server |
Yes | ftp://ftp.samkirkland.com/destinationPath/ | Deployment destination server & path. Formatted as protocol://domain.com:port/destinationPath/ protocol can be ftp , ftps , or sftp . Port is optional, when not specified it will default to 21 when using ftp, 22 when using sftp, and 990 when using ftps |
|
ftp-username |
Yes | username@samkirkland.com | FTP account username | |
ftp-password |
Yes | CrazyUniquePassword&%123 | FTP account password | |
local-dir |
No | deploy/ | ./ | Which local folder to deploy, path should be relative to the root and should include trailing slash. ./ is the root of the project |
git-ftp-args |
No | See git-ftp-args section below |
Custom git-ftp arguments, this field is passed through directly into the git-ftp script | |
known-hosts |
No | hostname ssh-rsa AAAAB3NzaC1y ... | The desired contents of your .ssh/known_hosts file. See known hosts setup |
git-ftp-args
Advanced options using Custom arguments, this field is passed through directly into the git-ftp script. See git-ftp's manual for all options. You can use as many arguments as you want, seperate them with a space
Below is an incomplete list of commonly used args:
Argument | Description |
---|---|
--dry-run |
Does not upload or delete anything, but tries to get the .git-ftp.log file from remote host |
--silent |
Be silent |
--all |
Transfer all files, even seemingly the same as the target site (default is differences only). Note: Only files committed to github are uploaded, if you'd like to upload files generated during the action run see .git-ftp-include |
--lock |
Locks remote files from being modified while a deployment is running |
--remote-root |
Specifies the remote root directory to deploy to. The remote path in the URL is ignored |
--key |
SSH private key file name for SFTP |
--branch |
Push a specific branch. I recommend creating a yaml action for each branch instead |
--pubkey |
SSH public key file name. Used with --key option |
--insecure |
Don't verify server's certificate |
--cacert <file> |
Use as CA certificate store. Useful when a server has a self-signed certificate |
Ignore specific files when deploying
Add patterns to .git-ftp-ignore
and all matching file names will be ignored. The patterns are interpreted as shell glob patterns.
Here are some glob pattern examples:
Ignore git related files:
.gitignore
*/.gitignore # ignore files in sub directories
*/.gitkeep
.git-ftp-ignore
.git-ftp-include
.gitlab-ci.yml
foobar.txt
Ignore a single file called foobar.txt
Ignore all files having extension .txt
*.txt
config
Ignore everything in a directory named config/*
Force upload specific files
The .git-ftp-include
file specifies intentionally untracked files to should upload. If you have a file that should always be uploaded, add a line beginning with !
followed by the file's name.
VERSION.txt
Always upload the file !VERSION.txt
build
Always upload the folder !build/
If you have a file that should be uploaded whenever a tracked file changes, add a line beginning with the untracked file's name followed by a colon and the tracked file's name.
Upload CSS file compiled from an SCSS file
css/style.css:scss/style.scss
If you have multiple source files, you can add multiple lines for each of them. Whenever one of the tracked files changes, the upload of the paired untracked file will be triggered.
css/style.css:scss/style.scss
css/style.css:scss/mixins.scss
If a local untracked file is deleted, any change of a paired tracked file will trigger the deletion of the remote file on the server.
All paths are usually relative to the Git working directory. When using the local-dir
option, paths of tracked files (right side of the colon) are relative to the set local-dir
.
# upload "html/style.css" triggered by html/style.scss
# with local-dir "html"
html/style.css:style.scss
If your source file is outside the local-dir
, prefix it with a / and define a path relative to the Git working directory.
local-dir
Uploading a file outside of # upload "dist/style.css" with local-dir "dist"
dist/style.css:/src/style.scss
It is also possible to upload whole directories. For example, if you use a package manager like composer, you can upload all vendor packages when the file composer.lock changes:
vendor/:composer.lock
But keep in mind that this will upload all files in the vendor folder, even those that are on the server already. And it will not delete files from that directory if local files are deleted.
Common Examples
Read more about the differences between these protocols https://www.sftp.net/sftp-vs-ftps
FTP (File Transfer Protocol)
ftp://ftp.samkirkland.com:21/mypath
FTP has existed since 1971, it's an ancient protocol with near universal support.
on: push
name: Publish Website
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@3.1.1
with:
ftp-server: ftp://ftp.samkirkland.com/
ftp-username: myFtpUserName
ftp-password: ${{ secrets.FTP_PASSWORD }}
FTPS (File Transfer Protocol over SSL)
ftps://ftp.samkirkland.com:21/mypath
Use the legacy FTP over a secure encrypted connection.
Notes about ftps:
- Most hosts don't offer FTPS, it's more common on windows/.net hosts and less common on linux hosting
- Most hosts don't have a correct certificate setup for ftp domains, even my host doesn't do it right. This means you'll likely have to add
--insecure
togit-ftp-args
on: push
name: Publish Website over FTPS
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@3.1.1
with:
ftp-server: ftps://ftp.samkirkland.com:21/
ftp-username: myFTPSUsername
ftp-password: ${{ secrets.FTPS_PASSWORD }}
git-ftp-args: --insecure # if your certificate is setup correctly this can be removed
SFTP (SSH File Transfer Protocol)
sftp://ftp.samkirkland.com:22/mypath
Similar in name to FTP but this protocol is entirely new and requires SSH access to the server.
Notes about SFTP:
- You CANNOT use a FTP account - they are not the same!
- You must have shell access to your server, please read you webhosts documentation
- You will need to create a SSH user to deploy over SFTP. Normally this is your cpanel or hosting providers username and password
- Most web hosts change the default port (21), check with your host for your port number
Known Hosts Setup
Windows
In powershell run ssh-keyscan -p <sshport> <hostname>
and copy the hash output
Example for samkirkland.com ssh-keyscan -p 7822 samkirkland.com
Linux, or OSX (using homebrew)
Install the OpenSSH packages and use ssh-keyscan <hostname>
and copy the hash output
Add the known-hosts
argument with your hosts hash
Example: knownhosts: ssh-rsa AAAAB3Nza...H1Q5Spw==
Note: If you receive a Connection refused
error, you must specify the ssh port to your host
on: push
name: Publish Website over SFTP
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@3.1.1
with:
ftp-server: sftp://ftp.samkirkland.com:7280/
ftp-username: mySFTPUsername
ftp-password: ${{ secrets.SFTP_PASSWORD }}
known-hosts: [samkirkland.com]:7822 ssh-rsa AAAA...5Spw==
# add the following line instead if your certificate is setup incorrectly
# git-ftp-args: --insecure
Build and Publish React/Angular/Vue Website
Make sure you have an npm script named 'build'. This config should work for most node built websites.
If you don't commit your
build
folder to github you MUST create a.git-ftp-include
file with the content!build/
so the folder is always uploaded!
on: push
name: Build and Publish Front End Framework Website
jobs:
FTP-Deploy-Action:
name: FTP-Deploy-Action
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.0
with:
fetch-depth: 2
- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: Build Project
run: |
npm install
npm run build --if-present
- name: List output files
run: ls
- name: FTP-Deploy-Action
uses: SamKirkland/FTP-Deploy-Action@3.1.1
with:
ftp-server: ftp://ftp.samkirkland.com/
ftp-username: myFTPUsername
ftp-password: ${{ secrets.FTP_PASSWORD }}
local-dir: build # This folder is NOT going to upload by default unless you add it to .git-ftp-include
Log only dry run: Use this mode for testing
Ouputs a list of files that will be created/modified to sync your source without making any actual changes
on: push
name: Publish Website Dry Run
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@3.1.1
with:
ftp-server: ftp://ftp.samkirkland.com/
ftp-username: myFTPUsername
ftp-password: ${{ secrets.FTP_PASSWORD }}
git-ftp-args: --dry-run
Want another example? Let me know by creating a github issue
FAQ
How to exclude .git files from the publish
See the .git-ftp-ignore
example section
All files are being uploaded instead of just different files
By default only different files are uploaded.
Verify you have with: fetch-depth: 2
in your actions/checkout@v2.1.0
step. The last 2 checkins are required in order to determine differences
If you've had multiple git commits without deploying, all files will be uploaded to get back in sync
Verify you don't have the --all
git-ftp-args flag set
How do I set a upload timeout?
github has a built-in timeout-minutes
option, see customized example below
on: push
name: Publish Website
jobs:
FTP-Deploy-Action:
name: FTP-Deploy-Action
runs-on: ubuntu-latest
timeout-minutes: 15 # time out after 15 minutes (default is 360 minutes)
steps:
....
Common Errors
Failed to upload files
- Fix 1: Verify your login credentials are correct, download a ftp client and test with the exact same host/username/password
- Fix 2: Remember if you are using SFTP or FTPS you cannot use a normal FTP account username/password. You must use a elevated account. Each host has a different process to setup a FTPS or SFTP account. Please contact your host for help.
- Fix 3: If you are using sftp or ftps you should add
git-ftp-args: --insecure
, most hosts setup certificates incorrectly :(
Can't access remote 'sftp://', exiting...
See "Failed to upload files" section above
Can't access remote 'ftps://', exiting...
See "Failed to upload files" section above
My files aren't uploading
V3+ uses github to determine when files have changes and only publish differences. This means files that aren't committed to github will not upload by default.
To change this behavior please see .git-ftp-ignore
documentation.
rm: Access failed: 553 Prohibited file name: ./.ftpquota
The .ftpquota
file is created by some FTP Servers and cannot be modified by the user
Add .ftpquota
to your .git-ftp-ignore
file
Error: SSL peer certificate or SSH remote key was not OK
Whitelist your host via the known-hosts
configuration option (see known hosts setup in SFTP) or add the --insecure
argument
Debugging locally
Instructions for debugging Windows
- Install docker
- Open powershell as Administrator
- Install act-cli by running
choco install act-cli
- Navigate to the repo folder
- Run
npm install
- this will install all dependencies to build this project - Run
npm build
- this will build the action javascript and watch/rebuild when files change - Run
npm run build-docker
- this will build the docker container (only needs to be done once) - Run
npm run run-docker
- this will spin up a local copy of the action defined in/debug/local-debug-deployment.yaml
. Update package.json to set any secret values
Instructions for debugging on Linux
- Install docker on a Debian-based distro you can run
sudo apt install docker docker.io
- Open the terminal
- Install act-cli
- Navigate to the repo folder
- Run
npm install
- this will install all dependencies to build this project - Run
npm build
- this will build the action javascript and watch/rebuild when files change - Run
npm run build-docker
- this will build the docker container (only needs to be done once) - Run
npm run run-docker
- this will spin up a local copy of the action defined in/debug/local-debug-deployment.yaml
. Update package.json to set any secret values