GitlabのCI/CDパイプラインでcommitを追加する
きっかけ
terraform-docsを使ってmoduleレジストリのドキュメント化を行っていた。
moduleを修正するたびに、手動でterraform-docs
を実行するわけなのだが、よく忘れる。
なので自動でドキュメント生成してコミットまで追加してくれる方法を考えた。
前提知識
- Gitlabを使用したことがある
- .gitlab-ci.ymlを使ってpipelineを構築したことがある
実装方法
結論はAccess Tokenを使ったやり方。
ちなみにGitHubの場合
GitHub Actions
だと簡単にコミットに追加できるよう準備されているのでこっちを使った方が良い。
今回はGitlabなので除外。
SSH Keyを使ったやり方
よく見かける方法がこれ。
でも鍵管理したくないので除外。
Access Tokenを使ったやり方
こっちが一番シンプルだった。
Access Tokenの払い出し
選択肢が複数ある。
- Personal Access Token
- Group Access Token
- Project Access Token
Personal Access Token
は個人アカウントに紐づくため、アカウントを削除しちゃうと動かなくなる。
Project Access Token
で最小権限でも良いが、moduleレジストリが増えるたびにtoken発行するのは面倒だ。
Group Access Token
でmodulesグループ配下で汎用的に使えるようにしておいた方が良さそう。
払い出し方
グループ >> 設定 >> アクセストークン
roleはDeveloper、scopeはwrite_repositoryを追加して作成する。
変数登録
tokenが発行されるので対象グループのCI/CDに変数を登録する。
グループ >> 設定 >> CICD >> 変数
Mask variableだけチェック入れておく。
CIの修正
moduleレジストリのciを次のように追記する。
tfdocs:
stage: build
image:
name: quay.io/terraform-docs/terraform-docs
entrypoint:
- ''
script:
- terraform-docs markdown table .
artifacts:
paths:
- README.md
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
auto-commit:
stage: deploy
image:
name: alpine/git
entrypoint:
- ''
before_script:
- git config --global user.name "$GITLAB_USER_NAME"
- git config --global user.email "$GITLAB_USER_EMAIL"
script:
- if [ -n "$(git status --porcelain)" ]; then # 変更差分チェック
- git add README.md
- git commit -m "[ci skip] Terraform-docs Updating README.md"
- git push -f https://oauth2:$COMMIT_ACCESS_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git HEAD:$CI_COMMIT_REF_NAME
- echo "Commit successful"
- fi
needs:
- tfdocs
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
生成したREADME.md
ファイルはartifacts
で、次のauto-commit
ジョブに引き継いでる。
before_scriptでユーザー情報を定義
$GITLAB_USER_NAME
と$GITLAB_USER_EMAIL
は予約変数で、pipelineを実行したユーザー情報が入る。
つまりtfdocsジョブ
で生成したREADME.mdのコミッターは自分になる。
before_script:
- git config --global user.name "$GITLAB_USER_NAME"
- git config --global user.email "$GITLAB_USER_EMAIL"
commitのコメントで無限ループ回避
[ci skip]
を先頭につけるだけで、CIの実行をスキップできる。
これがないと常に変更差分がある場合、無限にCIが動いてしまうので必須である。
- git commit -m "[ci skip] Terraform-docs Updating README.md"
本当は-oでci.skipを指定するのだが、コミット履歴から見分けが付きづらいので辞めた。
push時にToken指定してアクセスする
払い出したAccess Tokenをここで使用する。
oauth2に沿ったURLに修正する必要がある。
https://oauth2:<your_access_token>@gitlab.example.com/project_path/project_name.git
変数を使えば、どのプロジェクトでも汎用的に利用できるようになるのでオススメ。
- git push -f https://oauth2:$COMMIT_ACCESS_TOKEN@$CI_SERVER_HOST/$CI_PROJECT_PATH.git HEAD:$CI_COMMIT_REF_NAME
まとめ
Access Tokenを使って簡単にauto-commitができるようになった。
Access Tokenを使えば、プライベートリポジトリからpullしてCIを回すこともできるのでオススメ。
Discussion