GoでGitHubのカスタムアクションを作ると少し辛かった話
はじめに
最近、GitHubのカスタムアクションをGoで実装しました。しかし、作成したアクションの都合上、1つのアクションとしてまとめようとすると少し工夫が必要だったという話をしていきたいと思います。
GitHubのカスタムアクションとは
GitHub Actionsのワークフローで使用する独自のアクションを作成することができ、アクションはマシン上で直接実行することも、Dockerコンテナで実行することもできます。 アクションの種類はDocker
, JavaScript
, 複合アクション
の3つあります。
今回作ったもの
そして、以下が今回作ったものです。K6のCRD(Custom Resource Definition)の設定項目をGitHub ActionsにてオーバーライドしてKubernetesに適用することができるツールです。(開発途中)
- name: Configure EKS
run: |
aws eks update-kubeconfig --name eks
- name: Create K6 CRD
uses: ymktmk/operate-k6-crd@main
with:
method: create
parallelism: 1
template: ./example/k6.yaml
Dockerで作ると
以下のようにDockerfileを記述し、action.yamlで指定します。Dockerの場合はworkflowの一番初めにコンテナイメージをビルドし、実際に実行するタイミングでマウント& withにてセットした値を環境変数として設定します(with.methodの場合INPUT_METHOD)
しかし、今回はDockerを使うと致命的なミスが発覚しました😱
FROM golang:1.18
WORKDIR /work
COPY . /work
RUN GOARCH=amd64 GOOS=linux go build -ldflags="-s -w" -o app .
ENTRYPOINT ["/work/app"]
name: 'Operate K6 CRD'
description: 'Create and delete K6 Custom Resource Definitions to Kubernetes Cluster'
author: 'ymktmk'
runs:
using: 'docker'
image: 'Dockerfile'
# ----- 省略 ---- #
Dockerの何がいけなかったのか
今回はアクションの都合上~/.kube/configを扱いたかったのですがDockerで作成した際に隠しファイルはマウントできない感じになっていました。(GitHub ActionsでDockerを扱う都合上)
Composite Actionで解決する
そこで、Composite Actionを使うことで解消することができました。Composite Actionは再利用可能なActionを作成することができます。
以下がComposite Actionを再現したyamlファイルです。これで1つのアクションと見せかけて、Goを実行することができました👏
(GitHubのrelease機能を使ってバイナリファイルを置いて、それをダウンロードして実行する方が良いです。開発途中なのでお許しを)
name: 'Operate K6 CRD'
description: 'Create and delete K6 Custom Resource Definitions to Kubernetes Cluster'
author: 'ymktmk'
branding:
icon: 'k6'
color: 'orange'
inputs:
method:
description: 'set create or delete'
required: true
parallelism:
description: 'parallelism'
required: false
default: ''
template:
description: 'k6 template file path'
required: true
runs:
using: 'composite'
steps:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
- name: clone
shell: bash
run: |
git clone https://github.com/ymktmk/operate-k6-crd.git
cd operate-k6-crd && GOARCH=amd64 GOOS=linux go build -ldflags="-s -w" -o ../main main.go
- name: build & run
shell: bash
run: ./main
env:
INPUT_METHOD: ${{ inputs.method }}
INPUT_VUS: ${{ inputs.vus }}
INPUT_DURATION: ${{ inputs.duration }}
INPUT_RPS: ${{ inputs.rps }}
INPUT_PARALLELISM: ${{ inputs.parallelism }}
INPUT_FILE: ${{ inputs.file }}
INPUT_TEMPLATE: ${{ inputs.template }}
さいごに
最終的にaction.yamlはいけてない感じになってしまいましたが(JavaScriptで書けばおそらくスッキリする)、Dockerを使わなかったことでコンテナの起動時間を削減できて良かったと感じています。
Discussion