Bitbucket Pipelines:Git LFS のファイルがポインターのまま届く
Pipelines は、頼まない限り Git LFS のファイルを取ってきません。2018年に Pipelines で LFS が使えるようになったとき、Atlassian は取得に時間がかかり、多くのビルドには要らないとして、この既定を残しました(Atlassian の告知・英語)。ステップのクローンでは、LFS のファイルはどれもポインターという短いテキストで、開こうとした道具は止まります。git-lfs 3.7 で LFS を飛ばしたクローンを作り、その中の zip を開くと、こうなりました。
$ cat assets.zip
version https://git-lfs.github.com/spec/v1
oid sha256:031d5c8db194a1936ab800a2f24e8c4642182e51d0d95775137cfc8cf55b12ea
size 5108
$ unzip -l assets.zip
Archive: assets.zip
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. …
$ python -c "import zipfile; zipfile.ZipFile('assets.zip')"
zipfile.BadZipFile: File is not a zip file
ポインターかどうか
Build setup のクローンは GIT_LFS_SKIP_SMUDGE=1 付きで動きます。2022年のコミュニティの質問に貼られたステップのログに出ています(Build setup に時間がかかる)。スクリプトに入れられる確かめ方は2つです。
script:
- head -c 120 assets.zip
- git lfs ls-files
ポインターは version https://git-lfs.github.com/spec/v1 で始まり、最後の行が本物のファイルの大きさです。git lfs ls-files はファイルごとに印を付け、ID のあとの - がポインター、* が本物のファイルです。試したクローンでは 031d5c8db1 - assets.zip と出て、git lfs pull のあとは 031d5c8db1 * assets.zip になりました。この確かめ方にはイメージに git-lfs が要り、無いと Git は git: 'lfs' is not a git command と答えます。
git status には何も出ません。コミットに入っているのはポインターなので、Git から見ると足りないものはありません。
要るステップだけ lfs: true
pipelines:
default:
- step:
name: Build
clone:
lfs: true
script:
- unzip assets.zip
ファイルの一番上の clone: に書くと全部のステップに効き、どのステップも初めに LFS のファイルを全部取ってきます。Atlassian の Git クローンの動作は、ビルドの時間と資源を抑えるため、ステップごとに付けるか、ステップに要るファイルだけを取るよう勧めています。大きな LFS のファイルは、ビルドのディスクも埋めます(「No space left on device」)。
1つのファイルだけ
同じページに、ファイルが1つだけ要るステップの例があります。lfs は付けずに git-lfs を入れ、そのファイルを名指しで取ります。
- step:
clone:
lfs: false
script:
- apt-get update && apt-get install -y git-lfs
- git lfs pull --include=assets.zip
Atlassian の例は、この取得に認証を足していません。apt-get が使えるのは Debian と Ubuntu のイメージです。ほかのイメージではそのやり方で git-lfs を入れるか、入れた自前のイメージを作ります。
push で「'git-lfs' was not found on your path」
lfs: true のステップでコミットして push するには、イメージに git-lfs が要ります。無いと、push はこう止まります。
This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks'). error: failed to push some refs to …
この文面は、git lfs install がリポジトリに書く pre-push フックから出ます。試したクローンの .git/hooks/pre-push で中身を読みました。Atlassian の記事 Pipelines failing with "This repository is configured for Git LFS but 'git-lfs' was not found on your path"(英語)は、ステップのスクリプトで git-lfs を入れるか、毎回入れずに済むよう自前のイメージに入れています。文面のとおりフックを消すと、push するコミットの LFS のファイルを git-lfs が送らなくなります。
既定の認証で LFS のファイルを push する
git-lfs を入れても、新しい LFS のファイルを含むコミットの push は通らないことがあります。Atlassian の記事 How to push LFS files using Bitbucket Pipelines?(英語)の例です。
fatal: could not read Username for 'https://bitbucket.org': No such device or address … error: failed to push some refs to …
Pipelines がステップ自身のリポジトリ向けに用意する認証では、LFS の push ができません。Atlassian はこれを BCLOUD-23180(英語)として追っていて、2024年3月から未解決のバグです。記事は別の push のしかたを2つ挙げています。
write:repository:bitbucketの権限を付けた API トークンを、secured の変数に入れて使う:git push "https://${BB_USER}:${BB_API_TOKEN}@bitbucket.org/${BITBUCKET_REPO_FULL_NAME}.git"。リポジトリにプッシュして戻すは、read:repository:bitbucketも求めています。- SSH:
git remote set-url origin "$BITBUCKET_GIT_SSH_ORIGIN"。同じページでは、push できるよう、リポジトリの Pipelines の SSH キーを個人の SSH キーに足しています。
記事のコミットメッセージは [skip ci] で始まり、push でもう1つのパイプラインが動かないようにしています。
取ってこられないファイル
取得が「Object does not exist on the server」で失敗するときの原因として、Atlassian の Troubleshoot Git LFS in Bitbucket(英語)は2つを挙げています。ポインターはリポジトリにあるのに、ファイルが LFS の置き場に届いていない場合と、置き場が一時的に止まっていた場合です。前者は元のファイルからもう一度上げ直します。元のファイルが無ければ、取り戻せません。同じ記事によると、ワークスペースの容量を超える LFS の push を Bitbucket は断ります。使っている量は、ワークスペースの管理者が Workspace settings の Git LFS で見られます。
IntelliJ IDEA で Bitbucket Pipelines を見る
Pipeline Inbox for Bitbucket Pipelines は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。Bitbucket Cloud の全部のリポジトリのパイプラインを IDE のツールウィンドウに並べ、ステップ、失敗したステップと止まったコマンド、Bitbucket が書くそばから伸びるステップのログを見せます。一覧・ステップ・ログは無料。パイプラインの実行・やり直し・停止は Pro(月 US$1.50・30日の無料試用つき)。
Atlassian・Bitbucket・Bitbucket Pipelines は Atlassian の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは Atlassian・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:浅いクローンで止まる Git のコマンド(origin/main・git describe) · スケジュールしたパイプラインが動かない · 「Container 'build' failed to pull image」 · サービスに「Connection refused」(MySQL・PostgreSQL・Redis) · 「Not authorized to perform sts:AssumeRoleWithWebIdentity」(OIDC で AWS) · テストの結果が出ない · 変数が空になる · 「Host key verification failed」(SSH) · 「Cannot connect to the Docker daemon」 · 「authorization denied by plugin pipelines」(Docker) · 「Container 'docker' exceeded memory limit.」 · push したのに Pipelines が動かない · 「Container 'Build' exceeded memory limit.」 · 「Exceeded build time limit of 120 minutes」 · キャッシュが効かない · 「unexpected system error」 · 「command not found」 · サブモジュールを取ってこない · 「We couldn't clone the repository」 · 「No online runner available」 · 「No space left on device」 · 「Step exceeded processing limits」 · 次のステップにアーティファクトが無い · 前は通ったビルドが今は落ちる · Build setup に時間がかかる · ビルド時間を使い切った · 「Permission denied to update branch」 · 「You have reached your pull rate limit」(Docker Hub) · 「There is an error in your bitbucket-pipelines.yml」 · 「This pipeline was paused」(デプロイ) · condition: changesets で飛ばされるステップ(includePaths) · 1つが失敗しても走り続ける並列のステップ(fail-fast) · IntelliJ IDEA の Bitbucket Pipelines 用プラグインの比較 · English