共用サーバではFTPアップロードが一般的です。
ここで使う Github Action は https://github.com/marketplace/actions/ftp-deploy です
Github Actions用のFTPアカウントを作成します
複数のFTPアカウントを作成できるなら、develop環境用のFTPアカウント、production環境用のFTPアカウントをそれぞれ作成します。
develop環境用のFTPアカウント
項目 | 値 |
---|---|
ユーザー名 | ci_dev_mysite |
ホスト名 | ftp.example.jp |
ログインフォルダ | /home/users/12345/example/web/dev.example.jp |
production環境用のFTPアカウント
項目 | 値 |
---|---|
ユーザー名 | ci_prd_mysite |
ホスト名 | ftp.example.jp |
ログインフォルダ | /home/users/12345/example/web/prd.example.jp |
以下、develop環境用のFTPアカウントで説明します。
Github Actionsコンテナ内ディレクトリ、共用サーバ内ディレクトリ、URLの関係
(デプロイ元)Github Actionsコンテナ内ディレクトリ | (デプロイ先)共用サーバ内ディレクトリ | URL |
---|---|---|
./build/develop/secrets/.htpasswd | /home/users/12345/example/web/dev.example.jp/secrets/.htpasswd | アクセス不可 |
./build/develop/web/index.html | /home/users/12345/example/web/dev.example.jp/web/index.html | https://dev.example.jp/index.html |
.github/workflows/ の yaml に記述します
略(git push で実行するように設定しています)
# ----------------------------------------
# FTPアップロード
# ----------------------------------------
- name: developデプロイ
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
server: ${{ vars.DEV_FTP_HOST }}
username: ${{ vars.DEV_FTP_USER }}
password: ${{ secrets.DEV_FTP_PASS }}
protocol: ${{ vars.DEV_FTP_PROTOCOL }}
dry-run: ${{ vars.DEV_FTP_DRY_RUN }}
local-dir: ./build/develop/
server-dir: ./
Code language: PHP (php)
Github ActionsのSettingsで環境変数を設定します
ここでは Repository secrets、Repository variablesを使います。もちろん Environments secrets、Environments variablesを使うこともできます。
FTPパスワードはRepository secretsに保存します。
その他の値はRepository variablesに保存したほうが値を確認できるので便利です。
Repository secrets
Secret name | value |
---|---|
DEV_FTP_PASS | ******** |
Repository variables
Variable name | value | メモ |
---|---|---|
DEV_FTP_DRY_RUN | true | Secrets の必要なし。true と false を切り替えるので、値を確認できる Variables がいい |
DEV_FTP_HOST | ftp.example.jp | ※1 |
DEV_FTP_PROTOCOL | ftps | Secrets の必要なし。値を確認できる Variables がいい |
DEV_FTP_USER | ci_dev_mysite | ※1 |
※1 当初、これらも Secrets に保存していました。しかし production用のPRD_FTP_HOST、PRD_FTP_USER と値を混同していないかを確認できません。また他サイトの DEV_FTP_HOST、DEV_FTP_USER と値を混同していないかを確認できません。保存作業のたびにスクショを保存するのも面倒なので、値を確認できる Variables に保存することにしました。
ドライラン
DEV_FTP_DRY_RUN=true で実行すると、FTP接続はしますが、ファイルアップロードはしません。
デプロイ元、デプロイ先のファイルを比較して、アップロード予定のファイル一覧が表示されます。
ファイル一覧を確認してください。

ドライラン、安心だよね
初回実行
DEV_FTP_DRY_RUN=false で実行します。
初回はデプロイ元の全ファイルがアップロードされます。

1400ファイルで20分以上かかったよ
デプロイ元 | デプロイ先 アップロード前 | デプロイ先 アップロード後 |
---|---|---|
index.html | index.html | index.html(更新されます) |
a.php | (なし) | a.php(新規アップロードされます) |
(なし) | b.php | b.php(残ります) |
初回のアップロードが完了すると、デプロイ先に .ftp-deploy-sync-state.json というファイルが保存されます。

毎回、全ファイルをアップロードするのかな?
2回目以降
2回目からは .ftp-deploy-sync-state.json とデプロイ元のファイルを比較して、新規ファイル、更新ファイル、削除ファイルだけをFTP処理するので、初回ほど時間はかからないはずです。

2回めからは数秒で終わったよ
デプロイ元 | デプロイ先 アップロード前 | デプロイ先 アップロード後 |
---|---|---|
index.html(変更なし) | index.html | index.html(アップロードしません) |
(a.phpを削除した) | a.php | (削除されます) |
(なし) | b.php | b.php(残ります) |
c.php | (なし) | c.php(新規アップロードされます) |

更新ファイルかどうかをどのように判別しているのかな、ファイル日時?ファイルサイズ?
.ftp-deploy-sync-state.json にはファイルパスとハッシュ値が記録されています。jsonに記録されているハッシュ値とデプロイ元ファイルのハッシュ値が同じなら、アップロードしない、ハッシュ値が違うなら更新されたと判断してアップロードしているようです。

ファイル日時やファイルサイズの比較より、ハッシュ値の比較のほうが確実でクールね