shiplane 0.1.16 → 0.1.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 847be5563eac5f1b7d49c018a662a77d065d31022a1edf22bfeb347526459ada
4
- data.tar.gz: ca5d1d1635161bd9cf4a5286fb2b42a13886ecd5b65df934f5dec5a560b7902e
3
+ metadata.gz: 3ae8f35e9d9eb37af8026cc7664a99a91df38b4509013077f346b19b09120c68
4
+ data.tar.gz: 6187a0375ef86304831505932a475d046afa0b74d81a3214a11bcd27ea50beef
5
5
  SHA512:
6
- metadata.gz: 9109eed0795ebb3211b118563c89781f621b2bde7c16c38131c1d0b8f62075f1ed3a55da3a5a23ca584e75b211c237f1de4905b0d5bb0e7a17205e659c3d9b56
7
- data.tar.gz: c07ff2c9e6bf6d68f2f983fa8497c2f7128533e34b986eb765d4aa7ea114eada3df65a20ec91d1e27f55c783ed01ad9c6206fc71225ec8a3d341a6a338ead732
6
+ metadata.gz: 24e26faa8239207b66a7d47b72cee33a0b48641d3574123422d2b861254c2302585708001cc69810d163cbe2535190aa4d13e8923d1b420f87d013ba83bff963
7
+ data.tar.gz: b0e074456a000474e575ca1f273bf2eb49128de78d96f68e9859dba0b1c58a8416077571d4f03aba023745298648be7a91e08779ef7ee8d9fa1d1cd6d451db0f
data/README.md CHANGED
@@ -164,6 +164,11 @@ Shiplane::SafeBuild.wrap do
164
164
  end
165
165
  ```
166
166
 
167
+ #### Using Build Cache
168
+ Shiplane is designed to always build using the --no-cache flag in order to guaranteee clean, repeatable builds, but if you find yourself troubleshooting or otherwise needing to build multiple times, you might like to use the following flag to speed up the process. Note that this is intended to be a debugging tool. Using it for production building could potentially part of the build process to run in one context and another part to run in another. Such a case might cause both positive and negative results that are difficult to troubleshoot because they are not repeatable. Don't do this, but DO use this responsibly to make your life easier when troubleshooting.
169
+
170
+ `USE_BUILD_CACHE=true bundle exec cap production shiplane`
171
+
167
172
  ## Becoming Involved
168
173
  ### Community Channels
169
174
  You can join our [Discord community](https://discord.gg/drrn2YG) to ask any questions you might have or to get ahold of someone in the community who might be able to help you (I hang out here just about every day of the week and most of the weekend). There is no guarantee of service implied, but we absolutely believe in helping out our fellow developers and will do so as we are able. If you feel you know some stuff about Shiplane, feel free to hang out and please help out as well!
@@ -9,6 +9,9 @@ bootstrap:
9
9
  package_name: chefdk_3.6.57-1_amd64.deb
10
10
  package_url: https://packages.chef.io/files/stable/chefdk/3.6.57/ubuntu/18.04/chefdk_3.6.57-1_amd64.deb
11
11
  build:
12
+ registry:
13
+ # url: ghcr.io # for Github Container Service. Should work for similar services such as Gitlab
14
+ # url: :dockerhub # for default Dockerhub Service
12
15
  settings_folder: .shiplane
13
16
  environment_file: .env.production
14
17
  compose_filepath: docker-compose.yml
@@ -21,6 +21,87 @@ module Shiplane
21
21
  Dotenv.overload File.join(Dir.pwd, build_config.fetch('environment_file', '.env'))
22
22
  end
23
23
 
24
+ def build!
25
+ unless File.exist?(File.join(project_folder, Shiplane::SHIPLANE_CONFIG_FILENAME))
26
+ Shiplane::CheckoutArtifact.checkout!(sha)
27
+ Shiplane::ConvertComposeFile.convert_output!(project_folder, sha)
28
+ end
29
+
30
+ buildable_artifacts.each do |(artifact_name, attributes)|
31
+ compose_context = docker_config.fetch('services', {}).fetch(artifact_name.to_s, {})
32
+ Shiplane::ConvertDockerfile.convert_output!(project_folder, attributes, compose_context)
33
+
34
+ FileUtils.cd project_folder do
35
+ steps(artifact_name, attributes).select{|step| step.fetch(:condition, true) }.each do |step|
36
+ puts step[:notify_before] if step.has_key? :notify_before
37
+ success = system(step[:command])
38
+ raise StepFailureException.new(step[:command], artifact_name) unless success
39
+ puts step[:notify_after] if step.has_key? :notify_after
40
+ end
41
+ end
42
+ end
43
+ rescue StepFailureException => e
44
+ puts e.message
45
+ raise if ENV['RAISE_EXCEPTIONS_ON_FAILED_BUILD']
46
+ end
47
+
48
+ def steps(artifact_name, attributes)
49
+ [
50
+ { command: build_command(artifact_name), notify_before: "Building Artifact: #{artifact_name}...", notify_after: "Docker Compose Built", stop_on_failure: true },
51
+ { command: tag_command(artifact_name, attributes, sha), notify_before: "Tagging Build [#{sha}]...", stop_on_failure: true },
52
+ { command: tag_command(artifact_name, attributes, "#{postfix}-#{sha}"), notify_before: "Tagging Build [#{postfix}-#{sha}]...", stop_on_failure: true, condition: !!postfix },
53
+ { command: tag_command(artifact_name, attributes, "#{postfix}-latest"), notify_before: "Tagging Build [#{postfix}-latest]...", stop_on_failure: true, condition: !!postfix && tag_latest },
54
+ { command: tag_command(artifact_name, attributes), notify_before: "Tagging Build [latest]...", stop_on_failure: true, condition: tag_latest },
55
+ { command: token_login_command , notify_before: "Logging into Container Registry...", stop_on_failure: true },
56
+ { command: push_command(attributes, "#{sha}"), notify_before: "Pushing Image", notify_after: "Completed Artifact: #{artifact_name}...", stop_on_failure: true },
57
+ { command: push_command(attributes, "#{postfix}-#{sha}"), notify_before: "Pushing #{postfix} Image", notify_after: "Completed Artifact: #{artifact_name}...", stop_on_failure: true, condition: !!postfix },
58
+ { command: push_command(attributes, "#{postfix}-latest"), notify_before: "Pushing Latest #{postfix} Image", notify_after: "Completed Latest Artifact: #{artifact_name}...", stop_on_failure: true, condition: !!postfix && tag_latest },
59
+ { command: push_command(attributes, "latest"), notify_before: "Pushing Latest Image", notify_after: "Completed Latest Artifact: #{artifact_name}...", stop_on_failure: true, condition: tag_latest },
60
+ ]
61
+ end
62
+
63
+ # Commands
64
+ def build_command(artifact_name)
65
+ [
66
+ 'docker-compose',
67
+ 'build',
68
+ build_cache_option,
69
+ artifact_name,
70
+ ].compact.join(' ')
71
+ end
72
+
73
+ def token_login_command
74
+ @token_login_command ||= [
75
+ 'echo',
76
+ login_token,
77
+ '|',
78
+ 'docker',
79
+ 'login',
80
+ registry_url,
81
+ '--username',
82
+ login_username,
83
+ '--password-stdin',
84
+ ].compact.join(' ')
85
+ end
86
+
87
+ def tag_command(artifact_name, attributes, tag='latest')
88
+ [
89
+ 'docker',
90
+ 'tag',
91
+ build_output_image_name(artifact_name),
92
+ "#{repo_name(attributes)}:#{tag}",
93
+ ].compact.join(' ')
94
+ end
95
+
96
+ def push_command(attributes, tag='latest')
97
+ [
98
+ 'docker',
99
+ 'push',
100
+ "#{repo_name(attributes)}:#{tag}",
101
+ ].compact.join(' ')
102
+ end
103
+
104
+ # Properties
24
105
  def appname
25
106
  @appname ||= project_config['appname']
26
107
  end
@@ -45,44 +126,57 @@ module Shiplane
45
126
  build_config.fetch('artifacts', {})
46
127
  end
47
128
 
48
- def build!
49
- unless File.exist?(File.join(project_folder, Shiplane::SHIPLANE_CONFIG_FILENAME))
50
- Shiplane::CheckoutArtifact.checkout!(sha)
51
- Shiplane::ConvertComposeFile.convert_output!(project_folder, sha)
52
- end
129
+ def default_registry_configuration
130
+ {
131
+ 'url' => :dockerhub,
132
+ 'auth_method' => 'token',
133
+ }
134
+ end
53
135
 
54
- buildable_artifacts.each do |(artifact_name, attributes)|
55
- compose_context = docker_config.fetch('services', {}).fetch(artifact_name.to_s, {})
56
- Shiplane::ConvertDockerfile.convert_output!(project_folder, attributes, compose_context)
136
+ def dockerhub?
137
+ registry_configuration['url'] == :dockerhub
138
+ end
57
139
 
58
- FileUtils.cd project_folder do
59
- steps(artifact_name, attributes).select{|step| step.fetch(:condition, true) }.each do |step|
60
- puts step[:notify_before] if step.has_key? :notify_before
61
- success = system(step[:command])
62
- raise StepFailureException.new(step[:command], artifact_name) unless success
63
- puts step[:notify_after] if step.has_key? :notify_after
64
- end
65
- end
66
- end
67
- rescue StepFailureException => e
68
- puts e.message
69
- raise if ENV['RAISE_EXCEPTIONS_ON_FAILED_BUILD']
140
+ def token_auth?
141
+ registry_configuration['auth_method'] == 'token'
70
142
  end
71
143
 
72
- def steps(artifact_name, attributes)
144
+ def registry_configuration
145
+ @registry_configuration ||= default_registry_configuration.merge(build_config.fetch('registry', {}))
146
+ end
147
+
148
+ def registry_url
149
+ @registry_url ||= dockerhub? ? nil : registry_configuration['url']
150
+ end
151
+
152
+ def repo_name(attributes)
73
153
  [
74
- { command: "docker-compose build --no-cache #{artifact_name}", notify_before: "Building Artifact: #{artifact_name}...", notify_after: "Docker Compose Built", stop_on_failure: true },
75
- { command: "docker tag #{attributes['repo']}:#{sha} #{attributes['repo']}:#{postfix}-#{sha}", notify_before: "Tagging Build...", stop_on_failure: true, condition: !!postfix },
76
- { command: "docker tag #{attributes['repo']}:#{sha} #{attributes['repo']}:#{postfix}-latest", notify_before: "Tagging Build...", stop_on_failure: true, condition: !!postfix && tag_latest },
77
- { command: "docker tag #{attributes['repo']}:#{sha} #{attributes['repo']}:latest", notify_before: "Tagging Latest Build...", stop_on_failure: true, condition: tag_latest },
78
- { command: "echo '#{ENV['DOCKERHUB_PASSWORD']}' | docker login --username #{ENV['DOCKERHUB_USERNAME']} --password-stdin", notify_before: "Logging into DockerHub...", stop_on_failure: true },
79
- { command: "docker push '#{attributes['repo']}:#{sha}'", notify_before: "Pushing Image", notify_after: "Completed Artifact: #{artifact_name}...", stop_on_failure: true },
80
- { command: "docker push '#{attributes['repo']}:#{postfix}-#{sha}'", notify_before: "Pushing #{postfix} Image", notify_after: "Completed Artifact: #{artifact_name}...", stop_on_failure: true, condition: !!postfix },
81
- { command: "docker push '#{attributes['repo']}:#{postfix}-latest'", notify_before: "Pushing Latest #{postfix} Image", notify_after: "Completed Latest Artifact: #{artifact_name}...", stop_on_failure: true, condition: !!postfix && tag_latest },
82
- { command: "docker push '#{attributes['repo']}:latest'", notify_before: "Pushing Latest Image", notify_after: "Completed Latest Artifact: #{artifact_name}...", stop_on_failure: true, condition: tag_latest },
83
- ]
154
+ registry_url,
155
+ attributes['repo'],
156
+ ].compact.join('/')
157
+ end
158
+
159
+ def login_token
160
+ return ENV['DOCKERHUB_PASSWORD'] if dockerhub? && token_auth?
161
+
162
+ ENV['SHIPLANE_CONTAINER_REGISTRY_TOKEN']
163
+ end
164
+
165
+ def login_username
166
+ return ENV['DOCKERHUB_USERNAME'] if dockerhub? && token_auth?
167
+
168
+ ENV['SHIPLANE_CONTAINER_REGISTRY_USERNAME']
169
+ end
170
+
171
+ def build_output_image_name(artifact_name)
172
+ @build_output_image_name ||= "#{appname}-#{sha}_#{artifact_name}:latest"
173
+ end
174
+
175
+ def build_cache_option
176
+ ENV['USE_BUILD_CACHE'] == 'true' ? nil : "--no-cache"
84
177
  end
85
178
 
179
+ # API Helper Methods
86
180
  def self.build!(sha, postfix = nil)
87
181
  new(sha, postfix: postfix).build!
88
182
  end
@@ -32,10 +32,6 @@ module Shiplane
32
32
 
33
33
  def converted_output
34
34
  @converted_output ||= converted_compose_hash.dup.tap do |hash|
35
- build_config.fetch('artifacts', {}).each do |(appname, config)|
36
- hash.deep_merge!({ 'services' => { appname => { 'image' => "#{config['repo']}:#{sha}" } } })
37
- end
38
-
39
35
  hash.traverse! do |key, value|
40
36
  if (key == 'env_file' && value == '.env.development')
41
37
  [key, '.env.production']
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shiplane
4
- VERSION = "0.1.16"
4
+ VERSION = "0.1.17"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shiplane
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.16
4
+ version: 0.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Epperson
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.16
19
+ version: 0.1.17
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.16
26
+ version: 0.1.17
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: shiplane_deployers_capistrano_docker
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.16
33
+ version: 0.1.17
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.16
40
+ version: 0.1.17
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: dotenv
43
43
  requirement: !ruby/object:Gem::Requirement