Released Xcode 11.2 and macOS 10.15 (Catalina)

Hi Josh,

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):

version: 2.1

commands:
  enable_ruby_switcher:
    steps:
      - run:
          name: Install Ruby Switcher
          command: echo 'source /usr/local/share/chruby/auto.sh' >> ~/.bash_profile

jobs:
  build:
    macos:
      xcode: 11.2.0
   steps:
    - checkout
    - enable_ruby_switcher
    - run: bundle install

Using a command like this will mean that you don’t need to specify the Ruby version in your config.yml, you can keep the information in .ruby-version.

Sorry again for all of these changes – we’re reacting to the changes as Apple makes them – ideally yhe build environment would be stable and predictable – I know that’s what you need from us.

Marc

2 Likes