Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding compose env for local builds #118

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions lib/buildkite/config/docker_build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,23 @@ def prepare
end

dsl do
def builder(ruby)
def builder(ruby, compose: nil)
build_context = context.extensions.find(BuildContext)
build_context.ruby = ruby
return unless build_context.ruby.build?

command do
compose_options = {
build: "base",
config: ".buildkite/docker-compose.yml",
env: %w[PRE_STEPS RACK],
"image-name" => build_context.ruby.image_name_for(build_context.build_id),
"cache-from" => cache_from(build_context),
push: build_push(build_context),
"image-repository" => build_context.image_base,
}
compose_options.merge!(compose) if compose

label ":docker: #{build_context.ruby.prefix}#{build_context.ruby.version}"
key "docker-image-#{build_context.ruby.image_key}"
plugin :artifacts, {
Expand All @@ -66,16 +77,7 @@ def builder(ruby)
compressed: ".buildkite.tgz"
}

plugin :docker_compose, {
build: "base",
config: ".buildkite/docker-compose.yml",
env: %w[PRE_STEPS RACK],
"image-name" => build_context.ruby.image_name_for(build_context.build_id),
"cache-from" => cache_from(build_context),
push: build_push(build_context),
"image-repository" => build_context.image_base,
}

plugin :docker_compose, compose_options
env({
BUNDLER: build_context.bundler,
RUBYGEMS: build_context.rubygems,
Expand Down
31 changes: 17 additions & 14 deletions lib/buildkite/config/rake_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def build_env(build_context, pre_steps, env)
env ||= {}
pre_steps ||= []

env[:IMAGE_NAME] = build_context.image_name_for(build_context.build_id, prefix: nil)
env[:IMAGE_NAME] ||= build_context.image_name_for(build_context.build_id, prefix: nil)

if build_context.ruby.yjit_enabled?
env[:RUBY_YJIT_ENABLE] = "1"
Expand All @@ -33,7 +33,17 @@ def build_env(build_context, pre_steps, env)
env
end

def install_plugins(service = "default", env = nil, dir = ".")
def install_plugins(service = "default", env = nil, dir = ".", compose: nil)
compose_options = {
"env" => env,
"run" => service,
"pull" => service,
"pull-retries" => 3,
"config" => ".buildkite/docker-compose.yml",
"shell" => ["runner", *dir],
}
compose_options.merge!(compose) if compose

plugin :artifacts, {
download: ".dockerignore"
}
Expand All @@ -49,14 +59,7 @@ def install_plugins(service = "default", env = nil, dir = ".")
compressed: ".buildkite.tgz"
}

plugin :docker_compose, {
"env" => env,
"run" => service,
"pull" => service,
"pull-retries" => 3,
"config" => ".buildkite/docker-compose.yml",
"shell" => ["runner", *dir],
}.compact
plugin :docker_compose, compose_options.compact
end
end

Expand All @@ -65,15 +68,15 @@ def prepare
end

dsl do
def bundle(command, label:, env: nil)
def bundle(command, label:, env: nil, compose: nil)
build_context = context.extensions.find(BuildContext)

command do
label label
depends_on "docker-image-#{build_context.ruby.image_key}"
command command

install_plugins
install_plugins(compose: compose)

env build_env(build_context, nil, env)

Expand All @@ -85,7 +88,7 @@ def bundle(command, label:, env: nil)
end
end

def rake(dir, task: "test", label: nil, service: "default", pre_steps: nil, env: nil, retry_on: nil, soft_fail: nil, parallelism: nil)
def rake(dir, task: "test", label: nil, service: "default", pre_steps: nil, env: nil, retry_on: nil, soft_fail: nil, parallelism: nil, compose: nil)
build_context = context.extensions.find(BuildContext)

if task.start_with?("mysql2:") || (build_context.rails_version >= Gem::Version.new("7.1.0.alpha") && task.start_with?("trilogy:"))
Expand All @@ -99,7 +102,7 @@ def rake(dir, task: "test", label: nil, service: "default", pre_steps: nil, env:
depends_on "docker-image-#{build_context.ruby.image_key}"
command "rake #{task}"

install_plugins(service, %w[PRE_STEPS RACK], dir)
install_plugins(service, %w[PRE_STEPS RACK], dir, compose: compose)

env build_env(build_context, pre_steps, env)

Expand Down
28 changes: 28 additions & 0 deletions test/buildkite_config/test_docker_build.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,32 @@ def test_builder_gem_version
assert_equal ["base:buildkite-config-base:ruby-1-9-3-br-main"], compose["cache-from"]
assert_equal ["base:buildkite-config-base:ruby-1-9-3-br-"], compose["push"]
end

def test_builder_compose_options
pipeline = PipelineFixture.new do
use Buildkite::Config::DockerBuild

build_context.stub(:rails_version, Gem::Version.new("7.1")) do
builder Buildkite::Config::RubyConfig.new(version: "3.2"), compose: {
"cli_version": "2",
"image-name": "buildkite_base",
"cache-from": ["buildkite_base"],
"push": "",
"image-repository": "",
}
end
end

plugins = pipeline.to_h["steps"][0]["plugins"]

compose = plugins.find { |plugin|
plugin.key?("docker-compose#v1.0")
}.fetch("docker-compose#v1.0")

assert_equal "2", compose["cli_version"]
assert_equal "buildkite_base", compose["image-name"]
assert_equal ["buildkite_base"], compose["cache-from"]
assert_equal "", compose["push"]
assert_equal "", compose["image-repository"]
end
end
85 changes: 85 additions & 0 deletions test/buildkite_config/test_rake_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,21 @@ def test_env
assert_equal "buildkite-config-base:ruby-3-2-local", pipeline.to_h["steps"][0]["env"]["IMAGE_NAME"]
end

def test_env_image_name
pipeline = PipelineFixture.new do
build_context.ruby = Buildkite::Config::RubyConfig.new(prefix: "ruby:", version: Gem::Version.new("3.2"))
use Buildkite::Config::RakeCommand

build_context.stub(:rails_version, Gem::Version.new("7.1")) do
rake "test", task: "test:all", env: { "IMAGE_NAME": "override-at-command-definition" }
end
end

assert_includes pipeline.to_h["steps"][0], "env"
assert_includes pipeline.to_h["steps"][0]["env"], "IMAGE_NAME"
assert_equal "override-at-command-definition", pipeline.to_h["steps"][0]["env"]["IMAGE_NAME"]
end

def test_timeout_in_minutes
pipeline = PipelineFixture.new do
build_context.ruby = Buildkite::Config::RubyConfig.new(prefix: "ruby:", version: Gem::Version.new("3.2"))
Expand Down Expand Up @@ -220,6 +235,39 @@ def test_compose
assert_equal ["runner", "test"], compose["shell"]
end

def test_compose_options
pipeline = PipelineFixture.new do
build_context.ruby = Buildkite::Config::RubyConfig.new(prefix: "ruby:", version: Gem::Version.new("3.2"))
use Buildkite::Config::RakeCommand

build_context.stub(:rails_version, Gem::Version.new("7.1")) do
rake "test", task: "test:all", compose: {
"cli_version": "2",
"pull": "",
}
end
end

plugins = pipeline.to_h["steps"][0]["plugins"]

compose = plugins.find { |plugin|
plugin.key?("docker-compose#v1.0")
}.fetch("docker-compose#v1.0")

%w[env run pull config shell].each do |key|
assert_includes compose, key
end

assert_includes compose["env"], "PRE_STEPS"
assert_includes compose["env"], "RACK"

assert_equal "2", compose["cli_version"]
assert_equal "default", compose["run"]
assert_equal "", compose["pull"]
assert_equal ".buildkite/docker-compose.yml", compose["config"]
assert_equal ["runner", "test"], compose["shell"]
end

def test_multiple
pipeline = PipelineFixture.new do
build_context.ruby = Buildkite::Config::RubyConfig.new(version: Gem::Version.new("3.2"))
Expand Down Expand Up @@ -462,4 +510,41 @@ def test_bundle_command
assert_equal ["test-reports/*/*.xml"], step["artifact_paths"]
assert_equal 30, step["timeout_in_minutes"]
end

def test_bundle_command_options
pipeline = PipelineFixture.new do
build_context.ruby = Buildkite::Config::RubyConfig.new(prefix: "ruby:", version: Gem::Version.new("3.2"))
use Buildkite::Config::RakeCommand

build_context.stub(:rails_version, Gem::Version.new("7.1")) do
bundle "rubocop", label: "rubocop", compose: {
"cli_version": "2",
"pull": "",
}, env: {
"IMAGE_NAME": "override-at-command-definition",
}
end
end

step = pipeline.to_h["steps"][0]
assert_equal "override-at-command-definition", step["env"]["IMAGE_NAME"]

plugins = step["plugins"]

compose = plugins.find { |plugin|
plugin.key?("docker-compose#v1.0")
}.fetch("docker-compose#v1.0")

%w[run pull config shell].each do |key|
assert_includes compose, key
end

assert_predicate compose["env"], :nil?

assert_equal "2", compose["cli_version"]
assert_equal "default", compose["run"]
assert_equal "", compose["pull"]
assert_equal ".buildkite/docker-compose.yml", compose["config"]
assert_equal ["runner", "."], compose["shell"]
end
end