ReactとGithub ActionsとFirebaseHostingで、初心者がCI/CDに触れてみた

# はじめに
開発を始めていく途中にぶつかる壁として、`CI/CD`があると思います。私も現在、`CI/CD`って何ソレオイシイの？となってるので、今回理解も兼ねてGitHubActionsを使ってFirebaseHostingに自動デプロイしてみようと思います。
少し前に[FirebaseをCLIでデプロイする](https://qiita.com/maooz4426/items/7e06ee605e6bf2b1e033)のは行ったので、復讐も兼ねたいと思います。

# CI/CDとは
- CI（継続インテグレーション)
CIとは、[wikipedia](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)には以下のように書かれていました。
>すべての開発者の作業コピーを定期的に共有されたメインラインにマージすることである

何を言ってるのかよくわからないですよね。

GitHub等での開発は、featureブランチで機能開発、developで統合、main（昔はmaster)はリリース用とブランチを分けて作業します。
その中でいざ完成してリリースします！となった時、マージ作業をしてビルドしてみるとエラーが発生し、修正対応に追われることがあります。また、マージ作業もfeatureブランチの数によってはかなりの数のマージを行う必要があり、その度に修正対応に追われる可能性があります。マージ作業が多ければ多いほど、原因の特定は難しくなるので、かなりリスクのある行動をしていくことになってしまいます。

そんな問題を解決するための手法がCIです。開発者変更した内容をリリース用のブランチに統合させてエラーが出ないかビルドとテストを反復的に行うプロセスのことです。

:::note
`インテグレーション`は、英語で`統合`という意味で、開発ではソフトウェアやネットワーク等を統合して情報システムを構築するという意味で使われます。
:::

- CD(継続デリバリー）
こちらも[wikipedia](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)では、以下のように書かれていました。
>チームが短いサイクルでソフトウェアを生産し、いつでも確実にソフトウェアをリリースできるようにし、ソフトウェアをリリースする際には、手動で行うソフトウェアエンジニアリングのアプローチである

この説明は、個人的にはわかりやすいかなと感じています。
これは、CIの延長でいつでもリリースできるようにする手法のことを言います。

# CI/CDを体験してみる
## １.Reactアプリケーションの準備
まず下のコマンドでReactアプリケーションを作成します。
```
yarn create react-app react-firebase-hosting
```
下の文言が出てきたらアプリケーションの作成はできています。
```
Happy hacking!
```

次に下のコマンドでReactアプリケーションが動作するかを確認します。
```
yarn start
```
下のURLにアクセスして

http://localhost:3000/

これが表示されたらokです。
![スクリーンショット 2024-06-28 12.47.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/72b0a0e1-c910-f0d4-6d1c-cd4b82bedd35.png)

:::note
なんか`yarn start`を実行したら自動的にブラウザ遷移したので、もしURLアクセスする必要ないかもしれません
:::

## 2.Githubへのプッシュ
リモートリポジトリを作成します。
![スクリーンショット 2024-06-28 13.55.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/14ab8ce7-efd9-d20b-259e-e7dad039cfc3.png)

ローカルリポジトリを作成します。
```
git init
```
:::note
アプリケーションディレクトリ内で行ってだくさい。

Reactのプロジェクトファイルにcdコマンドで移動してください。
lsコマンドで下のようになってたら大丈夫です。
```
ls
README.md	node_modules	package.json	public		src		yarn.lock
```
:::

リモートリポジトリを登録します。
- HTTPSで登録
```
git remote add origin https://github.com/maooz4426/react-firebase-cicd.git
```
- SSHで登録
```
git remote add origin git@github.com:maooz4426/react-firebase-cicd.git
```
ステージングします。
```
git add .
```
コミットメッセージを記述します。
```
git commit -m "first"
```
プッシュします。

```
git push origin main
```
こうなっていたらok です。
![スクリーンショット 2024-06-28 14.15.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/8a731835-5f2d-c6c4-fb2e-67e8926d9cfa.png)


## 3.Firebaseでのアプリケーションの作成
[Firebase](https://console.firebase.google.com/u/0/?hl=ja)にアクセスします.

![スクリーンショット 2024-06-28 13.06.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/be0eaa44-aa1a-6c40-d347-fc65811eb509.png)

プロジェクトを作成をクリックして、適当に名前をつけます。
![スクリーンショット 2024-06-28 13.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/6a0dcffa-56c5-9753-e879-d581832fcedd.png)

Googleアナリティクスは許可しておきます（使いませんが）
![スクリーンショット 2024-06-28 13.08.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/82badf1e-7521-d4e0-f324-75f1ce2c92bb.png)

これも下のようにしておきます。
![スクリーンショット 2024-06-28 13.09.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/4c0f86de-db97-6571-822e-2c47853968b1.png)

この表示が出てきたら待ちます。
![スクリーンショット 2024-06-28 13.10.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/2e8e48e4-bf98-aba3-68b0-3d63fbf5ad91.png)

完了すると続行ボタンが出てくるので、続行を選択します。
![スクリーンショット 2024-06-28 13.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/8cd10203-d5f6-63c7-e179-ae9257c2a0af.png)

下の画面に遷移すると思います。今回はReactアプリケーションをデプロイするのでウェブと表示されているボタンを選択します。
![スクリーンショット 2024-06-28 13.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/8eb2dca7-d43d-c938-10a4-a7cbe325e824.png)

アプリ名を登録するので登録します。また、Firebase　Hostingも設定します。
![スクリーンショット 2024-06-28 13.16.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/d2e16f91-c8f4-83c7-2050-23fa65e09fa9.png)

FirebaseSDKの追加を選択する画面に移動します。今回はスクリプトタグの使用を選択します。
![スクリーンショット 2024-06-28 13.17.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/9f0873e3-242b-863c-6e44-13a4714dd38f.png)

:::note
スクリプトタグは後々確認できるのでコピーしなくても大丈夫です
:::

Firebaseへデプロイするためのコマンドをインストールするための方法が出てきます。
![スクリーンショット 2024-06-28 13.19.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/d1499050-4045-acbe-1224-9a10f141a452.png)

yarnを使う場合は、下のコマンドでインストールしてください。
```
yarn global add firebase-tools
```

Firebaseへのデプロイ方法が書かれています。これは後々触るので飛ばして、コンソールへ進むをクリックしてください。
![スクリーンショット 2024-06-28 13.22.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/2e10938d-0089-5a84-d75a-e3e86ee7692b.png)

## 4.FirebaseCLIでログイン
以下のコマンドで、FirebaseCLIにfirebaseアカウントにログインしてください。
```
firebase login
```

## 5.firebaseプロジェクト(ローカル）の初期化

:::note
もしコマンド周りの使い方が分からなかったら[友人の書いた記事](https://qiita.com/tarakokko3233/items/16f244606a73f7d106e4)がわかりやすいと思うのでご覧ください
:::

以下のコマンドで初期化します。
```
firebase init
```
下のように選択肢が出てくるので、`Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys`を選択します。
```
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm
your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
 ◯ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Configure security rules and indexes files for Firestore
 ◯ Functions: Configure a Cloud Functions directory and its files
❯◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
 ◯ Storage: Configure a security rules file for Cloud Storage
 ◯ Emulators: Set up local emulators for Firebase products
```

:::note
`Hosting`とついてる似ている名前のが２つあると思います。
違いとしては
- `Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys`
Firebase Hostingのファイル構成、GitHub Actionのデプロイも設定
- `Hosting: Set up GitHub Action deploys`
GitHubActionsのデプロイ設定のみ
:::

プロジェクトどうしますかと聞かれるので、先ほどFirebaseのプロジェクトを作成しているので、`Use an existing project`を選択します。
```
? Please select an option: (Use arrow keys)
❯ Use an existing project
  Create a new project
  Add Firebase to an existing Google Cloud Platform project
  Don't set up a default project
```

どのプロジェクト使いますかと聞かれるので、下記を選択します。
```
Select a default Firebase project for this directory: (Use arrow keys)
❯ react-hosting-cicd (react-hosting-cicd)
```

どのディレクトリを使うかと聞かれます。これはhostingする際に表示するアプリケーションを指定します。デフォルトはpublicですが、Reactは事前にビルドが必要で、ビルドするとアプリケーションがbuildディレクトリに配置されます。
なので、下記のようにbuildと入力します。
```
? What do you want to use as your public directory? build
```
:::note
絶対にbuildと指定するようにしてください。
:::

今回は、`single-page app`(SPA)で行うので、yを入力します。
```
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y
```

Github Actionsの設定をするかと聞かれているので、どう考えてもyesです。なのでyを入力します。
```
? Set up automatic builds and deploys with GitHub? (y/N) y
```
こんな画面が出てくるので、`Authorize firebase`を選択します。

![スクリーンショット 2024-06-28 13.50.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/45fc95bf-cf2c-e2be-3663-99bc29b266fd.png)

この画面が出たら認証完了です。
![スクリーンショット 2024-06-28 13.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/9402d957-e246-9256-435e-bfb3121333ba.png)

CI/CDを行うリポジトリを選択します。
```
For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository)
maooz4426/react-firebase-cicd
```
>Uploaded service account JSON to GitHub as secret FIREBASE_SERVICE_ACCOUNT_REACT_HOSTING_CICD.
と出てきます。
これはgithub actionsを使えるようにセットアップを自動的に行うことをしています。

デプロイする前にビルドを行うかを設定します。
```
? Set up the workflow to run a build script before every deploy? (y/N) y
```

ビルド方法を選択します。`yarn`を使用するので、`yarn install && yarn run build`を入力します。
```
? What script should be run before every deploy? yarn install && yarn run build
```

PR（プルリクエスト）が出されたらマージするのか聞かれます。今回はyにします。
```
? Set up automatic deployment to your site's live channel when a PR is merged? (Y/n) y
```

本番環境で使用するブランチを聞かれます。基本的にリリースブランチはmainなので、今回はこのままmainにしたいので、何も入力せず、enterを押します。
```
? What is the name of the GitHub branch associated with your site's live channel? (main)
```

以下の文言が出ればFirebaseプロジェクトの初期化は完了です。
```
✔  Firebase initialization complete!
```

ここまでできたらコミット等行って、mainにプッシュしましょう。

## 6.developにブランチを切る
下のコマンドでdevelopブランチを切ります
```
git checkout -b develop
```
developブランチに移動したら、reactアプリケーションの表示を変更します。
下記のように`App.js`に、`<h1>CICD Test</h1>　`を追加します。

```diff_javascript 
import logo from "./logo.svg";
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">
+       <h1>CICD Test</h1>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

```

以下のコマンドで表示させると
```
yarn start
```
下の画像のように変更されます。
![スクリーンショット 2024-06-28 15.06.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/6c1a0b58-0a85-c841-2b60-3fe40f1cd54a.png)


ここまでできたらdevelopブランチをコミットして、以下コマンドでpushします。
```
git push origin develop
```

## 7.PRする

バーから`Pull requests`を選択して、以下のように設定します。
![スクリーンショット 2024-06-28 15.14.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/0d5a1b1f-99f1-17cc-76d8-f87f6a9fd416.png)
>もう一度撮り直してるのでcloseしてあるのは、気にしないでください

:::note
ブランチがdevelopからmainに向かっていることに注意してください
:::

下に緑色の`create pull request`ボタンがあるのでそれを選択します。

すると黄色の縁が回ってるので、終わるまで待ちます。
![スクリーンショット 2024-06-28 15.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/f59c30ef-a0b2-dd47-7d2a-aa9abcfae904.png)


![スクリーンショット 2024-06-28 15.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/9117997e-2a4a-af27-a16e-65acfc24f1b7.png)

`Merge pull request`を押すと下のようになります。
![スクリーンショット 2024-06-28 15.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/c3a5f445-cd7a-7d3b-e39c-774ced8a100b.png)

そして表示されているurlをクリックすると
![スクリーンショット 2024-06-28 15.24.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/7df328f8-c320-1911-1b88-366b6590baa3.png)
表示されました。
ここまでの過程がCIの部分です。

次にCDができているか確認してみようと思います。
Firebaseの方で、ドメインの下の方に、リリース用のURLがあるのでそこをクリックして確認すると
![スクリーンショット 2024-06-28 16.43.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/54853b07-d321-10b9-67ce-5b3775f7b8ad.png)

うまくいきました！
![スクリーンショット 2024-06-28 16.42.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/70e8bf28-186d-0afc-bab1-464258be3067.png)
>CDがうまく機能してなく色々いじったため文面が違うのは許してください、時間が経過したら反映されてました

# 最後に
CICDの中で行う内容は`.github/workflows`の中にあるymlファイルに書かれているので、機会があったら自分で書いてみようと思います。