The last few releases of Xcode on CircleCI were problematic for Ruby users, due to issues with how Xcode 11 shipped the macOS SDK. This forced us to make some breaking changes with Ruby. My hope is that upgrading to Catalina will resolve these issues, and using Ruby will be more straight forward.
The system Ruby that comes bundled with 10.15 is 2.6.3. This is the ruby on the path by default.
@marc Is there a reason chruby auto-switching was disabled?
We use .ruby-version to keep our interpreters on the same version across our team and CI, which works great, or at least it did until now. Now I have to go back and add extra scripting to turn it on everywhere that our build scripts use ruby.
Sorry about the change with Ruby. It’s was my doing.
I’m trying to find a delicate balance with how much customization to do to macOS when we create the images. Here is a short history of the recent Ruby changes for context:
Our policy with Ruby has been to ship the system Ruby as the default Ruby, and to install the latest stable versions of Ruby as listed on ruby-lang.org. Switching was up to the user.
The images prior to Xcode 11 all had the system Ruby as the default image. chruby and the auto-switcher were installed, and sourced in ~/.bash_profile. Since we used a non-login shell by default on all operating systems, this mean that auto-switching didn’t run out of the box. If you changed your shell to bash --login, this would trigger ~/.bash_profile to be run before each step, and auto-switching would work.
When Xcode 11 shipped, things broke for our users. Xcode 11 included the macOS 10.15 SDK, which had the system headers for Catalina, including the Ruby 2.6 headers (rather than Ruby 2.3 that shipped with Mojave). This left our customers unable to install gems that had native dependencies. To work around this, I changed the default Ruby to be 2.6. To do this, I had to enable the chruby autoswitcher, by changing the default shell to be bash --login. I also created a ~/.ruby-version file with ruby 2.6 specified. This change to the shell broke a bunch of folk’s builds (sorry!), but it was the only way to make Ruby work with Xcode 11 on Mojave without major changes on our side. Most of the problems that caused people’s builds to break were because the autoswitcher was enabled when it wasn’t before. This change in behaviour affected people using all images, not just Xcode 11, which was frustrating for us and our users.
Our Xcode 11.2 image ships on Catalina, which solves the macOS SDK and Ruby header issue, so the system Ruby works again. So I’ve left the system Ruby as the default on Catalina (this change has broken people’s builds who are upgrading from 11.0 and 11.1, since they expected to be able to install gems out of the box without requiring sudo).
I decided to not include the auto-switcher by default on Xcode 11.2. With the autoswitcher enabled by default or off by default, peoples build will break when upgrading from earlier images.
The reason that I decided to leave it off by default, is that it’s easier for users who don’t expect it to understand the system. There is no “magic” happening in the default image. To enable autoswitching, you will have to add an explicit step to your build. In my opinion (and I’m not claiming to be right), it’s easier to explain to someone that they need to enable the autoswitcher to select different versions of Ruby, than to explain to someone that they need to remove the autoswitcher from their bash profile to disable it.
I’m trying to thing of the neatest way to enable autoswitching using a command. Maybe something like this (I might publish a macOS orb to do this):
@marc Thanks. I’ve always used a --login shell to run scripts on circle, so I guess I never noticed the changes you mentioned before.
I’m sure moving the VM over to a new OS is not easy for you guys. Just please, whatever config you decide works best for everyone, try to stick to it for future releases. (Easier said than done, I know… fingers crossed)
I was leaning towards putting it into .bash_profile as well, by just copying a profile out of my project and into ~/ right after code is checked out. (I never checked but I’m presuming a clean CircleCI VM has no ~/.bash_profile when it starts?)