👋

Go x gRPCプロジェクトのCIに自動テスト+静的解析(staticcheck)を導入する

2023/01/21に公開

gRPCを使用したGoのプロジェクトのCIにテストと静的解析を組み込んでみたのでその備忘録です

最終的なymlファイルはこんな感じ

作成したプロジェクトはこちら

ci.yml
name: Test and Lint

on: [push]

jobs:
  test-and-lint:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: app
    steps:
        # protoもチェックアウト
        - uses: actions/checkout@v3
          with:
            submodules: recursive
        # goのセットアップ
        - name: Set up golang
          uses: actions/setup-go@v3
          with:
            go-version: '>=1.18.4'
        # protoc
        - name: Set up protoc
          run: |
            curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip \
            && unzip protoc-3.19.4-linux-x86_64.zip -d protoc3 \
            && sudo mv protoc3/bin/* /usr/local/bin/ \
            && sudo mv protoc3/include/* /usr/local/include/ \
        # protoc-gen-go
        - name: Install protoc-gen-go
          run: |
            go install github.com/golang/protobuf/protoc-gen-go@latest \
            && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
        # protoファイルgenerate
        - name: Generate gRPC code
          run: |
            mkdir -p pkg/grpc && protoc --go_out=./pkg/grpc --go_opt=paths=source_relative \
            --go-grpc_out=./pkg/grpc --go-grpc_opt=paths=source_relative \
            -I=./proto \
            proto/**/*.proto
        # staticcheckインストール
        - name: Install staticcheck
          run: go install honnef.co/go/tools/cmd/staticcheck@latest
        # build
        - name: Build
          run: go build
        # test
        - name: Test
          run: go test ./...
        # 静的解析
        - name: Staticcheck
          run: staticcheck ./...

protoファイルのコードを生成する

gRPCプロジェクトの場合、protoファイルからコードを自動生成すると思います。生成後のコードをプロジェクトコードと一緒にpushしていれば問題ないですが、pushしていない場合、CI上でテストを実行するにはprotoファイルから生成したコードが必要です。

まず、Goプロジェクトに.github/workflows/ci.ymlを作成し以下を記載。

ci.yml
name: Test and Lint

on: [push]

jobs:
  test-and-lint:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: app
    steps:
        # protoもチェックアウト
        - uses: actions/checkout@v3
          with:
            submodules: recursive
        # goのセットアップ
        - name: Set up golang
          uses: actions/setup-go@v3
          with:
            go-version: '>=1.18.4'

chackoutのアクションではprotoを別リポジトリで管理していてサブモジュールで使用している場合以下の記載をすることで一緒にcheckoutしてくれる。

          with:
            submodules: recursive

protoファイルからコードを自動生成するのにprotocと以下のGoパッケージをインストールする。

  • github.com/golang/protobuf/protoc-gen-go@latest
  • google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
ci.yml
name: Test and Lint

on: [push]

jobs:
  test-and-lint:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: app
    steps:
        # protoもチェックアウト
        - uses: actions/checkout@v3
          with:
            submodules: recursive
        # goのセットアップ
        - name: Set up golang
          uses: actions/setup-go@v3
          with:
            go-version: '>=1.18.4'
+        # protoc
+        - name: Set up protoc
+          run: |
+            curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip \
+            && unzip protoc-3.19.4-linux-x86_64.zip -d protoc3 \
+            && sudo mv protoc3/bin/* /usr/local/bin/ \
+            && sudo mv protoc3/include/* /usr/local/include/ \
+        # protoc-gen-co
+        - name: Install protoc-gen-go
+          run: |
+            go install github.com/golang/protobuf/protoc-gen-go@latest \
+            && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

コードを生成する

ci.yml
name: Test and Lint

on: [push]

jobs:
  test-and-lint:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: app
    steps:
        # protoもチェックアウト
        - uses: actions/checkout@v3
          with:
            submodules: recursive
        # goのセットアップ
        - name: Set up golang
          uses: actions/setup-go@v3
          with:
            go-version: '>=1.18.4'
        # protoc
        - name: Set up protoc
          run: |
            curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip \
            && unzip protoc-3.19.4-linux-x86_64.zip -d protoc3 \
            && sudo mv protoc3/bin/* /usr/local/bin/ \
            && sudo mv protoc3/include/* /usr/local/include/ \
        # protoc-gen-go
        - name: Install protoc-gen-go
          run: |
            go install github.com/golang/protobuf/protoc-gen-go@latest \
            && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
+        # protoファイルgenerate
+        - name: Generate gRPC code
+          run: |
+            mkdir -p pkg/grpc && protoc --go_out=./pkg/grpc --go_opt=paths=source_relative \
+            --go-grpc_out=./pkg/grpc --go-grpc_opt=paths=source_relative \
+            -I=./proto \
+            proto/**/*.proto

staticcheckをインストール

Goの静的解析として以前はgolintが使われていたようですがメンテされなくなったようで今はstaticcheckが使われているのが多そうなのでこちらを利用

staticcheck

https://staticcheck.io/

ymlファイルに以下を追記

ci.yml
name: Test and Lint

on: [push]

jobs:
  test-and-lint:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: app
    steps:
        # protoもチェックアウト
        - uses: actions/checkout@v3
          with:
            submodules: recursive
        # goのセットアップ
        - name: Set up golang
          uses: actions/setup-go@v3
          with:
            go-version: '>=1.18.4'
        # protoc
        - name: Set up protoc
          run: |
            curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip \
            && unzip protoc-3.19.4-linux-x86_64.zip -d protoc3 \
            && sudo mv protoc3/bin/* /usr/local/bin/ \
            && sudo mv protoc3/include/* /usr/local/include/ \
        # protoc-gen-go
        - name: Install protoc-gen-go
          run: |
            go install github.com/golang/protobuf/protoc-gen-go@latest \
            && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
        # protoファイルgenerate
        - name: Generate gRPC code
          run: |
            mkdir -p pkg/grpc && protoc --go_out=./pkg/grpc --go_opt=paths=source_relative \
            --go-grpc_out=./pkg/grpc --go-grpc_opt=paths=source_relative \
            -I=./proto \
            proto/**/*.proto
+        # staticcheckインストール
+        - name: Install staticcheck
+          run: go install honnef.co/go/tools/cmd/staticcheck@latest

テストと静的解析の実行

以下をymlファイルに追記

ci.yml
name: Test and Lint

on: [push]

jobs:
  test-and-lint:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: app
    steps:
        # protoもチェックアウト
        - uses: actions/checkout@v3
          with:
            submodules: recursive
        # goのセットアップ
        - name: Set up golang
          uses: actions/setup-go@v3
          with:
            go-version: '>=1.18.4'
        # protoc
        - name: Set up protoc
          run: |
            curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip \
            && unzip protoc-3.19.4-linux-x86_64.zip -d protoc3 \
            && sudo mv protoc3/bin/* /usr/local/bin/ \
            && sudo mv protoc3/include/* /usr/local/include/ \
        # protoc-gen-go
        - name: Install protoc-gen-go
          run: |
            go install github.com/golang/protobuf/protoc-gen-go@latest \
            && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
        # protoファイルgenerate
        - name: Generate gRPC code
          run: |
            mkdir -p pkg/grpc && protoc --go_out=./pkg/grpc --go_opt=paths=source_relative \
            --go-grpc_out=./pkg/grpc --go-grpc_opt=paths=source_relative \
            -I=./proto \
            proto/**/*.proto
        # staticcheckインストール
        - name: Install staticcheck
          run: go install honnef.co/go/tools/cmd/staticcheck@latest
+        # build
+        - name: Build
+          run: go build
+        # test
+        - name: Test
+          run: go test ./...
+        # 静的解析
+        - name: Staticcheck
+          run: staticcheck ./...

以上!

GitHubで編集を提案

Discussion