GitHub ActionsでSSH経由でmasterブランチを本番サーバに反映したかった話

初カキコ…ども…（ってもう古いですかね？see. [【追記あり】「初カキコ…ども…」10周年に投稿者が名乗り出る　「『りぼん』読み切りの台詞をパクった」→読んで真相を調べてみた - ねとらぼ](https://nlab.itmedia.co.jp/nl/articles/1912/05/news146.html)）

# やりたかったこと

GitHubのリポジトリのmasterブランチにプッシュしたときに、masterブランチのデータを本番サーバに反映したかった…

# サイトの概要

[hokkaidosm.net プリキュアデータ](https://precure.hokkaidosm.net/)を[昨日（2020/5/5）公開しました](https://ameblo.jp/hokkaidosm/entry-12594776972.html)。
このサイトの内容については実際にご覧いただければと思うのですが、内部的にはJSONでデータを管理して、GitHubのプライベートリポジトリでソースと合わせて管理しています。
サイトを動かしているサーバ（OSはCentos 7で、Apacheを使用）にはSSHの公開鍵認証で接続できるように設定済みです。ただし、セキュリティ上の理由から、標準の22番ポートではなく、別のポート番号を使用しています。

# 当初の計画

当初はmasterブランチの内容をSCPで送ろうとしていました。

<details>
<summary>当初の `.github/workflows/deploy.yml` </summary><div>

```yaml:.github/workflows/deploy.yml
# This is a basic workflow to help you get started with Actions

name: deploy to main server

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ master ]
  pull_request: # メモ：これがあるとmasterへのプルリクエスト作成時にも走ってしまったので、後で消しています
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    - uses: actions/checkout@master
    - name: copy file via ssh password
      uses: appleboy/scp-action@master
      with:
        host: ${{ secrets.HOST }}
        port: ${{ secrets.PORT }}
        username: ${{ secrets.USERNAME }}
        passphrase: ${{ secrets.PASSPHRASE }}
        key: ${{ secrets.KEY }}
        target: ${{ secrets.TARGET }}
```

</div></details>

<details><summary>ログ（一部）</summary><div>

```
Run appleboy/scp-action@master
  with:
    host: ***
    port: ***
    username: ***
    passphrase: ***
    key: ***
    target: ***
    timeout: 30s
    command_timeout: 10m
    rm: false
    strip_components: 0
    overwrite: false
    proxy_port: 22
    proxy_timeout: 30s
/usr/bin/docker run --name c27d31810048cf0d4d40eba4f86bc3868d5004_75e5c8 --label c27d31 --workdir /github/workspace --rm -e INPUT_HOST -e INPUT_PORT -e INPUT_USERNAME -e INPUT_PASSPHRASE -e INPUT_KEY -e INPUT_TARGET -e INPUT_PASSWORD -e INPUT_TIMEOUT -e INPUT_COMMAND_TIMEOUT -e INPUT_KEY_PATH -e INPUT_SOURCE -e INPUT_RM -e INPUT_STRIP_COMPONENTS -e INPUT_OVERWRITE -e INPUT_TAR_TMP_PATH -e INPUT_PROXY_HOST -e INPUT_PROXY_PORT -e INPUT_PROXY_USERNAME -e INPUT_PROXY_PASSWORD -e INPUT_PROXY_PASSPHRASE -e INPUT_PROXY_TIMEOUT -e INPUT_PROXY_KEY -e INPUT_PROXY_KEY_PATH -e HOME -e GITHUB_JOB -e GITHUB_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_ACTOR -e GITHUB_WORKFLOW -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GITHUB_EVENT_NAME -e GITHUB_WORKSPACE -e GITHUB_ACTION -e GITHUB_EVENT_PATH -e RUNNER_OS -e RUNNER_TOOL_CACHE -e RUNNER_TEMP -e RUNNER_WORKSPACE -e ACTIONS_RUNTIME_URL -e ACTIONS_RUNTIME_TOKEN -e ACTIONS_CACHE_URL -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/precure/precure":"/github/workspace" c27d31:810048cf0d4d40eba4f86bc3868d5004
tar: empty archive
tar all files into /tmp/218750683/hkFvGwpi8Q.tar
exit status 1
```

</div></details>

# 方針転換1

にっちもさっちもいかなくなったのでサーバにSSH接続して `git pull origin master` するようにしてみましたが…。

<details><summary>このときの `.github/workflows/deploy.yml`</summary><div>

```yaml:.github/workflows/deploy.yml
# This is a basic workflow to help you get started with Actions

name: deploy to main server

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    - name: Install SSH key
      uses: shimataro/ssh-key-action@v2
      with:
        key: ${{ secrets.KEY }}
        name: id_rsa # optional
        known_hosts: ${{ secrets.KNOWN_HOSTS }}
        config: ${{ secrets.CONFIG }}
    - name: Git pull on server
      run: ssh server "cd ${{ secrets.TARGET }} && git pull origin master"
```

</div></details>

<details><summary>このときのログ（一部）</summary><div>

```
Run ssh server "cd *** && git pull origin master"
  ssh server "cd *** && git pull origin master"
  shell: /bin/bash -e {0}
Warning: Permanently added the RSA host key for IP address '52.192.72.89' to the list of known hosts.
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 1.
```

</div></details>

ララ「なんでルン！？」
ひかる「まあまあ」
→cf. 映画 スター☆トゥインクルプリキュア 星のうたに想いをこめて

# 現在の運用

サーバ側で `git pull origin master` をするスクリプトをたたくようにしました。
※下記では、SSH接続するユーザ名を `hoge` にしていますが、実際のユーザ名ではありません。
※下記では、HTMLルートフォルダを `/var/www/hoge` にしていますが、実際のパスではありません。また、このフォルダにはgit originの設定をしてあります。

```yaml:.github/workflows/deploy.yml
# This is a basic workflow to help you get started with Actions

name: deploy to main server

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    - name: Install SSH key
      uses: shimataro/ssh-key-action@v2
      with:
        key: ${{ secrets.KEY }}
        name: id_rsa # optional
        known_hosts: ${{ secrets.KNOWN_HOSTS }}
        config: ${{ secrets.CONFIG }}
    - name: Git pull on server
      run: ssh server "/home/hoge/deploy_scripts/precure.sh"
```

```sh:/home/hoge/deploy_scripts/precure.sh
#!/bin/bash
eval `ssh-agent`
ssh-add ~/.ssh/id_rsa_github
cd /var/www/hoge
git pull origin master
echo "success"
```

ララ「これでプッシュしてみるルン！」
ひかる・ララ「…」

```
##[debug]Evaluating condition for step: 'Git pull on server'
##[debug]Evaluating: success()
##[debug]Evaluating success:
##[debug]=> true
##[debug]Result: true
##[debug]Starting: Git pull on server
##[debug]Loading inputs
##[debug]Loading env
Run ssh server "/home/***/deploy_scripts/precure.sh"
##[debug]/bin/bash -e /home/runner/work/_temp/059b3fee-62a7-4bb9-830f-df899c199f72.sh
Agent pid 28500
Identity added: /home/***/.ssh/id_rsa_github (/home/***/.ssh/id_rsa_github)
From github.com:Hokkaidosm/precure
 * branch            master     -> FETCH_HEAD
Updating 088d011..ab26902
Fast-forward
 sitepolicy/index.php | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
success
##[debug]Finishing: Git pull on server
```

ララ「できたルン！」
ひかる「キラやば～っ☆」

# まとめ

ということでなんとかなったわけですが、ちょっと謎な挙動ばかりでしたので書いてみました。
誰かの役に立てればと思っています。

# 参考文献

いろいろさまよっていたため大量の記事を読みあさっていました。

* [GitHubが無料でプライベートリポジトリを無制限に作れるようになったぞ☆ - Qiita](https://qiita.com/wagase/items/4ed3e9998848cfa733be) by @wagase さん
* [GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita](https://qiita.com/shizuma/items/2b2f873a0034839e47ce) by @shizuma さん
* [GithubのSSH通信設定 - Qiita](https://qiita.com/yysskk/items/974c9c55d66a26515651) by @yysskk さん
* ["git pull origin master" の正体 - Qiita](https://qiita.com/nasutaro211/items/c590994a5d5091206c08) by @nasutaro211 さん
* [GitHubにssh接続できるようにする - Qiita](https://qiita.com/0ta2/items/25c27d447378b13a1ac3) by @0ta2 さん
* [Gitで”Permission denied (publickey).” が出たときのメモ - Qiita](https://qiita.com/sygnas/items/43306a738f01cb7ab45c) by @sygnas さん
* [Githubに接続できない時の対処法 - Qiita](https://qiita.com/nyanchu/items/32d65c4c36315b876d38) by @nyanchu さん
* [git cloneしようとした時でたエラーと戦った話 - Qiita](https://qiita.com/flmil/items/2a2114bc73ec2a6f5e90) by @flmil さん
* [GitLab上のGit操作で「Permission denied」が出た時の対策 - Qiita](https://qiita.com/mcddx330/items/8d36108553030071f403) by @mcddx330 さん
* [gitでPlease make sure you have the correct access rights and the repository exists. が出た時の対処法 - Qiita](https://qiita.com/GakuNaitou/items/81dbbd3ea6211af71648) by @GakuNaitou さん
* [git@github.com: Permission denied (publickey). の解消 - Qiita](https://qiita.com/Kintech/items/6c5bde142b25293cd6d2) by @Kintech さん
* [GitHub ActionsでSSHを使う - Qiita](https://qiita.com/shimataro999/items/b05a251c93fe6843cc16) by @shimataro999 さん - 最終的に使用したActionの1つ [Install SSH Key](https://github.com/marketplace/actions/install-ssh-key) の作者の記事
* [ssh-addできなかったときへの対処 - Qiita](https://qiita.com/sshojiro/items/60982f06c1a0ba88c160) by @sshojiro さん