Skip to content

Commit

Permalink
Stop bundling bootstrap Ruby (#1481)
Browse files Browse the repository at this point in the history
Since this buildpack is written in Ruby, it needs a Ruby installation
to be installed in order to run. As such, during buildpack compile, a
bootstrap Ruby is downloaded and installed.

As a performance optimisation, this bootstrap Ruby was vendored into
the buildpack archive published to the Buildpack Registry, via the
`[[publish.Vendor]]` entries in `buildpack.toml`. Since Ruby installs
are OS-specific, this meant bundling three copies of Ruby, even though
only one would ever be used. With the old build system this was still a
net benefit, since the official language buildpacks would be downloaded
in advance when a build worker first booted.

However, with the new build system architecture, the build system
workers are no longer booted en-mass in advance, but instead started
on demand. This means there is no worker idle time, and so speculative
downloading of possibly-needed assets no longer makes sense.

As such, the bundling of multiple copies of Ruby in the buildpack
registry archive has now been removed.

This not only makes non-Ruby builds faster (since they have no need
for a Ruby installation at all), but will also speed up Ruby builds,
since they'll only need to download one bootstrap Ruby (for their
specific stack), rather than a version for every stack.

GUS-W-16184923.
  • Loading branch information
edmorley committed Jul 9, 2024
1 parent 857e5f8 commit 9a1729e
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [Unreleased]

- Stop bundling bootstrap Ruby for each stack inside the buildpack archive on the buildpack registry (https://github.com/heroku/heroku-buildpack-ruby/pull/1481)

## [v276] - 2024-07-09

Expand Down
9 changes: 3 additions & 6 deletions bin/support/bash_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ curl_retry_on_18() {
}

# This function will install a version of Ruby onto the
# system for the buidlpack to use. It coordinates download
# system for the buildpack to use. It coordinates download
# and setting appropriate env vars for execution
#
# Example:
Expand All @@ -25,7 +25,7 @@ curl_retry_on_18() {
#
# This function relies on the env var `$STACK` being set. This
# is set in codon outside of the buildpack. An example of a stack
# would be "cedar-14".
# would be "heroku-24".
install_bootstrap_ruby()
{
local bin_dir=$1
Expand All @@ -42,10 +42,7 @@ install_bootstrap_ruby()

# The -d flag checks to see if a file exists and is a directory.
# This directory may be non-empty if a previous compile has
# already placed a Ruby executable here. Also
# when the buildpack is deployed we vendor a ruby executable
# at this location so it doesn't have to be downloaded for
# every app compile
# already placed a Ruby executable here.
if [ ! -d "$heroku_buildpack_ruby_dir" ]; then
heroku_buildpack_ruby_dir=$(mktemp -d)
# bootstrap ruby
Expand Down
14 changes: 0 additions & 14 deletions buildpack.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
name = "Ruby"
ruby_version = "3.1.6"

[publish]

[publish.Ignore]
files = [
"changelogs/",
Expand All @@ -15,15 +13,3 @@ files = [
"hatchet.json",
"hatchet.lock",
]

[[publish.Vendor]]
url = "https://heroku-buildpack-ruby.s3.us-east-1.amazonaws.com/heroku-20/ruby-3.1.6.tgz"
dir = "vendor/ruby/heroku-20"

[[publish.Vendor]]
url = "https://heroku-buildpack-ruby.s3.us-east-1.amazonaws.com/heroku-22/ruby-3.1.6.tgz"
dir = "vendor/ruby/heroku-22"

[[publish.Vendor]]
url = "https://heroku-buildpack-ruby.s3.us-east-1.amazonaws.com/heroku-24/amd64/ruby-3.1.6.tgz"
dir = "vendor/ruby/amd64/heroku-24"
22 changes: 0 additions & 22 deletions spec/helpers/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,11 @@
bootstrap_version = config["buildpack"]["ruby_version"]
expect(bootstrap_version).to eq(LanguagePack::RubyVersion::BOOTSTRAP_VERSION_NUMBER)

urls = config["publish"]["Vendor"].map {|h| h["url"] if h["dir"] != "." }.compact
urls.each do |url|
expect(url.include?(bootstrap_version)).to be_truthy, "expected #{url.inspect} to include #{bootstrap_version.inspect} but it did not"
end

expect(`ruby -v`).to match(Regexp.escape(LanguagePack::RubyVersion::BOOTSTRAP_VERSION_NUMBER))

bootstrap_version = Gem::Version.new(LanguagePack::RubyVersion::BOOTSTRAP_VERSION_NUMBER)
default_version = Gem::Version.new(LanguagePack::RubyVersion::DEFAULT_VERSION_NUMBER)

expect(bootstrap_version).to be >= default_version
end

it "doesn't contain unexpected entries" do
require 'toml-rb'
config = TomlRB.load_file("buildpack.toml")

urls = config["publish"]["Vendor"].map {|h| h["url"] if h["dir"] != "." }.compact
heroku_20 = urls.find_all {|url| url.include?("heroku-20") }
expect(heroku_20.length).to eq(1)

heroku_22 = urls.find_all {|url| url.include?("heroku-22") }
expect(heroku_22.length).to eq(1)

heroku_24 = urls.find_all {|url| url.include?("heroku-24") }
expect(heroku_24.length).to eq(1)

expect(urls.length).to eq(3)
end
end

0 comments on commit 9a1729e

Please sign in to comment.