GitHubActionsでWebサイトの更新を自動化

Webサイトへ更新するにあたり
・サーバーのコンパネでいちいち操作
・FTPツールの導入
が面倒くさいのでプッシュで簡単にデプロイ出来るよう設定。
自分が欲しい機能や理想を模索して、ようやく上手く出来たので備忘録として残す。

#### この記事で最終的に出来ること
・サーバー上に上がってるファイルとの同期(削除されたファイルも含め)
・特定のファイルやディレクトリをあげないようにする
　-下書きなどでGitHubで管理したいけどサーバーには上げたくない場合
・テスト環境と本環境で違う内容を管理したい
　-同じファイル名でdevelopブランチとmainブランチで異なる内容で管理
　-developブランチの特定のファイルやディレクトリをmainブランチにマージしない

#### 備考
「GitHubActionsでFTPデプロイ」で調べるとほぼ必ず「SamKirkland/FTP-Deploy-Action」の使用が出てくる。
しかし調べ方が悪いのか軒並み過去バージョンばかりで記述方法がバラバラ。
実装環境時が4.3.2だったので最新バージョン4.3.3(2022/12/27現在)ではないが、そこはご了承いただきたい。
またもっと良い書き方や管理方法があるかもしれないので、1つの方法としてみて頂ければ幸いだ。
(知識共有というより本当に備忘録感覚なので…はい…)


#### 今回の環境
・Windows
・SoueceTree
・サーバーは「コアサーバー」と「リトルサーバー」の2種類

# Actions secrets
先に暗号化設定をしておく。
リポジトリのSettings→Secrets→Actionsから設定できる。
「New repository secret」で以下の３つを設定
①Name:FTP_USERNAME　Secret：FTPアカウント名
　コア―サーバーならアカウント、リトルサーバーならFTPアカウントという名前のやつ
②Name:FTP_SERVER　Secret：FTPサーバー名
　コアサーバーならホスト、リトルサーバーならFTPサーバー
③Name:FTP_PASSWORD　Secret:FTPアカウントのパスワード
　コアサーバーならFTP用のパスワード、リトルサーバーなら自分で設定したやつ
尚、コアサーバーならコンパネ→サイト設定→該当サイトのFTP/SFTP接続情報から必要な情報が見れる。

# ymlの中身
ymlの名前は分かれば何でもいいと思う。デフォルトだとmain.yml。
自分の場合はテスト環境用と本環境用で分けているものもある。
```
on:
  push:
    branches:           
      - main    
name: FTP Deploy and Push
jobs:
  web-deploy:
      name: Deploy
      runs-on: ubuntu-latest
      steps:
      - name: Get latest code
        uses: actions/checkout@v2

      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@4.3.2
        with:                                        
          server: ${{ secrets.FTP_SERVER }}     
          username: ${{ secrets.FTP_USERNAME }} 
          password: ${{ secrets.FTP_PASSWORD }} 
          local-dir: ローカルディレクトリ
          server-dir: サーバーディレクトリ
          exclude: |
            **/.git*
            **/.git*/**
            **/node_modules/**
            **/test/**
            **/test-*/**
            **/test-*.html
```

いくつか簡易説明。

```
on:
  push:
    branches:           
      - main   
```
プッシュ時にmainブランチのものにActionsを走らせる。
別のブランチで走らせたいならmainの部分をそのブランチ名にする。

```
- name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@4.3.2
```
[SamKirkland/FTP-Deploy-Action](https://github.com/SamKirkland/FTP-Deploy-Action)を使用。
過去バージョンでは「アップロードしたファイルの削除は別途記述が必要」と完全同期ではなかった模様。今は「Sync files」で同期できる。
「@4.3.2」がバージョン。今後最新に変更する時はReadMeやIssueを読んで記述の変更が必要かどうか確認してから更新するといいのかも。

```
with:                                        
          server: ${{ secrets.FTP_SERVER }}     
          username: ${{ secrets.FTP_USERNAME }} 
          password: ${{ secrets.FTP_PASSWORD }} 
          local-dir: ローカルディレクトリ
          server-dir: サーバーディレクトリ
```
Secretで登録したキーをここで使う。一致しないと正常に動作しない。
「local-dir」は設定しなければroot以下が全て対象になる。
自分の場合
root/
├.git
├.github
└main/内容物
というファイル構成で、main以下のみをデプロイしたいので
```
          local-dir: ./main/
```
と記述している。
サーバーディレクトリはサーバーによるが、コア―サーバーなら「/public_html/ドメイン/」でリトルサーバーなら「/pub/ドメイン/」という記述になる。

```
exclude: 
            **/.git*
            **/.git*/**
            **/node_modules/**
            **/test/**
            **/test-*/**
            **/test-*.html
```
「GitHubで管理したいがサーバーにあげたくない」ものはここで記述。
ここで一番躓いた。[これ](https://github.com/SamKirkland/FTP-Deploy-Action/issues/202)を読んでやっと出来た。
上の3つ(`「**/.git*」「**/.git*/**」「**/node_modules/**」`がないと正常に動かない。Issueで「この３つは必要」って書いてあったのを読み落としていたので上手くいかなかったようだ。
4つ目以降にデプロイしたくないファイルやディレクトリを記述。
`**/test/**`はtestフォルダ以下全て。ワイルドカードを使用しているのでtestフォルダがどこにあっても複数あっても、そのフォルダ以下はデプロイしない。
`**/test-*/**`は「test-」から始まるフォルダとフォルダ以下全て。
`**/test-*.html`は「test-」から始まるhtml拡張子全て。拡張子の部分はワイルドカードにしたら他のもいけるのではなかろうか(試してないので分からんが)
「下書きはまだデプロイしたくない」というときとかにつかえる。
ファイル名をtest-からにするとか、下書き用フォルダ「test」を用意してそこにぶっこむとか。
自分の場合、htmlテンプレートと下書きを上げたくないのでテンプレートを格納しているフォルダと下書きのファイルをあげないようにしている。

### 注意
ブラウザ上のGitHubでymlを作った場合、ローカルで中身を編集するとプッシュの時にぶちギレられる(エラーを吐かれる)。
ymlを編集する時はGitHub上でのみにし、ローカルで弄らないのが安牌かな…。
ローカルで作った場合どうなるかはやってないので分からん。
【追記】GitHubで認証キーを作成し、SoueceTreeで設定すればローカルでも作成・編集できました。
参考：[GitHub Actionsの編集ができなくなったときの対応方法 (トークン認証の設定方法)](https://qiita.com/kter/items/84f3ece9a41a2bec535f)

# マージ除外
多分本当はもっといいやりかたあるんだろなとか思いながらやってるやつ。
テスト環境で問題なければ本環境にマージしたい。
しかし
・テスト環境でBASIC認証を導入していて本環境は導入していない
・上の都合で.htaccessはテスト環境と本環境で内容は異なり、.htpasswdは本環境にはいらない
・事情により特定のフォルダ以下を丸々マージに含めたくない
という状態。
.gitattributesで特定ファイルやフォルダをマージから除外出来ると知ったのでそのやり方でやった。難しいことはしてない。
参考：[git merge mergeしたくないファイルを除外する](https://fengdj521.hatenablog.com/entry/2015/12/16/122023)

①root直下に「.gitattributes」を作成
②「除外したいファイル =ours」と記載

以上。
```
main/.htaccess =ours
main/.htpasswd =ours
main/test/* =ours
main/test/** =ours
```
実際に書いたのはこんな感じ。構成は上記と似たような感じで
root/
├.git
├.github
├main/内容物
└.gitattributes
なのでパスはmainから書き始めている。
参考にしたサイトだとconfigもいじらないといけないらしいが、configに書かなくてもいけた…謎…。7年前だから流石に変わったのかな。
余談だけどVSCodeで作業してワークスペースを保存すると.vscodeフォルダもGit管理に含まれてしまうので、ワークスペースで保存しないか.gitignoreを用意したほうが良いなと思った。保存しない方向でいまはやってるけど。

# おまけ
更新やActionsの動作確認の通知がほしいと思って、[Actions Status Discord](https://github.com/sarisia/actions-status-discord)というDiscordに通知をくれるやつも導入してみた。

①通知をもらうDiscordサーバーのサーバー設定から連携サービス→ウェブフックを作る。名前決めたり通知してほしいチャンネルを設定したりして、「ウェブフックURLをコピー」でコピーしておく。
②Actions scretsにName:DISCORD_WEBHOOKでscretsに先程コピーしたURLを貼る。
③先程のymlに追記。
```
- name: Push Call Discord
        uses: sarisia/actions-status-discord@v1
        if: always()
        env:
          DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
        with:
         title: "タイトル"
         description: "共通説明"
```
with以下に追記した内容次第でDiscordに来る通知の内容を変えられる。詳細はReadMeに書かれているので参照されたし。

最終的なmain.ymlはこちら
```
on:
  push:
    branches:           
      - main    
name: FTP Deploy and Push Discord
jobs:
  web-deploy:
      name: Deploy
      runs-on: ubuntu-latest
      steps:
      - name: Get latest code
        uses: actions/checkout@v2

      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@4.3.2
        with:                                        
          server: ${{ secrets.FTP_SERVER }}     
          username: ${{ secrets.FTP_USERNAME }} 
          password: ${{ secrets.FTP_PASSWORD }} 
          local-dir: ローカルディレクトリ
          server-dir: サーバーディレクトリ
              
      - name: Push Call Discord
        uses: sarisia/actions-status-discord@v1
        if: always()
        env:
          DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
        with:
         title: "タイトル"
         description: "簡易説明"
```


# 終わり
趣味の個人サイトを作るとなったときにGitHub使う人がどのくらいいるんだろう…とか思いながらまとめてみた。
これでもし今後また個人サイト増やす時にこのあたり分からなくなっても大丈夫なはず。わーいやったね！