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 などのファイルを書くことで書いたコードが機能します。
具体的には
基本的に以下のように書きます
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ファイル
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ファイル
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で過剰に検出されてしまっているものを減らすことができます。
今回は以下のように書いています。
linters:
enable:
- goimports
- gofmt
脆弱性の検出
ここでは脆弱性(versionの更新がされていないなど)を検出します。
これは外部のパッケージなのでインストールしてから実行しています。
vulncheckの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ファイル
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に役立つツール
Discussion