GithubのActionsでRsyncを利用したデプロイ

# 前提条件
* 簡単なPhpやHtmlで構成されたプロジェクト
* composerを利用してないプロジェクト
* Rsyncが利用出来るサーバー

# やりたいの
* Rsyncでgitのソースをサーバーにアップ
* ソースのデプロイした後に簡単にサーバーでコンマンドを実行
* Staging・本番環境の関係なくデプロイはbranchのpushで自動デプロイ

# 環境周りの設定
利用するレポジトリの「Settings > Secrets」に入って、サーバーへ接続情報を登録します。
![img4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489182/985f945b-9905-88e9-0261-591d83853b2b.png)

## SSH用の鍵を登録
* Name：SSH_PRIVATE_KEY
* Value：ローカルのDeployerで使用している鍵（.pubでない方）の中身をコピーして入れる

## SSH用のユーザー名を登録
* Name：SSH_USERNAME
* Value：ログインID

## SSH用のHostを登録
* Name：SSH_HOSTNAME
* Value：サーバーIDかドメイン

# Actionsのworkflowを作成
対象リポジトリの「Actions」に入って新しくTempleteを利用して作成しても良いです。

## トリガーの部分
要求内容にも書いてますが、簡単なプロジェクトを想定しているのでStaging・本番環境の関係なくデプロイはbranchのpushで自動デプロイします。

```
name: deploy dev

on:
  push:
    branches:
      - deploy/*
```
もし本番を手動でしたい場合は「[GithubのActionsでLaravelのデプロイ](https://qiita.com/FattyRabbit/items/17a91f249ea088222db5)」をご参考してください。

## 環境変数の定義の部分

```
二つのブランチ（Staging、Production）についての変数を設定します。

  steps:
      - uses: actions/checkout@v2
      - name: Set staging env
        if: github.ref == 'refs/heads/deploy/staging'
        run: |
          echo ::set-env name=RSYNC_SOURCE::/
          echo ::set-env name=RSYNC_TARGET::Staging用のDirecotry

      - name: Set production env
        if: github.ref == 'refs/heads/deploy/pro'
        run: |
          echo ::set-env name=RSYNC_SOURCE::/
          echo ::set-env name=RSYNC_TARGET::本番用のDirecotry
```

## Rsyncでソースのアップ
今回は「[trendyminds/github-actions-rsync](https://github.com/jaredpalmer/github-actions-rsync)」を利用しますが、「ubuntu-latest」を利用するので直接に書いても大丈夫です。

```
      - name: Deploy by rsync
        uses: trendyminds/github-actions-rsync@master
        with:
          RSYNC_OPTIONS: -avzr --delete --exclude-from=.rsyncignore
          RSYNC_TARGET: $RSYNC_TARGET
          RSYNC_SOURCE: $RSYNC_SOURCE
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
          SSH_HOSTNAME: ${{ secrets.SSH_HOSTNAME }}
```
「.rsyncignore」のファイルで対象外のファイルを定義して利用しています。

## SSH接続情報の設定の部分
速度の改善するためにCacheをする方法を入れました。情報の設定はCacheがない場合のみに作成する感じです。

```
      - name: Cache ssh config
        id: cache-ssh-config
        uses: actions/cache@v1
        with:
          path: /home/runner/.ssh
          key: ${{ runner.os }}-ssh-config-${{ hashFiles('/home/runner/.ssh/private-key-for-deploy') }}
          restore-keys: |
            ${{ runner.os }}-ssh-config-

      - name: Make ssh config
        if: steps.cache-ssh-config.outputs.cache-hit != 'true'
        run: |
          mkdir -p /home/runner/.ssh
          touch /home/runner/.ssh/private-key-for-deploy
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > /home/runner/.ssh/private-key-for-deploy
          chmod 600 /home/runner/.ssh/private-key-for-deploy
          ssh-keyscan ${{ secrets.SSH_HOSTNAME }} >> ~/.ssh/known_hosts
```

## SSHを利用してサーバーでコマンドを実行
こちらについては「[appleboy/ssh-action](https://github.com/marketplace/actions/ssh-remote-commands)」を使うかと思いましたが、Actionsの環境変数をscript設定に反映するのが上手く行かなかったので直接書くことにしました。

上手く行かなかった定義です。

```
      - name: Multiple command
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOSTNAME }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          envs: RSYNC_TARGET
          script_stop: false
          script: |
            cd $RSYNC_TARGET
            ls -al
```
こちらが直接書いた内容です。

```
      - name: Make shell
        run: |
          touch ./ssh-script.sh
          echo "cd $RSYNC_TARGET" >> ssh-script.sh
          echo "ls -al" >> ssh-script.sh
          cat ssh-script.sh

      - name: Excute shell
        run: |
          ssh -i ~/.ssh/private-key-for-deploy ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOSTNAME }} 'bash -s' < ./ssh-script.sh
```

# 完成された定義
```
name: deploy dev

on:
  push:
    branches:
      - deploy/*

jobs:

  deploy:
    name: deploy
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set staging env
        if: github.ref == 'refs/heads/deploy/staging'
        run: |
          echo ::set-env name=RSYNC_SOURCE::/
          echo ::set-env name=RSYNC_TARGET::Staging用のDirectory

      - name: Set production env
        if: github.ref == 'refs/heads/deploy/pro'
        run: |
          echo ::set-env name=RSYNC_SOURCE::/
          echo ::set-env name=RSYNC_TARGET::本番用のDirectory

      - name: Deploy by rsync
        uses: trendyminds/github-actions-rsync@master
        with:
          RSYNC_OPTIONS: -avzr --delete --exclude-from=.rsyncignore
          RSYNC_TARGET: $RSYNC_TARGET
          RSYNC_SOURCE: $RSYNC_SOURCE
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
          SSH_HOSTNAME: ${{ secrets.SSH_HOSTNAME }}

      - name: Cache ssh config
        id: cache-ssh-config
        uses: actions/cache@v1
        with:
          path: /home/runner/.ssh
          key: ${{ runner.os }}-ssh-config-${{ hashFiles('/home/runner/.ssh/private-key-for-deploy') }}
          restore-keys: |
            ${{ runner.os }}-ssh-config-

      - name: Make ssh config
        if: steps.cache-ssh-config.outputs.cache-hit != 'true'
        run: |
          mkdir -p /home/runner/.ssh
          touch /home/runner/.ssh/private-key-for-deploy
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > /home/runner/.ssh/private-key-for-deploy
          chmod 600 /home/runner/.ssh/private-key-for-deploy
          ssh-keyscan ${{ secrets.SSH_HOSTNAME }} >> ~/.ssh/known_hosts

      - name: Make shell
        run: |
          touch ./ssh-script.sh
          echo "cd $RSYNC_TARGET" >> ssh-script.sh
          echo "ls -al" >> ssh-script.sh
          cat ssh-script.sh

      - name: Excute shell
        run: |
          ssh -i ~/.ssh/private-key-for-deploy ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOSTNAME }} 'bash -s' < ./ssh-script.sh
```

同じ記事：https://fatty-rabbit.tistory.com/13