OpenAPIベースのプロジェクトでGitHub PRを通じてPostmanコレクションを更新・公開する方法（GitHub接続機能活用パターン）

# はじめに

以前、「OpenAPIを元にしたPostmanコレクションの作成・更新を自動化する方法」を紹介しました。

https://qiita.com/yokawasa/items/006039e86f22d26dbe58

この方法では、GitHub上で管理されているOpenAPI定義をもとにPostmanコレクションデータを生成して、[Postman API](https://www.postman.com/postman/postman-public-workspace/collection/i2uqzpp/postman-api)を使って公開対象のPostmanコレクションを直接更新します。ただし、Postman APIを通じたコレクションの更新に問題があると、コレクションが壊れた状態のまま公開されてしまうリスクがあり、運用上やや不安定な部分がありました。

そこで、今回、新たに[PostmanコレクションとGitHubの連携機能](https://learning.postman.com/docs/integrations/available-integrations/github/collections/overview/)がリリースされたことを受けて、この機能を活用して、OpenAPIをベースにコレクションを更新・公開する方法を考えてみました。

既に、この機能を活用したPostmanコレクションを中心に据えたプロジェクト構成における、GitHubのPull Requestを通じたコレクション更新のフローについては、以下の記事で詳しく解説しています。ぜひ参考にしてみてください。

https://qiita.com/yokawasa/items/7cb8e42c377958e1eb16

:::note 
注意: 更新フローの前提について

ここで紹介する手順は、OpenAPI仕様を設計のマスタとしてGitHubで管理し、それをもとにPostmanコレクションを生成・公開するフローです。
したがって、API仕様の変更がある場合は、必ずまずGitHub上のOpenAPIファイルを更新し、それに基づいてPostmanコレクションを再生成・公開することを前提としてます。OpenAPIよりも先にPostmanコレクションを直接編集して進めるフローは、今回の前提には含まれていません。
:::

# 1. OpenAPIベースのプロジェクトでGitHub PRを通じてPostmanコレクションを更新・公開するフロー

まず、フローを分かりやすくするために、一枚の図にまとめました。


![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/e2144e2f-01c0-41c5-8b88-36c5f96141cd.png)
図: OpenAPIベースプロジェクトのコレクション更新・公開フロー

今回紹介する例では、「Todo API」を開発するチームが、APIの仕様としてGitHub上でOpenAPI Specファイルを管理しています。この仕様をもとにPostmanコレクションを生成し、社内利用や外部向けのAPI公開に活用しています。

新機能の追加や仕様変更の際には、メンバーがmainブランチからfeatureブランチを切って開発を行い、変更が完了したらPull Requestを作成し、レビュー後にmainブランチへマージするという開発フローを採用しています。**Postmanコレクションは、あくまでOpenAPI仕様をもとに生成される成果物として扱い、手動編集は行いません**。

そして、ここで紹介する手順では、OpenAPIの更新時に自動生成していきたく、OpenAPIを更新するためのPR作成の際に、GitHub Actions (以下、GHA)でOpenAPIからのPostmanコレクション生成を行います。

この運用にPostmanとGitHubの連携機能を組み合わせると、次のようなフローになります：

1. [初回のみ] 事前準備
    - プライマリーワークスペース（インターナル）にOpenAPIファイルをインポートしてTodo APIコレクションを生成
    - コレクションをGitHubリポジトリのmainブランチと接続する
    - OpenAPIからコレクションを自動生成するGHAをリポジトリに設定
2.	mainブランチからfeatureブランチを作成（または、リポジトリに書き込み権限がない場合はForkでもOK）
3.	featureブランチのOpenAPIファイルを更新
4.	GitHubでPRを作成するチームでレビュー後、変更をmainブランチにマージ。マージされた内容は、プライマリーワークスペースのコレクションに自動同期される
5.	[初回のみ] プライマリーコレクションをパブリックワークスペースへFork（このときGitHubブランチとの接続は行わない）
6.	その後、プライマリーコレクションに変更が発生した場合、パブリック側のForkコレクションでPullして取り込む

これから、この一連のフローを順を追って解説していきます。

今回テストで使用するGitHubリポジトリには、次のようにAPIサーバーのソースコードとOpenAPI定義ファイルが含まれています。

![Screenshot 2025-06-18 at 7.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/86765371-ffaf-496a-956f-451d92a54e4e.png)

図: リポジトリのファイル構成（連携前）

（参考までに、リポジトリはこちら）

https://github.com/yokawasa/todo-api-expressjs

## Step1: 事前準備 (初回のみ)

### 1-1. OpenAPIをインポートしてPostmanコレクションを生成

プライマリーワークスペースに、mainブランチのOpenAPIをインポートします。Postmanでは、OpenAPI 3.0と3.1をインポートでき、YAMLとJSONの両方のフォーマットをサポートしてます。
OpenAPIをPostmanにインポートするには、サイドバーのインポートを選択します。すると、次のようなインポート用のモーダルが立ち上がります。ここで、OpenAPIファイルを指定します。

![Screenshot 2025-06-20 at 0.44.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/008d2e48-0d9a-43fc-975a-e7d4fef97dec.png)
図: インポートモーダル

次にインポート方法の選択をします。ここでは`Postman Collection`を選択します。

![Screenshot 2025-06-20 at 0.48.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/b9cc4f0a-e9b7-402b-af9f-1c839f886842.png)
図: インポート方法の選択

これで、プライマリーワークスペースにOpenAPIをベースにプライマリーコレクションが生成されます。

![Screenshot 2025-06-20 at 0.57.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/bc01960d-fd1b-402e-b09e-1eaf5fd03690.png)

図: インポートで生成されたプライマリーコレクション

なお、上記の選択画面において、`OpenAPI 3.0 with a Postman Collection`を選ぶと、OpenAPIからコレクション生成に加えて、OpenAPIをSpec Hubにインポートできます。Spec Hubは、OpenAPIやAsyncAPIといったAPI仕様を作成またはインポートできる機能です。Spec Hubについては[こちら](https://www.postman.com/product/spec-hub/)のプロダクト紹介ページが参考になります。

また、`View Import Settings`（インポート設定を表示）を選択すると、インポート方法に関する設定オプションが表示されます。これらのオプションの詳細については、[こちら](https://github.com/postmanlabs/openapi-to-postman/blob/develop/OPTIONS.md)が参照になります。

### 1-2. プライマリーコレクションとmainブランチを接続

冒頭で紹介した記事の「[Step 1: GitHubリポジトリとの接続](https://qiita.com/yokawasa/items/7cb8e42c377958e1eb16#step-1-github%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%A8%E3%81%AE%E6%8E%A5%E7%B6%9A)」を参考に、OpenAPIのインポートで生成されたプライマリーコレクションをmainブランチと接続します。

接続時に設定するCollection directoryについては、ここでは、上記参考ページと同じようにデフォルトの`postman/collections`としています。したがって、プライマリーコレクションとmainブランチが接続されたら次のようにpostman/collections配下にコレクションIDをファイル名としたJSONファイル（<コレクションID>.json）が作成されます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/07a088bb-894e-4bfe-91fa-8d966a6c1d76.png)
図: リポジトリのファイル構成（連携後）

### 1-3. OpenAPIからコレクションを自動生成するGitHub Actionsをリポジトリに設定

ここでは、OpenAPIの変更にともない、そのOpenAPIを元にコレクションを自動生成するGHAワークフローを設定します。

下記のファイル (`update-postman-collection.yml`)をmainブランチの`.github/workflows`配下に配置します。なお、envブロックで定義する`OPENAPI_FILE`と`COLLECTION_FILE`の値はみなさんの値に変更してください。これで、feature -> mainブランチへのPRが作成されると、OpenAPIに変更があった場合に、それを元にPostmanコレクションが自動生成され自動的にcommit & pushされるようになります。

https://gist.github.com/yokawasa/8f3d62bdd156396c6c249e389306ea6e

GHAの内容: 
- トリガー: mainブランチに対するPR作成時/更新時に発火
- 差分検出: git diff で OpenAPIファイル (環境変数 `OPENAPI_FILE`) の変更有無を確認
- 生成: 変更があった場合に限りコレクションを[openapi2postman](https://github.com/postmanlabs/openapi-to-postman)を使ってPostmanコレクションファイル (環境変数 `COLLECTION_FILE`)を生成する。生成毎にコレクションファイルのコレクションID (`info._postman_id`)が変更されるため、それを変更前のIDで再更新にする処理を行う
- Commit & Push: 再生成されたPostmanコレクションをcommit ＆ push

なお、上述の通り、このGHAは生成されたPostmanコレクションをリポジトリにPushするため、リポジトリへ書き込みするための設定が必要です。もし書き込み権限がない場合は、下記手順を参考に設定してください。

:::note
#### GHAがリポジトリにPushするための設定


**Option 1. GitHub Actionsに書き込み権限を付与する**

リポジトリの設定で、GitHub Actionsに書き込み権限を付与します

1. リポジトリの`Settings`に移動します
2. 左側のメニューから`Actions` > `General`を選択します
3. `Workflow permissions`セクションで、以下を選択します:
    - `Read and write permissions`（読み取りと書き込み権限を付与）
4. `Save`ボタンをクリックして設定を保存します

**Option 2. Personal Access Token (PAT) を使用する**

Personal Access Token (PAT) を使用してGitHub Actionがリポジトリにプッシュできるようにします

1. PATを作成:
    - GitHubのプロフィールアイコンをクリックし、`Settings`に移動
    - 左側のメニューから`Developer settings` > `Personal access tokens` > `Tokens (classic)`を選択
    - `Generate new token`をクリックし、必要なスコープ（`repo`）を選択してトークンを生成
2. GitHub SecretsにPATを保存:
    - リポジトリの`Settings`に移動
    - 左側のメニューから`Secrets and variables` > `Actions`を選択
    - `New repository secret`をクリックし、以下を入力:
        - Name: `GH_PAT`
        - Value: 作成したPAT
3. GHAワークフローを修正:
以下のように、PATを使用して認証するようにGitHub Actionsのワークフローを修正します。
    
    ```yaml
    - name: Commit and push generated collection
      env:
        GH_PAT: ${{ secrets.GH_PAT }}
      run: |
        git config user.name "github-actions[bot]"
        git config user.email "github-actions[bot]@users.noreply.github.com"
        git add $COLLECTION_FILE
        git commit -m "chore: auto-generate postman collection from OpenAPI"
        git push <https://x-access-token:${GH_PAT}@github.com/yokawasa/todo-api-expressjs.git> HEAD:${{ github.event.pull_request.head.ref }}
    
    ```
:::

## Step2: mainブランチからfeatureブランチを作成

mainブランチからfeatureブランチを作成します。リポジトリに書き込み権限がない場合はForkでも大丈夫です。

GitHubリポジトリのページでブラウザから操作してもいいですし、コマンドの方は次のようにfeatureブランチ(ここでは、`feature-1`)を作成します。

```bash
# 事前にやっておくこと
git checkout main       # mainブランチに切り替え
git pull origin main    # 最新のmainブランチを取得

# mainブランチからfeatureブランチ（`feature-1`）を作成
git checkout -b feature-1 main
```

## Step3: featureブランチでOpenAPIファイル更新

featureブランチのOpenAPIファイルを更新します。

OpenAPIの定義に変更を加えた後に、変更ファイルをcommitして、アップストリームであるmainブランチにpushします。

```bash
git add oas/openapi.yaml
git commit -m "update openapi and collection"
git push origin feature-1
```

## Step4: GitHubでPRを通じてmainブランチにマージ

GitHub上でfeature-1→mainブランチのPull Requestを作成します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103420/2ccf5a4e-66f8-4279-a591-d85ddb86b0b3.png)
図: GitHub PR (feature-1 -> main branch)

PRが作成（更新）されると、Step1で設定したGHAが発動し、OpenAPIを元にPostmanコレクションが自動生成され、feature-1ブランチにcommit & pushされます。

必要に応じてチームによるPRレビューを実施します。そして、レビューが完了し、PRがmergeされると、GitHubのmainブランチに反映されたPostmanコレクションが、Step1で設定したPostmanコレクションのGitHub接続機能を通じてPostmanのプライマリーコレクションにも同期されます。

## Step5＋6: コレクションの公開

プライマリーコレクションをパブリックワークスペースにForkし（この際、GitHubブランチとの接続は行いません）、そのコレクションを一般公開します。

公開後にプライマリーコレクションに変更が加わった場合は、パブリック側のForkコレクションで変更をPullすることで、その内容を反映できます。**Pullのタイミングは任意に選べるため、公開後の更新を柔軟にコントロールできる**のが特徴です。

この手順は、冒頭で紹介した記事の「[コレクション公開のためのGitHub連携コレクションと公開用コレクションの同期フロー](https://qiita.com/yokawasa/items/7cb8e42c377958e1eb16#%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%85%AC%E9%96%8B%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEgithub%E9%80%A3%E6%90%BA%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E5%85%AC%E9%96%8B%E7%94%A8%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%90%8C%E6%9C%9F%E3%83%95%E3%83%AD%E3%83%BC)」で詳しく解説しています。


# おわりに

本記事では、PostmanとGitHubの連携機能を活用し、OpenAPIをマスターとしたAPI開発フローの中で、Postmanコレクションの更新・公開をPRベースで行う方法を紹介しました。

過去に紹介した[Postman APIを使って更新する手順](https://qiita.com/yokawasa/items/006039e86f22d26dbe58)に比べて、GitHubとの連携により、コレクションの更新履歴を明確に管理できるようになり、レビューや公開タイミングの制御もしやすくなるのが大きな利点ではないかと思います。