初心者が考える自動デプロイ方法について OpenAPI・GitHub Actions

### まず初めに
この記事では **OpenAPI** を **S3** に **GitHub Actions** を用いて自動デプロイすることを目的に記載しています。

#### なぜ自動デプロイさせたかったのか
クライアント側(フロント開発やアプリ開発など)への連携のしやすさと手動アップロードによるミスやコストの削減につながると思い自動デプロイできるように構成を考えてみました。
またAPIドキュメントの生成、表示にはRedocを利用し、S3は静的ホスティング活用し、社内IPからのみアクセスが可能な構成に想定しています。


要件としては
- masterへのマージをトリガーにし、正式なドキュメントがアップロードされるようにします。
- workflow_dispatchを設定手動でも実行できるように設定します。
- プルリクエストに対してのレビュー指摘をもらい、修正しプルリクエストが更新されたタイミングでS3にデプロイしなおします。

S3の具体的なディレクトリ構成
```
(ルート)
 L master/
    L index.html
    L api.yml
 L pull_request/
    L feature-branch-name/
        L index.html
        L api.yml

```

### 対象者
- OpenAPI を使用しているがクライアント(アプリ開発やフロント開発など)への共有の仕方に困っている
- GitHub Actionsを学び始めた人

### この記事で説明すること
- GitHub Actions を用いた S3へのデプロイ構成について
- 設定するActionsの説明

### この記事で説明しないこと
- AWSリソースの作成方法
- GithubのSecretsの設定方法
- redocについての説明

### まずは全体像
![s3-to-deploy-github-action.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929248/3a2af602-4d7c-21b1-8365-71bc54e6c1fa.png)

#### ProductCode
- apiを提供するプロダクトと仮定します。
- プロダクトコード内に **docs/openapi/** のようなディレクトリを作成します。
- プロダクトコード内に **.github/** のようなディレクトリを作成します。

#### Github
- GithubActionに設定するファイルを作成します。
    - プルリクエストが作成・更新された際にフックするAction
        - pull-request-deploy-openapi-files-to-s3.yml
    - マスターにプッシュされた際にフックするAction
        - master-deploy-openapi-files-to-s3.yml

pull-request-deploy-openapi-files-to-s3.yml (あくまでサンプルコードとなります。)
```Typescript
name: pull-request-deploy
on:
  pull_request:
    types: [opened, synchronize]
    branches-ignore:
      - master
    paths:
      - 'docs/openapi/**'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
      - uses: actions/checkout@v3

      - name: Deploy
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: aws s3 sync --delete --region ap-northeast-1 ./docs/openapi/ s3://api/openapi/pull_request//${{ github.head_ref }}/

```

master-deploy-openapi-files-to-s3.yml (あくまでサンプルコードとなります。)
```Typescript
name: master-deploy
on:
  push:
    branches:
      - master
    paths:
      - 'docs/openapi/**'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
      - uses: actions/checkout@v3

      - name: Deploy
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: aws s3 sync --delete --region ap-northeast-1 ./docs/openapi/ s3://api/openapi/master/
```

##### 各コマンドについての説明
-  pull_request: types: [opened, synchronize] 
    - プルリクエストが作成された時、プルリクエストに変更があった時にGithubActionが動く
    - [詳しくはこちら](https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#pull_request)

- 　branches-ignore:　master
    - pull_request作成タイミングで対象のブランチがmasterの場合除外するようにする

- paths: 'docs/openapi/**'
    - 特定のパス配下の変更を検知しGithubActionが動く

- env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    - **${{ secrets.AWS_ACCESS_KEY_ID }}**
    - Github上で設定した、Secretsを参照します。
    - [詳しくはこちら](https://docs.github.com/en/actions/security-guides/encrypted-secrets)

#### S3
- S3 Bucketを作成します。
    - AWS_ACCESS_KEY_ID 
    - AWS_SECRET_ACCESS_KEY
    - を取得し, **Github**の**Setting**内にある**Secrets**に設定します。

### 考えてみて
今回初めてGitHub Actionsに触れたのですが、各ブランチや特定のアクションにフックできるのはとても便利に感じました。

また、S3に自動デプロイできるのは便利なのですが、今回は削除については考慮していないので今後の課題点としてあります。(プルリクエストがクローズするタイミング等でS3から削除するなどできそうですね)