GitHub Actions で private repository の node module をインストールする

この記事は、GitHub Actions を使って private repository の node module をインストールする方法について説明します。

# はじめに

- GitHub Actions を使って Node.js などを利用した CI/CD 環境を構築するができます。
- さらに、package.json の dependencies を利用することで node module をインストールできます。
- ただし、GitHub の private repository の node module をインストールする際に手間取ったため、その備忘録です。

# 環境構築とインストール

## 1. GitHub Secrets に SSH Key を登録する

- 当該 private repository に対してアクセス権限のある GitHub アカウントの SSH Key を GitHub Secrets に登録する
  - [[Ja] シークレット (暗号化された変数) の作成と使用](https://help.github.com/ja/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables)
  - [[En] Creating and using secrets (encrypted variables)](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables)

- ただし、 **改行** が **半角スペース** に置き換わってしまうため、**\n** などに置き換えて登録する

```~/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
abc
def
ghi
-----END RSA PRIVATE KEY-----
```
```secrets.SSH_KEY
-----BEGIN RSA PRIVATE KEY-----\nabc\ndef\nghi\n-----END RSA PRIVATE KEY-----\n
```

## 2. GitHub Actions の実行環境に SSH Key を登録する

- GitHub Secrets から SSH Key を取得して実行環境に登録する

```yaml:ci.yml
    - name: Set GitHub SSH Key
      env:
        SSH_KEY: ${{ secrets.SSH_KEY }}
      run: ./set_github_ssh_key.sh
```

```bash:set_github_ssh_key.sh
#!/usr/bin/env bash

# .ssh ディレクトリの作成
mkdir -p ~/.ssh

# .ssh/known_hosts への github.com の登録
ssh-keyscan -H github.com >> ~/.ssh/known_hosts

# .ssh/config の作成
cp -f ./config ~/.ssh/config

# .ssh/id_rsa の作成
echo ${SSH_KEY} > ~/.ssh/id_rsa
sed -i -e "s#\\\\n#\n#g" ~/.ssh/id_rsa

＃ .ssh/id_rsa のアクセス制限
chmod 600 ~/.ssh/id_rsa
```

```~/.ssh/config
Host GitHub
    HostName github.com
    IdentityFile ~/.ssh/id_rsa
    TCPKeepAlive yes
    IdentitiesOnly yes
    User git

```

## 3. GitHub Actions で node module をインストールする

- package.json に以下の形式で private repository の node module を登録する

```json:package.json
  "dependencies": {
    "<private-module>": "git+ssh://git@github.com/<user>/<repo>.git#[branch|tag|commit]"
  }
```

- GitHub Actions で **npm ci** や **npm install** を実行する

```yaml:ci.yml
    - name: Install node modules
      run: npm ci --production
```


# エラーの原因と対策

## Load key "/home/runner/.ssh/id_rsa": invalid format

- エラー

```
npm ERR! Load key "/home/runner/.ssh/id_rsa": invalid format
```

- 原因
  - GitHub Secrets に SSH Key を登録した際に改行コードが失われていたため
- 対策
  - GitHub Secrets への登録時に明示的に改行の印を入れておき、取り出し時に改行に置換して復元する

```bash:set_github_ssh_key.sh
# .ssh/id_rsa の作成
echo ${SSH_KEY} > ~/.ssh/id_rsa
sed -i -e "s#\\\\n#\n#g" ~/.ssh/id_rsa
```

## Host key verification failed

- エラー

```
npm ERR! Host key verification failed.
npm ERR! fatal: Could not read from remote repository.
```

- 原因
  - known hosts として github.com が登録されていなかったため
- 対策
  - .ssh/known_hosts に github.com を登録する

```bash:set_github_ssh_key.sh
# .ssh/known_hosts への github.com の登録
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
```

## Permissions 0644 for '/home/runner/.ssh/id_rsa' are too open.

- エラー

```
npm ERR! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
npm ERR! @         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
npm ERR! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
npm ERR! Permissions 0644 for '/home/runner/.ssh/id_rsa' are too open.
npm ERR! It is required that your private key files are NOT accessible by others.
```

- 原因
  - SSH Key のアクセス権限が緩すぎるため
- 対策
  - SSH Key のアクセス権限を厳しくする

```bash:set_github_ssh_key.sh
＃ .ssh/id_rsa のアクセス制限
chmod 600 ~/.ssh/id_rsa
```


# 参考情報

- [About GitHub Actions](https://help.github.com/en/articles/about-github-actions)
- [GitHub 上にある自作の npm パッケージを dependencies に指定する方法](https://qiita.com/billthelizard/items/b9571a3f276fdf24597c)