はじめに #
Gitlab CI/CDのPipeline実行中に生成されたfileをcommit & pushしたいことが稀にありますが、わりとハマりごとあったのでメモとして残します。
1. .gitlab-ci.yml
の用意
#
基本的には、以下の流れ + .gitlab-ci.yml
でPipeline内部でpushができます。
- read/write repositoryの権限を持ったTOKENを作成
~/.netrc
等でlogin情報を記載- branchがdetached HEADになり、変更がcommitできないので、これの対処
- 変更をpush
push:
image: bitnami/git
before_script:
- echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword $ACCESS_TOKEN" > ~/.netrc # loginはnetrcを利用
- git config --global user.name "gitlab.runner"
- git config --global user.email "dummy"
script:
- git clone $CI_PROJECT_URL # Pipelineでは(HEAD detached at b7931aa)のようなデタッチドヘッドになるので、自分でcloneする。
- cd $CI_PROJECT_NAME
- touch "test-$(date '+%Y-%m-%d %H:%M:%S').txt"
- git add .
- git commit -m "[ci skip] ADD FILE $(date '+%Y-%m-%d %H:%M:%S')" # [ci skip]を入れないと、無限ループになる可能性があるので注意する。
- git push origin HEAD
2. detached HEAD #
pipeline内では自動でprojectのcodeがcloneされていますが、branchを確認するとdetached HEADになり変更してもcommitやpushができない状態です。
$ git branch
* (HEAD detached at 677de8a)
解決方法は以下に記載されているようにいくつかありますが、今回はmainに直接pushしたいので別途projectをcloneすることで回避しました。 https://stackoverflow.com/questions/69267025/detached-head-in-gitlab-ci-pipeline-how-to-push-correctly
3. TOKENの権限 #
Gitlab CI/CDではPipline内のみで使える$CI_JOB_TOKEN
は、cloneはできますがpushはできない権限になっています。
意外とCI/CD内部でpushしたい要望があるらしく、$CI_JOB_TOKEN
にAllow Git push requests to the repositoryのflagを付けれる機能が検討 + 検証用にリリースされています。
- https://gitlab.com/gitlab-org/gitlab/-/issues/389060
- https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html#push-to-a-project-repository-using-a-job-token
残念ながら本番リリースはまだらしい?ので、今回は新規でTOKENを払い出します。
$CI_JOB_TOKEN
が使えないので、projectに対してTOKENを発行する必要があります。
- projectに紐づくTOKENにします。
- 必要な権限は、read/write_repositoryです。
Project/Group Access Tokenは、free版では使用できないようです。その場合は個人Token等を利用します。 https://forum.gitlab.com/t/gitlab-impossible-to-enable-group-access-token/81540/7
またgitlabでは最長365日のTOKENしか作れなくなっているので、有効期限切れに注意します。 https://about.gitlab.com/blog/2023/10/25/access-token-lifetime-limits/
その後、Variablesに登録しておきましょう。
4. 実際に実行してみる #
これら設定をすると、以下のようにPipeline内部でpushをすることが可能になります。
おわりに #
今回のコードやPipelineの実行結果は以下に載せています。参考にどうぞ。