手動FTPデプロイ〜手動Slack通知をGithubActionsで少しいい感じにする

## デプロイフローをいい感じにしたい！

現在携わっているプロジェクトのフロントリポジトリの運用がほぼ手動なので、GithubActionsを使ってデプロイフローをいい感じにしたいです。
この記事はそのGithubActionsに入門しつつ試行錯誤しながら実装する過程のメモです。

### ブランチと環境

プロジェクトは新規開発で１人開発な0->1なプロジェクトを途中で引き継いだものになります。
引き継いだ段階で環境、ブランチ、それぞれ一つしかなかったため、とりあえずこちらの記事など参考にしながらブランチとリリース戦略について考えてみました。


https://techblog.insightedge.jp/entry/branch-strategy-github-flow

#### ブランチ

GitHub Flowの方がシンプルで管理しやすそうでしたが、検証環境のバージョン管理ができないのは不安なため、Github上で以下３つのブランチを切って管理するようにしました。
言い訳を追記すると、テストちゃんと書ければGithub Flowでも綺麗に運用できそうですが、現状私にテスト書くスキルと時間的な余裕がないため検証環境ブランチはあったほうが安心ということになりました。。

- Devブランチ
- Stgブランチ
- Prodブランチ

#### 環境

Nuxt.jsでフロントエンド部分を開発しており、静的ファイルを生成し、これをさくらのレンタルサーバー上にアップロード（デプロイ）します。環境として３つ作ってありますが、これは簡易的にディレクトリを区切っているだけのものになります。

- Dev環境
- Stg環境
- Prod環境

現在は手動で静的ファイルを生成し、FTPで手動アップロードをしているためGithubActionsでこの辺は自動化したい。

## こんな風にしたい！

リポジトリへのpush・mergeでデプロイ〜通知が自動で実行されるようにしたいです。
イメージとして以下のような感じ...

![](https://storage.googleapis.com/zenn-user-upload/8b11310bb6b9-20240214.png)

とりあえずステップバイステップにやってみましょう。

## GithubのDevブランチにpushされたらさくらにデプロイされてSlackに通知がいくようなGithubActionsの設定をしてみる

### GithubActionsの概要

GithubActionsの設定のためにはプロジェクトの中にに.github/workflowディレクトリを作成し、その中にyamlの設定ファイルを書いていきます。設定項目はGithubのワークフローファイルを理解するセクションが非常にわかりやすかった。

平たくまとめると、`on:`でトリガーイベントを設定し、`jobs:`で処理のグループ化、`steps:`で行いたい処理を、`run:`に実行したいコマンドを記述したり、よくある複雑なタスクや処理をパッケージ化したactionsなどで設定していく感じっぽいです。

https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions#%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B

以下よりGithubのDevブランチにpushされたらさくらにのDev環境にデプロイまでに必要な項目などをメモしていきます。

### devブランチにpushされた時

```yaml
on:
  push:
    branches:
      - dev
```

**push**

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#push

### job設定

```yaml
jobs:
  build-and-deploy:                      // job名の設定
    runs-on: ubuntu-latest　　　// 実行環境の設定
```

https://docs.github.com/ja/actions/using-jobs/using-jobs-in-a-workflow

https://docs.github.com/ja/actions/using-jobs/choosing-the-runner-for-a-job

### steps

stepsに実行する処理を記述していきます。

####  リポジトリのチェックアウト

```yaml
    steps:
      - name: Checkout
        uses: actions/checkout@v4
```

平たくいうとGithubActionsの作業ディレクトリへ対象のリポジトリをコピーします。

https://github.com/marketplace/actions/checkout

具体的にどんなことが実行されているかは下記記事を参照...

https://qiita.com/shun198/items/14cdba2d8e58ab96cf95#actionscheckoutv4%E3%81%A3%E3%81%A6%E4%BD%95%E3%81%97%E3%81%A6%E3%82%8B%E3%81%AE

#### Node環境の設定

今回作成したアプリがNuxt.jsによるものなので、Nuxt用にNode.jsの環境設定する必要があります。actionsのこちらを利用します。

```yaml
      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '20' 
```

https://github.com/marketplace/actions/setup-node-js-environment

#### ビルド

こんな感じでdev環境用に環境変数設定ファイルを指定したコマンドを作っているので、stepの中でこちらを実行します。

```json:package.json
  "scripts": {
    "gendev": "nuxt generate --dotenv .env.dev",          // こんな感じで
     ...
```

パッケージのインストールもします。

```yaml
      - name: Install Dependencies
        run: npm install
      - name: Generate Static Files
        run: npm run gendev
```

#### さくらへのFTPアップロード

こちらもいい感じのactionsがあったのでこちらを利用させてもらう。

https://github.com/marketplace/actions/ftp-deploy

直書きしたくない値ははシークレット登録しておき、環境変数として読み込んで設定する。

![](https://storage.googleapis.com/zenn-user-upload/b6584f4fbd4c-20240215.png)

今回のプロジェクトだと必要な項目はこんな感じに。

```yaml
      - name: Upload to Sakura Rental Server
        uses: SamKirkland/FTP-Deploy-Action@v4.3.4
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          local-dir: .output/public/
          server-dir: /piyopiyo/
```

https://qiita.com/hoshimado/items/e2073b7a6d40a23cfb55

#### slackへ通知

slack通知も良さげなactionsがあったのでこちらを利用。
https://github.com/marketplace/actions/slack-notify

slackへの通知のためにはslackの通知したいチャンネルのwebhook URLを設定する必要があるが、それはこちら🔽から取得できる。

https://slack.com/apps/A0F7XDUAZ?tab=more_info

```yaml
      - name: Notify to Slack
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_WEBHOOK: ${{ secrets.FRONTEND_CH_SLACK_WEBHOOK_URL }}
          SLACK_USERNAME: 'フロントエンド環境デプロイ通知'
          SLACK_TITLE: 'Dev環境にデプロイが完了しました🚀'
          SLACK_MESSAGE: |
            ${{ github.event.head_commit.message }}
            <@user_id>
```

上記の設定でこんな感じになります。

![](https://storage.googleapis.com/zenn-user-upload/5aea48a06e07-20240219.png)

ちなみにSlackのIncoming Webhooksのメッセージでメンション飛ばしたい時は`<@user_id>`こんな感じで書く必要がある。

https://qiita.com/ryo-yamaoka/items/7677ee4486cf395ce9bc

あとメッセージの中に改行やスペースを入れたい場合は`SLACK_MESSAGE: |`のようにパイプを使用する必要がある。
パイプ|を使用すると、YAML内で複数行にわたるテキストをそのままの形式で保持することができて、パイプがない場合は、文字列は一行として扱われるらしい...

https://zenn.dev/vcook/articles/1df885f899ff88


### Devブランチ〜環境デプロイ自動化まとめ

こんな感じになりました。

```yaml
name: Deploy to Dev Environment

on:
  push:
    branches:
      - dev

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '20'

      - name: Install Dependencies
        run: npm install

      - name: Generate Static Files
        run: npm run gendev

      - name: Upload to Sakura Rental Server
        uses: SamKirkland/FTP-Deploy-Action@v4.3.4
        with:
          server: ${{ secrets.FTP_SERVER }}
          username: ${{ secrets.FTP_USERNAME }}
          password: ${{ secrets.FTP_PASSWORD }}
          local-dir: .output/public/
          server-dir: /piyopiyo/

      - name: Notify to Slack
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_WEBHOOK: ${{ secrets.FRONTEND_CH_SLACK_WEBHOOK_URL }}
          SLACK_USERNAME: 'フロントエンド環境デプロイ通知'
          SLACK_TITLE: 'Dev環境にデプロイが完了しました🚀'
          SLACK_MESSAGE: |
            ${{ github.event.head_commit.message }}
            <@user_id>
```
## Devのものを参考にStg・ProdブランチにmergeされたらさくらにデプロイされてSlackに通知がいくようなGithubActionsの設定をしてみる

Devのものとほとんど変わりませんが、発火条件となるイベントがpushではなくプルリクマージとなるのでその部分のメモ。
Stg環境にマージされたら〜なイベントは以下のように書きます。

```yaml
name: Deploy to Stg Environment

on:
  pull_request:
    types: [closed]
    branches:
      - stg

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    if: github.event.pull_request.merged == true
```

**pull_request**

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#pull_request


**pull request がマージされたときに pull_request ワークフローを実行する**

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#running-your-pull_request-workflow-when-a-pull-request-merges

本当はmergeのタイミングでリリースタグが自動採番されるようにしたかったが、実装がうまくできなかったので採番は手動で行い、releaseタグが発行されたらslackの通知が行くようにしました。。

以下は今回書いたサンプルyamlです。

https://github.com/pistachiyoda/githubactions_sample

図にまとめるとこうなります。


![スクリーンショット 2024-02-19 16.29.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241199/21701eac-fe29-5b1b-4302-4c3f3c0f3e26.png)

## まとめ

GithubActionsに入門しつつ、push,mergeベースのデプロイ,自動通知が実装されて運用上少し楽になったので当初の目的は達成できましたが、まだまだ改良したいポイントがあります。

- とりあえず引き継いだままFTPアップロードしてるけどLFTP,rsyncとかにした方がいい
- 重複してる処理はまとめたい
- リリースタグはやっぱり自動採番したい...etc

この辺はまた近々改良したいと思います！