Docker + GoでGitHub Actionsを作ったらWORKDIRが効かなくてハマった

GitHub Actions Advent Calendar 2022 の8日目が空いていたのでお邪魔します。

ECRに指定したタグのDocker imageが存在するかチェックするActionを作りました。

github.com

imageが存在しない場合はビルドしてからデプロイ、する場合はビルドをスキップしてデプロイだけ行う、というケースに対応することを想定しています。

aws-cliで確認しようと思うとレスポンスをjqで処理したり、利用するAPIによってはexit 1したりするのが面倒なので、その辺を考えなくていいのがメリットです。

利用法(2022/12/12時点)

- name: Check if Docker image with tag exists in ECR
  uses: mnmandahalf/check-ecr-image-exists@v0.1.3

内部ではaws-sdk-goを利用しているのですが、いざMarketplaceに公開した後にアクションを利用すると、entrypointで実行しているスクリプト内でのgo run /app/ecr.go の実行時に同階層かつカレントディレクトリにあるはずのgo.modが見つからず、モジュールがインポートできないという事象が発生しました。

/app/ecr.go:10:2: no required module provides package github.com/aws/aws-sdk-go-v2/aws: go.mod file not found in current directory or any parent directory; see 'go help modules'
/app/ecr.go:11:2: no required module provides package github.com/aws/aws-sdk-go-v2/config: go.mod file not found in current directory or any parent directory; see 'go help modules'
/app/ecr.go:12:2: no required module provides package github.com/aws/aws-sdk-go-v2/credentials: go.mod file not found in current directory or any parent directory; see 'go help modules'
/app/ecr.go:13:2: no required module provides package github.com/aws/aws-sdk-go-v2/service/ecr: go.mod file not found in current directory or any parent directory; see 'go help modules'

結論から言うとWORKDIR命令の結果いるはずの場所にいないのが原因のようでした。

https://docs.github.com/ja/actions/creating-actions/dockerfile-support-for-github-actions#workdir

GitHub では、ワーキング ディレクトリのパスを環境変数 GITHUB_WORKSPACE に設定します。 Dockerfile では、WORKDIR 命令を使用しないことをお勧めします。 アクションが実行される前に、GitHub では、GITHUB_WORKSPACE ディレクトリを、Docker イメージ内にあったその場所になにがあってもその上にマウントし、GITHUB_WORKSPACE をワーキング ディレクトリとして設定します。 詳細については、"Docker ドキュメントの環境変数の使用" に関するページと WORKDIR リファレンスを参照してください。

ワーキングディレクトリが変わってしまっているので、結果的に cd /app && go run ecr.go することで解決しました。

手元でdocker buildしてテストしてもワーキングディレクトリがWORKDIRになっている状態なのでテストにならないのが罠だなと思いました。

皆様もDockerでActionsを作成するときはお気をつけください。