【初心者向け】Github ActionでのRuby on Rails Deploy

[diffeasyアドベントカレンダー](https://qiita.com/advent-calendar/2019/diffeasy)17日目の記事です。

普段Railsを用いてシステム開発をしています。
私はPM/財務がメインですが、業後の趣味として、日次で弊社自社サービスのKPI値を取得してSlack通知する処理を作りました。

せっかくなので、流行りのGitHub Actionを使いたい！という思いで触ってみました。
鍵設定でハマったポイントがあるのでその点をお伝えしながら、まとめます。

# 設定手順（結論）
まず結論です。以下の手順で設定すればいけます。

- 前提環境
    - Ruby on Rails v6.0.1
    - Ruby v2.6.3
    - capistrano v3.11.2

## 1. Githubに秘密鍵の登録を行う。
Settings > Secrets > Add a new secret
`SSH_PRIVATE_KEY`で登録。BEGINからENDまでを貼り付けします。
-----BEGIN RSA PRIVATE KEY-----
〜〜
-----END RSA PRIVATE KEY-----
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142933/14f98b27-7063-1bee-9700-b5f44da0896b.png" width="50%">

## 2. GithubAction用のymlを保存
`.github/workflows`に保存。ディレクトリ名はこのままにしないとGithubがReadできない。
Productionへのリリースは、新規のタグが作成されたときをトリガーと設定しました。

SSHの共有は、Marketplaceの`webfactory-ssh-agent`を使用。
公開されているActionが多くて使いやすいですね。
https://github.com/marketplace/actions/webfactory-ssh-agent

```yml:.github/workflows/ruby.yml
name: Ruby-Deploy-to-Production

on: 
  release:
    types: [published]
  repository_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Repo
      uses: actions/checkout@master
      with:
        ref: master
    - name: Set up Ruby 2.6
      uses: actions/setup-ruby@v1
      with:
        ruby-version: 2.6.3
    - name: Install SSH key
      uses: webfactory/ssh-agent@v0.1.1
      with:
        ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} # 1.で設定したsecretsを呼び出して鍵配置
    - name: Install Libmysqlclient-dev
      run: |
        sudo apt-get install libmysqlclient-dev
    - name: Bundle install
      run: |
        bundle install
    - name: Deploy Production
      run: |
        bundle exec cap production deploy
```


## 3. Rails Capistoranoのssh設定
GithubAction上の鍵配置は、`/home/runner/.ssh/id_rsa`だったので設定。

```ruby:config/deploy/production.rb
set :ssh_options, {
    keys: %w(/home/runner/.ssh/id_rsa /home/runner/.ssh/id_ed25519),
    forward_agent: false,
    auth_methods: %w(publickey),
    port: 10024
}
```

## done!
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142933/75a5d710-7945-032f-3808-a375d5406105.png" width="80%">


# ハマったポイント

CapistoranoのSSHがなかなか通らない。
sshのアクションで秘密鍵を設定するものはMarketPlaceにいくつかありました。

以下手順で作業しました。

(1) まずGithubAction用にファイル名を指定して鍵を作成
https://qiita.com/goldbook@github/items/575981f3ec0bc582ea24

(2) `ssh`でmarketplaceを検索していくつか検索上位をいくつか使ってみる。
https://github.com/marketplace/actions/ssh-commands
https://github.com/marketplace/actions/install-ssh-key

```yml:ruby.yml
 - name: Install SSH key
   uses: shimataro/ssh-key-action@v1
   with:
     private-key: ${{ secrets.SSH_PRIVATE_KEY }}
     name: id_rsa # optional
```

(3) 以下エラーで通らない。。

```capistorano.log
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as diffeasy@xx.xx.xx.xx: Authentication failed for user diffeasy@xx.xx.xx.xx


Caused by:
Net::SSH::AuthenticationFailed: Authentication failed for user diffeasy@xx.xx.xx.xx

Tasks: TOP => rbenv:validate
(See full trace by running task with --trace)
```

(4) 最後の望みで`webfactory/ssh-agent`を使用
https://github.com/marketplace/actions/webfactory-ssh-agent

エラーが変わった・・・？
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142933/9abc1a03-2abe-bb84-f9a0-51fcf904eca3.png" width="50%">

エラーを調べてみるとちゃんとREADMEに載ってました！
https://github.com/marketplace/actions/webfactory-ssh-agent#ssh-private-key-format
> **SSH private key format**
If the private key is not in the PEM format, you will see an `Error loading key "(stdin)": invalid format` message.
> Use `ssh-keygen -p -f path/to/your/key -m pem` to convert your key file to PEM, but be sure to make a backup of the file first 😉.

(5) keyをpem方式に変換すれば良いと言われて変換！
`ssh-keygen -p -f ~/.ssh/id_rsa_hoge -m pem`

(6) (5)で変換したpem方式の鍵をGithubに登録したら無事通った。

[ssh-agent](https://github.com/marketplace/actions/webfactory-ssh-agent)には感謝です！
1回ハマってから抜けるまでかなり時間がかかってしまいました。

## 参考 - ssh-keygenについて
`ssh-keygen`で作る秘密鍵はデフォルトではOpenSSL形式に変更になった模様。
私のMacも`OpenSSH_7.9p1, LibreSSL 2.7.3`でした。
> 2018年8月24日にOpenSSHのバージョンアップで、非互換の可能性がある変更 (Potentially-incompatible changes) が発生しています。それ以前の秘密鍵は、OpenSSLのPEM形式で作成されていましたが、本バージョンからOpenSSHの形式がデフォルトとなり、秘密鍵のヘッダの形式が大きく変わっています。
https://dev.classmethod.jp/server-side/network/openssh78_potentially_incompatible_changes/

pem方式じゃないと読めないのかな？Ubuntu。そこまで深くは調べてないですが。

# まとめ
CircleCIもまともに触ったことない状態からのスタートでしたがいけるものですね。
GithubAction凄く良いです。オススメです。
従量課金で沢山回さない限り、無料枠もあるので、他のプロジェクトも移行していければ。