GitHub Actions を用いてFTPサーバーへ自動Deployする方法

# 概要

現時点2022-05-08で、GitHub ActionsでFTPサーバーへのアップロードを自動化する手順を記載する。

目的は以下の2つ。

- GitHub Actionsを試してみる（初めて触れてみる）
- 公開サーバーへの静的ファイルのFTPアップロードを、プルリクエストをトリガーとして自動実行する
    - 過去の経緯が背景で、静的WebサイトはFTPでのアップロードを実施しており、今回はこの方式を「変更しない」ものとする

利用するGitHub Actionsライブラリは以下。

- SamKirkland/FTP-Deploy-Action
    - https://github.com/SamKirkland/FTP-Deploy-Action

# 設定手順

GitHub Actionsを実行するトリガーは、次を設定するものとする。

- main ブランチにpushされた場合
    - main ブランチにpull requestがマージされた場合、がここに含まれる（pull requestが作成されたタイミング、は含まない）
- GitHub Actions のworkflow画面から「`Run workflow`」ボタンが押された場合
    - Manually running a workflow
        - https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow


## 0. 必要なモノ

- FTPサーバーへのログイン情報
    - FTPサーバーアドレス
    - ログインユーザー名
    - ログインパスワード

- FTPサーバー側の格納先フォルダパス
    - 例：「`/www/static-webapp/app-name`」など

- GitHub側のアップロード対象フォルダパス
    - 例：「`./public/`」など
    - ※これを指定しない場合は、対象のGitHubリポジトリのルートからすべてがアップロード対象となる、ので注意。


## 1. FTPサーバー側の設定（さくらサーバーの場合）

さくらサーバーでは、デフォルトで「海外IPからのログイン規制：有効」なので、これを解除しておく必要がある。
この設定が無いサーバーの場合は、本節での前準備は不要。

1. さくらのレンタルサーバーへログイン
1. セキュリティ＞国外IPアドレスフィルター＞国外IPアドレスからのアクセス制限
    - 「有効（制限する）」→「無効（制限しない）」へ変更
    - 「保存する」を押下

## 2. Github側の設定

### 2-1. Secrets を設定（パスワードなど、直書きしたくない値を環境変数として設定）

1. GitHub > Setting > Secrets > Actions > New repository sercet
1. 「Add secret」ボタンを押下
1. 以下の「キー」を追加し、それぞれの値を設定する（※キー名称は変更可能だが、その場合は後述のyamlファイル記載も合わせて変更の事）
    - `FTP_SERVER`
        - FTPサーバーアドレス
    - `FTP_USERNAME`
        - FTPログインユーザー名
    - `FTP_PASSWORD`
        - FTPログインパスワード
    - `FTP_SERVER_DIR`
        - FTPサーバー側の格納先フォルダパス
        - 例：「`~/www/static-webapp/app-name/`」
            - 最後を「`/`」で終えること。理由は以下を参照
            - https://github.com/SamKirkland/FTP-Deploy-Action#settings
                - server-dir
                - `Folder to upload to (on the server), must end with trailing slash /`

### 2-2. GitHub Actoinsを設定

1. GitHub > Actions
1. 「set up a workflow yourself」ボタンを押下
1. テンプレートとして以下が提示されるので、これを編集
    * テンプレート
        * `# This is a basic workflow to help you get started with Actions` で始まるサンプル
    * 具体的には、後述の「`main.yaml`」のように編集する
        * 冒頭の「`name`」は任意の名称に変更
            * `GitHub > Actions > Workflows > All Workflows` 配下に表示される名称になる
        * 「`on`」配下から「`pull_request`」を削除
            * pullリクエストがマージされた時（＝pushされた時）のみ、実行するように変更
            * テンプレートでは「`build`」なので、pullリクエストも対象としている様子
        * 「`jobs`」配下のキー名称を任意に変更
            * 変えなくても良いが、デフォルトでは「`build`」なので変更したほうが分かり易い。今回の例では「`ftp-deploy`」としている
            * [SamKirkland/FTP-Deploy-Action](https://github.com/SamKirkland/FTP-Deploy-Action) のサンプルコードでは「`web-deploy`」に変更している
        * 「`steps`」配下のコメント「`Runs a single command using the runners shell`」とある行以降を、変更
            * ここで、GitHub側のアップロード対象は「`./public`」フォルダ配下に限定している
                * 最後を「`/`」で終えているのは、利用ライブラリの仕様
                    - https://github.com/SamKirkland/FTP-Deploy-Action#settings
                    - local-dir
                    - `Folder to upload from, must end with trailing slash /`


4. 「Start commit」ボタンを押下
    * コミットのタイトルとコメントは任意に入力
    * 「Commit new file」ボタンを押して登録
![mainブランチに対してコミットする](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125588/e2ca7315-9736-8d9c-08d0-0215546428fe.png)

1. 「View to runs」を押下
    * 初回コミット後、先ずはワンパスが実行され、その実行状況を確認できる
![実行中の画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125588/bfd478ca-7142-de57-b124-5865501f4c4c.png)
![初回実行が完了後の画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125588/35958137-3f54-329c-2cdf-7c5a27aad55d.png)

```main.yaml
name: FTP for XXXXXX to sakura

# Controls when the workflow will run
on:
  # Triggers the workflow on push but only for the main branch
  push:
    branches: [ main ]

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

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "ftp-deploy". The default job name is "build".
  ftp-deploy:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      # Runs a single command using the runners shell
      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@4.3.0
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          server-dir: ${{ secrets.FTP_SERVER_DIR }}
          local-dir: ./public/
```

#### (補足)設定済みのGitHub Actionsの参照方法

登録したワークフローファイルは、「View workflow file」ボタンから参照できる。
![ワークフローファイルの参照方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125588/6faa3e50-645a-6ee8-3d9a-0daab46c4f75.png)

参照先で、編集ボタン（鉛筆アイコン）から修正が可能。
![参照画面から編集が可能](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125588/601d9ccf-b50d-6d64-70be-5c827424881d.png)


## 3. FTPサーバーへログインして、期待した通りにアップロードされていることを確認

1. FTPへログインして、アップロードされたファイルを確認
1. （さくらサーバーの場合）コントロールパネルへログインして、サーバーへのログイン状況を確認
    * さくらのレンタルサーバー＞セキュリティ＞サーバーログイン履歴
    * 「アドレス」を見ると、自身のログイン（FTP or コントロールパネル）以外のログイン元IPがあるはず
        * 参考までに、この「自身以外のログインIPアドレス」の所属国名をnslookup等で確認すると、私の実行時は「`US`」と表示された
            * これが、冒頭で「国外IP制限：無効」とする必要がある理由
        * もちろん、自身のログインIPアドレスは「`JP`」表示される

以上ー。

# その他：GitHubのブラウザUIから手動実行する方法

本設定例では、実行トリガーとして「`workflow_dispatch`」を設定しているので、GitHubのブラウザUIの「Run workflow」ボタンから即時実行が可能。

![ワークフローを選択してRun workflowから実行できる](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125588/227e254b-c160-510b-ad5c-c84730fbb167.png)


# 参考サイト

- github actionsを用いたFTP自動デプロイ。（例：さくらサーバー）
    - https://zenn.dev/hirof1990/articles/2f8eeab56b8637
- GitHub Actionsを使ってFTP自動デプロイ（Webサイト公開）を実現！ソフトを使った手動アップロードを卒業する
    - https://arrown-blog.com/githubactions-ftp-deploy/
- GitHub - SamKirkland_FTP-Deploy-Action
    - https://github.com/SamKirkland/FTP-Deploy-Action
- Quickstart for GitHub Actions 
    - https://docs.github.com/en/actions/quickstart#creating-your-first-workflow