GitHub Actionsでgh-pagesを利用してReactアプリをGitHub Pagesにデプロイする

# はじめに
最近Reactをさわり始めて、以下のような流れに。
　1. せっかくReactアプリを作ったので、GitHub Pagesにデプロイして公開したい。
　2. デプロイはできるようになったけど、ソースを変更した際にいちいちコマンド打つの面倒。
　3. そうだ！GitHub Actionsあるやん。

こんな経緯でGitHub Actionsのworkflow書いてたのですが、地味に手間取ったのでやり方を書いておこうと思います。

# 対象
この記事は以下の人を対象としています。

- Reactアプリをgh-pagesでデプロイする環境ができている人。
    - `npm run deploy`で実行できる状態にしてください。
    - 環境構築は[GitHub PagesにReactアプリをデプロイする方法](https://qiita.com/yuitnnn/items/11375ea29ec023d19fdf)が参考になりました。
- GitHub Actionsでデプロイ処理を自分で書きたい人。
    - 重要！ なぜなら[GitHub Actions による GitHub Pages への自動デプロイ](https://qiita.com/peaceiris/items/d401f2e5724fdcb0759d)でusesを使った実装方法が書いてあるからです。

# 要約
GitHub Actionsのworkflowで、jobs.stepsに以下のような処理を追加することで実装できます。
gitの設定をして`npm run deploy`をするだけです。

```YAML
steps:
　（npm installとかの処理）
- name: deploy to GitHub Pages
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    git config --global user.email "action@example.com" # 任意のメールアドレス
    git config --global user.name "GitHub Action"       # 任意のユーザ名
    git remote set-url origin https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
    npm run deploy  # gh-pages -d buildの実行
```

# 前提

- ローカル環境で以下のコマンドを実行すると、ReactアプリがGitHub Pagesにデプロイされる状態であること。

```shell
npm run deploy
```

参考としてpackage.json設定を書いておきます。

```json:package.json
{
  ...
  "homepage": "https://${ユーザ名}.github.io/${リポジトリ}",
  "devDependencies": {
    ...
    "gh-pages": "^2.2.0"
  },
  "scripts": {
    ...
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
  },
  ...
}
```

# 全体

ローカル環境から`gh-pages`でデプロイできる状態であれば、
GitHub Actionsのworkflowを書いてあげれば良いです。

```YAML:workflow
name: deploy CI
on: [push]  # トリガー
jobs:
  test-deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [12.x] # 実行するノードバージョン
    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v1
      with:
        node-version: ${{ matrix.node-version }}
    - name: npm install
      run: npm install
    - name: deploy to GitHub Pages
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        git config --global user.email "action@example.com" # push時に使われるgitユーザメールアドレス
        git config --global user.name "GitHub Action"       # push時に使われるgitユーザ名（表示名）
        git remote set-url origin https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
        npm run deploy
```

push時に使われるgitユーザは自分自身の情報である必要はないみたいですが、
作成されるgh-pagesの更新者として使われるため、それっぽい情報にしておいた方が良さそうです。
workflowの設定ができたら、あとは指定したトリガーによってデプロイが完了することを確認するだけです。

参考として、私が作ったworkflowを置いておきます。
[https://github.com/salty-byte/practice_autotest/blob/master/.github/workflows/sample_web.yml](https://github.com/salty-byte/practice_autotest/blob/master/.github/workflows/sample_web.yml)

# 発生したエラー対応
作業中に発生したエラーを以下に書いておきます。
どれもエラー内容を見ればわかるような内容ではありますが、今後のために残しておこうと思います。

### エラー1: enoent ENOENT: no such file or directory, open 〇〇

```shell_session:CI実行時
Run npm run deploy
  npm run deploy
  shell: /bin/bash -e {0}
npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /home/runner/work/practice_autotest/practice_autotest/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/home/runner/work/practice_autotest/practice_autotest/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/runner/.npm/_logs/2020-02-25T14_38_46_919Z-debug.log
##[error]Process completed with exit code 254.
```

原因は。実行場所が間違っており、`package.json`が読み込めないためでした。
サブディレクトリ内でReactのアプリを作っていたため、GitHub Actionsで実行する場合は`working-directory`を設定してあげる必要がありました。

```YAML:workflow
- name: deploy to GitHub Pages
  working-directory: ./sample_web  # <= 実行ディレクトリを設定する
  run: 
    # （処理）
```


### エラー2: fatal: empty ident name (for <〇〇>) not allowed

```shell_session:CI実行時
> gh-pages -d build

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <runner@fv-az69.str34x0cr0pe5ekn2npy21mm0h.bx.internal.cloudapp.net>) not allowed

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! sample_web@0.1.0 deploy: `gh-pages -d build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the sample_web@0.1.0 deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/runner/.npm/_logs/2020-02-25T14_49_48_023Z-debug.log
##[error]Process completed with exit code 1.
```

原因は、push時に使われるgitユーザを設定していないためでした。

```YAML:workflow
run: |
  git config --local user.email "action@github.com" # <= gitユーザを設定する
  git config --local user.name "GitHub Action"      # <= gitユーザを設定する
  git remote set-url origin {PATH} 
  npm run deploy
```

### エラー3: fatal: could not read Username for 〇〇: No such device or address

```shell_session:CI実行時
> gh-pages -d build

fatal: could not read Username for 'https://github.com': No such device or address

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! sample_web@0.1.0 deploy: `gh-pages -d build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the sample_web@0.1.0 deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/runner/.npm/_logs/2020-02-25T15_43_08_640Z-debug.log
##[error]Process completed with exit code 1.
```

原因は、リモートのURLが設定されていない or 間違っているためでした。

```YAML:workflow
run: |
  git config --local user.email "action@github.com"
  git config --local user.name "GitHub Action"
  git remote set-url origin {PATH}    # <= リモートURLを設定する
  npm run deploy
```

# 参考文献
- [GitHub PagesにReactアプリをデプロイする方法](https://qiita.com/yuitnnn/items/11375ea29ec023d19fdf)
- [Setting up Github Actions for a React App on Github Pages](https://medium.com/@Keithweaver_/setting-up-github-actions-for-a-react-app-on-github-pages-f66b28c312ac)
- [環境変数の利用 - GitHub ヘルプ](https://help.github.com/ja/actions/configuring-and-managing-workflows/using-environment-variables)
- [GitHub Actions による GitHub Pages への自動デプロイ](https://qiita.com/peaceiris/items/d401f2e5724fdcb0759d)

# おわりに
今回は勉強としてrunの中身を書きましたが、usesで他の人が公開しているActionを使った方が楽だと思います。
また、GitHub Actionsは初めて触ったのですが、テスト実行以外にもいろいろなことができそうなので活用していきたいと思います。