Ruby 3 rollout
- [x] Ship opt-in
HOMEBREW_RUBY3 - [x] Support system Ruby 3 on Linux (this is mostly for non-x86_64 users) under
HOMEBREW_RUBY3(already supported underHOMEBREW_USE_RUBY_FROM_PATH) - #16192 - [x] Enable
HOMEBREW_RUBY3by default forHOMEBREW_DEVELOPERusers - #16241 - [x] Vendor 3.1 gems - #16267
- [x] Enable
HOMEBREW_RUBY3for everyone (land this just after a tag and this will effectively be a week of dev-cmd only users initially) - #16268- Until 2.6 is dropped, this should be done initially by an unconditional set as not all
HOMEBREW_RUBY3checks can be removed because of Dependabot (which we want to stay on 2.6 for a little longer). Some checks, such as 2.6 Portable Ruby downloads, can be removed however.
- Until 2.6 is dropped, this should be done initially by an unconditional set as not all
- [x] Bump
HOMEBREW_REQUIRED_RUBY_VERSION- #16294- This is a breaking change for anyone using custom system Ruby (e.g. some Linux users)
- [x] Drop 2.6 vendored gems - #16313
- [x] Remove remaining Ruby 2.6 support code (except Gemfile bounds), including macOS system Ruby code - #16316
- [x] Update all gems based on the new 3.1 minimum. Remove remaining
HOMEBREW_RUBY3checks and bumpGemfilebounds (and removedid_you_meanentry from Gemfile) - #16338 - [x] Bump
TargetRubyVersionin RuboCop, but disable all cops that trigger new failures (to avoid chicken/egg issue) - #16341 - [ ] Enable all cops disabled in the previous step and fix the potentially many new failures - #16346 + others TBC
Each step should ideally be in its own PR (for easy reverts) and the state of brew after each step should be stable (i.e. no state should be release-blocking and steps shouldn't need to be done "quickly" after each other). Goal is to avoid "mega PRs".
[ ] Support system Ruby 3 on Linux (this is mostly for non-x86_64 users) under
HOMEBREW_RUBY3(already supported underHOMEBREW_USE_RUBY_FROM_PATH)
This seems like a nice-to-have rather than a blocker. Could be moved to the end.
- Until 2.6 is dropped, this should be done initially by an unconditional set as not all
HOMEBREW_RUBY3checks can be removed because of Dependabot (which we want to stay on 2.6 for a little longer).
Why is this?
- This is a breaking change for anyone using custom system Ruby (e.g. some Linux users)
This is fine, we can make this a minor Homebrew version bump.
Meta-comment: other than the above questions: this all seems perfect. Thanks for the step-by-step plan, @Bo98 🎉
Why is this?
https://github.com/Homebrew/brew/blob/53107a51db65ca7fe8c65d02958fbd1cca0d09cf/Library/Homebrew/Gemfile#L5-L11
We don't want Dependabot to start updating to 2.6-incompatible gems until after we've bumped HOMEBREW_REQUIRED_RUBY_VERSION, so the Gemfile should still have a restrictive ~> 2.6.0 for the no-env case (since Dependabot will have no Homebrew envs).
However it can't be restrictive for actual users, so we will need to check some env that users have but Dependabot doesn't. HOMEBREW_RUBY3 seems the easiest way to do that but we could introduce a new one.
We don't want Dependabot to start updating to 2.6-incompatible gems until after we've bumped
HOMEBREW_REQUIRED_RUBY_VERSION, so the Gemfile should still have a restrictive~> 2.6.0for the no-env case (since Dependabot will have no Homebrew envs).
Makes sense 👍🏻
I've removed the explicit HOMEBREW_DEV_CMD_RUN stage as I don't think it's necessary given I don't think it needs to be longer than a week, and we can just have the enable-for-all stage be on master for a week before tagging. I can of course add it if issues occur and we need longer than expected.
I'd like to get this done before Christmas, so my proposed schedule (subject to any delays from issues arising):
- Today (21st Nov), enable for
HOMEBREW_DEVELOPER - 27th Nov, after a tag, vendor 3.1 gems and enable Ruby 3.1 for all and let that sit on
masterfor dev-cmd-run users - 4th Dec, release tag as usual, which will enable Ruby 3.1 for all users
- If no critical bug reports in the first 48 hours, remove 2.6 vendored gems and bump
HOMEBREW_REQUIRED_RUBY_VERSION. Next tag (w/c 11th Dec?) should be a minor version bump so prepare accordingly. - After the minor version tag, we'll update all gems that were stuck on old versions, including RuboCop.
The reason for the vendored gems overlap is because vendored gems are messy to revert (any revert would require bumping vendor-version), but an overlap makes it much simpler in that it would allow a separate commit to enable Ruby 3.1 for everyone that can be independently reverted. Overlap will be for one brew tag only.
I realise that slightly complicates Dependabot for a few days, but I can handle that if any vendored gem gets updated - or just stall them briefly if non-critical.
- Today (21st Nov), enable for
HOMEBREW_DEVELOPER
👍🏻
- 27th Nov, after a tag, vendor 3.1 gems and enable Ruby 3.1 for all and let that sit on
masterfor dev-cmd-run users
Is this just vendoring the same gems that we vendor for 2.6 and removing the need for a bundle install run?
If so: 👍🏻. If not: let's talk more.
- 4th Dec, release tag as usual, which will enable Ruby 3.1 for all users
- If no critical bug reports in the first 48 hours, remove 2.6 vendored gems and bump
HOMEBREW_REQUIRED_RUBY_VERSION. Next tag (w/c 11th Dec?) should be a minor version bump so prepare accordingly.- After the minor version tag, we'll update all gems that were stuck on old versions, including RuboCop.
All sounds good.
I realise that slightly complicates Dependabot for a few days, but I can handle that if any vendored gem gets updated - or just stall them briefly if non-critical.
Not a big deal for a few days 👍🏻
Appreciate the forward planning, great work here @Bo98.
Is this just vendoring the same gems that we vendor for 2.6 and removing the need for a bundle install run?
Yes
Will do next stage after #16259, so that it won't conflict and we can apply the vendored gem cleanup to 3.1 from the get go.
@Bo98 that PR is shipped now 👍🏻
I don't see this explicitly mentioned already so I'm adding it here just in case. The JSON API and website generation for formula.brew.sh seems to still run on Ruby 2.6 so that should get updated as well before enabling Ruby 3.x for everyone.
- https://github.com/Homebrew/formulae.brew.sh/blob/master/.github/workflows/scheduled.yml
That one is a little different in that technically speaking it's nothing to do with brew's Ruby. It's for the Rakefile that invokes brew through shell rather than Ruby.
Can also update that too however if everyone is fine with installing their own Ruby 3.1+ for local testing for that.
Can also update that too however if everyone is fine with installing their own Ruby 3.1+ for local testing for that.
Yup 👍🏻
Ah, in that case, it's probably something that should happen as a follow-up but shouldn't delay the other Ruby 3 work.
This update has broken brew on my Intel Mac. Every command fails in the same way:
~: ⇒ brew upgrade
==> Downloading https://ghcr.io/v2/homebrew/portable-ruby/portable-ruby/blobs/sha256:02180ca8b8295422ae84921bcf034b7ee8ce5575488bd5e6a37a192e53cd5d34
############################################################################################################################################################################# 100.0%
==> Pouring portable-ruby-3.1.4.el_capitan.bottle.tar.gz
Error: Failed to install ruby 3.1.4!
Error: Failed to install Homebrew Portable Ruby (and your system version is too old)!
I've tested the various solutions that come up when searching for this error, such as brew update-reset, brew clean -dfx, brew cleanup, etc. (This also means I can't run brew doctor.)
The tar file does get downloaded:
~: ⇒ exa -la /Users/myuser/Library/Caches/Homebrew/ | grep ruby
.rw-r--r--@ 13M myuser 26 Oct 16:00 portable-ruby-3.1.4.el_capitan.bottle.tar.gz
Abbreviated system info:
⇒ system_profiler SPSoftwareDataType SPHardwareDataType
Software:
System Software Overview:
System Version: macOS 14.1.2 (23B92)
Kernel Version: Darwin 23.1.0
Hardware:
Hardware Overview:
Model Name: MacBook Pro
Model Identifier: MacBookPro16,1
Processor Name: 6-Core Intel Core i7
Memory: 32 GB
System Firmware Version: 2020.41.1.0.0 (iBridge: 21.16.1069.0.0,0)
OS Loader Version: 580~743
I haven't tested installing Ruby separately from Homebrew and / or setting HOMEBREW_USE_RUBY_FROM_PATH.
I'd be happy to file a separate issue if that would be more appropriate, but this seemed like the right place since HOMEBREW_RUBY3 seems to be what broke it for me (and possibly other Intel Mac users).
and possibly other Intel Mac users
You're the first to report in the few days it's been out so it's unlikely to be widespread.
Here's what it happening under the hood:
cd "$(brew --repo)/Library/Homebrew/vendor"
tar xzf ~/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz
cd portable-ruby
./3.1.4/bin/ruby --version
echo $? # aborts if this is not zero
# cleanup the above by doing
rm -rf "$(brew --repo)/Library/Homebrew/vendor/portable-ruby/3.1.4"
Try those out manually and let me know what's happening. The error message I agree is probably not as useful as it could be.
It failed on the tar command:
/usr/local/Homebrew/Library/Homebrew/vendor|stable ⇒ tar xzf ~/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz
tar: Error opening archive: Failed to open '/Users/myuser/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz'
I was able to open the archive with sudo and run the other commands. But it seems like this is probably not the expected subsequent output of the ruby comnmand:
/usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby|stable ⇒ ./3.1.4/bin/ruby --version
[1] 12130 killed ./3.1.4/bin/ruby --version
I would have thought that would print a version string if everything worked correctly.
If sha256sum ~/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz prints 02180ca8b8295422ae84921bcf034b7ee8ce5575488bd5e6a37a192e53cd5d34, then all I can think of is that you have something on your system that is blocking it, such as security software perhaps?
.rw-r--r--@ 13M myuser 26 Oct 16:00 portable-ruby-3.1.4.el_capitan.bottle.tar.gz
Also probably worth seeing that that @ is about as that's not expected either:
xattr ~/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz
I've also encountered the same issue as reported by @doorisajar on a x86_64 Mac.
Cleaning update and re-fetching:
$ brew update-reset
...
$ rm -rf "$(brew --repo)/Library/Homebrew/vendor/portable-ruby/3.1.4"
$ rm ~/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz
$ brew
==> Downloading https://ghcr.io/v2/homebrew/portable-ruby/portable-ruby/blobs/sha256:02180ca8b8295422ae84921bcf034b7ee8ce5575488bd5e6a37a192e53cd5d34
####################################################################################################################################################################################### 100.0%
==> Pouring portable-ruby-3.1.4.el_capitan.bottle.tar.gz
Error: Failed to install ruby 3.1.4!
Error: Failed to install Homebrew Portable Ruby (and your system version is too old)!
$ cd "$(brew --repo)/Library/Homebrew/vendor"
$ tar xzf ~/Library/Caches/Homebrew/portable-ruby-3.1.4.el_capitan.bottle.tar.gz
$ cd portable-ruby
$ ./3.1.4/bin/ruby --version
Killed: 9
$ echo $?
137
$ system_profiler SPSoftwareDataType SPHardwareDataType
Software:
System Software Overview:
System Version: macOS 13.6.1 (22G313)
Kernel Version: Darwin 22.6.0
Boot Volume: Macintosh HD
Boot Mode: Normal
Computer Name: ...
User Name: ...
Secure Virtual Memory: Enabled
System Integrity Protection: Enabled
Time since boot: 4 days, 22 hours, 14 minutes
Hardware:
Hardware Overview:
Model Name: MacBook Pro
Model Identifier: MacBookPro15,1
Processor Name: 6-Core Intel Core i7
Processor Speed: 2.6 GHz
Number of Processors: 1
Total Number of Cores: 6
L2 Cache (per Core): 256 KB
L3 Cache: 9 MB
Hyper-Threading Technology: Enabled
Memory: 16 GB
...
Edit: The antivirus software is flagging Ruby 3 as abnormal.
The antivirus software is flagging Ruby 3 as abnormal.
This is likely your cause then. Which one do you use and can you submit a false positive report to them?
The antivirus software is flagging Ruby 3 as abnormal.
This is likely your cause then. Which one do you use and can you submit a false positive report to them?
Cylance Protect. I'm in the process of figuring out how to report it as a false positive.
Is there a workaround to force Ruby 2? Or what's the mechanism to temporarily pin to an older version of Homebrew that's pre-ruby 3?
I'm in the process of figuring out how to report it as a false positive.
If you can't find a dedicated form: it might be through support tickets.
Is there a workaround to force Ruby 2? Or what's the mechanism to temporarily pin to an older version of Homebrew that's pre-ruby 3?
We're removing Ruby 2 support entirely for 4.2.0. The workaround I recommend is simply adding Portable Ruby to the whitelist, which all AV software I've seen should allow you to do (unless you're in a work environment?). If this is impossible and Cylance refuse to fix the issue, let me know and we can maybe consider functionality to allow you to use your own Ruby build.
I'm in the same boat (Cylance) and am submitting a whitelist request to my org. I'll update with the outcome. Thanks for the help!
I'm in the process of figuring out how to report it as a false positive.
If you can't find a dedicated form: it might be through support tickets.
Is there a workaround to force Ruby 2? Or what's the mechanism to temporarily pin to an older version of Homebrew that's pre-ruby 3?
The workaround I recommend is simply adding Portable Ruby to the whitelist, which all AV software I've seen should allow you to do (unless you're in a work environment?).
It's a corporate environment, yes. There is not support for managing the whitelist at the workstation.
As a temporary workaround to anyone encountering this portable ruby antivirus issue:
cd /usr/local/Homebrew # or whatever your Homebrew location is
git checkout 4.1.22
This will put Homebrew at a version prior to the Ruby 3 change. brew will function for the purposes of installing software and upgrading specific formula. If Homebrew upgrades itself as part of an upgrade, you're back at the problem state again.
My org was able to whitelist Ruby 3.1.4 in Cylance, and it solved the issue. Everything seems to be working normally now!
Thanks for closing this out @Bo98 and everyone for work here!