shipitron 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.buildkite/pipeline.yml +94 -0
- data/.dockerignore +1 -0
- data/.gitattributes +1 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Deskfile +15 -0
- data/Dockerfile +40 -15
- data/Dockerfile.release +29 -6
- data/Dockerfile.staging +70 -0
- data/Gemfile +2 -0
- data/README.md +53 -15
- data/docker-compose.yml +54 -0
- data/lib/shipitron.rb +19 -2
- data/lib/shipitron/cli.rb +42 -42
- data/lib/shipitron/client.rb +9 -0
- data/lib/shipitron/client/bootstrap_application.rb +1 -0
- data/lib/shipitron/client/create_ecs_services.rb +7 -7
- data/lib/shipitron/client/deploy_application.rb +2 -0
- data/lib/shipitron/client/ensure_deploy_not_running.rb +2 -1
- data/lib/shipitron/client/fetch_clusters.rb +1 -0
- data/lib/shipitron/client/force_deploy.rb +1 -0
- data/lib/shipitron/client/generate_deploy.rb +41 -0
- data/lib/shipitron/client/load_application_config.rb +17 -0
- data/lib/shipitron/client/load_templates.rb +1 -0
- data/lib/shipitron/client/register_ecs_task_definitions.rb +5 -5
- data/lib/shipitron/client/run_ecs_tasks.rb +101 -72
- data/lib/shipitron/docker_image.rb +4 -1
- data/lib/shipitron/find_docker_volume_name.rb +68 -0
- data/lib/shipitron/git_info.rb +57 -0
- data/lib/shipitron/mustache_yaml_parser.rb +12 -8
- data/lib/shipitron/s3_copy.rb +46 -0
- data/lib/shipitron/server/deploy_application.rb +2 -0
- data/lib/shipitron/server/docker/build_image.rb +4 -1
- data/lib/shipitron/server/docker/configure.rb +46 -10
- data/lib/shipitron/server/docker/push_image.rb +3 -0
- data/lib/shipitron/server/docker/run_build_script.rb +17 -10
- data/lib/shipitron/server/download_build_cache.rb +11 -3
- data/lib/shipitron/server/fetch_deploy.rb +50 -0
- data/lib/shipitron/server/git/clone_local_copy.rb +4 -5
- data/lib/shipitron/server/git/update_cache.rb +2 -1
- data/lib/shipitron/server/run_post_build.rb +40 -1
- data/lib/shipitron/server/transform_cli_args.rb +4 -0
- data/lib/shipitron/server/update_ecs_task_definitions.rb +2 -1
- data/lib/shipitron/server/upload_build_cache.rb +10 -9
- data/lib/shipitron/version.rb +1 -1
- data/scripts/docker-entrypoint.sh +37 -3
- data/scripts/release-entrypoint.sh +20 -0
- data/shipitron.gemspec +11 -8
- data/test.yml +5 -0
- metadata +78 -25
- data/build_dev.sh +0 -27
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'shipitron'
|
2
2
|
require 'shipitron/consul_keys'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
module Shipitron
|
5
6
|
module Server
|
@@ -9,22 +10,48 @@ module Shipitron
|
|
9
10
|
include ConsulKeys
|
10
11
|
|
11
12
|
required :application
|
13
|
+
optional :registry
|
12
14
|
|
13
15
|
before do
|
14
16
|
configure_consul_client!
|
15
17
|
end
|
16
18
|
|
17
19
|
def call
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
username = fetch_scoped_key('docker_user')
|
21
|
+
password = fetch_scoped_key('docker_password')
|
22
|
+
|
23
|
+
if username && password
|
24
|
+
Logger.info `docker login --username #{username} --password #{password}`
|
25
|
+
if $? != 0
|
26
|
+
fail_with_error!(message: 'Docker login failed.')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
if registry
|
31
|
+
case registry
|
32
|
+
when /docker\.io/
|
33
|
+
# do nothing
|
34
|
+
when /\d+\.dkr\.ecr\.us-east-1\.amazonaws\.com/
|
35
|
+
# ECR
|
36
|
+
config_file = Pathname.new('/home/shipitron/.docker/config.json')
|
37
|
+
config_file.parent.mkpath
|
38
|
+
|
39
|
+
config_hash = {}
|
40
|
+
if config_file.file?
|
41
|
+
config_file.open('rb') do |file|
|
42
|
+
json = file.read
|
43
|
+
config_hash = JSON.parse(json) rescue {}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
config_hash['credHelpers'] ||= {}
|
48
|
+
config_hash['credHelpers'][registry] = 'ecr-login'
|
49
|
+
|
50
|
+
config_file.open('wb') do |file|
|
51
|
+
file.puts(JSON.generate(config_hash))
|
52
|
+
file.chmod(0600)
|
53
|
+
end
|
54
|
+
end
|
28
55
|
end
|
29
56
|
end
|
30
57
|
|
@@ -33,6 +60,15 @@ module Shipitron
|
|
33
60
|
context.application
|
34
61
|
end
|
35
62
|
|
63
|
+
def registry
|
64
|
+
context.registry
|
65
|
+
end
|
66
|
+
|
67
|
+
def fetch_scoped_key(key)
|
68
|
+
value = fetch_key(key: "shipitron/#{application}/#{key}")
|
69
|
+
value = fetch_key(key: "shipitron/#{key}") if value.nil?
|
70
|
+
value
|
71
|
+
end
|
36
72
|
end
|
37
73
|
end
|
38
74
|
end
|
@@ -8,8 +8,11 @@ module Shipitron
|
|
8
8
|
|
9
9
|
required :docker_image
|
10
10
|
required :named_tag
|
11
|
+
optional :skip_push, default: false
|
11
12
|
|
12
13
|
def call
|
14
|
+
return if context.skip_push
|
15
|
+
|
13
16
|
Logger.info "Pushing docker image #{docker_image} and #{docker_image.name_with_tag(named_tag)}"
|
14
17
|
|
15
18
|
Logger.info `docker tag #{docker_image} #{docker_image.name_with_tag(named_tag)}`
|
@@ -9,17 +9,16 @@ module Shipitron
|
|
9
9
|
|
10
10
|
required :application
|
11
11
|
required :docker_image
|
12
|
-
required :
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
context.build_script ||= 'shipitron/build.sh'
|
17
|
-
end
|
12
|
+
required :git_info
|
13
|
+
required :named_tag
|
14
|
+
optional :build_script, default: 'shipitron/build.sh'
|
15
|
+
optional :registry
|
18
16
|
|
19
17
|
def call
|
20
18
|
Logger.info 'Building docker image'
|
21
19
|
|
22
|
-
docker_image.
|
20
|
+
docker_image.registry = registry if registry != nil
|
21
|
+
docker_image.tag = git_info.short_sha
|
23
22
|
|
24
23
|
FileUtils.cd("/home/shipitron/#{application}") do
|
25
24
|
unless Pathname.new(build_script).exist?
|
@@ -27,7 +26,7 @@ module Shipitron
|
|
27
26
|
end
|
28
27
|
|
29
28
|
cmd = TTY::Command.new
|
30
|
-
result = cmd.run!("#{build_script} #{docker_image}")
|
29
|
+
result = cmd.run!("#{build_script} #{docker_image} #{named_tag}")
|
31
30
|
|
32
31
|
if result.failure?
|
33
32
|
fail_with_error!(message: "build script exited with non-zero code: #{result.exit_status}")
|
@@ -44,13 +43,21 @@ module Shipitron
|
|
44
43
|
context.docker_image
|
45
44
|
end
|
46
45
|
|
47
|
-
def
|
48
|
-
context.
|
46
|
+
def git_info
|
47
|
+
context.git_info
|
48
|
+
end
|
49
|
+
|
50
|
+
def named_tag
|
51
|
+
context.named_tag
|
49
52
|
end
|
50
53
|
|
51
54
|
def build_script
|
52
55
|
context.build_script
|
53
56
|
end
|
57
|
+
|
58
|
+
def registry
|
59
|
+
context.registry
|
60
|
+
end
|
54
61
|
end
|
55
62
|
end
|
56
63
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'shipitron'
|
2
2
|
require 'shipitron/fetch_bucket'
|
3
|
+
require 'shipitron/s3_copy'
|
3
4
|
|
4
5
|
module Shipitron
|
5
6
|
module Server
|
@@ -9,11 +10,12 @@ module Shipitron
|
|
9
10
|
required :application
|
10
11
|
required :s3_cache_bucket
|
11
12
|
required :build_cache_location
|
13
|
+
required :region
|
12
14
|
|
13
15
|
def call
|
14
16
|
Logger.info "Downloading build cache from bucket #{s3_cache_bucket}"
|
15
17
|
|
16
|
-
s3_file = bucket.files.
|
18
|
+
s3_file = bucket.files.head("#{application}.build-cache.archive")
|
17
19
|
if s3_file.nil?
|
18
20
|
Logger.warn 'Build cache not found.'
|
19
21
|
return
|
@@ -21,8 +23,14 @@ module Shipitron
|
|
21
23
|
|
22
24
|
build_cache = Pathname.new("/home/shipitron/#{application}/#{build_cache_location}")
|
23
25
|
build_cache.parent.mkpath
|
24
|
-
|
25
|
-
|
26
|
+
|
27
|
+
result = S3Copy.call(
|
28
|
+
source: "s3://#{s3_cache_bucket}/#{application}.build-cache.archive",
|
29
|
+
destination: build_cache.to_s,
|
30
|
+
region: context.region
|
31
|
+
)
|
32
|
+
if result.failure?
|
33
|
+
fail_with_error!(message: 'Failed to download build cache!')
|
26
34
|
end
|
27
35
|
|
28
36
|
Logger.info 'Download complete.'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'shipitron'
|
2
|
+
require 'aws-sdk-s3'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Shipitron
|
6
|
+
module Server
|
7
|
+
class FetchDeploy
|
8
|
+
include Metaractor
|
9
|
+
|
10
|
+
required :deploy_bucket
|
11
|
+
required :deploy_bucket_region
|
12
|
+
required :deploy_id
|
13
|
+
|
14
|
+
def call
|
15
|
+
s3_key = "#{Shipitron::DEPLOY_BUCKET_PREFIX}#{context.deploy_id}"
|
16
|
+
Logger.info "Fetching deploy config from s3://#{deploy_bucket}/#{s3_key}"
|
17
|
+
|
18
|
+
response = client.get_object(
|
19
|
+
bucket: deploy_bucket,
|
20
|
+
key: s3_key
|
21
|
+
)
|
22
|
+
|
23
|
+
context.deploy_options =
|
24
|
+
JSON.parse(response.body.read)
|
25
|
+
.transform_keys {|k| k.to_sym }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def client
|
31
|
+
Aws::S3::Client.new(
|
32
|
+
region: deploy_bucket_region,
|
33
|
+
**client_opts
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def client_opts
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
|
41
|
+
def deploy_bucket
|
42
|
+
context.deploy_bucket
|
43
|
+
end
|
44
|
+
|
45
|
+
def deploy_bucket_region
|
46
|
+
context.deploy_bucket_region
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'shipitron'
|
2
2
|
require 'shellwords'
|
3
|
+
require 'shipitron/git_info'
|
3
4
|
|
4
5
|
module Shipitron
|
5
6
|
module Server
|
@@ -12,7 +13,7 @@ module Shipitron
|
|
12
13
|
optional :repository_branch
|
13
14
|
|
14
15
|
before do
|
15
|
-
context.repository_branch ||= '
|
16
|
+
context.repository_branch ||= 'main'
|
16
17
|
end
|
17
18
|
|
18
19
|
def call
|
@@ -22,10 +23,8 @@ module Shipitron
|
|
22
23
|
end
|
23
24
|
|
24
25
|
Logger.info 'Using this git commit:'
|
25
|
-
|
26
|
-
|
27
|
-
Logger.info `git --no-pager log --format='%aN (%h): %s' -n 1`.chomp
|
28
|
-
end
|
26
|
+
context.git_info = GitInfo.from_path(path: "/home/shipitron/#{application}")
|
27
|
+
Logger.info context.git_info.one_liner
|
29
28
|
end
|
30
29
|
|
31
30
|
private
|
@@ -13,7 +13,7 @@ module Shipitron
|
|
13
13
|
optional :repository_branch
|
14
14
|
|
15
15
|
before do
|
16
|
-
context.repository_branch ||= '
|
16
|
+
context.repository_branch ||= 'main'
|
17
17
|
end
|
18
18
|
|
19
19
|
def call
|
@@ -25,6 +25,7 @@ module Shipitron
|
|
25
25
|
else
|
26
26
|
Logger.info 'Fetching new git commits'
|
27
27
|
FileUtils.cd('/home/shipitron/git-cache') do
|
28
|
+
`git gc --auto`
|
28
29
|
`git fetch -f #{Shellwords.escape repository_url} #{Shellwords.escape repository_branch}:#{Shellwords.escape repository_branch}`
|
29
30
|
end
|
30
31
|
end
|
@@ -9,6 +9,7 @@ module Shipitron
|
|
9
9
|
|
10
10
|
required :region
|
11
11
|
required :clusters
|
12
|
+
required :git_info
|
12
13
|
optional :post_builds
|
13
14
|
|
14
15
|
def call
|
@@ -26,7 +27,41 @@ module Shipitron
|
|
26
27
|
container_overrides: [
|
27
28
|
{
|
28
29
|
name: post_build.container_name,
|
29
|
-
command: post_build.command_ary
|
30
|
+
command: post_build.command_ary,
|
31
|
+
environment: [
|
32
|
+
{
|
33
|
+
name: "GIT_SHA",
|
34
|
+
value: git_info.sha
|
35
|
+
},
|
36
|
+
{
|
37
|
+
name: "GIT_SHORT_SHA",
|
38
|
+
value: git_info.short_sha
|
39
|
+
},
|
40
|
+
{
|
41
|
+
name: "GIT_EMAIL",
|
42
|
+
value: git_info.email
|
43
|
+
},
|
44
|
+
{
|
45
|
+
name: "GIT_NAME",
|
46
|
+
value: git_info.name
|
47
|
+
},
|
48
|
+
{
|
49
|
+
name: "GIT_MESSAGE",
|
50
|
+
value: git_info.summary
|
51
|
+
},
|
52
|
+
{
|
53
|
+
name: "GIT_TIMESTAMP",
|
54
|
+
value: git_info.timestamp
|
55
|
+
},
|
56
|
+
{
|
57
|
+
name: "GIT_BRANCH",
|
58
|
+
value: git_info.branch
|
59
|
+
},
|
60
|
+
{
|
61
|
+
name: "GIT_TAG",
|
62
|
+
value: git_info.tag
|
63
|
+
}
|
64
|
+
]
|
30
65
|
}
|
31
66
|
]
|
32
67
|
},
|
@@ -75,6 +110,10 @@ module Shipitron
|
|
75
110
|
def clusters
|
76
111
|
context.clusters
|
77
112
|
end
|
113
|
+
|
114
|
+
def git_info
|
115
|
+
context.git_info
|
116
|
+
end
|
78
117
|
end
|
79
118
|
end
|
80
119
|
end
|
@@ -12,6 +12,7 @@ module Shipitron
|
|
12
12
|
required :application
|
13
13
|
required :repository_url
|
14
14
|
optional :repository_branch
|
15
|
+
optional :registry
|
15
16
|
required :s3_cache_bucket
|
16
17
|
required :build_cache_location
|
17
18
|
required :image_name
|
@@ -23,6 +24,7 @@ module Shipitron
|
|
23
24
|
optional :ecs_services
|
24
25
|
optional :ecs_service_templates
|
25
26
|
optional :build_script
|
27
|
+
optional :skip_push, default: false
|
26
28
|
optional :post_builds
|
27
29
|
|
28
30
|
before do
|
@@ -37,6 +39,7 @@ module Shipitron
|
|
37
39
|
application
|
38
40
|
repository_url
|
39
41
|
repository_branch
|
42
|
+
registry
|
40
43
|
s3_cache_bucket
|
41
44
|
build_cache_location
|
42
45
|
named_tag
|
@@ -44,6 +47,7 @@ module Shipitron
|
|
44
47
|
clusters
|
45
48
|
ecs_services
|
46
49
|
build_script
|
50
|
+
skip_push
|
47
51
|
].each_with_object(cli_args) { |k, args| args[k] = context[k] }
|
48
52
|
|
49
53
|
cli_args.docker_image = DockerImage.new(name: context.image_name)
|
@@ -14,11 +14,12 @@ module Shipitron
|
|
14
14
|
required :docker_image
|
15
15
|
required :ecs_task_defs
|
16
16
|
optional :ecs_task_def_templates
|
17
|
+
optional :registry
|
17
18
|
|
18
19
|
before do
|
19
20
|
context.ecs_task_def_templates ||= []
|
20
21
|
context.templates = context.ecs_task_def_templates
|
21
|
-
context.template_context = { tag: docker_image.tag }
|
22
|
+
context.template_context = { tag: docker_image.tag, registry: context.registry }
|
22
23
|
end
|
23
24
|
|
24
25
|
organize [
|
@@ -9,6 +9,7 @@ module Shipitron
|
|
9
9
|
required :application
|
10
10
|
required :s3_cache_bucket
|
11
11
|
required :build_cache_location
|
12
|
+
required :region
|
12
13
|
|
13
14
|
def call
|
14
15
|
Logger.info "Uploading build cache to bucket #{s3_cache_bucket}"
|
@@ -19,11 +20,15 @@ module Shipitron
|
|
19
20
|
return
|
20
21
|
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
result = S3Copy.call(
|
24
|
+
source: build_cache.to_s,
|
25
|
+
destination: "s3://#{s3_cache_bucket}/#{application}.build-cache.archive",
|
26
|
+
region: context.region
|
27
|
+
)
|
28
|
+
if result.failure?
|
29
|
+
Logger.warn 'Failed to upload build cache!'
|
30
|
+
else
|
31
|
+
Logger.info 'Upload complete.'
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
@@ -39,10 +44,6 @@ module Shipitron
|
|
39
44
|
def build_cache_location
|
40
45
|
context.build_cache_location
|
41
46
|
end
|
42
|
-
|
43
|
-
def bucket
|
44
|
-
@bucket ||= FetchBucket.call!(name: s3_cache_bucket).bucket
|
45
|
-
end
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|