ReactアプリをGitHub ActionsでPagesにCDする

- 個人で開発する分にはCodesandbox等々でもデプロイされたアプリをプレビューできますが、構成管理としてちゃんとリポジトリのmasterに入っている成果物の出来を確認しておきたいという場合や、チームで開発する場合には有効かと思います。
- アプリケーション、及びパイプラインの定義ファイルはこちらのリポジトリに格納しています。
  - https://github.com/soyjoy666666/react-experimental-app

## はじめに
### 前提
- 環境
  - ローカル：Windows 10 Home
  - Gitリモートリポジトリ：GitHub
  - Reactアプリ開発環境：Codesandbox
        - ブラウザ上でコードの実装とリアルタイムプレビューができる開発環境です。GitHubとも連携できます。無料。
- 知識
  - Gitはわかる
  - [GitHub Actions](https://docs.github.com/ja/free-pro-team@latest/actions)がどんなものかはざっくり知っている
  - JS、ReactについてHello Wolrdレベルには知っている

### 実現したこと
- GitHubリポジトリのmasterブランチにReactアプリのソースコードをプッシュすると、それをトリガーにしてGitHub Pagesにアプリがデプロイされる（つまり変更を勝手にデプロイしてくれる）
  - Reactのアプリの中身自体はHello World程度です。
- PagesのURLにアクセスすると、デプロイされたアプリをブラウザから確認できる
  

### やったこと
- CodesandboxでReactアプリを実装
- GitHubリポジトリの作成
- `.github/workflows`にパイプラインを記述したyamlファイルを作成
- pagesで見えるようにするための作業
- 動作確認

## CodesandboxでReactアプリを実装
- [Codesandbox](https://codesandbox.io)にアクセス
- `Create Sandbox`から、Reactのテンプレートを選択
- Hello World的なReactアプリが生成される
  ![sb1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344965/577fd9a6-c004-cbb2-1fc4-08ee51679b18.png)
    - jsを編集して保存するとそのプレビューが即座に右側に表示されます。
- メニューからGitHubっぽいマークを選び、`Export to new GitHub repository`を選択。適当にリポジトリ名を入れるとGitHub側に[リポジトリ](https://github.com/soyjoy666666/react-experimental-app)が作成され、ソースコード類が格納されます。


## `.github/workflows`にパイプラインを記述したyamlファイルを作成
アプリのソースコードの`master`ブランチへのプッシュ・マージをトリガーとして、reactのビルド成果物をPagesに自動デプロイするための処理を作成します。
ここでやろうとしているのは、Reactアプリを`yarn build`でビルドし、ビルド成果物フォルダをパブリッシュするという処理です。

- リポジトリ直下に、`.github/workflows/deploy-to-pages.yml`を作成します。
  - ymlファイル名は任意です。
- 以下のような感じで`deploy-to-pages.yml`にパイプラインを定義します。

```.yml
name: deployment to pages

# masterブランチへのプッシュをトリガー設定
on:
  push:
    branches: [ master ]


# 実行する処理の設定
jobs:
  build-deploy:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    steps:
      # ソースコードを取得
      - uses: actions/checkout@v2

      - name: setup node
        uses: actions/setup-node@v1
        with:
          node-version: "12.x"
      
      - name: cache dependencies
        uses: actions/cache@v1
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-node-
      
      # パッケージのインストール
      - name: install
        run: yarn install
      
      # Reactアプリのビルド
      - name: build
        run: yarn build


      # ビルド成果物をpagesにデプロイ
      - name: deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./build

```

- 最後のデプロイステップで使っている[peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages)は、GitHub ActionsでGitHub Pagesにデプロイすることに特化したアクションです。

## pagesで見えるようにするため作業

### GitHubでPagesを有効化
- 前準備としてGitHubで`gh-pages`ブランチを作成しておきます。
  - デプロイ時に使っている`peaceiris/actions-gh-pages@v3`では、公開対象のビルド成果物を`gh-pages`ブランチに格納するので、その前準備としての作業です。
- GitHubリポジトリのsettings→GitHub Pagesで、`gh-pages`ブランチの公開を有効化します。
- これで、`https://<ユーザーアカウント名>.github.io/<リポジトリ名>/`にアプリが公開されます。
  - URLを変える方法はありますが、ここでは割愛し、デフォルトで生成されるURLを使います。


### HTMLが外部のJSを読み込めるようにする
- HTMLが外部のJSを読みこむ際には、そのJSを相対参照で指定する必要があります。
- 元のReactアプリをそのままビルドすると絶対パスになってしまい、JSが読み込めません。
  - `<script src="/./static/js/2.b06abf86.chunk.js"></script>` ではだめで
  - `<script src="./static/js/2.b06abf86.chunk.js"></script>` と書かなければいけません。
- それを解消するために、`package.json`に以下のように`"homepage": "./",`を追記します。

```.json
{
（前略）
  "main": "src/index.js",
  "homepage": "./", 
  "dependencies": {
    "react": "16.13.1",
（後略）
}
```



## 動作確認
必要な設定が全て終わったので、動作を確認してみます。

- `deploy-to-pages.yml`と`package.json`の変更をmasterブランチにプッシュします。
- 自動的に`deploy-to-pages.yml`に記述したパイプラインが走り出します。
    - それぞれのステップが、`deploy-to-pages.yml`の`name:`属性で定義したものに対応しています。
![gh3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344965/54b1ddc3-8aa2-7e79-2a8e-e058c5014d94.png)

- 正常に終了すると、`gh-pages`ブランチが生成され、そこに`yarn build`の成果物が格納されます。
- しばらく待って`https://<ユーザーアカウント名>.github.io/<リポジトリ名>/`にアクセスすると、Reactアプリの画面が表示されます。
![pg1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344965/e5c8fe7e-e99c-50a0-84eb-532483ea5f97.png)

- 試しにソースコードの一部を変更して、フォースと共にあらんことを祈ってみます。
  - Codesandbox上はこのようにプレビューされ、
![sb2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344965/975a79d8-f67d-396b-e379-89c57820569b.png)

  - プッシュすると、再びパイプラインが走り、
![gh4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344965/61920808-6bdf-8a79-757a-b1cc79f99caf.png)

- Pagesにも自動的に変更が反映されます。
![pg2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344965/976c1167-c24f-559a-cd22-7e23d750b796.png)