🕌

Golangで学ぶGithub actions入門

2022/07/09に公開

Github actionsでできること

より良い開発者体験や開発効率を求めてCI/CDの構築は今や欠かせないものになりつつあります。
そこで、Github actionsでどのようにCI/CDを構築すればよいか、開発にGolangを使っている場合をサンプルに説明します。Github actionsをこれから始めていく人が概要を掴みやすい内容の記事になっています。

初めにGithub actionsの説明について見ていきます。
以下は公式サイトからの引用です。

ソフトウェア開発ワークフローをリポジトリの中で自動化し、カスタマイズし、実行しましょう。
CI/CDを含む好きなジョブを実行してくれるアクションを、見つけたり、作成したり、共有したり、完全にカスタマイズされたワークフロー中でアクションを組み合わせたりできます。

要するにソフトウェア開発の中でやらないといけない作業を自動化することができ、それを自分の好きなようにカスタマイズできるということができるみたいです。

自動化できること

では、Github actionsで何が自動化できるのでしょうか。
主によく使われるものをいくつかあげてみました。
これ以外にも自動化できるものはあるので、興味があれば調べてみて下さい。

CI
・テスト
・静的解析
・脆弱性診断

CD
・自動デプロイ
・slackへの通知

Github actionsの大きな流れ

Github actionが走る流れは以下のようになります。

1.pushなどの指定したイベントが起きる

2.検証環境が立ち上がる

3.リポジトリからソースコードをとってくる

4.指定した言語のセットアップが行われる

5.指定した処理が実行される

これらを.github/workflowsディレクトリの中にymlファイルとして記述することで処理が行われるようになります。
扱っている開発環境によって、検証に使えるライブラリなどが変わってくるので、言語によってよく使われているライブラリは調べてみて下さい。

細かい説明は省きますが、以下のような記述でmasterブランチにpushするとGithub actionsが走ってHello Worldが出力されます。ymlファイルの記述を見ると先ほどの大まかな流れに沿っていることが分かると思います。言語は使用していないので指定した言語のセットアップは行われていません。(リポジトリはこちら)

.github/.workflows/hello.yml
name: Sample actions

on:
  push:
    branches: master

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Run a one-line script
        run: echo Hello World!

GolangでのGithub actions

次に具体的にGolangだとどのようにGithub actionsを組んでいけば良いのか具体的なymlファイルを元にしながら見ていきます。

・テスト
単純なテストなのでそのままgo testを実行しています。

.github/.workflows/test.yml
name: Test

on:
  push:
    branches:
      - master

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set up Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.17

      - name: Get dependencies
        run: go get -v -t -d ./...

      - name: Test code
        run: go test -v .

・静的解析
golangci-lintを使うのが一般的です。
lintの設定は色々できるみたいなので、厳密なチェックを行いたい場合はオプションを設定することができます。

.github/.workflows/lint.yml
name: golangci-lint
on:
  push:
    tags:
      - v*
    branches:
      - master
  pull_request:
jobs:
  golangci:
    name: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-go@v3
        with:
          go-version: 1.17
      - uses: actions/checkout@v3
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v3
        with:
          # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
          version: v1.29

・lambdaでのデプロイ
環境変数はsecretキーとして設定できるので、githubのsettingで設定して使います。

.github/.workflows/deploy.yml
name: deploy to lambda

on:
  push:
    branches: [master]

jobs:
  build:
    name: Build Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Setup Go
        uses: actions/setup-go@v2

      - name: Checkout Code
        uses: actions/checkout@v2

      - name: Get Dependencies
        run: go get -v

      - name: Build
        run: go build -v main.go

      - name: Zip
        run: zip function.zip main

      - name: Deploy
        uses: appleboy/lambda-action@master
        with:
          aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY }}
          aws_secret_access_key: ${{ secrets.AWS_SECRET_KEY }}
          aws_region: ${{ secrets.AWS_REGION }}
          function_name: goLambdaDeploy
          zip_file: function.zip

・テスト実行にDBが必要な場合
serviceを使ってテスト用のDBを立てる

.github/.workflows/test.yml
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:

  test:
    name: Test
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:12
        env:
          POSTGRES_USER: root
          POSTGRES_PASSWORD: secret
          POSTGRES_DB: simple_bank
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.15
      id: go

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2

    - name: Install golang-migrate
      run: |
        curl -L https://github.com/golang-migrate/migrate/releases/download/v4.12.2/migrate.linux-amd64.tar.gz | tar xvz
        sudo mv migrate.linux-amd64 /usr/bin/migrate
        which migrate

    - name: Run migrations
      run: make migrateup

    - name: Test
      run: make test

// 追加したいこと
reviewdogの構築

終わりに

細かいymlファイルの書き方は説明しませんでしたが、何となくGithub actionsがおこなっていることのイメージがついたのではないでしょうか。
実際の開発だと、テストにmakefileを使ったり、DBを伴うテストが必要な場合もあります。
その際はDBコンテナを立ち上げる必要があったりして、記述が複雑になったりすることがありますが、基本的な流れが分かっていればそこまで難しいものでもありません。
Github actionsの公式ドキュメントにもymlファイルのサンプルがあるので、それを参考にしながら開発環境に取り入れてみて下さい!

参考

Go言語 GitHub Actions テストとリリース
GitHub Actions で Go パッケージの CI 作業を一通り行う

Discussion