1.この記事で達成したいこと
- GitHub Actionsでyqのコンテナイメージを使ってマニフェストを更新したい
- yqはPythonのパッケージマネージャのpipでも扱うことが出来るけどコンテナイメージで扱うほうが都合がよさそうなのでコンテナイメージでがんばりたい
- コンテナイメージで扱うというのは、docker runコマンドでyqのイメージをスポットで使う感じ
- yqの使い方についてはjqのyaml版と思って大丈夫。詳細は以前書いた記事を参考にしてほしい。
- yqコマンド(jq wrapper for YAML)使い方備忘録
$ docker run --rm -v "$PWD:$PWD" -w="$PWD" \
--entrypoint yq linuxserver/yq \
<yqコマンド>
GitHub Actions上でDockerコンテナイメージを扱う方法と注意点
- やることは addnab/docker-run-action を使うだけ
- 基本的な使い方はaddnab/docker-run-actionの上記のリンクにサンプルコードを添えて書かれている
- しかし、docker runコマンドのときのように同アクションを使おうとすると、ホストとコンテナ間でマニフェストが置かれたディレクトリをマウントするところでつまずいた
- そこで、この記事では特に同アクションを使う際のホストとコンテナ間でディレクトリをマウント方法する方法について、yqのコンテナイメージを使って解説していきたい
2.前提
- addnab/docker-run-actionの検証リポジトリはpublic
- public/private問わず、同Actionsを使う際の注意点は同じはずだけど念のため書いておく
- yqは以下のとおり2種類あるが、ここでは https://hub.docker.com/r/linuxserver/yq を扱う
↓この記事で使うyq | ||
---|---|---|
Github | https://github.com/kislyuk/yq | https://github.com/mikefarah/yq |
Docker Image | https://hub.docker.com/r/linuxserver/yq | https://hub.docker.com/r/mikefarah/yq |
3.環境情報
- ローカル始めバージョンを書いておく必要があるものはない
- 使うActionやyqのイメージのバージョンについては後述するWorkflowを参照してほしい
4.この記事で扱うサンプルコード(つまずいたところは解決済)
- yqのコンテナイメージで更新対象のマニフェスト(manifests/deployment.yml.tmpl)
- 書き換え箇所はマニフェストのごく一部なので抜粋する
---
apiVersion: apps/v1
kind: Deployment
metadata:
# 略
spec:
replicas: 3
selector:
matchLabels:
app: sampleapp
template:
metadata:
labels:
app: sampleapp
spec:
affinity:
# 略
containers:
- name: sampleapp
image: <REGISTRY>/<CONTAINER_IMAGE>:<IMAGE_TAG>
ports:
- containerPort: 80
- yqのコンテナイメージを使うWorkflow(.github/workflows/mod_manifest.yml)
jobs:
main:
runs-on: 'ubuntu-20.04'
env:
MANIFEST_PATH: 'manifests'
steps:
- name: Modify image tag
uses: addnab/docker-run-action@v3
with:
## yqのイメージを指定
image: linuxserver/yq:2.13.0
## docker runコマンドで渡していたオプションを書く
## ">"を使い、適宜改行する
## -vオプションの使い方はやや注意なので後述
options: >
--rm -v ${{ github.workspace }}/${{ env.MANIFEST_PATH }}:/opt/${{ env.MANIFEST_PATH }}
-w=/opt/${{ env.MANIFEST_PATH }}
--entrypoint yq
shell: bash
run: >
yq -ry '.spec.template.spec.containers[0].image
|="'${{ secrets.REGISTRY }}'/'${{ secrets.CONTAINER_IMAGE }}':'${{ github.sha }}'"'
/opt/${{ env.MANIFEST_PATH }}/deployment.yml.tmpl > /opt/${{ env.MANIFEST_PATH }}/deployment.yml
5.addnab/docker-run-actionでディレクトリをマウントする間違ったやり方
- -vオプションで指定するホスト側のパスを「リポジトリのルートディレクトリからマニフェストの 相対パス 」とする
- name: Modify image tag
uses: addnab/docker-run-action@v3
with:
## yqのイメージを指定
image: linuxserver/yq:2.13.0
## docker runコマンドで渡していたオプションを書く
## ">"を使い、適宜改行する
## -vオプションで指定するホスト側のパスを「リポジトリのルートディレクトリからマニフェストの相対パス」とする
options: >
--rm -v ${{ env.MANIFEST_PATH }}:/opt/${{ env.MANIFEST_PATH }}
-w=/opt/${{ env.MANIFEST_PATH }}
--entrypoint yq
shell: bash
run: >
yq -ry '.spec.template.spec.containers[0].image
|="'${{ env.REGISTRY }}'/'${{ env.CONTAINER_IMAGE }}':'${{ github.sha }}'"'
/opt/${{ env.MANIFEST_PATH }}/deployment.yml.tmpl > /opt/${{ env.MANIFEST_PATH }}/deployment.yml
- 実行するとエラーとなってしまう、、
- yq: error: argument files: can’t open ‘/opt/manifests/deployment.yml.tmpl’: [Errno 2] No such file or directory: ‘/opt/manifests/deployment.yml.tmpl’
- エラーログ抜粋
Run addnab/docker-run-action@v3
with:
image: linuxserver/yq:2.13.0
options: --rm -v manifests:/opt/manifests -w=/opt/manifests --entrypoint yq
shell: bash
run: yq -ry '.spec.template.spec.containers[0].image |="'your_registry'/'your_container_image':'xxxxxxxxxxxxxx'"' /opt/manifests/deployment.yml.tmpl > /opt/manifests/deployment.yml
env:
MANIFEST_PATH: manifests
REGISTRY: your_registry
CONTAINER_IMAGE: your_container_image
略
Unable to find image 'linuxserver/yq:2.13.0' locally
2.13.0: Pulling from linuxserver/yq
略
Digets: 略
Status: Downloaded newer image for linuxserver/yq:2.13.0
usage: yq [-h] [--yaml-output] [--yaml-roundtrip] [--width WIDTH]
[--indentless-lists] [--in-place] [--version]
[jq_filter] [files [files ...]]
yq: error: argument files: can't open '/opt/manifests/deployment.yml.tmpl': [Errno 2] No such file or directory: '/opt/manifests/deployment.yml.tmpl'
6.解決策
- -vオプションで指定するホスト側のパスを「GitHub Actionsのホスト側の 絶対パス 」とする
- Runnerのワーキングディレクトリは、GITHUB_WORKSPACE で取得できる!
options: >
- --rm -v ${{ env.MANIFEST_PATH }}:/opt/${{ env.MANIFEST_PATH }} ##ホストの相対パス:コンテナ側の絶対パス
+ --rm -v ${{ github.workspace }}/${{ env.MANIFEST_PATH }}:/opt/${{ env.MANIFEST_PATH }} ##ホストの絶対パス:コンテナ側の絶対パス
-w=/opt/${{ env.MANIFEST_PATH }}
--entrypoint yq
7.[備考]GITHUB_WORKSPACEとは
- GitHubのドキュメントのGITHUB_WORKSPACEの説明文の頼りにすると、Runnerのデフォルトの作業ディレクトリと書かれている
GITHUB_WORKSPACE
The default working directory on the runner for steps, and the default location of your repository when using the checkout action. For example, /home/runner/work/my-repo-name/my-repo-name.
参考:https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
7-1.GITHUB_WORKSPACE ${{ github.workspace }}をechoしてみる
- 呼び出すには、${{ github.workspace }} とすればよいので、pwdやlsコマンドと併せて実行してみる
steps:
- uses: actions/checkout@v2
- run: echo -n "github.workspace ${{ github.workspace }}"
- run: pwd
- run: ls -la
結果
- run: echo -n “github.workspace ${{ github.workspace }}”
github.workspace /home/runner/work/actions-dispatch-playground/actions-dispatch-playground
- run: pwd
/home/runner/work/actions-dispatch-playground/actions-dispatch-playground
- run: ls -la
total 40
drwxr-xr-x 5 runner docker 4096 Jan 31 02:43 .
drwxr-xr-x 3 runner docker 4096 Jan 31 02:43 ..
drwxr-xr-x 8 runner docker 4096 Jan 31 02:43 .git
drwxr-xr-x 3 runner docker 4096 Jan 31 02:43 .github
-rw-r--r-- 1 runner docker 8429 Jan 31 02:43 .gitignore
-rw-r--r-- 1 runner docker 1069 Jan 31 02:43 LICENSE
-rw-r--r-- 1 runner docker 42 Jan 31 02:43 README.md
drwxr-xr-x 2 runner docker 4096 Jan 31 02:43 manifests
GITHUB_WORKSPACE ${{ github.workspace }}のGitHubのドキュメントで書かれている、
The default working directory on the runner for steps, and the default location of your repository when using the checkout action
とは、リポジトリのルートディレクトリ とみてよさそう。