Nextプロジェクトをxserverに自動deployする

# はじめに
deployというのは「実行ファイルを実際のWebサーバー上に配置して、利用できる状態にすること」です。わかりやすく言えば、開発環境からテスト環境や本番環境に上げることを指します。サーバに作ったものをアップロードしよう！って感じですね。
普通にサーバにSSH接続して、ターミナル開いて、git cloneするという手動でdeployする方法もあるんですが、めんどいのでこれを自動化させようという話です。
この自動化においてはgithub actionsというツールを使用します。

参考サイト：[GitHub に Push するだけで、レンタルサーバーにサイト公開してみた](https://www.to-r.net/media/github-actions/)(2020-05-11)

このサイトの「Githubに秘密鍵を登録する」ってところからやっていきますね。SSHキーを準備するってところは上記サイトを見てください。
ちなみにサイトに書いてるXserverのサーバーパネルに入ってSSH設定を～ってのをやると、それまで登録していたチームメンバーのSSHキーが全削除されて誰もSSH接続できなくなります。まあ公開鍵登録・更新のところから登録済み公開鍵を表示を押してそこに自分の鍵を追加で書けばいいんですが、文字数制限があります。一人分以上はvscodeからやらないとだめです。

# 実際にやってみよう
1. GitHubのrepositoryのsettingに入り、Securityの中のSecrets and variablesの中のActionsを押してください。下のほうにあります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802679/f9b27b2b-17e7-03de-6639-c089c748b3f0.png)


2. ここのRepository secretsの"New repository secret"を押してください。
3. Nameを"SSH_PRIVATE_KEY"にして、SecretにSSHキーをコピペしてください。そしてAdd　secretを押しましょう。最後に改行あると思います。これがないとだめっぽいです
4. それではテスト環境用と本番環境用のbranchを用意しましょう。Codeタブのbranchのところを押してください
5. "New branch"を押して、masterをsourceとしたstagingを作り、stagingをsourceとしたproductionを作成してください。stagingはテスト環境。productionは本番環境です
5. 次にvscodeに戻りましょう。作成中のプロジェクトに戻ってください。プロジェクト直下に".github"というディレクトリを作成し、その中に"workflows"というディレクトリを作成してください。そしてその中にyamlファイルを作成していきます。github actions側が勝手にこれを判断して動かしてくれます。まずは、テスト環境へのdeployを考えましょう。staging.yamlを追加してください
```.github/workflows/staging.yaml
name: deploy to test

on:
  push:
    branches:
      - staging

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: build
        uses: actions/setup-node@v1
        with:
          node-version: '20.x'
      - run: npm install && npm run build
        env:
            ASSET_PREFIX: '/prod/[作成したいフォルダ]'
            NEXT_PUBLIC_BASE_URL: 'https://[テスト用ドメイン名]/prod/[作成したいフォルダ]/ 
      - name: ssh key generate
        run: echo "$SSH_PRIVATE_KEY" > key && chmod 600 key
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
      - name: rsync deploy
        run: |
          ssh -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p [ポート番号] [ユーザ名]@[ホスト名] 'rm -rf /home/[ユーザ名]/[ドメイン名]/public_html/prod/[作成したいフォルダ]/*'
          rsync -auzrv --delete --exclude .htaccess -e "ssh -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p [ポート番号]" --delete ./out/* [ユーザ名]@[ホスト名]:/home/[ユーザ名]/[ドメイン名]/public_html/prod/[作成したいフォルダ]/ --exclude .htaccess
```

ちなみにプルリクがmergeされたときやpushされたときも「on push」らしい。

一旦これをstage -> commit -> pushしてみてください。そして、masterからstagingにmergeしましょう。上のタブのPull requestsからNew pull requestを押してください。
そのまま"Confirm merge"まで進んでください。そして上のタブのActionsを押してください。そこでくるくる回るやつが緑のチェックに変わったら成功です。テスト環境のURLにアクセスしてみてください。

次に本番環境用です。さっきと同じことをするだけです。prod.yamlをstaging.yamlと同じところに作成してください。
```.github/workflows/prod.yaml
name: deploy to production

on:
  push:
    branches:
      - production

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: build
        uses: actions/setup-node@v1
        with:
          node-version: '20.x'
      - run: npm install && npm run build
        env:
            ASSET_PREFIX: '/[作成したいフォルダ]'
            NEXT_PUBLIC_BASE_URL: 'https://[本番用ドメイン名]/[作成したいフォルダ]/ 
      - name: ssh key generate
        run: echo "$SSH_PRIVATE_KEY" > key && chmod 600 key
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
      - name: rsync deploy
        run: |
          ssh -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p [ポート番号] [ユーザ名]@[ホスト名] 'rm -rf /home/[ユーザ名]/[ドメイン名]/public_html/prod/[作成したいフォルダ]/*'
          rsync -auzrv --delete --exclude .htaccess -e "ssh -i key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p [ポート番号]" --delete ./out/* [ユーザ名]@[ホスト名]:/home/[ユーザ名]/[ドメイン名]/public_html/prod/[作成したいフォルダ]/ --exclude .htaccess
```

これをpushしてmasterからstagingにmergeしてください。そのあとにstagingからproductionにmergeしましょう。
※絶対にdelete branchしないこと！

ここまでうまくいけば自動deployは終わりです。本番環境に試験的に上げたやつはサーバに入って削除しておきましょうね。