Refactor to tag builds correctly
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
class TwoFer
|
class TwoFer
|
||||||
def self.two_fer(name)
|
def self.two_fer(name)
|
||||||
"One for #{name || "you"}, one for me."
|
name = "you" if name.nil?
|
||||||
|
"One for #{name}, one for me."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ Aws.config.update({
|
|||||||
module Pipeline
|
module Pipeline
|
||||||
def self.spike
|
def self.spike
|
||||||
puts "OK"
|
puts "OK"
|
||||||
# AnalyzerBuild.("ruby")
|
AnalyzerBuild.("ruby")
|
||||||
repo = Pipeline::AnalyzerRepo.new("/home/ccare/code/exercism/sample-analyzer")
|
# repo = Pipeline::AnalyzerRepo.new("/home/ccare/code/exercism/sample-analyzer")
|
||||||
repo.fetch!
|
# repo.fetch!
|
||||||
puts "DONE"
|
puts "DONE"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -24,9 +24,11 @@ require "pipeline/analyzer_build"
|
|||||||
require "pipeline/validation/check_invokable"
|
require "pipeline/validation/check_invokable"
|
||||||
require "pipeline/validation/check_environment_invariants"
|
require "pipeline/validation/check_environment_invariants"
|
||||||
require "pipeline/validation/check_fixtures"
|
require "pipeline/validation/check_fixtures"
|
||||||
|
require "pipeline/validation/fixture_check_error.rb"
|
||||||
require "pipeline/validate_build"
|
require "pipeline/validate_build"
|
||||||
require "pipeline/util/container_driver"
|
require "pipeline/util/container_driver"
|
||||||
require "pipeline/util/runc_configurator"
|
require "pipeline/util/runc_configurator"
|
||||||
require "pipeline/util/img_wrapper"
|
require "pipeline/util/img_wrapper"
|
||||||
require "pipeline/util/runc_wrapper"
|
require "pipeline/util/runc_wrapper"
|
||||||
require "pipeline/build_image"
|
require "pipeline/build_image"
|
||||||
|
require "pipeline/publish_image"
|
||||||
|
|||||||
@@ -1,104 +1,35 @@
|
|||||||
class Pipeline::AnalyzerBuild
|
class Pipeline::AnalyzerBuild
|
||||||
include Mandate
|
include Mandate
|
||||||
|
|
||||||
attr_accessor :img, :target_sha, :build_tag
|
attr_accessor :img, :runc, :target_sha, :build_tag, :image_tag
|
||||||
|
|
||||||
initialize_with :track_slug
|
initialize_with :track_slug
|
||||||
|
|
||||||
def call
|
def call
|
||||||
@build_tag = "master"
|
setup_utiliies
|
||||||
@img = File.expand_path "./opt/img"
|
|
||||||
repo.fetch!
|
|
||||||
checkout
|
|
||||||
build
|
build
|
||||||
validate
|
validate
|
||||||
return
|
publish
|
||||||
puts "login"
|
|
||||||
login_to_repository
|
|
||||||
tag_build
|
|
||||||
push_build
|
|
||||||
logout
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def checkout
|
def setup_utiliies
|
||||||
@target_sha = repo.checkout(build_tag)
|
@img = Pipeline::Util::ImgWrapper.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def build
|
def build
|
||||||
Dir.chdir(repo.workdir) do
|
@build_tag = "master"
|
||||||
cmd = "#{build_cmd} -t #{local_tag} ."
|
@image_tag = Pipeline::BuildImage.(build_tag, image_name, repo, img)
|
||||||
exec_cmd cmd
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate
|
def validate
|
||||||
Pipeline::ValidateBuild.(track_slug, local_tag)
|
Pipeline::ValidateBuild.(image_tag, "fixtures/#{track_slug}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def login_to_repository
|
def publish
|
||||||
ecr = Aws::ECR::Client.new(region: 'eu-west-1')
|
Pipeline::PublishImage.(img, image_name, image_tag, build_tag)
|
||||||
authorization_token = ecr.get_authorization_token.authorization_data[0].authorization_token
|
|
||||||
plain = Base64.decode64(authorization_token)
|
|
||||||
user,password = plain.split(":")
|
|
||||||
exec_cmd "#{img} login -u AWS -p \"#{password}\" #{registry_endpoint}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def logout
|
def image_name
|
||||||
exec_cmd "#{img} logout #{registry_endpoint}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def tag_build
|
|
||||||
exec_cmd "#{tag_cmd} #{local_tag} #{remote_tag}"
|
|
||||||
exec_cmd "#{tag_cmd} #{local_tag} #{remote_human_tag}"
|
|
||||||
exec_cmd "#{tag_cmd} #{local_tag} #{remote_latest_tag}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def push_build
|
|
||||||
exec_cmd "#{push_cmd} #{remote_tag}"
|
|
||||||
exec_cmd "#{push_cmd} #{remote_human_tag}"
|
|
||||||
exec_cmd "#{push_cmd} #{remote_latest_tag}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def push_cmd
|
|
||||||
"#{img} push -state /tmp/state-img"
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_cmd
|
|
||||||
"#{img} build -state /tmp/state-img"
|
|
||||||
end
|
|
||||||
|
|
||||||
def tag_cmd
|
|
||||||
"#{img} tag -state /tmp/state-img"
|
|
||||||
end
|
|
||||||
|
|
||||||
def exec_cmd(cmd)
|
|
||||||
puts "> #{cmd}"
|
|
||||||
puts "------------------------------------------------------------"
|
|
||||||
success = system({}, cmd)
|
|
||||||
raise "Failed #{cmd}" unless success
|
|
||||||
end
|
|
||||||
|
|
||||||
def local_tag
|
|
||||||
"#{slug}:#{target_sha}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def remote_tag
|
|
||||||
"#{registry_endpoint}/#{slug}:#{target_sha}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def remote_human_tag
|
|
||||||
"#{registry_endpoint}/#{slug}:#{build_tag}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def remote_latest_tag
|
|
||||||
"#{registry_endpoint}/#{slug}:latest"
|
|
||||||
end
|
|
||||||
|
|
||||||
def registry_endpoint
|
|
||||||
"681735686245.dkr.ecr.eu-west-1.amazonaws.com"
|
|
||||||
end
|
|
||||||
|
|
||||||
def slug
|
|
||||||
"#{track_slug}-analyzer-dev"
|
"#{track_slug}-analyzer-dev"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
class Pipeline::BuildImage
|
class Pipeline::BuildImage
|
||||||
include Mandate
|
include Mandate
|
||||||
|
|
||||||
attr_accessor :target_sha, :build_tag
|
attr_accessor :target_sha
|
||||||
|
|
||||||
initialize_with :track_slug, :repo, :img
|
initialize_with :build_tag, :image_slug, :repo, :img
|
||||||
|
|
||||||
def call
|
def call
|
||||||
@build_tag = "master"
|
|
||||||
repo.fetch!
|
repo.fetch!
|
||||||
checkout
|
checkout
|
||||||
build
|
build
|
||||||
@@ -24,10 +23,6 @@ class Pipeline::BuildImage
|
|||||||
end
|
end
|
||||||
|
|
||||||
def local_tag
|
def local_tag
|
||||||
"#{slug}:#{target_sha}"
|
"#{image_slug}:#{target_sha}"
|
||||||
end
|
|
||||||
|
|
||||||
def slug
|
|
||||||
"#{track_slug}-analyzer-dev"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
64
lib/pipeline/publish_image.rb
Normal file
64
lib/pipeline/publish_image.rb
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
class Pipeline::PublishImage
|
||||||
|
include Mandate
|
||||||
|
|
||||||
|
initialize_with :img, :image_name, :image_tag, :build_tag
|
||||||
|
|
||||||
|
def call
|
||||||
|
puts "PUBLISHING #{image_tag}"
|
||||||
|
puts "Login to repo"
|
||||||
|
login_to_repository
|
||||||
|
tag_build
|
||||||
|
push_build
|
||||||
|
logout
|
||||||
|
end
|
||||||
|
|
||||||
|
def login_to_repository
|
||||||
|
ecr = Aws::ECR::Client.new(region: 'eu-west-1')
|
||||||
|
authorization_token = ecr.get_authorization_token.authorization_data[0].authorization_token
|
||||||
|
plain = Base64.decode64(authorization_token)
|
||||||
|
user,password = plain.split(":")
|
||||||
|
img.login("AWS", password, registry_endpoint)
|
||||||
|
end
|
||||||
|
|
||||||
|
def logout
|
||||||
|
img.logout(registry_endpoint)
|
||||||
|
end
|
||||||
|
|
||||||
|
def registry_endpoint
|
||||||
|
"681735686245.dkr.ecr.eu-west-1.amazonaws.com"
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_build
|
||||||
|
img.tag(image_tag, remote_tag)
|
||||||
|
img.tag(image_tag, remote_human_tag) unless build_tag.nil?
|
||||||
|
img.tag(image_tag, remote_latest_tag)
|
||||||
|
end
|
||||||
|
|
||||||
|
def push_build
|
||||||
|
img.push(remote_tag)
|
||||||
|
img.push(remote_human_tag) unless build_tag.nil?
|
||||||
|
img.push(remote_latest_tag)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_tag
|
||||||
|
"#{registry_endpoint}/#{image_tag}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_human_tag
|
||||||
|
"#{registry_endpoint}/#{image_name}:#{build_tag}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def remote_latest_tag
|
||||||
|
"#{registry_endpoint}/#{image_name}:latest"
|
||||||
|
end
|
||||||
|
|
||||||
|
def registry_endpoint
|
||||||
|
"681735686245.dkr.ecr.eu-west-1.amazonaws.com"
|
||||||
|
end
|
||||||
|
|
||||||
|
def slug
|
||||||
|
image_tag
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
module Pipeline::Util
|
module Pipeline::Util
|
||||||
class ImgWrapper
|
class ImgWrapper
|
||||||
|
|
||||||
attr_accessor :binary_path, :state_location, :suppress_output
|
attr_accessor :binary_path, :state_location, :suppress_output
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@@ -17,6 +18,22 @@ module Pipeline::Util
|
|||||||
exec_cmd "#{binary_path} unpack -state #{state_location} #{local_tag}"
|
exec_cmd "#{binary_path} unpack -state #{state_location} #{local_tag}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def login(user, password, registry_endpoint)
|
||||||
|
exec_cmd "#{binary_path} login -u #{user} -p \"#{password}\" #{registry_endpoint}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def logout(registry_endpoint)
|
||||||
|
exec_cmd "#{binary_path} logout #{registry_endpoint}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag(image, new_tag)
|
||||||
|
exec_cmd "#{tag_cmd} #{image} #{new_tag}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def push(remote_tag)
|
||||||
|
exec_cmd "#{push_cmd} #{remote_tag}"
|
||||||
|
end
|
||||||
|
|
||||||
def push_cmd
|
def push_cmd
|
||||||
"#{binary_path} push -state #{state_location}"
|
"#{binary_path} push -state #{state_location}"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ module Pipeline::Validation
|
|||||||
initialize_with :container_driver, :fixtures_folder
|
initialize_with :container_driver, :fixtures_folder
|
||||||
|
|
||||||
def call
|
def call
|
||||||
clean_and_setup
|
|
||||||
exercise_folders = Dir.glob("#{fixtures_folder}/*")
|
exercise_folders = Dir.glob("#{fixtures_folder}/*")
|
||||||
exercise_folders.each do |exercise_folder|
|
exercise_folders.each do |exercise_folder|
|
||||||
exercise_slug = exercise_folder.split("/").last
|
exercise_slug = exercise_folder.split("/").last
|
||||||
@@ -15,11 +14,8 @@ module Pipeline::Validation
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def clean_and_setup
|
|
||||||
FileUtils.rm_rf("#{workdir}/iteration/")
|
|
||||||
end
|
|
||||||
|
|
||||||
def validate_status(exercise, fixture_folder)
|
def validate_status(exercise, fixture_folder)
|
||||||
|
FileUtils.rm_rf("#{workdir}/iteration/")
|
||||||
FileUtils.cp_r "#{fixture_folder}/iteration", "#{workdir}/iteration"
|
FileUtils.cp_r "#{fixture_folder}/iteration", "#{workdir}/iteration"
|
||||||
|
|
||||||
container_driver.run_analyzer_for(exercise)
|
container_driver.run_analyzer_for(exercise)
|
||||||
@@ -28,10 +24,20 @@ module Pipeline::Validation
|
|||||||
expected = JSON.parse(File.read("#{fixture_folder}/expected_analysis.json"))
|
expected = JSON.parse(File.read("#{fixture_folder}/expected_analysis.json"))
|
||||||
|
|
||||||
raise "Incorrect expected_status" if expected["status"].nil?
|
raise "Incorrect expected_status" if expected["status"].nil?
|
||||||
raise "Incorrect status when validating #{fixture_folder}" if expected["status"] != analysis["status"]
|
|
||||||
|
if expected["status"] != analysis["status"]
|
||||||
|
mismatch = "<#{analysis["status"]}> not <#{expected["status"]}>"
|
||||||
|
msg = "Incorrect status (#{mismatch}) when validating #{fixture_folder}"
|
||||||
|
err = FixtureCheckError.new(msg)
|
||||||
|
raise err
|
||||||
|
end
|
||||||
expected["comments"] ||= []
|
expected["comments"] ||= []
|
||||||
analysis["comments"] ||= []
|
analysis["comments"] ||= []
|
||||||
raise "Incorrect comments when validating #{fixture_folder}" if expected["comments"].sort != analysis["comments"].sort
|
if expected["comments"].sort != analysis["comments"].sort
|
||||||
|
msg = "Incorrect comments when validating #{fixture_folder}."
|
||||||
|
msg += " Got: " + analysis["comments"].to_json
|
||||||
|
raise FixtureCheckError.new(msg)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def workdir
|
def workdir
|
||||||
|
|||||||
7
lib/pipeline/validation/fixture_check_error.rb
Normal file
7
lib/pipeline/validation/fixture_check_error.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class FixtureCheckError < StandardError
|
||||||
|
|
||||||
|
def initialize(*args)
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"status": "unapprove"
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"status": "disapprove",
|
||||||
|
"comments": [
|
||||||
|
{
|
||||||
|
"comment": "demo.sample.comment",
|
||||||
|
"params": { "p1": "hello world" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
48
test/pipeline/validation/check_features_test.rb
Normal file
48
test/pipeline/validation/check_features_test.rb
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
module Pipeline::Validation
|
||||||
|
class CheckFixturesTest < Minitest::Test
|
||||||
|
|
||||||
|
attr_reader :img, :runc, :container_driver
|
||||||
|
|
||||||
|
def setup
|
||||||
|
track_slug = "demo"
|
||||||
|
demo_analyzer_repo = "/home/ccare/code/exercism/sample-analyzer"
|
||||||
|
repo = Pipeline::AnalyzerRepo.new(demo_analyzer_repo)
|
||||||
|
workdir = "/tmp/analyzer-scratch/#{SecureRandom.uuid}"
|
||||||
|
|
||||||
|
@img = Pipeline::Util::ImgWrapper.new
|
||||||
|
@runc = Pipeline::Util::RuncWrapper.new
|
||||||
|
configurator = Pipeline::Util::RuncConfigurator.new
|
||||||
|
configurator.seed_from_env
|
||||||
|
|
||||||
|
image_tag = Pipeline::BuildImage.("master", track_slug, repo, img)
|
||||||
|
|
||||||
|
@container_driver = Pipeline::Util::ContainerDriver.new(runc, img, configurator, workdir)
|
||||||
|
container_driver.prepare_workdir
|
||||||
|
container_driver.unpack_image(image_tag)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_checks_when_ok
|
||||||
|
Pipeline::Validation::CheckFixtures.(container_driver, "test-fixtures/demo-ok")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_checks_fails_when_status_incorrect
|
||||||
|
err = assert_raises FixtureCheckError do
|
||||||
|
Pipeline::Validation::CheckFixtures.(container_driver, "test-fixtures/demo-failure")
|
||||||
|
end
|
||||||
|
expected_message = "Incorrect status (<approve> not <unapprove>) when validating test-fixtures/demo-failure/approval/example1"
|
||||||
|
assert_equal expected_message, err.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_checks_fails_when_comments_incorrect
|
||||||
|
err = assert_raises FixtureCheckError do
|
||||||
|
Pipeline::Validation::CheckFixtures.(container_driver, "test-fixtures/demo-failure2")
|
||||||
|
end
|
||||||
|
expected_message = "Incorrect comments when validating test-fixtures/demo-failure2/disapprove-comments/example1. Got: [{\"comment\":\"demo.sample.comment\",\"params\":{\"p1\":\"hello\"}}]"
|
||||||
|
assert_equal expected_message, err.message
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2,22 +2,14 @@ require 'test_helper'
|
|||||||
require 'json'
|
require 'json'
|
||||||
|
|
||||||
module Pipeline
|
module Pipeline
|
||||||
class SpikeTest < Minitest::Test
|
class BuildAndValidateTest < Minitest::Test
|
||||||
|
|
||||||
def test_build_image
|
def test_build_and_validate_realish_image
|
||||||
track_slug = "demo"
|
|
||||||
demo_analyzer_repo = "/home/ccare/code/exercism/sample-analyzer"
|
demo_analyzer_repo = "/home/ccare/code/exercism/sample-analyzer"
|
||||||
repo = Pipeline::AnalyzerRepo.new(demo_analyzer_repo)
|
repo = Pipeline::AnalyzerRepo.new(demo_analyzer_repo)
|
||||||
|
|
||||||
refute repo.nil?
|
|
||||||
|
|
||||||
img = Pipeline::Util::ImgWrapper.new
|
img = Pipeline::Util::ImgWrapper.new
|
||||||
|
image_tag = Pipeline::BuildImage.("master", "demo", repo, img)
|
||||||
image_tag = Pipeline::BuildImage.(track_slug, repo, img)
|
Pipeline::ValidateBuild.(image_tag, "test-fixtures/demo")
|
||||||
|
|
||||||
puts image_tag
|
|
||||||
|
|
||||||
Pipeline::ValidateBuild.(image_tag, "fixtures/#{track_slug}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user