ruby / setup-ruby

An action to download a prebuilt Ruby and add it to the PATH in 5 seconds
https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
MIT License
804 stars 263 forks source link

Wrong cache version is being pulled #644

Closed makrsmark closed 2 weeks ago

makrsmark commented 2 months ago

Ensure the following before filing this issue

Are you running on a GitHub-hosted runner or a self-hosted runner?

GitHub-hosted runner

Link to the failed workflow job (must be a public workflow job, so the necessary information is available)

N/A (private repo)

Any other notes?

My repo is configured to update dependencies via dependabot on a weekly basis. This results in several workflow runs happening at the same time. What happens is one will succeed while the others fail.

This is some of the setup-ruby output from a failing workflow.

Cache key: setup-ruby-bundler-cache-v6-ubuntu-22.04-x64-ruby-3.1.3-wd-/home/runner/work/wurl-workers/wurl-workers-with--without--only--Gemfile.lock-1024f2d7ec17eca5d662d57aabb33f2b5dbf3151f63ba7387703c6f4a510398c
Cache Size: ~136 MB (142370178 B)
/usr/bin/tar -xf /home/runner/work/_temp/50327c27-7f83-405b-9160-d7fadc540f8c/cache.tzst -P -C /home/runner/work/wurl-workers/wurl-workers --use-compress-program unzstd
Received 142370178 of 142370178 (100.0%), 135.5 MBs/sec
Cache restored successfully
Found cache for key: setup-ruby-bundler-cache-v6-ubuntu-22.04-x64-ruby-3.1.3-wd-/home/runner/work/wurl-workers/wurl-workers-with--without--only--Gemfile.lock-e79244d076684691f3e3bee941acbd598e01782903e729f356995601ebfe812f

1024f2d7ec17eca5d662d57aabb33f2b5dbf3151f63ba7387703c6f4a510398cis from the correct PR while
e79244d076684691f3e3bee941acbd598e01782903e729f356995601ebfe812f is from an older PR and also used for the master build once that PR is merged successfully.

This build will eventually fail when running wearerequired/lint-action due to the following:

  bundler: failed to load command: rubocop (/home/runner/work/wurl-workers/wurl-workers/vendor/bundle/ruby/3.1.0/bin/rubocop)
  /opt/hostedtoolcache/Ruby/3.1.3/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.26/lib/bundler/definition.rb:507:in `materialize': Could not find rspec-expectations-3.13.2 in locally installed gems (Bundler::GemNotFound)
    from /opt/hostedtoolcache/Ruby/3.1.3/x64/lib/ruby/gems/3.1.0/gems/bundler-2.3.26/lib/bundler/definition.rb:187:in `specs'
  Error: RuboCop is not installed

It should be noted that I configured the action to run rubocop in the bundler context (rubocop_command_prefix: bundle exec) The Gemfile.lock for this workflow specifies rspec-expectations-3.13.2 while the Gemfile.lock on the older PR (and master) uses spec-expectations 3.13.3. I can see this is also what's used during the workflow when it performs bundle install. The current workaround is to rebase the PR which will update the Gemfile.lock to be based off of the most recent cache.

From what I can tell in the code, setup-ruby pulls the latest cache instead of the cache for the previous version of the Gemfile.lock. Is this possible to change?

dentarg commented 2 months ago

I think it is this assumption that doesn't pan out in the above scenario:

https://github.com/ruby/setup-ruby/blob/2eb6adbfb1f8850489a1f947f9421d777ea89485/bundler.js#L133-L134 https://github.com/ruby/setup-ruby/blob/2eb6adbfb1f8850489a1f947f9421d777ea89485/bundler.js#L156-L160

After Found cache for key, can you see bundle clean being run?

Are you able to share complete logs?

dentarg commented 2 months ago

Maybe you can workaround this issue by not utilizing the cache for Dependabot PRs, if you can set cache-version dynamically when needed (otherwise set it to 0). (Just trying to be creative here)

makrsmark commented 2 months ago

That should work, but at that point I think I'd rather just require/force a rebase which would build with the right cache

makrsmark commented 2 months ago

bundle clean is definitely being run truncated logs from setup-ruby

Run ruby/setup-ruby@v1
Using 3.1.3 as input from file .ruby-version
Modifying PATH
  Entries added to PATH to use selected Ruby:
    /opt/hostedtoolcache/Ruby/3.1.3/x64/bin
Downloading Ruby
  https://github.com/ruby/ruby-builder/releases/download/toolcache/ruby-3.1.3-ubuntu-22.04.tar.gz
  Took   0.98 seconds
Extracting  Ruby
  /usr/bin/tar -xz -C /opt/hostedtoolcache/Ruby/3.1.3 -f /home/runner/work/_temp/b21f1b26-b8ea-4fff-96c5-d9c7f2784605
  Took   0.43 seconds
Print Ruby version
  /opt/hostedtoolcache/Ruby/3.1.3/x64/bin/ruby --version
  ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-linux]
  Took   0.02 seconds
Installing Bundler
  Using Bundler 2.3.26 from Gemfile.lock BUNDLED WITH 2.3.26
  /opt/hostedtoolcache/Ruby/3.1.3/x64/bin/gem install bundler -v 2.3.26
  Successfully installed bundler-2.3.26
  1 gem installed
  Took   0.62 seconds
> bundle install
/opt/hostedtoolcache/Ruby/3.1.3/x64/bin/bundle config --local path /home/runner/work/wurl-workers/wurl-workers/vendor/bundle
/opt/hostedtoolcache/Ruby/3.1.3/x64/bin/bundle config --local deployment true
Cache key: setup-ruby-bundler-cache-v6-ubuntu-22.04-x64-ruby-3.1.3-wd-/home/runner/work/wurl-workers/wurl-workers-with--without--only--Gemfile.lock-40e03469642f65d170a10d46989297876d25d983c6a4a78a4b5b6c87aeb41b8f
Received 16777216 of 142370178 (11.8%), 16.0 MBs/sec
Cache Size: ~136 MB (142370178 B)
/usr/bin/tar -xf /home/runner/work/_temp/18a875df-35be-4152-a1b8-1c4b53211098/cache.tzst -P -C /home/runner/work/wurl-workers/wurl-workers --use-compress-program unzstd
Received 142370178 of 142370178 (100.0%), 67.9 MBs/sec
Cache restored successfully
Found cache for key: setup-ruby-bundler-cache-v6-ubuntu-22.04-x64-ruby-3.1.3-wd-/home/runner/work/wurl-workers/wurl-workers-with--without--only--Gemfile.lock-e79244d076684691f3e3bee941acbd598e01782903e729f356995601ebfe812f
/opt/hostedtoolcache/Ruby/3.1.3/x64/bin/bundle install --jobs 4
Fetching source index from https://rubygems.org/
Fetching gem metadata from https://rubygems.pkg.github.com/wurlinc/..
Using rake 13.2.1
Using concurrent-ruby 1.3.4
... < truncated > ...
Fetching rspec-expectations 3.13.3
... < truncated > ...
Installing factory_bot 6.5.0
Using rspec-collection_matchers 1.2.1
Using rspec-rails 6.1.5
Installing rubocop-rspec 3.0.5
Using rubocop-rspec_rails 2.30.0
Bundle complete! 81 Gemfile dependencies, 625 gems now installed.
Bundled gems are installed into `./vendor/bundle`
1 installed gem you directly depend on is looking for funding.
  Run `bundle fund` for details
/opt/hostedtoolcache/Ruby/3.1.3/x64/bin/bundle clean
Removing factory_bot (6.4.6)
Removing rspec-expectations (3.13.2)
Removing rubocop-rspec (3.0.4)
Removing unicode-display_width (2.5.0)
Saving cache
/usr/bin/tar --posix -cf cache.tzst --exclude cache.tzst -P -C /home/runner/work/wurl-workers/wurl-workers --files-from manifest.txt --use-compress-program zstdmt
Cache Size: ~136 MB (142360636 B)
Cache saved successfully
Took  31.35 seconds

note that rspec-expectations (3.13.3) is being installed and rspec-expectations (3.13.2) is being removed, despite 3.13.2 being in the Gemfile.lock

makrsmark commented 2 months ago

also, i am in agreement. I think the problem is the restore key ends up being setup-ruby-bundler-cache-v6-ubuntu-22.04-x64-ruby-3.1.3-wd-/home/runner/work/wurl-workers/wurl-workers-with--without--only--Gemfile.lock- and ideally, the hash of the previous Gemfile.lock should be appended

MSP-Greg commented 2 months ago

note that rspec-expectations (3.13.3) is being installed and rspec-expectations (3.13.2) is being removed, despite 3.13.2 being in the Gemfile.lock

I'm working on other things, so I really haven't dove into this.

But, doesn't the above imply an issue with Bundler? The cache only allows Bundler to skip installing a gem iff it exists in the cache. It should have no effect on what gems are installed. Assuming a lock file exists...

MSP-Greg commented 2 months ago

There is no way to log Gemfile.lock before setup-ruby starts the Bundler operations. That might be a helpful option for debugging, possibly with before/after flags.

Have you logged/dumped Gemfile.lock to GHA log after setup-ruby?

makrsmark commented 2 months ago

I have not, though i expect it to be updated. Is there a good way to do that in a GHA context?

MSP-Greg commented 2 months ago

At present, the only way is to log it after the setup-ruby step. Just a cat Gemfile.lock should work. Logging the 'before' would require a change to the setup-ruby code.

This issue seems to imply that Bundler is changing/updating the lock file, and that shouldn't be happening.

JFYI, most of the repos I work do not have a committed lock file.

makrsmark commented 2 weeks ago

Sorry for the month delay, but this looks like an issue with the wearerequired/lint-action we're using https://github.com/wearerequired/lint-action/issues/835 Explanation, for anyone else who runs into the issue.

What's happening is our Gemfile will have a non-versioned dependency on DepA. Dependabot will create PRs for DepA and DepB. While the workflow for DepA is running, it gets cached. The workflow for DepB will run a workflow and use the new cached version but the Gemfile.lock is pointing to the old version of DepA. This results in the Gemfile.lock being updated to point to the new version of DepA. THEN, wearerrequired/lint-action runs and one of the first things it does is do a git checkout of the branch (https://github.com/wearerequired/lint-action/blob/master/src/index.js#L55) resetting the Gemfile.lock to point to the old version of DepA. Then, when it goes to run some ruby, it fails because it is looking for the old version of DepA but the new version is installed.

Thanks for giving me some ideas in how to look into it!