Summary
With bundler-cache: true and no Gemfile.lock committed (lockless
workflow, e.g. lock deliberately untracked), the bundle cache key
degenerates: hashFiles('Gemfile.lock') is empty, so the
vendor/bundle cache key becomes effectively constant across runs and
dependency changes. Jobs restore a stale or partially-invalid
vendor/bundle from an arbitrary earlier run. In our case the restored
rspec-support gem was missing lib/rspec/support/source.rb, and the
run then crashed fatally inside rspec's summary formatter
(LoadError), hiding all real test failures.
Observed on
- ruby/setup-ruby@v1,
bundler-cache: true
- Repository with
Gemfile.lock in .gitignore (CI re-resolves deps)
- ubuntu 22.04, Ruby 3.3.12
- run: metanorma/uniword PR CI, 2026-09-24
Expected
When no Gemfile.lock exists, either:
- skip the bundle cache entirely (fresh
bundle install every run —
slower but correct), or
- derive the cache key from
Gemfile + *.gemspec hashes and
git rev-parse HEAD (or the run id), so every dependency change
produces a distinct cache entry and stale bundles are never
restored.
A warning (::warning::) that the bundle cache was skipped/derated
for lockless workflows would also make the failure mode diagnosable.
Workaround we applied
rm -rf vendor/bundle in a pre-setup step (forces pristine install).
Versions
- ruby/setup-ruby@v1 (current main as of 2026-09-24)
- Bundler 4.0.x
Summary
With
bundler-cache: trueand no Gemfile.lock committed (locklessworkflow, e.g. lock deliberately untracked), the bundle cache key
degenerates:
hashFiles('Gemfile.lock')is empty, so thevendor/bundle cache key becomes effectively constant across runs and
dependency changes. Jobs restore a stale or partially-invalid
vendor/bundle from an arbitrary earlier run. In our case the restored
rspec-support gem was missing
lib/rspec/support/source.rb, and therun then crashed fatally inside rspec's summary formatter
(LoadError), hiding all real test failures.
Observed on
bundler-cache: trueGemfile.lockin .gitignore (CI re-resolves deps)Expected
When no Gemfile.lock exists, either:
bundle installevery run —slower but correct), or
Gemfile+*.gemspechashes andgit rev-parse HEAD(or the run id), so every dependency changeproduces a distinct cache entry and stale bundles are never
restored.
A warning (
::warning::) that the bundle cache was skipped/deratedfor lockless workflows would also make the failure mode diagnosable.
Workaround we applied
rm -rf vendor/bundlein a pre-setup step (forces pristine install).Versions