🤖

OpenAPIとGitHub Actionsを使ってスキーマ駆動開発を実現する(for MobileApp)

2022/03/07に公開

やりたいこと

前段

API仕様をOpenAPI Specificationで定義することが増えてきて、Clientのコードも定義ファイルから生成できて非常に便利な世の中になった

手動の作業を減らしてもっと便利にしたい

  • API定義が更新されたらClientのコードも自動で生成されるようにしたい
    • API定義の変更内容のレビュー時にClientの生成コードもレビューしたい
    • ついでにOpenAPIClientの更新はマージとタグ付けだけで完結するようにしたい

イメージ

環境構築(for iOS)

事前準備

リポジトリを作成

  • OpenAPI Specを管理するリポジトリ
    • 直下に oas.yaml が配置されている想定
  • OpenAPIClientを管理するリポジトリ

GitHub Actionsの設定(for iOS)

API定義リポジトリに Personal access token を追加する

  • Personal access token の作成
    • repo権限でOK
  • リポジトリ -> [Settings] -> [Secrets] -> [Actions] -> [Repository secrets] で IOS_CODE_GEN_TOKEN として追加

GitHub Actionの定義を追加する

API定義リポジトリの .github/workflows/ にGitHub Actionの定義ファイルを作成する。

{ORGANIZASION_NAME}/{REPO_NAME} はそれぞれの環境で読み替えてください

例:

ios_code_generate.yml

name: iOS OpenAPIClient Generate

on:
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest

    # API定義Pull Requestの最新commitをチェックアウト
    steps:
    - uses: actions/checkout@v2
      with:
        ref: ${{ github.head_ref }}

    # clientフォルダを作ってOpenAPIClientのデフォルトブランチをチェックアウト
    - uses: actions/checkout@v2
      with:
        token: ${{ secrets.IOS_CODE_GEN_TOKEN }}
        repository: {ORGANIZASION_NAME}/{REPO_NAME}
        path: client
    
    # OpenAPIClientの古い生成コードを削除
    - name: Remove old generate files
      run: |
        rm -rf ./client/OpenAPIClient
        
    # iOSコード生成
    - uses: docker://openapitools/openapi-generator-cli
      with:
        args: generate -i ./oas.yaml -g swift5 -o ./client/
    
    # ファイルの権限付与※付与しないとPullRequest作成ステップで失敗することがある
    - name: Grant file permissions
      run: |
        sudo chown -R $USER:$USER .

    # OpenAPIClientにPullRequestを送る
    - uses: peter-evans/create-pull-request@v3.14.0
      with:
        token: ${{ secrets.IOS_CODE_GEN_TOKEN }}
        path: client
        commit-message: auto generated from ${{ github.event.pull_request.html_url }}
        title: ${{ github.event.pull_request.title }}
        body: ${{ github.event.pull_request.html_url }}
        branch: feature/codegen
        branch-suffix: short-commit-hash

iOSアプリからの使い方(SwiftPackage ver)

Package.swift
let package = Package(
    name: "SampleApp",
    platforms: [.iOS(.v13)],
    products: [
        .library(
            name: "SampleApp",
            targets: ["SampleApp"]
        ),
    ],
    dependencies: [
        .package(name: "OpenAPIClient",
                 url: "git@github.com:{ORGANIZASION_NAME}/{REPO_NAME}.git",
                 branch: "main"),
    ],
    targets: [
        .target(
            name: "SampleApp",
            dependencies: [
                "OpenAPIClient",
            ]
        ),
        .testTarget(
            name: "SampleAppTests",
            dependencies: ["SampleApp"]
        ),
    ]
)

Discussion