Skip to content

Add support for GIT LFS checkout#3909

Open
lizrabuya wants to merge 6 commits into
feat/git-checkout-featuresfrom
feat/sup-6529/lfs-checkout
Open

Add support for GIT LFS checkout#3909
lizrabuya wants to merge 6 commits into
feat/git-checkout-featuresfrom
feat/sup-6529/lfs-checkout

Conversation

@lizrabuya
Copy link
Copy Markdown
Contributor

@lizrabuya lizrabuya commented May 11, 2026

Description

Add configuration and environment variables when the backend sets BUILDKITE_GIT_LFS_ENABLED=true in the job environment. When BUILDKITE_GIT_LFS_ENABLED=true is set, the agent will check if the git-lfs binary is installed and proceed to perform a git lfs fetch + git lfs checkout.

Changes

Configuration & CLI (clicommand/bootstrap.go, internal/job/config.go)

  • Added a new GitLFSEnabled bool field to ExecutorConfig, backed by env var BUILDKITE_GIT_LFS_ENABLED
  • Exposed it as a --git-lfs-enabled CLI flag on the bootstrap command with usage description
  • Wired the flag through from BootstrapConfig into ExecutorConfig

Checkout behaviour (internal/job/checkout.go)

  • Added a fail-fast binary check: if GitLFSEnabled is true and git-lfs is not on PATH, the checkout fails immediately with a descriptive error before any fetch/checkout work
  • Added git lfs install --local after clone/clean but before fetch, so the LFS filter is registered in the local repo config
  • Added a call to gitLFSFetchCheckout after the main git checkout (and after submodule updates) to explicitly pull down and materialise LFS objects

LFS fetch helper (internal/job/git.go)

  • Added gitLFSFetchCheckout, which runs git lfs fetch then git lfs checkout, wrapping each failure with a distinct error prefix ("git lfs fetch: ..." / "git lfs checkout: ...") so the failing step is identifiable from logs alone

Smudge bypass (internal/job/executor.go)

  • Set GIT_LFS_SKIP_SMUDGE=1 in setUp so LFS objects are never downloaded implicitly during git checkout; the explicit gitLFSFetchCheckout call handles download instead

Tests (internal/job/checkout_test.go)

  • Added TestDefaultCheckoutPhase_GitLFS covering four scenarios: LFS disabled, LFS enabled with binary present, LFS enabled with binary missing (PATH restricted via t.Setenv), and LFS enabled with a failing git lfs command (fake git-lfs script that exits 1)

Windows test caveats

Two of the LFS error-path subtests (LFS enabled git lfs command fails and LFS enabled git lfs fetch fails) are skipped on Windows. They cannot run there for a fundamental reason, not flakiness:

  • These tests work by overriding PATH to point at a fake git-lfs script that exits non-zero, so we can assert our error-wrapping behaviour.
  • Git for Windows ships its own git-lfs.exe inside GIT_EXEC_PATH (the Git installation's libexec/git-core directory). When git resolves a subcommand like git lfs ..., it looks in GIT_EXEC_PATH before falling back to PATH.
  • That means our PATH override is bypassed entirely on Windows — the real bundled git-lfs.exe runs, succeeds, and the test fails because we expected our fake to return an error.
  • The Go code being exercised (error wrapping in gitLFSFetchCheckout and git lfs install --local failure handling) is platform-agnostic, so the Linux runs give us the real coverage. Skipping on Windows is a test-harness limitation, not a behavioural gap.

Additionally, the two happy-path subtests (LFS disabled, LFS enabled binary present) use os.MkdirTemp + a best-effort RemoveAll in t.Cleanup rather than t.TempDir(). On Windows, git's child processes (credential helpers, the git-lfs filter-process) can keep file handles open past their parent's exit. t.TempDir()'s cleanup is strict and fails the test on unlinkat ... being used by another process errors; the best-effort variant lets the test pass while still cleaning up what it can.

Testing

  • Tests have run locally (with go test ./...). Buildkite employees may check this if the pipeline has run automatically.
  • Code is formatted (with go tool gofumpt -extra -w .)

Disclosures / Credits

The main function changes were implemented by me based on the recommendation from the research done for this function. I used Claude to review the code and to assist with writing the tests.

@lizrabuya lizrabuya changed the title Enable git-lfs checkout Add Git LFS Config and Environment Variables May 11, 2026
@lizrabuya lizrabuya changed the base branch from main to feat/git-checkout-features May 11, 2026 06:57
@lizrabuya lizrabuya changed the title Add Git LFS Config and Environment Variables Add Git LFS support May 11, 2026
@lizrabuya lizrabuya force-pushed the feat/sup-6529/lfs-checkout branch from f9e4186 to 255aa11 Compare May 11, 2026 07:10
@lizrabuya lizrabuya changed the title Add Git LFS support Add support for GIT LFS checkout May 11, 2026
@lizrabuya lizrabuya marked this pull request as ready for review May 22, 2026 04:48
@lizrabuya lizrabuya requested review from a team as code owners May 22, 2026 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant