🐭

go:embed を使った場合に GitHub Actions をどうするか

2021/03/03に公開

TL;DR

touch config.json を走らせる

探索的解決

大望のGo 1.16,ついにリリースされましたね。私はio/fsが一番楽しみでした。Go Teamの方々ありがとうございます。
今回はGo 1.16の新機能, go:embed についてです。使い方とかはググってください。
https://pkg.go.dev/embed/

GitHub ActionsでGo 1.16から新しく導入されたgo:embedを使ってconfig.jsonなどを埋めこむ運用を今後することは増えると思います。私事ですがGoの良さは1 binaryにすべて閉じ込めることができることも1つだと思っているので,.envをおいたりはもちろん,環境変数で設定するのもどうもしっくりこないこともありました。とはいえどうせDockerがあるので手間はそこまでかわらないですが……。
できれば main.go に直書きしてbuild時に含めてしまいたい,お恥ずかしながら,そんな危ないことを個人プロジェクトではしていることもあります(公開repoでは絶対にやらないでくださいね)。

脱線しました。多くの場合.env的なものは,gitにはconfig.sample.json.env.sampleといったファイルだけを含め,各々が手元でconfig.json.envにsecretな値をいれ,config.json.envはignoreされている,といった運用が多いことでしょう。
こういった運用をされている場合,ignoreされる前に空ファイルを作成してしまうというのも1つの手ではあるのですが,なんとなく嫌な感じがしてしまいますし,ちょっとヒヤッとしますよね。

Goはbuild時にembedされているfileを埋め込むので,build時にembedする対象のファイルが無いとエラーになります。よってこのような運用だとGitHub Actionsやその他CIでtestを通す前にそもそもbuildでエラーになることがあります。

これを解決するため,私は

name: test

on: [ push ]

jobs:

  build:
    name: test
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.16
      uses: actions/setup-go@v1
      with:
        go-version: 1.16
      id: go

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

    - name: Get dependencies
      run: |
        touch config.json
        go get -v -t -d ./...
	
    - name: Test
      run: go test ./...

こうしています。Get dependenciesの中のgo get -v -t -d ./... の前に touch config.json をいれています。
今回はsecretな値を使わないものだけをtestしているのでいいですが,testにそれらが必要な場合は

    - name: Get dependencies
      env:
        SECRET: ${{ secrets.SECRET }}
      run: |
        echo $SECRET > config.json
        go get -v -t -d ./...

みたいな感じにするといいと思います。JSONの構造とかがややこしい場合はちょっと面倒ですが……。

おわり

Discussion