Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows lockfiles are broken #2

Closed
wuputah opened this issue Oct 14, 2011 · 3 comments
Closed

Windows lockfiles are broken #2

wuputah opened this issue Oct 14, 2011 · 3 comments

Comments

@wuputah
Copy link
Contributor

wuputah commented Oct 14, 2011

Gemfile + Gemfile.lock:
https://gist.github.com/b54c6bc9fb536503c1e5

@wuputah
Copy link
Contributor Author

wuputah commented Oct 14, 2011

~/code/customers % git clone git@gist.github.com:b54c6bc9fb536503c1e5.git
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (4/4), done.

~/code/customers % cd b54c6bc9fb536503c1e5

code/customers/b54c6bc9fb536503c1e5 (master) % h create -s cedar
malloc_limit=1000000000 (8000000)
heap_min_slots=1000000 (10000)
Creating glowing-waterfall-7416... done, stack is cedar
http://glowing-waterfall-7416.herokuapp.com/ | git@heroku.com:glowing-waterfall-7416.git
Git remote heroku added

code/customers/b54c6bc9fb536503c1e5 (master) % gp heroku master
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.90 KiB, done.
Total 4 (delta 0), reused 4 (delta 0)

-----> Heroku receiving push
-----> Ruby app detected
-----> Installing dependencies using Bundler version 1.1.rc
       Running: bundle install --without development:test --path vendor/bundle
       You are trying to install in deployment mode after changing
       your Gemfile. Run `bundle install` elsewhere and add the
       updated Gemfile.lock to version control.
       If this is a development machine, remove the Gemfile freeze
       by running `bundle install --no-deployment`.
       You have added to the Gemfile:
       * source: git://github.com/arsduo/koala.git (at master)
       * source: rubygems repository http://rubygems.org/
       * rails (= 3.1.1)
       * pg
       * oa-basic
       * koala
       * omniauth
       * json
       * mechanize (= 1.0.0)
       * htmlentities
       * rake (= 0.8.7)
       * mixpanel_client
       * geokit
       * airbrake
       * exception_notification
       * delayed_job (= 2.1.4)
       * uglifier
       * thin
       * newrelic_rpm
       You have changed in the Gemfile:
       * koala from `git://github.com/arsduo/koala.git (at master)` to `no specified source`

 !
 !     Failed to install gems via Bundler.
 !
 !     Heroku push rejected, failed to compile Ruby app

To git@heroku.com:glowing-waterfall-7416.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@heroku.com:glowing-waterfall-7416.git'

@hone
Copy link
Member

hone commented Oct 16, 2011

It's because of codon:

Settings are listed in order of priority. The top value will be used.

       frozen
       Set for the current user (/app/.bundle/config): "1"

       path
       Set for the current user (/app/.bundle/config): "vendor/bundle"

       disable_shared_gems
       Set for the current user (/app/.bundle/config): "1"

       without
       Set for the current user (/app/.bundle/config): "development:test"

hone added a commit to hone/heroku-buildpack-ruby that referenced this issue Oct 16, 2011
hone added a commit to hone/heroku-buildpack-ruby that referenced this issue Oct 16, 2011
@hone hone closed this as completed Oct 16, 2011
@hone
Copy link
Member

hone commented Oct 16, 2011

This will go out on monday's deploy.

GBognar pushed a commit to GBognar/heroku-buildpack-ruby that referenced this issue Jul 10, 2012
lyoshenka referenced this issue in lyoshenka/heroku-buildpack-ruby-jekyll Nov 7, 2012
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
puneet-sutar referenced this issue in puneet-sutar/heroku-buildpack-ruby Jan 3, 2017
kingdonb pushed a commit to kingdonb/heroku-buildpack-ruby-with-sqlite3 that referenced this issue Aug 14, 2017
SteveLTN pushed a commit to ThisisDeploy/heroku-buildpack-ruby that referenced this issue Jan 16, 2019
schneems added a commit that referenced this issue Nov 4, 2019
# This is the 1st commit message:

Failing test for Bundler 2 and Ruby 2.5.5

When you deploy an app with Bundler 2.0.1 in the Gemfile.lock with Bundler 2.0.2 on the system, it works the first time, but on the second deploy it fails:

```
  1) Bundler deploys with version 2.x
     Failure/Error: app.push!

     Hatchet::App::FailedDeploy:
       Could not deploy 'hatchet-t-31aafb8954' (default_ruby) using 'Hatchet::GitApp' at path: './repos/rack/default_ruby'
        if this was expected add `allow_failure: true` to your deploy hash.
       output:
       Buildpack: nil
       Repo: https://git.heroku.com/hatchet-t-31aafb8954.git
       remote: Compressing source files... done.
       remote: Building source:
       remote:
       remote: -----> Ruby app detected
       remote: -----> Compiling Ruby/Rack
       remote: -----> Using Ruby version: ruby-2.5.5
       remote: -----> Installing dependencies using bundler 2.0.2
       remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
       remote:        Activating bundler (2.0.1) failed:
       remote:        Could not find 'bundler' (2.0.1) required by your /tmp/build_a9c801af0c0fc42d984cfda6569e532c/Gemfile.lock.
       remote:        To update to the latest version installed on your system, run `bundle update --bundler`.
       remote:        To install the missing version, run `gem install bundler:2.0.1`
       remote:        Checked in 'GEM_PATH=vendor/bundle/ruby/2.5.0', execute `gem env` for more information
       remote:
       remote:        To install the version of bundler this project requires, run `gem install bundler -v '2.0.1'`
       remote:        Bundler Output: Activating bundler (2.0.1) failed:
       remote:        Could not find 'bundler' (2.0.1) required by your /tmp/build_a9c801af0c0fc42d984cfda6569e532c/Gemfile.lock.
       remote:        To update to the latest version installed on your system, run `bundle update --bundler`.
       remote:        To install the missing version, run `gem install bundler:2.0.1`
       remote:        Checked in 'GEM_PATH=vendor/bundle/ruby/2.5.0', execute `gem env` for more information
       remote:
       remote:        To install the version of bundler this project requires, run `gem install bundler -v '2.0.1'`
       remote:
       remote:  !
       remote:  !     Failed to install gems via Bundler.
       remote:  !
       remote:  !     Push rejected, failed to compile Ruby app.
       remote:
       remote:  !     Push failed
       remote: Verifying deploy...
       remote:
       remote: !  Push rejected to hatchet-t-31aafb8954.
       remote:
       To https://git.heroku.com/hatchet-t-31aafb8954.git
        ! [remote rejected] master -> master (pre-receive hook declined)
       error: failed to push some refs to 'https://git.heroku.com/hatchet-t-31aafb8954.git'
```

The first deploy succeeds because there is no cache. The second deploy fails because the cache exists and `which bundler` points to a file generated by this bundler template (in `vendor/bundle/bin/bundle`): https://github.com/bundler/bundler/blob/905dce42705d0e92fa5c74ce4b9133c7d77a6fb1/lib/bundler/templates/Executable.bundler

It fails due to this code which is run:

```
  def activate_bundler(bundler_version)
    if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
      bundler_version = "< 2"
    end
    gem_error = activation_error_handling do
      gem "bundler", bundler_version
    end
```

The `bundler_version` here will be 2.0.1 but it sees that it's own version is 2.0.2.

This can potentially be mitigated by manually setting `BUNDLER_VERSION=2.0.2`, however I'm not in love with that solution as it doesn't seem like it should be required.

Another solution is to not call this `vendor/bundle/bin/bundle` executable directly and instead go through a shim such as:

```
#!/usr/bin/env ruby
require 'rubygems'

version = "#{bundler.version}"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
    version = $1
    ARGV.shift
  end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('bundler', 'bundle', version)
else
gem "bundler", version
load Gem.bin_path("bundler", "bundle", version)
end
```

This is similar (if not identical) to the shim that rubygems would install and use on a "normal" system. On Heroku we do not use this system since we do not actually install bundler through rubygems, but rather we pre-package it as a tarball, put it on S3 and then download it. We invoke bundler, not through rubygems, but by placing it's executable on the PATH and then letting the OS find it directly.

There are two fixes listed here:

- Use BUNDLE_VERSION env var
  - Pros: Fixes the problem. A relatively small change.
  - Cons: Requires us to propagate this env var into the dyno and/or remember to set it any time we invoke bundler. This will be very hard to catch incorrect uses as failure to include it does not always make things fail right away, but they may fail in the future. There's also no guarantee that this will continue to work into the future. I.e. this might be a fix for today
- Write our own shim file and pretend to be rubygems
  - Pros: Fixes the problem
  - Cons: We're effectively forking Rubygems shim logic with this method, any bugfixes or upstream changes to Rubygems would need to be mirrored in the buildpack, not great. Possibly brittle. A large change.

I'm interested in looking for a third solution, one where Heroku will behave more like a "normal" install of Ruby w/ Bundler. Ideally we would find a way for all `bundle` calls when the client's codebase does not include a `bin/bundle` binstub, to go through whatever version of Rubygems is on the system for all invocations of `bundle` as this is how it will eventually be executed on the Dyno.
- Pros: Fixes the problem. No need to worry about following upstream fixes or changes to Rubygems shim logic.
- Cons: There might be additional Rubygems bugs that we're successfully avoiding today due to our current (accidental?) logic. This would be the largest change.

# This is the commit message #2:

Update to 2.5.7
schneems added a commit that referenced this issue Nov 4, 2019
# This is the 1st commit message:

Failing test for Bundler 2 and Ruby 2.5.5

When you deploy an app with Bundler 2.0.1 in the Gemfile.lock with Bundler 2.0.2 on the system, it works the first time, but on the second deploy it fails:

```
  1) Bundler deploys with version 2.x
     Failure/Error: app.push!

     Hatchet::App::FailedDeploy:
       Could not deploy 'hatchet-t-31aafb8954' (default_ruby) using 'Hatchet::GitApp' at path: './repos/rack/default_ruby'
        if this was expected add `allow_failure: true` to your deploy hash.
       output:
       Buildpack: nil
       Repo: https://git.heroku.com/hatchet-t-31aafb8954.git
       remote: Compressing source files... done.
       remote: Building source:
       remote:
       remote: -----> Ruby app detected
       remote: -----> Compiling Ruby/Rack
       remote: -----> Using Ruby version: ruby-2.5.5
       remote: -----> Installing dependencies using bundler 2.0.2
       remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
       remote:        Activating bundler (2.0.1) failed:
       remote:        Could not find 'bundler' (2.0.1) required by your /tmp/build_a9c801af0c0fc42d984cfda6569e532c/Gemfile.lock.
       remote:        To update to the latest version installed on your system, run `bundle update --bundler`.
       remote:        To install the missing version, run `gem install bundler:2.0.1`
       remote:        Checked in 'GEM_PATH=vendor/bundle/ruby/2.5.0', execute `gem env` for more information
       remote:
       remote:        To install the version of bundler this project requires, run `gem install bundler -v '2.0.1'`
       remote:        Bundler Output: Activating bundler (2.0.1) failed:
       remote:        Could not find 'bundler' (2.0.1) required by your /tmp/build_a9c801af0c0fc42d984cfda6569e532c/Gemfile.lock.
       remote:        To update to the latest version installed on your system, run `bundle update --bundler`.
       remote:        To install the missing version, run `gem install bundler:2.0.1`
       remote:        Checked in 'GEM_PATH=vendor/bundle/ruby/2.5.0', execute `gem env` for more information
       remote:
       remote:        To install the version of bundler this project requires, run `gem install bundler -v '2.0.1'`
       remote:
       remote:  !
       remote:  !     Failed to install gems via Bundler.
       remote:  !
       remote:  !     Push rejected, failed to compile Ruby app.
       remote:
       remote:  !     Push failed
       remote: Verifying deploy...
       remote:
       remote: !  Push rejected to hatchet-t-31aafb8954.
       remote:
       To https://git.heroku.com/hatchet-t-31aafb8954.git
        ! [remote rejected] master -> master (pre-receive hook declined)
       error: failed to push some refs to 'https://git.heroku.com/hatchet-t-31aafb8954.git'
```

The first deploy succeeds because there is no cache. The second deploy fails because the cache exists and `which bundler` points to a file generated by this bundler template (in `vendor/bundle/bin/bundle`): https://github.com/bundler/bundler/blob/905dce42705d0e92fa5c74ce4b9133c7d77a6fb1/lib/bundler/templates/Executable.bundler

It fails due to this code which is run:

```
  def activate_bundler(bundler_version)
    if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
      bundler_version = "< 2"
    end
    gem_error = activation_error_handling do
      gem "bundler", bundler_version
    end
```

The `bundler_version` here will be 2.0.1 but it sees that it's own version is 2.0.2.

This can potentially be mitigated by manually setting `BUNDLER_VERSION=2.0.2`, however I'm not in love with that solution as it doesn't seem like it should be required.

Another solution is to not call this `vendor/bundle/bin/bundle` executable directly and instead go through a shim such as:

```
#!/usr/bin/env ruby
require 'rubygems'

version = "#{bundler.version}"

if ARGV.first
  str = ARGV.first
  str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
  if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
    version = $1
    ARGV.shift
  end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('bundler', 'bundle', version)
else
gem "bundler", version
load Gem.bin_path("bundler", "bundle", version)
end
```

This is similar (if not identical) to the shim that rubygems would install and use on a "normal" system. On Heroku we do not use this system since we do not actually install bundler through rubygems, but rather we pre-package it as a tarball, put it on S3 and then download it. We invoke bundler, not through rubygems, but by placing it's executable on the PATH and then letting the OS find it directly.

There are two fixes listed here:

- Use BUNDLE_VERSION env var
  - Pros: Fixes the problem. A relatively small change.
  - Cons: Requires us to propagate this env var into the dyno and/or remember to set it any time we invoke bundler. This will be very hard to catch incorrect uses as failure to include it does not always make things fail right away, but they may fail in the future. There's also no guarantee that this will continue to work into the future. I.e. this might be a fix for today
- Write our own shim file and pretend to be rubygems
  - Pros: Fixes the problem
  - Cons: We're effectively forking Rubygems shim logic with this method, any bugfixes or upstream changes to Rubygems would need to be mirrored in the buildpack, not great. Possibly brittle. A large change.

I'm interested in looking for a third solution, one where Heroku will behave more like a "normal" install of Ruby w/ Bundler. Ideally we would find a way for all `bundle` calls when the client's codebase does not include a `bin/bundle` binstub, to go through whatever version of Rubygems is on the system for all invocations of `bundle` as this is how it will eventually be executed on the Dyno.
- Pros: Fixes the problem. No need to worry about following upstream fixes or changes to Rubygems shim logic.
- Cons: There might be additional Rubygems bugs that we're successfully avoiding today due to our current (accidental?) logic. This would be the largest change.

# This is the commit message #2:

Update to 2.5.7
schneems added a commit that referenced this issue Aug 28, 2020
When the move from bundler flags to bundler env vars was first merged in an issue was reported #1046 , this lead to an investigation and bug report to bundler rubygems/rubygems#3890 which lead to some older issues/prs:

- rubygems/bundler#3552
- rubygems/bundler#6628

The issue is that global configuration and local configuration results in different behavior when installing and using some features in bundler, notedly the ability to specify install path. Due to this change, when the switch to bundler environment variables happened, it caused the size of some applications' slugs to increase dramatically, this was because the gems were essentially being installed twice.

The issue appears to not be in Bundler 2.1.4 so we're bumping the version for 2.x series. In the 1.x series an environment variable `BUNDLE_GLOBAL_PATH_APPENDS_RUBY_SCOPE=1` can be used to force the desired behavior.
# This is the commit message #2:

Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
schneems added a commit that referenced this issue Sep 3, 2020
* Revert "Revert "[close #943] Use Bundler env vars for config (#1039)" (#1047)"

This reverts commit 858adcb.

* Fix gem installation location bug with Bundler env vars

When the move from bundler flags to bundler env vars was first merged in an issue was reported #1046 , this lead to an investigation and bug report to bundler rubygems/rubygems#3890 which lead to some older issues/prs:

- rubygems/bundler#3552
- rubygems/bundler#6628

The issue is that global configuration and local configuration results in different behavior when installing and using some features in bundler, notedly the ability to specify install path. Due to this change, when the switch to bundler environment variables happened, it caused the size of some applications' slugs to increase dramatically, this was because the gems were essentially being installed twice.

The issue appears to not be in Bundler 2.1.4 so we're bumping the version for 2.x series. In the 1.x series an environment variable `BUNDLE_GLOBAL_PATH_APPENDS_RUBY_SCOPE=1` can be used to force the desired behavior.
# This is the commit message #2:

Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>

Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
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

No branches or pull requests

2 participants