GitHub Actionsでsshコマンド経由でアプリをデプロイする。

hypnotoadで動いているアプリについて、GitHubからWebhook経由でデプロイしていたのですが、GitHub Actionsを導入するとWebhookを廃止できるので、Actionsに乗り換えました。

Before

  1. (開発マシン)リポジトリにpush
  2. (デプロイ先サーバ)webhookが動く
  3. (デプロイ先サーバ)更新されたリポジトリをwebhook経由でgit pull
  4. (デプロイ先サーバ)hook経由でhypnotoadにhot deploy

After

  1. (開発マシン)リポジトリにpush
  2. (GitHub)Actionsが動く
  3. (デプロイ先サーバ)更新されたリポジトリをActions経由でgit pull
  4. (デプロイ先サーバ)Actions経由でhypnotoadにhot deploy

どうやってActionsで実現するか

hot deployするのにデプロイ先サーバ上でhypnotoadコマンドを実行する必要があるため、Actionsで立ち上がったDockerコンテナから、ssh経由でhypnotoadコマンドを実行します。やりたいことは以下の記事と大体一緒です。
GitHub Actions で快適なデプロイを実現する(rsync・laravel) – 自主的20%るぅる

sshするのにわざわざechoしたりchmodすると、それだけでstepを消費して保守しづらくなるため、sshを使うためのActionsを導入します。使い方が直感的でわかりやすいため、以下の記事のActionsを使用しました。
GitHub ActionsでSSHを使う – Qiita
KNOWN_HOSTSはオプションですが、どのみちsshコマンド実行時にfingerprintの確認があったり中間者攻撃されたら困るしで、実質設定必須です。
私はsshのポート番号とユーザ名もSecretsに登録しています。

他にも色々なActionsがあるので、自分にあったものを探すか作るかするといいと思います。
GitHub Marketplace · Actions to improve your workflow

実際に書いたActions

on:
  push:
    branches:
      - master
name: Deploy to retrorocket.biz
jobs:
  publish:
    name: Deploy to retrorocket.biz
    runs-on: ubuntu-latest
    steps:
    - name: Install SSH key
      uses: shimataro/ssh-key-action@v1
      with:
        private-key: ${{ secrets.SSH_KEY }}
        public-key: ${{ secrets.SSH_KEY_PUBLIC }}
        known-hosts: ${{ secrets.KNOWN_HOSTS }}
    - name: Git pull
      run: ssh -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_USER }}@retrorocket.biz 'cd /アプリのディレクトリまでのパス; and git pull'
    - name: Hypnotoad hot deploy
      run: ssh -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_USER }}@retrorocket.biz '/usr/local/bin/hypnotoad /アプリまでのパス'

Secretsに登録した値は以下のようにWorkflowのログからも値が見えなくなるので、より安全にCI/CDが運用できます。

ssh -p *** ***@retrorocket.biz '/usr/local/bin/hypnotoad /アプリまでのパス'

おかげさまでWebhookを無くして運用ができるようになりました。今まではWebhookのスクリプト自体を別リポジトリでバージョン管理する必要があって嫌だったのと、Webhookを動作させるためのリソースが必要だったのですが、Actionsだとリポジトリに紐付けて管理ができるので素晴らしいですね。

以下の記事のように、「秘密鍵を扱うActionに第三者が作ったものを採用していいのか」という問題がありますが、その点はActionsに限らずすべてのOSSやソフトウェアに言えることなので、セキュリティと利便性を天秤にかけて運用すれば良いと思っています。
Github Actions でハマった点と解決方法 – kawasin73のブログ

どうでもいいけどSyntaxHighlighter Evolved、yml対応してないんですね…これ書いたらymlのbrush追加しておきます。 追加しました。

追記(2020/01/21)

コメントを頂いて改善できそうだったため改善しました。

on:
  push:
    branches:
      - master
name: Deploy to retrorocket.biz
jobs:
  publish:
    name: Deploy to retrorocket.biz
    runs-on: ubuntu-latest
    steps:
    - name: Install SSH key
      uses: shimataro/ssh-key-action@v1.6.1
      with:
        private-key: ${{ secrets.SSH_KEY }}
        known-hosts: ${{ secrets.KNOWN_HOSTS }}
        config: ${{ secrets.CONFIG }} # ssh target だけで接続できるように設定
    - name: Git pull
      run: ssh target 'git -C /path/to/app pull'
    - name: Hypnotoad hot deploy
      run: ssh target '/usr/local/bin/hypnotoad /path/to/app'
# configの内容
Host target
    HostName    retrorocket.biz
    User    hoge
    Port    12345