dpl 1.10.17.travis.6637.6 → 2.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +74 -0
- data/CONTRIBUTING.md +392 -0
- data/Gemfile +17 -3
- data/Gemfile.lock +373 -0
- data/LICENSE +16 -19
- data/NOTES.md +275 -0
- data/README.md +1977 -707
- data/Rakefile +2 -2
- data/bin/dpl +7 -3
- data/lib/dpl.rb +20 -0
- data/lib/dpl/assets/atlas/install +19 -0
- data/lib/dpl/assets/dpl/README.erb.md +133 -0
- data/lib/dpl/assets/dpl/git_ssh +2 -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 +36 -48
- data/lib/dpl/ctx.rb +2 -0
- data/lib/dpl/ctx/bash.rb +543 -0
- data/lib/dpl/ctx/test.rb +242 -0
- data/lib/dpl/helper/assets.rb +36 -0
- data/lib/dpl/helper/cmd.rb +167 -0
- data/lib/dpl/helper/config_file.rb +47 -0
- data/lib/dpl/helper/env.rb +39 -0
- data/lib/dpl/helper/interpolate.rb +126 -0
- data/lib/dpl/helper/memoize.rb +20 -0
- data/lib/dpl/helper/squiggle.rb +22 -0
- data/lib/dpl/helper/zip.rb +69 -0
- data/lib/dpl/provider.rb +562 -234
- data/lib/dpl/provider/dsl.rb +369 -0
- data/lib/dpl/provider/examples.rb +128 -0
- data/lib/dpl/provider/status.rb +59 -0
- data/lib/dpl/providers.rb +40 -0
- data/lib/dpl/providers/anynines.rb +65 -0
- data/lib/dpl/providers/atlas.rb +49 -0
- data/lib/dpl/providers/azure_web_apps.rb +59 -0
- data/lib/dpl/providers/bintray.rb +313 -0
- data/lib/dpl/providers/bluemixcloudfoundry.rb +92 -0
- data/lib/dpl/providers/boxfuse.rb +48 -0
- data/lib/dpl/providers/cargo.rb +19 -0
- data/lib/dpl/providers/chef_supermarket.rb +128 -0
- data/lib/dpl/providers/cloud66.rb +40 -0
- data/lib/dpl/providers/cloudfiles.rb +56 -0
- data/lib/dpl/providers/cloudfoundry.rb +81 -0
- data/lib/dpl/providers/codedeploy.rb +179 -0
- data/lib/dpl/providers/datica.rb +60 -0
- data/lib/dpl/providers/elasticbeanstalk.rb +195 -0
- data/lib/dpl/providers/engineyard.rb +107 -0
- data/lib/dpl/providers/firebase.rb +41 -0
- data/lib/dpl/providers/gae.rb +74 -0
- data/lib/dpl/providers/gcs.rb +105 -0
- data/lib/dpl/providers/hackage.rb +47 -0
- data/lib/dpl/providers/hephy.rb +101 -0
- data/lib/dpl/providers/heroku.rb +111 -0
- data/lib/dpl/providers/heroku/api.rb +119 -0
- data/lib/dpl/providers/heroku/git.rb +50 -0
- data/lib/dpl/providers/lambda.rb +202 -0
- data/lib/dpl/providers/launchpad.rb +74 -0
- data/lib/dpl/providers/netlify.rb +30 -0
- data/lib/dpl/providers/npm.rb +88 -0
- data/lib/dpl/providers/openshift.rb +46 -0
- data/lib/dpl/providers/opsworks.rb +142 -0
- data/lib/dpl/providers/packagecloud.rb +190 -0
- data/lib/dpl/providers/pages.rb +17 -0
- data/lib/dpl/providers/pages/api.rb +102 -0
- data/lib/dpl/providers/pages/git.rb +251 -0
- data/lib/dpl/providers/puppetforge.rb +44 -0
- data/lib/dpl/providers/pypi.rb +120 -0
- data/lib/dpl/providers/releases.rb +214 -0
- data/lib/dpl/providers/rubygems.rb +89 -0
- data/lib/dpl/providers/s3.rb +243 -0
- data/lib/dpl/providers/scalingo.rb +63 -0
- data/lib/dpl/providers/script.rb +28 -0
- data/lib/dpl/providers/snap.rb +59 -0
- data/lib/dpl/providers/surge.rb +55 -0
- data/lib/dpl/providers/testfairy.rb +93 -0
- data/lib/dpl/providers/transifex.rb +66 -0
- data/lib/dpl/support/aws_sdk_patch.rb +23 -0
- data/lib/dpl/support/gems.rb +69 -0
- data/lib/dpl/support/gstore_patch.rb +6 -0
- data/lib/dpl/support/version.rb +83 -0
- data/lib/dpl/version.rb +2 -2
- metadata +98 -169
- data/.coveralls.yml +0 -1
- data/.github/CONTRIBUTING.md +0 -173
- data/.github/stale.yml +0 -53
- data/.gitignore +0 -13
- data/.rspec +0 -2
- data/.travis.yml +0 -56
- data/dpl-anynines.gemspec +0 -3
- data/dpl-atlas.gemspec +0 -3
- data/dpl-azure_webapps.gemspec +0 -3
- data/dpl-bintray.gemspec +0 -3
- data/dpl-bitballoon.gemspec +0 -3
- data/dpl-bluemix_cloud_foundry.gemspec +0 -3
- data/dpl-boxfuse.gemspec +0 -3
- data/dpl-cargo.gemspec +0 -3
- data/dpl-catalyze.gemspec +0 -3
- data/dpl-chef_supermarket.gemspec +0 -20
- data/dpl-cloud66.gemspec +0 -3
- data/dpl-cloud_files.gemspec +0 -3
- data/dpl-cloud_foundry.gemspec +0 -3
- data/dpl-code_deploy.gemspec +0 -3
- data/dpl-deis.gemspec +0 -3
- data/dpl-elastic_beanstalk.gemspec +0 -3
- data/dpl-engine_yard.gemspec +0 -3
- data/dpl-firebase.gemspec +0 -3
- data/dpl-gae.gemspec +0 -3
- data/dpl-gcs.gemspec +0 -3
- data/dpl-hackage.gemspec +0 -3
- data/dpl-hephy.gemspec +0 -3
- data/dpl-heroku.gemspec +0 -3
- data/dpl-lambda.gemspec +0 -3
- data/dpl-launchpad.gemspec +0 -3
- data/dpl-npm.gemspec +0 -3
- data/dpl-openshift.gemspec +0 -3
- data/dpl-ops_works.gemspec +0 -3
- data/dpl-packagecloud.gemspec +0 -3
- data/dpl-pages.gemspec +0 -3
- data/dpl-puppet_forge.gemspec +0 -3
- data/dpl-pypi.gemspec +0 -3
- data/dpl-releases.gemspec +0 -8
- data/dpl-rubygems.gemspec +0 -3
- data/dpl-s3.gemspec +0 -3
- data/dpl-scalingo.gemspec +0 -3
- data/dpl-script.gemspec +0 -3
- data/dpl-snap.gemspec +0 -3
- data/dpl-surge.gemspec +0 -3
- data/dpl-testfairy.gemspec +0 -3
- data/dpl-transifex.gemspec +0 -3
- data/dpl.gemspec +0 -3
- data/gemspec_helper.rb +0 -51
- data/lib/dpl/error.rb +0 -3
- data/notes/engine_yard.md +0 -1
- data/notes/heroku.md +0 -3
- data/spec/cli_spec.rb +0 -36
- data/spec/provider_spec.rb +0 -191
- data/spec/spec_helper.rb +0 -20
@@ -0,0 +1,17 @@
|
|
1
|
+
module Dpl
|
2
|
+
module Providers
|
3
|
+
class Pages < Provider
|
4
|
+
def self.new(ctx, args)
|
5
|
+
return super unless registry_key.to_sym == :pages
|
6
|
+
arg = args.detect { |arg| arg.include? '--strategy' }
|
7
|
+
strategy = arg ? arg.split('=', 2).last : 'git'
|
8
|
+
Provider[:"pages:#{strategy}"].new(ctx, args)
|
9
|
+
end
|
10
|
+
|
11
|
+
opt '--strategy NAME', 'GitHub Pages deployment strategy', default: 'git', enum: %w(api git), internal: true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'dpl/providers/pages/git'
|
17
|
+
require 'dpl/providers/pages/api'
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
module Dpl
|
4
|
+
module Providers
|
5
|
+
class Pages
|
6
|
+
class Api < Pages
|
7
|
+
PAGES_PREVIEW_MEDIA_TYPE = 'application/vnd.github.mister-fantastic-preview+json'
|
8
|
+
|
9
|
+
# suppress warnings about preview API
|
10
|
+
ENV['OCTOKIT_SILENT'] = 'true'
|
11
|
+
|
12
|
+
TIMEOUTS = {
|
13
|
+
timeout: 180,
|
14
|
+
open_timeout: 180
|
15
|
+
}
|
16
|
+
|
17
|
+
gem 'octokit', '~> 4.14.0'
|
18
|
+
|
19
|
+
status :alpha
|
20
|
+
|
21
|
+
full_name 'GitHub Pages (API)'
|
22
|
+
|
23
|
+
description sq(<<-str)
|
24
|
+
This provider requests GitHub Pages build for the repository given by
|
25
|
+
the `--repo` flag, or the current one, if the flag is not given.
|
26
|
+
Note that `dpl` does not perform any check about the fitness of the request;
|
27
|
+
it is assumed that the target repository (and the branch that GitHub Pages is
|
28
|
+
configured to use) is ready for building.
|
29
|
+
For example, if your GitHub Pages is configured to use `gh-pages` but the
|
30
|
+
deployment is run on the `master` branch, you would have to ensure that the
|
31
|
+
`gh-pages` would be updated accordingly during the build.
|
32
|
+
str
|
33
|
+
|
34
|
+
opt '--repo SLUG', 'GitHub repo slug', default: :repo_slug
|
35
|
+
opt '--github_token TOKEN', 'GitHub oauth token with repo permission', required: true, secret: true
|
36
|
+
|
37
|
+
msgs pages_not_found: 'GitHub Pages not found for %{slug}. ' \
|
38
|
+
'Given token has insufficient scope (\'repo\' or \'public_repo\'), ' \
|
39
|
+
'or GitHub Pages is not enabled for this repo (see https://github.com/%{slug}/settings)',
|
40
|
+
build_pages_request_timeout: 'GitHub Pages build request timed out',
|
41
|
+
deploy_start: 'Requesting GitHub Pages build using API'
|
42
|
+
|
43
|
+
def validate
|
44
|
+
error :pages_not_found unless pages_enabled?
|
45
|
+
end
|
46
|
+
|
47
|
+
def deploy
|
48
|
+
info :deploy_start
|
49
|
+
|
50
|
+
api.request_page_build slug
|
51
|
+
|
52
|
+
response = api.pages slug
|
53
|
+
logger.debug response
|
54
|
+
|
55
|
+
Timeout::timeout(30) do
|
56
|
+
until response.status == 'built'
|
57
|
+
response = api.pages slug
|
58
|
+
logger.debug response
|
59
|
+
sleep 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
latest_pages_build = api.latest_pages_build slug
|
64
|
+
if msg = latest_pages_build.error.message
|
65
|
+
error "Build failed: #{msg}"
|
66
|
+
end
|
67
|
+
|
68
|
+
info "Pages deployed to #{response.html_url}, using commit #{latest_pages_build.commit}"
|
69
|
+
logger.debug latest_pages_build
|
70
|
+
|
71
|
+
rescue Octokit::Forbidden => fb
|
72
|
+
error fb.message
|
73
|
+
rescue Timeout::Error => to
|
74
|
+
error :build_pages_request_timeout
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def slug
|
80
|
+
repo || repo_slug
|
81
|
+
end
|
82
|
+
|
83
|
+
def api
|
84
|
+
::Octokit.default_media_type = PAGES_PREVIEW_MEDIA_TYPE unless @api
|
85
|
+
|
86
|
+
@api ||= Octokit::Client.new(**creds, auto_paginate: true, connection_options: { request: TIMEOUTS })
|
87
|
+
end
|
88
|
+
|
89
|
+
def creds
|
90
|
+
{ access_token: github_token }
|
91
|
+
end
|
92
|
+
|
93
|
+
def pages_enabled?
|
94
|
+
api.pages slug
|
95
|
+
rescue Octokit::NotFound => e
|
96
|
+
false
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
module Dpl
|
2
|
+
module Providers
|
3
|
+
class Pages
|
4
|
+
class Git < Pages
|
5
|
+
status :alpha
|
6
|
+
|
7
|
+
full_name 'GitHub Pages'
|
8
|
+
|
9
|
+
description sq(<<-str)
|
10
|
+
tbd
|
11
|
+
str
|
12
|
+
|
13
|
+
gem 'octokit', '~> 4.14.0'
|
14
|
+
gem 'public_suffix', '~> 3.0.3'
|
15
|
+
|
16
|
+
required :github_token, :deploy_key
|
17
|
+
|
18
|
+
opt '--repo SLUG', 'Repo slug', default: :repo_slug
|
19
|
+
opt '--github_token TOKEN', 'GitHub oauth token with repo permission', secret: true
|
20
|
+
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'
|
21
|
+
opt '--target_branch BRANCH', 'Branch to push force to', default: 'gh-pages'
|
22
|
+
opt '--keep_history', 'Create incremental commit instead of doing push force', default: true
|
23
|
+
opt '--commit_message MSG', default: 'Deploy %{project_name} to %{url}:%{target_branch}'
|
24
|
+
opt '--allow_empty_commit', 'Allow an empty commit to be created', requires: :keep_history
|
25
|
+
opt '--verbose', 'Be verbose about the deploy process'
|
26
|
+
opt '--local_dir DIR', 'Directory to push to GitHub Pages', default: '.'
|
27
|
+
opt '--fqdn FQDN', 'Write the given domain name to the CNAME file'
|
28
|
+
opt '--project_name NAME', 'Used in the commit message only (defaults to fqdn or the current repo slug)'
|
29
|
+
opt '--name NAME', 'Committer name', note: 'defaults to the current git commit author name'
|
30
|
+
opt '--email EMAIL', 'Committer email', note: 'defaults to the current git commit author email'
|
31
|
+
opt '--committer_from_gh', 'Use the token\'s owner name and email for the commit', requires: :github_token
|
32
|
+
opt '--deployment_file', 'Enable creation of a deployment-info file'
|
33
|
+
opt '--github_url URL', default: 'github.com'
|
34
|
+
|
35
|
+
needs :git
|
36
|
+
|
37
|
+
msgs login: 'Authenticated as %s',
|
38
|
+
invalid_token: 'The provided GitHub token is invalid (error: %s)',
|
39
|
+
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.',
|
40
|
+
setup_deploy_key: 'Moving deploy key %{deploy_key} to %{path}',
|
41
|
+
check_deploy_key: 'Checking deploy key',
|
42
|
+
deploy: 'Deploying branch %{target_branch} to %{github_url}',
|
43
|
+
keep_history: 'The deployment is configured to preserve the target branch if it exists on remote.',
|
44
|
+
work_dir: 'Using temporary work directory %{work_dir}',
|
45
|
+
committer_from_gh: 'The repo is configured to use committer user and email.',
|
46
|
+
setup_dir: 'The source dir for deployment is %s',
|
47
|
+
git_clone: 'Cloning the branch %{target_branch} from the remote repo',
|
48
|
+
git_init: 'Initializing local git repo',
|
49
|
+
git_checkout: 'Checking out orphan branch %{target_branch}',
|
50
|
+
copy_files: 'Copying %{src_dir} contents to %{work_dir}',
|
51
|
+
git_config: 'Configuring git committer to be %{name} <%{email}>',
|
52
|
+
prepare: 'Preparing to deploy %{target_branch} branch to gh-pages',
|
53
|
+
git_push: 'Pushing to %{url}'
|
54
|
+
|
55
|
+
cmds git_clone: 'git clone --quiet --branch="%{target_branch}" --depth=1 "%{remote_url}" . > /dev/null 2>&1',
|
56
|
+
git_init: 'git init .',
|
57
|
+
git_checkout: 'git checkout --orphan "%{target_branch}"',
|
58
|
+
check_deploy_key: 'ssh -i %{key} -T git@github.com 2>&1 | grep successful > /dev/null',
|
59
|
+
copy_files: 'rsync -rl --exclude .git --delete "%{src_dir}/" .',
|
60
|
+
git_config_email: 'git config user.email %{quoted_email}',
|
61
|
+
git_config_name: 'git config user.name %{quoted_name}',
|
62
|
+
deployment_file: 'touch "deployed at %{now} by %{name}"',
|
63
|
+
cname: 'echo "%{fqdn}" > CNAME',
|
64
|
+
git_add: 'git add -A .',
|
65
|
+
git_commit_hook: 'cp %{path} .git/hooks/pre-commit',
|
66
|
+
git_commit: 'git commit %{git_commit_opts} -qm %{quoted_commit_message}',
|
67
|
+
git_show: 'git show --stat-count=10 HEAD',
|
68
|
+
git_push: 'git push%{git_push_opts} --quiet "%{remote_url}" "%{target_branch}":"%{target_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_checkout: 'Failed to create the orphan branch',
|
74
|
+
git_push: 'Failed to push the build to %{url}:%{target_branch}'
|
75
|
+
|
76
|
+
def login
|
77
|
+
github_token? ? login_token : setup_deploy_key
|
78
|
+
end
|
79
|
+
|
80
|
+
def setup
|
81
|
+
info :setup_dir, src_dir
|
82
|
+
info :committer_from_gh if committer_from_gh?
|
83
|
+
info :git_config
|
84
|
+
end
|
85
|
+
|
86
|
+
def prepare
|
87
|
+
info :deploy
|
88
|
+
info :keep_history if keep_history?
|
89
|
+
debug :work_dir
|
90
|
+
Dir.chdir(work_dir)
|
91
|
+
end
|
92
|
+
|
93
|
+
def deploy
|
94
|
+
git_clone? ? git_clone : git_init
|
95
|
+
copy_files
|
96
|
+
git_config
|
97
|
+
git_commit
|
98
|
+
git_push
|
99
|
+
git_status if verbose?
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def login_token
|
105
|
+
user.login
|
106
|
+
info :login, user.login
|
107
|
+
error :insufficient_scopes unless sufficient_scopes?
|
108
|
+
rescue Octokit::Unauthorized => e
|
109
|
+
error :invalid_token, e.message
|
110
|
+
end
|
111
|
+
|
112
|
+
def setup_deploy_key
|
113
|
+
path = '~/.dpl/deploy_key'
|
114
|
+
info :setup_deploy_key, path: path
|
115
|
+
mv deploy_key, path
|
116
|
+
chmod 0600, path
|
117
|
+
setup_git_ssh path
|
118
|
+
shell :check_deploy_key, key: path
|
119
|
+
end
|
120
|
+
|
121
|
+
def git_clone?
|
122
|
+
keep_history? && git_branch_exists?
|
123
|
+
end
|
124
|
+
|
125
|
+
def git_clone
|
126
|
+
shell :git_clone, echo: false
|
127
|
+
end
|
128
|
+
|
129
|
+
def git_init
|
130
|
+
shell :git_init
|
131
|
+
shell :git_checkout
|
132
|
+
end
|
133
|
+
|
134
|
+
def copy_files
|
135
|
+
shell :copy_files
|
136
|
+
end
|
137
|
+
|
138
|
+
def git_config
|
139
|
+
shell :git_config_name, echo: false
|
140
|
+
shell :git_config_email, echo: false
|
141
|
+
end
|
142
|
+
|
143
|
+
def git_commit
|
144
|
+
info :prepare
|
145
|
+
shell :git_commit_hook, path: asset(:git, :detect_private_key).path, echo: false if deploy_key?
|
146
|
+
shell :deployment_file if deployment_file?
|
147
|
+
shell :cname if fqdn?
|
148
|
+
shell :git_add
|
149
|
+
shell :git_commit
|
150
|
+
shell :git_show
|
151
|
+
end
|
152
|
+
|
153
|
+
def git_push
|
154
|
+
shell :git_push, echo: false
|
155
|
+
end
|
156
|
+
|
157
|
+
def git_status
|
158
|
+
shell 'git status'
|
159
|
+
end
|
160
|
+
|
161
|
+
def git_branch_exists?
|
162
|
+
git_ls_remote?(remote_url, target_branch)
|
163
|
+
end
|
164
|
+
|
165
|
+
def git_commit_opts
|
166
|
+
' --allow-empty' if allow_empty_commit?
|
167
|
+
end
|
168
|
+
|
169
|
+
def git_push_opts
|
170
|
+
' --force' unless keep_history?
|
171
|
+
end
|
172
|
+
|
173
|
+
def name
|
174
|
+
str = super if name?
|
175
|
+
str ||= user.name if committer_from_gh?
|
176
|
+
str ||= git_author_name
|
177
|
+
str = "#{str} (via Travis CI)" if ENV['TRAVIS'] && !name?
|
178
|
+
str
|
179
|
+
end
|
180
|
+
memoize :name
|
181
|
+
|
182
|
+
def email
|
183
|
+
str = super if email?
|
184
|
+
str ||= user.email if committer_from_gh?
|
185
|
+
str || git_author_email
|
186
|
+
end
|
187
|
+
memoize :email
|
188
|
+
|
189
|
+
def commit_message
|
190
|
+
interpolate(super)
|
191
|
+
end
|
192
|
+
|
193
|
+
def project_name
|
194
|
+
super || fqdn || repo_slug
|
195
|
+
end
|
196
|
+
|
197
|
+
def sufficient_scopes?
|
198
|
+
api.scopes.include?('public_repo') || api.scopes.include?('repo')
|
199
|
+
end
|
200
|
+
|
201
|
+
def remote_url
|
202
|
+
github_token? ? https_url_with_token : git_url
|
203
|
+
end
|
204
|
+
|
205
|
+
def https_url_with_token
|
206
|
+
"https://#{github_token}@#{url}"
|
207
|
+
end
|
208
|
+
|
209
|
+
def git_url
|
210
|
+
"git@#{github_url}:#{slug}.git"
|
211
|
+
end
|
212
|
+
|
213
|
+
def url
|
214
|
+
"#{github_url}/#{slug}.git"
|
215
|
+
end
|
216
|
+
|
217
|
+
def slug
|
218
|
+
repo || repo_slug
|
219
|
+
end
|
220
|
+
|
221
|
+
def user
|
222
|
+
@user ||= api.user
|
223
|
+
end
|
224
|
+
|
225
|
+
def src_dir
|
226
|
+
@src_dir ||= expand(local_dir)
|
227
|
+
end
|
228
|
+
|
229
|
+
def work_dir
|
230
|
+
@work_dir ||= tmp_dir
|
231
|
+
end
|
232
|
+
|
233
|
+
def api
|
234
|
+
@api ||= Octokit::Client.new(access_token: github_token, api_endpoint: api_endpoint)
|
235
|
+
end
|
236
|
+
|
237
|
+
def api_endpoint
|
238
|
+
github_url == 'github.com' ? 'https://api.github.com/' : "https://#{github_url}/api/v3/"
|
239
|
+
end
|
240
|
+
|
241
|
+
def now
|
242
|
+
Time.now
|
243
|
+
end
|
244
|
+
|
245
|
+
def debug(*args)
|
246
|
+
info *args if verbose?
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Dpl
|
2
|
+
module Providers
|
3
|
+
class Puppetforge < Provider
|
4
|
+
status :alpha
|
5
|
+
|
6
|
+
full_name 'Puppet Forge'
|
7
|
+
|
8
|
+
description sq(<<-str)
|
9
|
+
tbd
|
10
|
+
str
|
11
|
+
|
12
|
+
gem 'puppet', '~> 5.5.14', require: 'puppet/face'
|
13
|
+
gem 'puppet-blacksmith', '~> 3.3.1', require: 'puppet_blacksmith'
|
14
|
+
|
15
|
+
opt '--username NAME', 'Puppet Forge user name', required: true, alias: :user
|
16
|
+
opt '--password PASS', 'Puppet Forge password', required: true, secret: true
|
17
|
+
opt '--url URL', 'Puppet Forge URL to deploy to', default: 'https://forgeapi.puppetlabs.com/'
|
18
|
+
|
19
|
+
msgs upload: 'Uploading to Puppet Forge %s/%s'
|
20
|
+
|
21
|
+
def validate
|
22
|
+
file.metadata
|
23
|
+
end
|
24
|
+
|
25
|
+
def deploy
|
26
|
+
build
|
27
|
+
info :upload, forge.username, file.name
|
28
|
+
forge.push!(file.name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def file
|
32
|
+
@file ||= Blacksmith::Modulefile.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def build
|
36
|
+
Puppet::Face['module', :current].build('./')
|
37
|
+
end
|
38
|
+
|
39
|
+
def forge
|
40
|
+
@forge ||= Blacksmith::Forge.new(username, password, url)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Dpl
|
2
|
+
module Providers
|
3
|
+
class Pypi < Provider
|
4
|
+
status :alpha
|
5
|
+
|
6
|
+
full_name 'PyPI'
|
7
|
+
|
8
|
+
description sq(<<-str)
|
9
|
+
tbd
|
10
|
+
str
|
11
|
+
|
12
|
+
env :pypi
|
13
|
+
|
14
|
+
VERSION = /\A\d+(?:\.\d+)*\z/
|
15
|
+
|
16
|
+
opt '--username NAME', 'PyPI Username', required: true, alias: :user
|
17
|
+
opt '--password PASS', 'PyPI Password', required: true, secret: true
|
18
|
+
opt '--server SERVER', 'Release to a different index', default: 'https://upload.pypi.org/legacy/'
|
19
|
+
opt '--distributions DISTS', 'Space-separated list of distributions to be uploaded to PyPI', default: 'sdist'
|
20
|
+
opt '--docs_dir DIR', 'Path to the directory to upload documentation from', default: 'build/docs'
|
21
|
+
opt '--skip_existing', 'Do not overwrite an existing file with the same name on the server.'
|
22
|
+
opt '--upload_docs', 'Upload documentation', default: false, type: :boolean, note: 'most PyPI servers, including upload.pypi.org, do not support uploading documentation'
|
23
|
+
opt '--twine_check', 'Whether to run twine check', default: true
|
24
|
+
opt '--remove_build_dir', 'Remove the build dir after the upload', default: true
|
25
|
+
opt '--setuptools_version VER', format: VERSION
|
26
|
+
opt '--twine_version VER', format: VERSION
|
27
|
+
opt '--wheel_version VER', format: VERSION
|
28
|
+
|
29
|
+
msgs login: 'Authenticated as %{username}',
|
30
|
+
upload_docs: 'Uploading documentation (skip using "skip_upload_docs: true")'
|
31
|
+
|
32
|
+
cmds setup_py: 'python setup.py %{distributions}',
|
33
|
+
twine_check: 'twine check dist/*',
|
34
|
+
twine_upload: 'twine upload %{skip_existing_option} -r pypi dist/*',
|
35
|
+
rm_dist: 'rm -rf dist/*',
|
36
|
+
upload_docs: 'python setup.py upload_docs %{docs_dir_option} -r %{server}'
|
37
|
+
|
38
|
+
errs install: 'Failed to install pip, setuptools, twine or wheel.',
|
39
|
+
setup_py: 'setup.py failed',
|
40
|
+
twine_check: 'Twine check failed',
|
41
|
+
twine_upload: 'Twine upload failed.',
|
42
|
+
upload_docs: 'Uploading docs failed.'
|
43
|
+
|
44
|
+
|
45
|
+
def install
|
46
|
+
script :install
|
47
|
+
end
|
48
|
+
|
49
|
+
def login
|
50
|
+
write_config
|
51
|
+
info :login
|
52
|
+
end
|
53
|
+
|
54
|
+
def setup
|
55
|
+
shell :setup_py
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate
|
59
|
+
shell :twine_check if twine_check?
|
60
|
+
end
|
61
|
+
|
62
|
+
def deploy
|
63
|
+
shell :twine_upload
|
64
|
+
upload_docs if upload_docs?
|
65
|
+
shell :rm_dist if remove_build_dir?
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
PYPIRC = sq(<<-rc)
|
71
|
+
[distutils]
|
72
|
+
index-servers = pypi
|
73
|
+
pypi
|
74
|
+
[pypi]
|
75
|
+
repository: %{server}
|
76
|
+
username: %{username}
|
77
|
+
password: %{password}
|
78
|
+
rc
|
79
|
+
|
80
|
+
def write_config
|
81
|
+
write_file('~/.pypirc', pypirc)
|
82
|
+
end
|
83
|
+
|
84
|
+
def pypirc
|
85
|
+
interpolate(PYPIRC, opts, secure: true)
|
86
|
+
end
|
87
|
+
|
88
|
+
def upload_docs
|
89
|
+
info :upload_docs
|
90
|
+
shell :upload_docs
|
91
|
+
end
|
92
|
+
|
93
|
+
def skip_existing_option
|
94
|
+
'--skip-existing' if skip_existing?
|
95
|
+
end
|
96
|
+
|
97
|
+
def docs_dir_option
|
98
|
+
'--upload-dir ' + docs_dir if docs_dir
|
99
|
+
end
|
100
|
+
|
101
|
+
def setuptools_arg
|
102
|
+
version_arg(:setuptools)
|
103
|
+
end
|
104
|
+
|
105
|
+
def twine_arg
|
106
|
+
version_arg(:twine)
|
107
|
+
end
|
108
|
+
|
109
|
+
def wheel_arg
|
110
|
+
version_arg(:wheel)
|
111
|
+
end
|
112
|
+
|
113
|
+
def version_arg(name)
|
114
|
+
arg = name.to_s
|
115
|
+
arg << "==#{send(:"#{name}_version")}" if send(:"#{name}_version") =~ VERSION
|
116
|
+
arg
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|