-
-
Couldn't load subscription status.
- Fork 1.8k
Description
Describe the problem as clearly as you can
I'm hopeful we can come up with a compromise to a significant pain point that's worsening over time, not getting better.
In Bundler 2.2, PLATFORMS in Gemfile.lock only includes the local machine's architecture when that machine causes a Gemfile.lock to be built (but confusingly, not if it is merely updated). Bundler lockfiles cease to become architecture independent, even though Ruby is supposed to be. Any attempt to install using that lockfile on any other architecture fails unless new architectures are manually added. This even includes developers upgrading e.g. macOS versions from 11 to 12 and similar, since their platform includes a Darwin kernel version. On Heroku, this broke the world for a while, as the 2.2 approach appeared to not be backwards compatible with Bundler 2.1 that Heroku provided at the time.
Developers are forced to constantly remember to check, double check and where necessary hand-maintain their Gemfile.lock's PLATFORMS, to nanny things through CI (e.g. macOS development, AWS Linux CI) or just allow for the fact that they might not be on the same precise e.g. macOS version as their peers, or might be using Arch Linux, or a different CPU (e.g. M1), or whatever.
There is presently no clean way around this. Unfrozen is too permissive and has unrelated side effect of mutable Ruby gem versions, rather than only dealing with native extension platforms. Bundler should not be locking itself to the arbitrary architecture of the local developer machine IMHO; its job is to lock gem versions. I am aware of this comment but it doesn't really seem to resonate; the "safety" argument talks about a gem which doesn't have a particular architecture variant and installs then runs on CI presumably building "generic" native extensions, CI passes, then subsequently an architecture-specific variant is pushed but it's buggy and this gets deployed after the CI run to Production. If the timing of things were thus, it'd still happen regardless of what PLATFORMS might say - it'd still build generic on CI because no arch-specific version existed. Meanwhile, if malicious code is being pushed to RubyGems, then there are far bigger issues at play and far greater concern than specific platform variant locking.
A reasonable solution IMHO might be to provide a configuration option that allows alternative platforms, as if the running platform was included in the PLATFORMS array, without needing to modify Gemfile.lock. That could be a bundle config item or env var. That's not a question of just forcing to ruby, the resolution of which allegedly is buggy or unsafe and is the whole reason why the new 2.2 behaviour was introduced anyway - though if Bundler guaranteed and formally documented that forcing to ruby was still fully supported, perhaps that would be acceptable (now that it works again, thanks to this fix!). Otherwise we're building on sand.
Did you try upgrading rubygems & bundler?
Yes. Bundler 2.2.x is working as designed. I do not believe this design is helpful, with widespread community posts across forums and blogs indicating the developer pain it has inadvertently introduced.
Post steps to reproduce the problem
Cause a Gemfile.lock to be generated under Bundler 2.2.x on one architecture. Try to bundle install on another. This will fail, even though Ruby and gems all work just fine on the target architecture. In Bundler 2.1 and all earlier versions, the gems would install.
What were you expecting to happen?
- If the gem is not compatible with the chosen platform, the native extension build will fail, just as it always has.
- If the gem can build on the chosen platform, then it should do so, and not have Bundler fail the whole thing.
What actually happened?
Bundler refuses to install the gems:
Your bundle only supports platforms ["x86_64-darwin-21"] but your local platform
is x86_64-linux. Add the current platform to the lockfile with `bundle lock
--add-platform x86_64-linux` and try again.