Skip to content

Commit

Permalink
Merge pull request #888 from heroku/cnb
Browse files Browse the repository at this point in the history
Cloud Native Buildpack Support
  • Loading branch information
schneems committed Mar 16, 2020
2 parents 01e563c + 42655e5 commit b9d0465
Show file tree
Hide file tree
Showing 25 changed files with 702 additions and 75 deletions.
28 changes: 28 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: 2.1
orbs:
buildpacks: jkutner/buildpacks@0.0.7
ruby: circleci/ruby@0.2.1
jobs:
build:
machine: true
steps:
- buildpacks/install-pack:
version: "0.7.0"
- checkout
- run:
command: |
rvm install 2.6.5
rvm use ruby-2.6.5
export PATH="/opt/circleci/.rvm/rubies/ruby-2.6.5/bin:$PATH"
export GEM_HOME="/opt/circleci/.rvm/gems/ruby-2.6.5"
export GEM_PATH="/opt/circleci/.rvm/gems/ruby-2.6.5"
gem install bundler -v 2.1.0
bundle install
bundle exec rake hatchet:setup_ci
rspec spec/cnb/
workflows:
main:
jobs:
- build

2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## Master (unreleased)

* Cloud Native Buildpack support (https://github.com/heroku/heroku-buildpack-ruby/pull/888)

## v211 (3/12/2020)

* Fix issue where the wrong version of bundler is used on CI apps (https://github.com/heroku/heroku-buildpack-ruby/pull/961)
Expand Down
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"scripts": {
"test-setup": "bundle exec rake hatchet:setup_ci",
"test": "bundle exec rspec-queue --max-requeues=3 --timeout 180 --queue $REDIS_URL || { cat log/test_order.log; $(exit 1); }"
"test": "bundle exec rspec-queue --max-requeues=3 --timeout 180 --queue $REDIS_URL --exclude-pattern 'cnb/**/*' || { cat log/test_order.log; $(exit 1); }"
},
"buildpacks": [
{ "url": "https://github.com/heroku/heroku-buildpack-apt" },
Expand Down
17 changes: 17 additions & 0 deletions bin/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

LAYERS_DIR=$1
PLATFORM_DIR=$2
ENV_DIR="$PLATFORM_DIR/env"
PLAN=$3
APP_DIR=$(pwd)
BIN_DIR=$(cd $(dirname $0); pwd)
BUILDPACK_DIR=$(dirname $BIN_DIR)

# legacy buildpack uses $STACK
STACK=$CNB_STACK_ID

source "$BIN_DIR/support/bash_functions.sh"
heroku_buildpack_ruby_install_ruby "$BIN_DIR" "$BUILDPACK_DIR"

$heroku_buildpack_ruby_dir/bin/ruby $BIN_DIR/support/ruby_build $APP_DIR $LAYERS_DIR $PLATFORM_DIR $PLAN
13 changes: 12 additions & 1 deletion bin/detect
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#!/bin/sh

if [ -f "$1/Gemfile" ]; then
if [ -z "$CNB_STACK_ID" ]; then
# v2 API
APP_DIR=$1
else
PLATFORM_DIR=$1
PLAN=$2
# working is the cwd now
# v3 API
APP_DIR=$(pwd)
fi

if [ -f "$APP_DIR/Gemfile" ]; then
echo "Ruby"
exit 0
else
Expand Down
33 changes: 33 additions & 0 deletions bin/support/ruby_build
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env ruby

# This script compiles an application so it can run on Heroku.
# It will install the application's specified version of Ruby, it's dependencies
# and certain framework specific requirements (such as calling `rake assets:precompile`
# for rails apps). You can see all features described in the devcenter
# https://devcenter.heroku.com/articles/ruby-support
$stdout.sync = true

$:.unshift File.expand_path("../../../lib", __FILE__)
require "language_pack"
require "language_pack/shell_helpers"

APP_DIR=ARGV[0]
LAYER_DIR=ARGV[1]
PLATFORM_DIR=ARGV[2]
ENV_DIR="#{PLATFORM_DIR}/env"
PLAN=ARGV[3]

begin
LanguagePack::Instrument.trace 'compile', 'app.compile' do
LanguagePack::ShellHelpers.initialize_env(ENV_DIR)
if pack = LanguagePack.detect(ARGV[0], nil, LAYER_DIR)
pack.topic("Compiling #{pack.name}")
pack.log("compile") do
pack.build
end
end
end
rescue Exception => e
LanguagePack::ShellHelpers.display_error_and_exit(e)
end

7 changes: 7 additions & 0 deletions buildpack.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
api = "0.2"

[buildpack]
id = "heroku/ruby"
version = "0.0.1"
name = "Ruby"
ruby_version = "2.6.5"

Expand All @@ -21,3 +25,6 @@ ruby_version = "2.6.5"
[[publish.Vendor]]
url = "https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-18/ruby-2.6.5.tgz"
dir = "vendor/ruby/heroku-18"

[[stacks]]
id = "heroku-18"
2 changes: 1 addition & 1 deletion hatchet.lock
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
- - "./repos/ci/ruby_no_rails_test"
- 3916137106d59b008b67d738abe6a1438f8fbde6
- - "./repos/heroku/ruby-getting-started"
- 7abd8af85c7ba6486bb03a4964da9cea98766b06
- 9ddca7b694875499165eb56adffd3e29b38405c5
- - "./repos/jruby/jruby_naether"
- 4a11f8af5a3cca21f3659394e5bbac3cca9b6a2c
- - "./repos/multibuildpack/node_multi"
Expand Down
116 changes: 107 additions & 9 deletions lib/language_pack/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require "language_pack/shell_helpers"
require "language_pack/cache"
require "language_pack/helpers/bundler_cache"
require "language_pack/helpers/layer"
require "language_pack/metadata"
require "language_pack/fetcher"
require "language_pack/instrument"
Expand All @@ -26,15 +27,16 @@ class LanguagePack::Base
# changes directory to the build_path
# @param [String] the path of the build dir
# @param [String] the path of the cache dir this is nil during detect and release
def initialize(build_path, cache_path=nil)
def initialize(build_path, cache_path = nil, layer_dir=nil)
self.class.instrument "base.initialize" do
@build_path = build_path
@stack = ENV.fetch("STACK")
@cache = LanguagePack::Cache.new(cache_path) if cache_path
@cache = LanguagePack::Cache.new(cache_path)
@metadata = LanguagePack::Metadata.new(@cache)
@bundler_cache = LanguagePack::BundlerCache.new(@cache, @stack)
@id = Digest::SHA1.hexdigest("#{Time.now.to_f}-#{rand(1000000)}")[0..10]
@fetchers = {:buildpack => LanguagePack::Fetcher.new(VENDOR_URL) }
@layer_dir = layer_dir

Dir.chdir build_path
end
Expand Down Expand Up @@ -80,6 +82,25 @@ def default_process_types
# this is called to build the slug
def compile
write_release_yaml
instrument 'base.compile' do
Kernel.puts ""
warnings.each do |warning|
Kernel.puts "\e[1m\e[33m###### WARNING:\e[0m"# Bold yellow
Kernel.puts ""
puts warning
Kernel.puts ""
end
if deprecations.any?
topic "DEPRECATIONS:"
puts @deprecations.join("\n")
end
Kernel.puts ""
end
mcount "success"
end

def build
write_release_toml
instrument 'base.compile' do
Kernel.puts ""
warnings.each do |warning|
Expand All @@ -98,11 +119,40 @@ def compile
mcount "success"
end

def write_release_yaml
def build_release
release = {}
release["addons"] = default_addons
release["config_vars"] = default_config_vars
release["default_process_types"] = default_process_types

release
end

def write_release_toml
release = build_release

layer = LanguagePack::Helpers::Layer.new(@layer_dir, "env", launch: true)
FileUtils.mkdir_p("#{layer.path}/env.launch")
release["config_vars"].each do |key, value|
File.open("#{layer.path}/env.launch/#{key.upcase}.override", 'w') do |f|
f.write(value)
end
end

release_toml = release["default_process_types"].map do |type, command|
<<PROCESSES
[[processes]]
type = "#{type}"
command = "#{command}"
PROCESSES
end
File.open("#{@layer_dir}/launch.toml", 'a') do |f|
f.write(release_toml.join("\n"))
end
end

def write_release_yaml
release = build_release
FileUtils.mkdir("tmp") unless File.exists?("tmp")
File.open("tmp/heroku-buildpack-release-step.yml", 'w') do |f|
f.write(release.to_yaml)
Expand All @@ -111,6 +161,11 @@ def write_release_yaml
warn_webserver
end

# write out the release. Pick v2a or v3 release format
def write_release
@layer_dir ? write_release_toml : write_release_yaml
end

def warn_webserver
return if File.exist?("Procfile")
msg = "No Procfile detected, using the default web server.\n"
Expand Down Expand Up @@ -152,8 +207,10 @@ def setup_language_pack_environment
end

def add_to_profiled(string)
FileUtils.mkdir_p "#{build_path}/.profile.d"
File.open("#{build_path}/.profile.d/ruby.sh", "a") do |file|
profiled_path = @layer_dir ? "#{@layer_dir}/ruby/profile.d/" : "#{build_path}/.profile.d/"

FileUtils.mkdir_p profiled_path
File.open("#{profiled_path}/ruby.sh", "a") do |file|
file.puts string
end
end
Expand All @@ -173,12 +230,53 @@ def add_to_export(string)
end
end

def set_export_default(key, val)
add_to_export "export #{key}=${#{key}:-#{val}}"
# option can be :path, :default, :override
# https://github.com/buildpacks/spec/blob/366ac1aa0be59d11010cc21aa06c16d81d8d43e7/buildpack.md#environment-variable-modification-rules
def export(key, val, layer: nil, option: nil)
if layer
# don't replace if the key is already set
return if ENV[key] && option == :default

filename =
if option.nil? || option == :path
key
elsif option == :default
"#{key}.override"
else
"#{key}.#{option}"
end

FileUtils.mkdir_p("#{layer.path}/env.build")
File.open("#{layer.path}/env.build/#{filename}", "w") do |f|
f.write(val)
end
else
string =
if option == :default
"export #{key}=${#{key}:-#{val}}"
elsif option == :path
"export #{key}=#{val}:$#{key}"
else
%{export #{key}="#{val.gsub('"','\"')}"}
end

export = File.join(ROOT_DIR, "export")
File.open(export, "a") do |file|
file.puts string
end
end
end

def set_export_default(key, val, layer = nil)
export key, val, layer: layer, option: :default
end

def set_export_override(key, val, layer = nil)
export key, val, layer: layer, option: :override
end

def set_export_override(key, val)
add_to_export %{export #{key}="#{val.gsub('"','\"')}"}
def set_export_path(key, val, layer = nil)
export key, val, layer: layer, option: :path
end

def log_internal(*args)
Expand Down

0 comments on commit b9d0465

Please sign in to comment.