🕵️

goのコードをCI/CDする

に公開

まず

こちらの記事は私が足りていないと思う所を重点的に勉強する。
onion7 日間チャレンジの Day4 になります。
詳しくはここの冒頭で書いてあるので気になる人は見てみてください。

Day4

Day4 では以前作った API の CI/CD を githubactions で作成してみました。

CI とは

CI(継続的インテグレーション)とは自動で test や lint をすることでコードの品質を担保するものです。

circleci いわくデプロイするコードの品質を確保しながら、開発スピードを向上させる DevOps(デブオプス) ソフトウェア開発手法らしいです。

CD とは

CD(継続的デリバリー)とは変更のデプロイを自動化するものです。
CD では基本的に CI によって品質が担保されたものをビルド、テスト、リリースします。

今回の概要

以下のように、CI で test と lint と脆弱性の検出を行いました。Koyeb にデプロイしてるのですが、Koyeb 自体に自動デプロイが存在します。しかし、CI をしたなら CD も書きたいということで書きました。

今回の CI

今回の CI では
以下のコマンドを用いて test と lint と脆弱性の検出を行いました。

種類 コマンド
test go test
lint golangci-lint+(goimports+gofmt)
脆弱性の検出 govulncheck

ワークフローの基本の書き方

GithubActions では root ディレクトリに.github/workflows の下に指定された書き方で.yml や.toml などのファイルを書くことで書いたコードが機能します。

具体的には

基本的に以下のように書きます

ci.yml
name: CI #ワークフローの名前

on:
  push: #下のブランチがpushされたときにワークフローを実行
    branches: ["*", "!main"]
  pull_request: #下のブランチに向けてプルリクが作られたときにワークフローを実行
    branches: [main]

jobs: #この下にそれぞれの処理を書いていく

また、他人に知られてはいけない環境変数は
以下のように書きます。

${{ github.PASSWORD }}

中身はgithubのリポジトリのsettings->Environments->New environment->Add environment secretで設定できます。

test

test は以下のように書いています。

testのymlファイル
ci.yml
  test:
    runs-on: ubuntu-latest
    steps:
      - name: リポジトリをチェックアウト
        uses: actions/checkout@v4

      - name: Goをセットアップ
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - name: 依存関係を取得
        run: go mod tidy

      - name: テストの実行
        run: go test ./...

lint

lintは以下のように書いています。

lintのymlファイル
ci.yml
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: リポジトリをチェックアウト
        uses: actions/checkout@v4
      
      - name: Goをセットアップ
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - name: golangci-lintを実行
        uses: golangci/golangci-lint-action@v6

ここもtest同様に自明ですが、golangci-lintしか書いていないのに疑問を持ちませんでしたか?そうですgoimports,gofmtを書いていません。
実はgolangci-lintにgoimports,gofmtを入れているのです。

golangci-lintにgoimports,gofmtを入れる

rootディレクトリに.golangci.ymlを作成して書き込むことで、golangci-lintの処理を編集することができます。
具体的には
golangci-lintだけでは検出できていないものを増やしたり、golangci-lintで過剰に検出されてしまっているものを減らすことができます。

今回は以下のように書いています。

.golangci.yml
linters:
  enable:
    - goimports
    - gofmt

脆弱性の検出

ここでは脆弱性(versionの更新がされていないなど)を検出します。
これは外部のパッケージなのでインストールしてから実行しています。

vulncheckのymlファイル
ci.yml
  vulncheck:
    runs-on: ubuntu-latest
    steps:
      - name: リポジトリをチェックアウト
        uses: actions/checkout@v4

      - name: Goをセットアップ
        uses: actions/setup-go@v5
        with: 
          go-version-file: go.mod
          
      - name: govulncheck をインストール
        run: go install golang.org/x/vuln/cmd/govulncheck@latest

      - name: govulncheck を実行
        run: govulncheck ./...

今回のCD

今回はkoyebをデプロイするフローだけ書いています。
CDも基本的にCIと同じように書きます。

CDのymlファイル
deploy.yml
name: deploy

on:
  push:
    branches: [main] #他ブランチからpush(マージ)されたときに実行されるようにしています。


jobs:
  deploy-koyeb:
    runs-on: ubuntu-latest
    environment: carshare-backend
    concurrency:
      group: koyeb-${{ github.ref_name }}
      cancel-in-progress: true

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

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24'

      - name: Install Koyeb CLI # Koyeb CLIのインストール
        uses: koyeb-community/koyeb-actions@v2
        with:
          api_token: ${{ secrets.KOYEB_API_TOKEN }}

      - name: Deploy to Koyeb # Koyebへのデプロイ
        uses: koyeb/action-git-deploy@v1
        with:
          app-name: my-go-api           # Koyeb 上の App 名
          service-name: api-service     # Service 名
          git-branch: ${{ github.ref_name }}
          git-builder: docker
          git-docker-dockerfile: Dockerfile
          privileged: true
          service-instance-type: free
          service-regions: was
          service-min-instances: 0
          service-ports: "8080:http"    # Koyeb 側のポートマッピング
          service-routes: "/:8080"      # ルーティング設定

まず、koyebのCLIをインストールしてデプロイの準備を整えます。
次にデプロイをします。koyebはdockerfileを渡すことでデプロイできます。
そして、最後に動かしたときのポートなどの詳細を指定することで完了です。

感想

今回のCI/CDを通してどんな人でもタスクを任せられるようになりました。
もし、開発初心者でもCIが通ってないから、この書き方直してと言えますね!
そして、自分のコードも書き直すことにもなりました...
皆さんもコードの品質は意識して書きましょうね!

Day3↓

Day5↓

参考資料

workflowについて
ymlの構文
GitHub Actionsを用いたCI/CDの基礎
goでのCI/CD
goのCIに役立つツール

GitHubで編集を提案

Discussion