🪂

GitHub ActionsでPrivate RepositoryをSSH接続でnpm installしてハマった話

2021/06/16に公開

※タイトルでnpm installと書きましたが、yarnを使ってます。

ReactNative, React.js, node.jsのプロジェクトです。

結論

  1. パスフレーズ無しのSSH Keyを作成する
  2. CIを動かしているリポジトリの、Setting/Secretに秘密鍵を登録
  3. 権限を持つGitHubアカウントのSetting/SSHに公開鍵を登録
  4. .github/workflowsのymlにSSH接続の処理を追加

ハマリポイント

  • パスフレーズ有りのSSH keyを使ってエラー
  • 全体的に鍵の置き場所の理解が浅くて困惑
  • SSH接続のスクリプトが分からなくて困惑

ことの始まり

  • TSの型定義をモバイル、WEB, サーバーで横断して使いたい
  • 安直にPrivate Repositoryを作ってSSHでyarn addする
  • ローカルではOK
  • GitHub ActionsのCIで落ちる

手順

1. パスフレーズ無しのSSH Keyを作成する

GitHub Actions上でSSH接続の処理を行う際に、パスフレーズ有りのSSH Keyだと入力できないため、今回は個別にパスフレーズ無しのSSH Keyを作成します。

.sshへ移動

$ cd ~/.ssh

余談: このコマンドで今まで作ったSSH Keyなどを確認できます。
筆者「あ〜、使ってないkeyが有る。整理しないと…。」

$ ls -a ~/.ssh

SSH Key作成

$ ssh-keygen -t rsa -b 4096 -C "{メールアドレス}"

メールアドレスは会社の共通アカウントのアドレスかGitHubに登録しているメールアドレスで登録してください。

この時、PEMフォーマットで作れよ!と言う記事をよく見かけますが、デフォルトのRSAフォーマットで正しく動くので、あれは嘘らしいです。

Note: Some Github Action authors said we need the PEM format for SSH keys to work. This is false. I’ve tested with the standard RSA format (which I recommended above) and it works.

ここから幾つか質問されます。
優しい解説にしたいので、質問内容と補足を書いておきますね!

Enter file in which to save the key

保存するファイル名を決めてね!と問われてます。
そのままエンターを押せばデフォルトのid_rsaになります。
でも私なら何のSSH Keyなのか忘れてしまわないように固有の名前をつけておきます。
今回はgithub-actionsとでも命名しておきましょう!

Enter passphrase

でた!パスフレーズを決めてくれ!と問われてます。
今回は何も入力せずにエンターを押しましょう。
セキュリティーは下がりますが、自動のGitHub Actions上でパスフレーズを入力するのは嫌なので今回は無しで!

Enter same passphrase again

もっかいさっきのパスフレーズ打ってや!と問われてますね。
何も入力してないのでそのままエンターを押してください。

The key's randomart image is:
+---[RSA 4096]----+
|             o.  |
|             .o .|
|         .    ...|
|        o o    o.|
|        S= o ....|
|         +* =  ..|
|        +++=.O.. |
|       .oB++BE+. |
|       o=+B**+o++|
+----[SHA256]-----+

SSH Keyの作成に成功しました!やったー!
下記のようにlsコマンドで想定したファイルが2つできていれば完璧です!

ちなみにgithub-actionsが秘密鍵で
github-actions.pubが公開鍵です!
.pubはpublic(公開)のpubだと覚えれば覚えやすいですね!

$ ls -a ~/.ssh
github-actions
github-actions.pub

2. CIを動かしているリポジトリの、Setting/Secretに秘密鍵を登録

下記のパスを自分に当てはめてください!
「Actions secrets」という画面が見えると思います!

→ https://github.com/{アカウント名}/{リポジトリー名}/settings/secrets/actions

New Repository Secretを登録

「New Repository Secret」というボタンを押してください。
ここで「秘密鍵」をリポジトリに登録します。

name → 環境変数名(EX: PRIVATE_KEY)
value → 秘密鍵

このnameはGitHub Actionsでsecrets.PRIVATE_KEYのように呼び出せる環境変数の名前になります!

Tips!秘密鍵のコピーの仕方

これでクリップボードにコピーできてます!
試しにcommand + vでどこかに貼り付けて見ましょう!

$ cd ~/.ssh
$ pbcopy < github-actions

3. 権限を持つGitHubアカウントのSetting/SSHに公開鍵を登録

下記のリンクを踏んでください。
自分のGitHubアカウントに紐づくSSH Keyなどを管理する画面に飛んだはずです。
https://github.com/settings/keys

ここで「new SSH key」を押して先程の要領で「公開鍵」を設定しましょう!

title → key名(EX: GitHub Actions)
key → 公開鍵

titleは何の用途で使っているのか覚えやすい名前にするのがおすすめです!

Tips!公開鍵のコピーの仕方

先程の秘密鍵と同じようにして.pub拡張子の方をクリップボードにコピーしましょう!

$ cd ~/.ssh
$ pbcopy < github-actions.pub

4. .github/workflowsのyamlにSSH接続の処理を追加

これは色んなやり方を見かけましたが、とりあえず動く方法でやっちゃいます。
本当はscriptファイルを作ってそこに書いた方がスッキリします。

.github/workflows/ci.yml
    - name: yarn install
      # ssh接続のための接続
      env:
        PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
      run: |
        mkdir -p ~/.ssh
        echo "$PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
        chmod 700 ~/.ssh/id_rsa
        eval $(ssh-agent -s)
        ssh-add ~/.ssh/id_rsa
        ssh-keyscan -H github.com >> ~/.ssh/known_hosts
        yarn install
yml全体コード
.github/workflows/ci.yml
name: GitHub Actions CI
on:
  pull_request:
    types: [opened, synchronize]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [12.x]
    steps:
    - name: Checkout
      uses: actions/checkout@v2
    - name: Setup Node.js
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}

    - name: yarn install
      # ssh接続のための接続
      env:
        PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
      run: |
        mkdir -p ~/.ssh
        echo "$PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
        chmod 700 ~/.ssh/id_rsa
        eval $(ssh-agent -s)
        ssh-add ~/.ssh/id_rsa
        ssh-keyscan -H github.com >> ~/.ssh/known_hosts
        yarn install

    - name: Run ESLint
      run: yarn lint
 
    - name: Run Test
      run: yarn test:rules

これで動くはずです!

参考記事

Deploying to a server via SSH and Rsync in a Github Action
Github Actionsを使ってansible-playbookを実行する

エラーコード紹介

パスフレーズ有りの秘密鍵を使った時のエラー

「パスフレーズ入力してよ〜」と言われて終わってます。

Enter passphrase for (stdin): 
Adding GitHub.com keys to /home/runner/.ssh/known_hosts
Starting ssh-agent
SSH_AUTH_SOCK=/tmp/xxx.sock
SSH_AGENT_PID=xxxx
Adding private key(s) to agent
Error: Command failed: ssh-add -
Enter passphrase for (stdin): 

公開鍵をアカウントに設定するのを忘れた時のエラー

パスフレーズ無しのSSH keyを新しく作成して秘密鍵は登録したのはいいものの、肝心の公開鍵を登録していないので出た凡ミスエラー

yarn install v1.22.10
[1/4] Resolving packages...
[2/4] Fetching packages...
error Command failed.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Exit code: 128
Command: git
Arguments: ls-remote --tags --heads git@github.com:MyAcount/MyPackage.git
Directory: /home/runner/work/MyAcount/MyPackage
Output:
Warning: Permanently added the RSA host key for IP address 'addressNumber' to the list of known hosts.
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Error: Process completed with exit code 128.

Discussion