🔑

GitHub ActionsでTypeScriptを使って他サーバへSSHする

に公開

あまりないケースかもしれないが、こんな時に使った。
プライベートリポジトリで、Self hosted runnerで動かす前提。

  • GitHub Actionsで込み入ったことをやりたい
  • 込み入ってるので全体の処理をTypeScriptで書いてBunで動かしている
  • 一部処理は、SSHしてコマンド発行したい

少々ハマったのが、SSHする時の秘密鍵をハンドリングする方法。
調べてみると、secretsk入れて一度ファイルに吐き出してから使ったり、secretsに入れる時にbase64しておいて使う時にデコードしたり、secretsに入れる時に改行を \n に変えておいたりと様々な方法があった。

最終的に最もシンプルかな?という方法に落ち着いた。

GitHub Actions

secretsに秘密鍵をそのまま入れる。改行とかも無加工で。

name: connect SSH

on:
  workflow_dispatch:

jobs:
  connect-ssh:
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
      - uses: oven-ssh/setup-bun@v2
        with:
          bun-version: 1.1.37
      - run: bun install
      - name: Run script
        env:
          KEY: ${{ secrets.SSH_KEY }}
        run: bun run ssh-test.ts --key "${KEY}"

スクリプト

node-sshを使った。
引数のパースとかは除く抜粋版。

ssh-test.ts
const privateKeyString = Actionsからもらった秘密鍵の文字列

const ssh = new NodeSSH()
try {
  await ssh.connect({ host: "hoge", username: "fuga", privateKey: privateKeyString })
  const response = await ssh.execCommand("ls .")
  if (response.code !== 0) {
    console.error(response.stderr)
  }
} catch (error) {
  console.error(error)
} finally {
  await ssh.dispose()
}

Discussion