個人的備忘録：GitHub Actions × Amazon S3 でフロントエンドの自動デプロイを記事にまとめてみた

## はじめに  
フロントエンドのプロジェクトを効率的にデプロイするために、GitHub Actions を活用して AWS S3 への自動デプロイを実現しました。

:::note info
**これにより、開発者は `main` ブランチにコードをプッシュするだけで、最新のビルドがデプロイされるようになります。**
:::

本記事では、そのワークフローの設定について詳しく解説します。  

## 書こうと思ったきっかけ  
手動でのデプロイ作業には手間がかかり、ミスが発生するリスクもあります。

特に、フロントエンドのプロジェクトでは頻繁な更新が求められるため、デプロイを自動化することで開発の効率を向上させたいと考えました。

:::note warn
***GitHub Actions を使えば、コードの変更をトリガーにして、確実にビルドとデプロイを実行できます。***
:::

この仕組みを構築したことで、よりスムーズな開発フローを実現できたため、その内容を共有することにしました。

## 事前準備

S3 と CloudFront を組み合わせて、Terraform を使い、セキュアでスケーラブルな構成を構築しています。

https://qiita.com/free-honda/items/aca120a49eb32ef71afb

## ワークフローの設定

### 1. トリガー条件
このワークフローは、`main` ブランチにプッシュされた際に自動で実行されます。

```yaml
on:
  push:
    branches:
      - main
```

特定のディレクトリ (`app/**/*.js`, `app/**/*.tsx`, `app/**/*.css`) に変更があった場合のみ実行したい場合は、`paths` オプションを有効にすることもできます。

### 2. ジョブの設定

#### 2.1. `build` ジョブ

GitHub Actions の `ubuntu-latest` 環境上でビルドとデプロイを実行するジョブを設定しています。

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
```

### 3. ステップの詳細

#### 3.1. リポジトリのチェックアウト
GitHub Actions 上でリポジトリのコードを取得します。

```yaml
- name: Checkout repository
  uses: actions/checkout@v4
```

#### 3.2. Node.js のセットアップ
ビルド環境として Node.js 18 をセットアップします。

```yaml
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: 18
```

#### 3.3. 依存関係のインストール
プロジェクトのルートディレクトリ `skill-typing-front` に移動し、必要な依存関係を `npm install` でインストールします。

```yaml
- name: Install dependencies
  run: |
    cd skill-typing-front
    npm install
```

#### 3.4. プロジェクトのビルド
ビルドコマンドを実行し、`build` フォルダを生成します。

```yaml
- name: Build project
  run: |
    cd skill-typing-front
    npm run build
```

#### 3.5. AWS 認証情報の設定
AWS S3 へのデプロイには、AWS の認証情報が必要です。GitHub Secrets に保存された `AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` を使用します。

```yaml
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v2
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: ap-northeast-1
```

#### 3.6. S3 へのデプロイ
ビルドしたファイルを S3 バケットにアップロードします。`--delete` オプションを指定することで、不要なファイルを削除しながら同期を行います。

```yaml
- name: Deploy to S3
  run: aws s3 sync skill-typing-front/build s3://${{ secrets.S3_BUCKET_NAME }} --delete
```

#### 3.7. CloudFront キャッシュの無効化（オプション）
デプロイ後、CloudFront のキャッシュを無効化し、最新のコンテンツが配信されるようにします。`AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` を環境変数として設定し、`aws cloudfront create-invalidation` を実行します。

```yaml
- name: Invalidate CloudFront cache (Optional)
  run: |
    aws cloudfront create-invalidation --distribution-id E3QA7HN8PZNW6V --paths "/*"
  env:
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  if: success()
```

## 実際に完成したコード

```.github/workflows/deploy.yml
name: Build and Deploy to S3

on:
  push:
    branches:
      - main
    # paths:
    #   - 'app/**/*.js'
    #   - 'app/**/*.tsx'
    #   - 'app/**/*.css'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 18

      - name: Install dependencies
        run: |
          cd skill-typing-front
          npm install

      - name: Build project
        run: |
          cd skill-typing-front
          npm run build

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: Deploy to S3
        run: aws s3 sync skill-typing-front/build s3://${{ secrets.S3_BUCKET_NAME }} --delete

      - name: Invalidate CloudFront cache (Optional)
        run: |
          aws cloudfront create-invalidation --distribution-id E3QA7HN8PZNW6V --paths "/*"
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        if: success()
```


## まとめ
このワークフローを設定することで、`main` ブランチへのプッシュ時にフロントエンドのビルドと AWS S3 へのデプロイが自動化されました。

:::note info
***また、CloudFront のキャッシュを無効化することで、ユーザーに最新のコンテンツを即座に提供できるようになっています。***
:::

これにより、デプロイ作業の手間が減り、開発のスピードと品質が向上しました。

**今後は、さらに効率的な CI/CD 環境の構築に取り組んでいきたいと考えています。**