travis_dpl_test 2.0.3.beta.4.ror
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +172 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +392 -0
- data/Gemfile +32 -0
- data/Gemfile.lock +611 -0
- data/LICENSE +19 -0
- data/README.md +2744 -0
- data/Rakefile +210 -0
- data/bin/dpl +11 -0
- data/config/transliterate.yml +733 -0
- data/dpl.gemspec +23 -0
- data/lib/dpl/assets/atlas/install +19 -0
- data/lib/dpl/assets/convox/install +11 -0
- data/lib/dpl/assets/dpl/README.erb.md +138 -0
- data/lib/dpl/assets/dpl/git_ssh +8 -0
- data/lib/dpl/assets/git/detect_private_key +8 -0
- data/lib/dpl/assets/hephy/filter_log +3 -0
- data/lib/dpl/assets/pypi/install +4 -0
- data/lib/dpl/assets/scalingo/install +6 -0
- data/lib/dpl/cli.rb +100 -0
- data/lib/dpl/ctx/bash.rb +549 -0
- data/lib/dpl/ctx/test.rb +255 -0
- data/lib/dpl/ctx.rb +4 -0
- data/lib/dpl/helper/assets.rb +38 -0
- data/lib/dpl/helper/cmd.rb +169 -0
- data/lib/dpl/helper/config_file.rb +49 -0
- data/lib/dpl/helper/cookbook_site_streaming_uploader.rb +249 -0
- data/lib/dpl/helper/env.rb +92 -0
- data/lib/dpl/helper/github.rb +22 -0
- data/lib/dpl/helper/interpolate.rb +160 -0
- data/lib/dpl/helper/memoize.rb +23 -0
- data/lib/dpl/helper/squiggle.rb +24 -0
- data/lib/dpl/helper/transliterate.rb +13 -0
- data/lib/dpl/helper/wrap.rb +11 -0
- data/lib/dpl/helper/zip.rb +71 -0
- data/lib/dpl/provider/dsl.rb +410 -0
- data/lib/dpl/provider/examples.rb +132 -0
- data/lib/dpl/provider/status.rb +61 -0
- data/lib/dpl/provider.rb +651 -0
- data/lib/dpl/providers/anynines.rb +71 -0
- data/lib/dpl/providers/azure_web_apps.rb +63 -0
- data/lib/dpl/providers/bintray.rb +324 -0
- data/lib/dpl/providers/bluemixcloudfoundry.rb +98 -0
- data/lib/dpl/providers/boxfuse.rb +52 -0
- data/lib/dpl/providers/cargo.rb +32 -0
- data/lib/dpl/providers/chef_supermarket.rb +132 -0
- data/lib/dpl/providers/cloud66.rb +46 -0
- data/lib/dpl/providers/cloudfiles.rb +62 -0
- data/lib/dpl/providers/cloudformation.rb +281 -0
- data/lib/dpl/providers/cloudfoundry.rb +89 -0
- data/lib/dpl/providers/codedeploy.rb +190 -0
- data/lib/dpl/providers/convox.rb +130 -0
- data/lib/dpl/providers/datica.rb +64 -0
- data/lib/dpl/providers/ecr.rb +129 -0
- data/lib/dpl/providers/elasticbeanstalk.rb +207 -0
- data/lib/dpl/providers/engineyard.rb +113 -0
- data/lib/dpl/providers/firebase.rb +45 -0
- data/lib/dpl/providers/flynn.rb +35 -0
- data/lib/dpl/providers/gae.rb +78 -0
- data/lib/dpl/providers/gcs.rb +132 -0
- data/lib/dpl/providers/git_push.rb +273 -0
- data/lib/dpl/providers/gleis.rb +74 -0
- data/lib/dpl/providers/hackage.rb +53 -0
- data/lib/dpl/providers/hephy.rb +107 -0
- data/lib/dpl/providers/heroku/api.rb +123 -0
- data/lib/dpl/providers/heroku/git.rb +54 -0
- data/lib/dpl/providers/heroku.rb +111 -0
- data/lib/dpl/providers/lambda.rb +211 -0
- data/lib/dpl/providers/launchpad.rb +80 -0
- data/lib/dpl/providers/netlify.rb +38 -0
- data/lib/dpl/providers/npm.rb +130 -0
- data/lib/dpl/providers/nuget.rb +41 -0
- data/lib/dpl/providers/openshift.rb +52 -0
- data/lib/dpl/providers/opsworks.rb +146 -0
- data/lib/dpl/providers/packagecloud.rb_ +194 -0
- data/lib/dpl/providers/pages/api.rb +106 -0
- data/lib/dpl/providers/pages/git.rb +262 -0
- data/lib/dpl/providers/pages.rb +18 -0
- data/lib/dpl/providers/puppetforge.rb +50 -0
- data/lib/dpl/providers/pypi.rb +125 -0
- data/lib/dpl/providers/releases.rb +234 -0
- data/lib/dpl/providers/rubygems.rb +97 -0
- data/lib/dpl/providers/s3.rb +251 -0
- data/lib/dpl/providers/scalingo.rb +69 -0
- data/lib/dpl/providers/script.rb +32 -0
- data/lib/dpl/providers/snap.rb +68 -0
- data/lib/dpl/providers/surge.rb +59 -0
- data/lib/dpl/providers/testfairy.rb +101 -0
- data/lib/dpl/providers/transifex.rb +72 -0
- data/lib/dpl/providers.rb +48 -0
- data/lib/dpl/string_ext.rb +23 -0
- data/lib/dpl/support/aws_sdk_patch.rb +26 -0
- data/lib/dpl/support/gems.rb +73 -0
- data/lib/dpl/support/gstore_patch.rb +8 -0
- data/lib/dpl/support/version.rb +84 -0
- data/lib/dpl/version.rb +5 -0
- data/lib/dpl.rb +23 -0
- data/status.json +237 -0
- metadata +161 -0
@@ -0,0 +1,273 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class GitPush < Provider
|
6
|
+
register :git_push
|
7
|
+
|
8
|
+
status :dev
|
9
|
+
|
10
|
+
full_name 'Git (push)'
|
11
|
+
|
12
|
+
description sq(<<-STR)
|
13
|
+
Experimental, generic provider for updating a Git remote branch with
|
14
|
+
changes produced by the build, and optionally opening a pull request.
|
15
|
+
STR
|
16
|
+
|
17
|
+
gem 'octokit', '~> 7'
|
18
|
+
gem 'public_suffix', '~> 5'
|
19
|
+
|
20
|
+
env :github, :git
|
21
|
+
|
22
|
+
required :token, %i[deploy_key name email]
|
23
|
+
|
24
|
+
opt '--repo SLUG', 'Repo slug', default: :repo_slug
|
25
|
+
opt '--token TOKEN', 'GitHub token with repo permission', secret: true, alias: :github_token
|
26
|
+
opt '--deploy_key PATH', 'Path to a file containing a private deploy key with write access to the repository', see: 'https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys'
|
27
|
+
opt '--branch BRANCH', 'Target branch to push to', required: true
|
28
|
+
opt '--base_branch BRANCH', 'Base branch to branch off initially, and (optionally) create a pull request for', default: 'master'
|
29
|
+
opt '--name NAME', 'Committer name', note: 'defaults to the GitHub name or login associated with the GitHub token' # , default: :user_name
|
30
|
+
opt '--email EMAIL', 'Committer email', note: 'defaults to the GitHub email associated with the GitHub token' # , default: :user_email
|
31
|
+
opt '--commit_message MSG', default: 'Update %{base_branch}', interpolate: true
|
32
|
+
opt '--allow_empty_commit', 'Allow an empty commit to be created'
|
33
|
+
opt '--force', 'Whether to push --force', default: false
|
34
|
+
opt '--local_dir DIR', 'Local directory to push', default: '.'
|
35
|
+
opt '--pull_request', 'Whether to create a pull request for the given branch'
|
36
|
+
opt '--allow_same_branch', 'Whether to allow pushing to the same branch as the current branch', default: false, note: 'setting this to true risks creating infinite build loops, use conditional builds or other mechanisms to prevent build from infinitely triggering more builds'
|
37
|
+
opt '--host HOST', default: 'github.com'
|
38
|
+
opt '--enterprise', 'Whether to use a GitHub Enterprise API style URL'
|
39
|
+
|
40
|
+
needs :git
|
41
|
+
|
42
|
+
msgs login: 'Authenticated as %s',
|
43
|
+
invalid_token: 'The provided GitHub token is invalid (error: %s)',
|
44
|
+
insufficient_scopes: 'Dpl does not have permission to access %{url} using the provided GitHub token. Please make sure the token have the repo or public_repo scope.',
|
45
|
+
same_branch: 'Prevented from pushing to the same branch as the current build branch %{git_branch}. This is meant to prevent infinite build loops. If you do need to push back to the same branch enable `allow_same_branch` and take precautions to prevent infinite loops as needed, for example using conditional builds.',
|
46
|
+
setup_deploy_key: 'Moving deploy key %{deploy_key} to %{path}',
|
47
|
+
check_deploy_key: 'Checking deploy key',
|
48
|
+
setup: 'Source dir: %{src_dir}, branch: %{branch}, base branch: %{base_branch}',
|
49
|
+
git_clone: 'Cloning the branch %{branch} to %{work_dir}',
|
50
|
+
git_branch: 'Switching to branch %{branch}',
|
51
|
+
copy_files: 'Copying %{src_dir} contents to %{work_dir}',
|
52
|
+
git_config: 'Configuring git committer to be: %{name} <%{email}>',
|
53
|
+
git_push: 'Pushing to %{url} HEAD:%{branch}',
|
54
|
+
pr_exists: 'Pull request exists.',
|
55
|
+
pr_created: 'Pull request #%{number} created.',
|
56
|
+
stop: 'There are no changes to commit, stopping.'
|
57
|
+
|
58
|
+
cmds git_clone: 'git clone --quiet --branch="%{clone_branch}" "%{remote_url}" . > /dev/null 2>&1',
|
59
|
+
git_branch: 'git checkout -b "%{branch}"',
|
60
|
+
check_deploy_key: 'ssh -i %{key} -T git@github.com 2>&1 | grep successful > /dev/null',
|
61
|
+
copy_files: 'rsync -rl --exclude .git --delete "%{src_dir}/" .',
|
62
|
+
git_config_email: 'git config user.email %{quoted_email}',
|
63
|
+
git_config_name: 'git config user.name %{quoted_name}',
|
64
|
+
git_add: 'git add -A .',
|
65
|
+
git_commit_hook: 'cp %{path} .git/hooks/pre-commit',
|
66
|
+
git_commit: 'git commit %{git_commit_opts} -q %{git_commit_msg_opts}',
|
67
|
+
git_show: 'git show --stat-count=10 HEAD',
|
68
|
+
git_push: 'git push %{git_push_opts} --quiet "%{remote_url}" HEAD:"%{branch}" > /dev/null 2>&1'
|
69
|
+
|
70
|
+
errs copy_files: 'Failed to copy %{src_dir}.',
|
71
|
+
check_deploy_key: 'Failed to authenticate using the deploy key',
|
72
|
+
git_init: 'Failed to create new git repo',
|
73
|
+
git_push: 'Failed to push the build to %{url}:%{branch}'
|
74
|
+
|
75
|
+
def validate
|
76
|
+
error :same_branch if same_branch? && !allow_same_branch?
|
77
|
+
end
|
78
|
+
|
79
|
+
def setup
|
80
|
+
info :setup
|
81
|
+
info :git_config
|
82
|
+
end
|
83
|
+
|
84
|
+
def login
|
85
|
+
token? ? login_token : setup_deploy_key
|
86
|
+
end
|
87
|
+
|
88
|
+
def prepare
|
89
|
+
Dir.chdir(work_dir)
|
90
|
+
end
|
91
|
+
|
92
|
+
def deploy
|
93
|
+
git_clone
|
94
|
+
copy_files
|
95
|
+
return info :stop unless git_dirty?
|
96
|
+
|
97
|
+
push
|
98
|
+
pull_request if pull_request?
|
99
|
+
end
|
100
|
+
|
101
|
+
def push
|
102
|
+
git_config
|
103
|
+
git_commit
|
104
|
+
git_push
|
105
|
+
end
|
106
|
+
|
107
|
+
def pull_request
|
108
|
+
pr_exists? ? info(:pr_exists) : create_pr
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def same_branch?
|
114
|
+
git_branch == branch
|
115
|
+
end
|
116
|
+
|
117
|
+
def login_token
|
118
|
+
return unless github?
|
119
|
+
|
120
|
+
info :login, user.login
|
121
|
+
error :insufficient_scopes unless sufficient_scopes?
|
122
|
+
rescue Octokit::Unauthorized => e
|
123
|
+
error :invalid_token, e.message
|
124
|
+
end
|
125
|
+
|
126
|
+
def setup_deploy_key
|
127
|
+
path = '~/.dpl/deploy_key'
|
128
|
+
info(:setup_deploy_key, path:)
|
129
|
+
mv deploy_key, path
|
130
|
+
chmod 0600, path
|
131
|
+
setup_git_ssh path
|
132
|
+
shell :check_deploy_key, key: path
|
133
|
+
end
|
134
|
+
|
135
|
+
def git_clone
|
136
|
+
shell :git_clone, echo: false
|
137
|
+
shell :git_branch unless branch_exists?
|
138
|
+
end
|
139
|
+
|
140
|
+
def clone_branch
|
141
|
+
branch_exists? ? branch : base_branch
|
142
|
+
end
|
143
|
+
|
144
|
+
def copy_files
|
145
|
+
shell :copy_files
|
146
|
+
end
|
147
|
+
|
148
|
+
def git_config
|
149
|
+
shell :git_config_name, echo: false
|
150
|
+
shell :git_config_email, echo: false
|
151
|
+
end
|
152
|
+
|
153
|
+
def branch_exists?
|
154
|
+
git_ls_remote?(remote_url, branch)
|
155
|
+
end
|
156
|
+
|
157
|
+
def git_commit
|
158
|
+
shell :git_commit_hook, path: asset(:git, :detect_private_key).path, echo: false if deploy_key?
|
159
|
+
shell :git_add
|
160
|
+
shell :git_commit
|
161
|
+
shell :git_show
|
162
|
+
end
|
163
|
+
|
164
|
+
def git_push
|
165
|
+
shell :git_push, echo: false
|
166
|
+
end
|
167
|
+
|
168
|
+
def git_push_opts
|
169
|
+
'--force' if force?
|
170
|
+
end
|
171
|
+
|
172
|
+
def git_commit_opts
|
173
|
+
' --allow-empty' if allow_empty_commit?
|
174
|
+
end
|
175
|
+
|
176
|
+
def git_commit_msg_opts
|
177
|
+
msg = interpolate(commit_message, vars:)
|
178
|
+
msg.split("\n").reject(&:empty?).map { |message| %(-m #{quote(message)}) }
|
179
|
+
end
|
180
|
+
|
181
|
+
def name
|
182
|
+
str = super if name?
|
183
|
+
str ||= user_name
|
184
|
+
str = "#{str} (via Travis CI)" if ENV['TRAVIS'] && !name?
|
185
|
+
str
|
186
|
+
end
|
187
|
+
memoize :name
|
188
|
+
|
189
|
+
def email
|
190
|
+
str = super if email?
|
191
|
+
str || user_email
|
192
|
+
end
|
193
|
+
memoize :email
|
194
|
+
|
195
|
+
def project_name
|
196
|
+
super || repo_slug
|
197
|
+
end
|
198
|
+
|
199
|
+
def remote_url
|
200
|
+
token? ? https_url_with_token : git_url
|
201
|
+
end
|
202
|
+
|
203
|
+
def https_url_with_token
|
204
|
+
"https://#{token}@#{url}"
|
205
|
+
end
|
206
|
+
|
207
|
+
def git_url
|
208
|
+
"git@#{host}:#{slug}.git"
|
209
|
+
end
|
210
|
+
|
211
|
+
def url
|
212
|
+
"#{host}/#{slug}.git"
|
213
|
+
end
|
214
|
+
|
215
|
+
def slug
|
216
|
+
repo || repo_slug
|
217
|
+
end
|
218
|
+
|
219
|
+
def src_dir
|
220
|
+
@src_dir ||= expand(local_dir)
|
221
|
+
end
|
222
|
+
|
223
|
+
def work_dir
|
224
|
+
@work_dir ||= tmp_dir
|
225
|
+
end
|
226
|
+
|
227
|
+
def sufficient_scopes?
|
228
|
+
scopes.include?('public_repo') || scopes.include?('repo')
|
229
|
+
end
|
230
|
+
|
231
|
+
def user
|
232
|
+
@user ||= github.user
|
233
|
+
end
|
234
|
+
|
235
|
+
def user_name
|
236
|
+
user.name || user.login
|
237
|
+
end
|
238
|
+
|
239
|
+
def user_email
|
240
|
+
user.email
|
241
|
+
end
|
242
|
+
|
243
|
+
def scopes
|
244
|
+
@scopes ||= github.scopes
|
245
|
+
end
|
246
|
+
|
247
|
+
def pr_exists?
|
248
|
+
!!github.pulls(repo).detect { |pull| pull.head.ref == branch }
|
249
|
+
end
|
250
|
+
|
251
|
+
def create_pr
|
252
|
+
pr = github.create_pull_request(repo, base_branch, branch, "Update #{base_branch}")
|
253
|
+
info :pr_created, number: pr.number
|
254
|
+
end
|
255
|
+
|
256
|
+
def github?
|
257
|
+
host.include?('github') || enterprise?
|
258
|
+
end
|
259
|
+
|
260
|
+
def github
|
261
|
+
@github ||= Octokit::Client.new(access_token: token, api_endpoint: api_url, auto_paginate: true)
|
262
|
+
end
|
263
|
+
|
264
|
+
def api_url
|
265
|
+
enterprise? ? "https://#{host}/api/v3/" : 'https://api.github.com/'
|
266
|
+
end
|
267
|
+
|
268
|
+
def now
|
269
|
+
Time.now
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Gleis < Provider
|
6
|
+
register :gleis
|
7
|
+
|
8
|
+
status :alpha
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
gem 'gleis', '~> 0.8.0'
|
15
|
+
|
16
|
+
env :gleis
|
17
|
+
|
18
|
+
opt '--app APP', 'Gleis application to upload to', default: :repo_name
|
19
|
+
opt '--username NAME', 'Gleis username', required: true
|
20
|
+
opt '--password PASS', 'Gleis password', required: true, secret: true
|
21
|
+
opt '--key_name NAME', 'Name of the SSH deploy key pushed to Gleis', default: 'dpl_deploy_key'
|
22
|
+
opt '--verbose'
|
23
|
+
|
24
|
+
needs :ssh_key
|
25
|
+
|
26
|
+
cmds login: 'gleis auth login %{username} %{password} --skip-keygen',
|
27
|
+
logout: 'gleis auth logout',
|
28
|
+
validate: 'gleis app status -a %{app}',
|
29
|
+
add_key: 'gleis auth key add %{file} %{key_name}',
|
30
|
+
remove_key: 'gleis auth key remove %{key_name}',
|
31
|
+
git_url: 'gleis app git -a %{app} -q',
|
32
|
+
deploy: 'git push %{push_opts} -f %{git_url} HEAD:refs/heads/master'
|
33
|
+
|
34
|
+
errs login: 'Login failed',
|
35
|
+
validate: 'Application not found',
|
36
|
+
add_key: 'Adding SSH key failed',
|
37
|
+
remove_key: 'Removing key failed',
|
38
|
+
git_url: 'Failed to retrieve Git URL',
|
39
|
+
deploy: 'Deploying application failed'
|
40
|
+
|
41
|
+
attr_reader :git_url
|
42
|
+
|
43
|
+
def login
|
44
|
+
shell :login
|
45
|
+
end
|
46
|
+
|
47
|
+
def setup
|
48
|
+
@git_url = shell :git_url, capture: true
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate
|
52
|
+
shell :validate
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_key(file)
|
56
|
+
shell :add_key, file:
|
57
|
+
end
|
58
|
+
|
59
|
+
def deploy
|
60
|
+
shell :deploy
|
61
|
+
end
|
62
|
+
|
63
|
+
def remove_key
|
64
|
+
shell :remove_key
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def push_opts
|
70
|
+
'-v' if verbose?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Hackage < Provider
|
6
|
+
register :hackage
|
7
|
+
|
8
|
+
status :alpha
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
env :hackage
|
15
|
+
|
16
|
+
opt '--username USER', 'Hackage username', required: true
|
17
|
+
opt '--password USER', 'Hackage password', required: true, secret: true
|
18
|
+
opt '--publish', 'Whether or not to publish the package'
|
19
|
+
|
20
|
+
cmds check: 'cabal check',
|
21
|
+
sdist: 'cabal sdist',
|
22
|
+
upload: 'cabal upload %{upload_opts} %{path}'
|
23
|
+
|
24
|
+
errs check: 'cabal check failed',
|
25
|
+
sdist: 'cabal sdist failed',
|
26
|
+
upload: 'cabal upload failed'
|
27
|
+
|
28
|
+
def validate
|
29
|
+
shell :check
|
30
|
+
end
|
31
|
+
|
32
|
+
def prepare
|
33
|
+
shell :sdist
|
34
|
+
end
|
35
|
+
|
36
|
+
def deploy
|
37
|
+
tar_files.each do |path|
|
38
|
+
shell :upload, path:
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def upload_opts
|
45
|
+
opts_for(%i[publish username password])
|
46
|
+
end
|
47
|
+
|
48
|
+
def tar_files
|
49
|
+
Dir.glob('dist/*.tar.gz').sort
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Hephy < Provider
|
6
|
+
register :hephy
|
7
|
+
|
8
|
+
status :beta
|
9
|
+
|
10
|
+
description sq(<<-STR)
|
11
|
+
tbd
|
12
|
+
STR
|
13
|
+
|
14
|
+
env :hephy
|
15
|
+
|
16
|
+
opt '--controller NAME', 'Hephy controller', required: true, example: 'hephy.hephyapps.com'
|
17
|
+
opt '--username USER', 'Hephy username', required: true
|
18
|
+
opt '--password PASS', 'Hephy password', required: true, secret: true
|
19
|
+
opt '--app APP', 'Deis app', required: true
|
20
|
+
opt '--cli_version VER', 'Install a specific Hephy CLI version', default: 'stable'
|
21
|
+
opt '--verbose', 'Verbose log output'
|
22
|
+
|
23
|
+
needs :git, :ssh_key
|
24
|
+
path '~/.dpl'
|
25
|
+
|
26
|
+
INSTALL = 'https://raw.githubusercontent.com/teamhephy/workflow-cli/master/install-v2.sh'
|
27
|
+
|
28
|
+
cmds install: 'curl -sSL %{INSTALL} | bash -x -s %{cli_version} && mv deis ~/.dpl',
|
29
|
+
login: 'deis login %{controller} --username=%{username} --password=%{password}',
|
30
|
+
add_key: 'deis keys:add %{key}',
|
31
|
+
validate: 'deis apps:info --app=%{app}',
|
32
|
+
deploy: 'filter_log git push %{verbose} %{url} HEAD:refs/heads/master -f',
|
33
|
+
run: 'deis run -a %{app} -- %{cmd}',
|
34
|
+
remove_key: 'deis keys:remove %{key_name}'
|
35
|
+
|
36
|
+
errs login: 'Login failed.',
|
37
|
+
add_key: 'Adding keys failed.',
|
38
|
+
validate: 'Application could not be verified.',
|
39
|
+
deploy: 'Deploying application failed.',
|
40
|
+
run: 'Running command failed.',
|
41
|
+
remove_key: 'Removing keys failed.'
|
42
|
+
|
43
|
+
def install
|
44
|
+
shell :install
|
45
|
+
end
|
46
|
+
|
47
|
+
def setup
|
48
|
+
install_hephy_log_filter
|
49
|
+
end
|
50
|
+
|
51
|
+
def login
|
52
|
+
shell :login
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_key(key)
|
56
|
+
shell(:add_key, key:)
|
57
|
+
wait_for_ssh_access(host, port)
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate
|
61
|
+
shell :validate
|
62
|
+
end
|
63
|
+
|
64
|
+
def deploy
|
65
|
+
shell :deploy
|
66
|
+
end
|
67
|
+
|
68
|
+
def run_cmd(cmd)
|
69
|
+
shell :run, app:, cmd:
|
70
|
+
end
|
71
|
+
|
72
|
+
def remove_key
|
73
|
+
shell :remove_key
|
74
|
+
end
|
75
|
+
|
76
|
+
def verbose
|
77
|
+
verbose? ? '-v' : ''
|
78
|
+
end
|
79
|
+
|
80
|
+
def host
|
81
|
+
url.host
|
82
|
+
end
|
83
|
+
|
84
|
+
def port
|
85
|
+
url.port
|
86
|
+
end
|
87
|
+
|
88
|
+
def url
|
89
|
+
@url ||= URI.parse("ssh://git@#{builder}:2222/#{app}.git")
|
90
|
+
end
|
91
|
+
|
92
|
+
def builder
|
93
|
+
parts = host.split('.')
|
94
|
+
parts[0] = [parts[0], 'builder'].join('-')
|
95
|
+
parts.join('.')
|
96
|
+
end
|
97
|
+
|
98
|
+
def host
|
99
|
+
controller.gsub(%r{https?://}, '').split(':')[0]
|
100
|
+
end
|
101
|
+
|
102
|
+
def install_hephy_log_filter
|
103
|
+
asset(:filter_log).copy('~/.dpl/')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Heroku
|
6
|
+
class Api < Heroku
|
7
|
+
register :'heroku:api'
|
8
|
+
|
9
|
+
status :stable
|
10
|
+
|
11
|
+
full_name 'Heroku API'
|
12
|
+
|
13
|
+
description sq(<<-STR)
|
14
|
+
tbd
|
15
|
+
STR
|
16
|
+
|
17
|
+
opt '--api_key KEY', 'Heroku API key', required: true, secret: true
|
18
|
+
opt '--version VERSION', internal: true # used in triggering a build, not sure this should be exposed?
|
19
|
+
|
20
|
+
msgs pack: 'Creating application archive',
|
21
|
+
upload: 'Uploading application archive',
|
22
|
+
build: 'Triggering Heroku build (deployment)',
|
23
|
+
pending: 'Heroku build still pending',
|
24
|
+
failed: 'Heroku build failed'
|
25
|
+
|
26
|
+
cmds pack: 'tar -zcf %{escaped_archive_file} --exclude .git .',
|
27
|
+
upload: 'curl %{curl_opts} %{escaped_put_url} -X PUT -H "Content-Type:" -H "Accept: application/vnd.heroku+json; version=3" -H "User-Agent: %{user_agent}" --data-binary @%{escaped_archive_file}',
|
28
|
+
log: 'curl %{curl_opts} %{escaped_output_stream_url} -H "Accept: application/vnd.heroku+json; version=3" -H "User-Agent: %{user_agent}"'
|
29
|
+
|
30
|
+
attr_reader :data
|
31
|
+
|
32
|
+
def deploy
|
33
|
+
pack
|
34
|
+
upload
|
35
|
+
build
|
36
|
+
log
|
37
|
+
verify
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def pack
|
43
|
+
shell :pack
|
44
|
+
end
|
45
|
+
|
46
|
+
def upload
|
47
|
+
shell :upload, echo: false
|
48
|
+
end
|
49
|
+
|
50
|
+
def build
|
51
|
+
info :build
|
52
|
+
res = http.post("/apps/#{app}/builds") do |req|
|
53
|
+
req.headers['Content-Type'] = 'application/json'
|
54
|
+
req.body = JSON.dump(source_blob: { url: get_url, version: })
|
55
|
+
end
|
56
|
+
handle_error(res) unless res.success?
|
57
|
+
@data = symbolize(JSON.parse(res.body))
|
58
|
+
end
|
59
|
+
|
60
|
+
def log
|
61
|
+
shell :log, echo: false
|
62
|
+
end
|
63
|
+
|
64
|
+
def verify
|
65
|
+
loop do
|
66
|
+
case build_status
|
67
|
+
when 'pending'
|
68
|
+
info :pending
|
69
|
+
sleep 5
|
70
|
+
when 'succeeded'
|
71
|
+
break
|
72
|
+
else
|
73
|
+
error :failed
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def build_status
|
79
|
+
res = http.get("/apps/#{app}/builds/#{build_id}")
|
80
|
+
JSON.parse(res.body)['status']
|
81
|
+
end
|
82
|
+
|
83
|
+
def archive_file
|
84
|
+
expand("~/.dpl.#{app}.tgz")
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_url
|
88
|
+
source['get_url']
|
89
|
+
end
|
90
|
+
|
91
|
+
def put_url
|
92
|
+
source['put_url']
|
93
|
+
end
|
94
|
+
|
95
|
+
def source
|
96
|
+
# this says the endpoint /sources is deprecated: https://devcenter.heroku.com/articles/platform-api-reference#source
|
97
|
+
# this says to use /apps/example-app/sources: https://devcenter.heroku.com/articles/build-and-release-using-the-api#sources-endpoint
|
98
|
+
@source ||= begin
|
99
|
+
res = http.post('/sources')
|
100
|
+
handle_error(res) unless res.success?
|
101
|
+
JSON.parse(res.body)['source_blob']
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_id
|
106
|
+
data[:id]
|
107
|
+
end
|
108
|
+
|
109
|
+
def output_stream_url
|
110
|
+
data[:output_stream_url]
|
111
|
+
end
|
112
|
+
|
113
|
+
def version
|
114
|
+
super || git_sha
|
115
|
+
end
|
116
|
+
|
117
|
+
def curl_opts
|
118
|
+
tty? ? '' : '-sS'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Heroku
|
6
|
+
class Git < Heroku
|
7
|
+
register :'heroku:git'
|
8
|
+
|
9
|
+
status :alpha
|
10
|
+
|
11
|
+
full_name 'Heroku Git'
|
12
|
+
|
13
|
+
description sq(<<-STR)
|
14
|
+
tbd
|
15
|
+
STR
|
16
|
+
|
17
|
+
required :api_key, %i[username password]
|
18
|
+
|
19
|
+
opt '--api_key KEY', 'Heroku API key', secret: true
|
20
|
+
opt '--username USER', 'Heroku username', alias: :user
|
21
|
+
opt '--password PASS', 'Heroku password', secret: true
|
22
|
+
opt '--git URL', 'Heroku Git remote URL'
|
23
|
+
|
24
|
+
needs :git, :git_http_user_agent
|
25
|
+
|
26
|
+
cmds fetch: 'git fetch origin $TRAVIS_BRANCH --unshallow',
|
27
|
+
push: 'git push %{remote} HEAD:refs/heads/master -f'
|
28
|
+
|
29
|
+
def prepare
|
30
|
+
write_netrc if write_netrc?
|
31
|
+
end
|
32
|
+
|
33
|
+
def deploy
|
34
|
+
shell :fetch, assert: false
|
35
|
+
shell :push
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def remote
|
41
|
+
git || "https://git.heroku.com/#{app}.git"
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_netrc?
|
45
|
+
remote.start_with?('https://')
|
46
|
+
end
|
47
|
+
|
48
|
+
def write_netrc
|
49
|
+
super('git.heroku.com', email, api_key || password)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|