heroku-headless 0.1.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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +21 -0
- data/Rakefile +2 -0
- data/heroku-headless.gemspec +19 -0
- data/lib/heroku-headless.rb +7 -0
- data/lib/heroku-headless/creates_uuids.rb +8 -0
- data/lib/heroku-headless/deployer.rb +95 -0
- data/lib/heroku-headless/disposable_app_deleter.rb +20 -0
- data/lib/heroku-headless/disposable_deployer.rb +54 -0
- data/lib/heroku-headless/documents_actions.rb +9 -0
- data/lib/heroku-headless/talks_to_heroku.rb +9 -0
- data/lib/heroku-headless/version.rb +3 -0
- metadata +77 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Pete Hodgson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# HerokuHeadless
|
2
|
+
|
3
|
+
## What?
|
4
|
+
Push from your git repo to a heroku app without any external configuration.
|
5
|
+
|
6
|
+
## Why?
|
7
|
+
Heroku's workflow is geared towards pushing to a heroku app from a dev workstation. This gem makes it easy to push to a heroku app as part of a CI/CD setup.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'heroku-headless'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install heroku-headless
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/heroku-headless/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Pete Hodgson"]
|
6
|
+
gem.email = ["phodgson@thoughtworks.com"]
|
7
|
+
gem.description = %q{Push from your git repo to a heroku app without any external configuration.}
|
8
|
+
gem.summary = %q{Heroku's workflow is geared towards pushing to a heroku app from a dev workstation. This gem makes it easy to push to a heroku app as part of a CI/CD setup.}
|
9
|
+
gem.homepage = "https://github.com/moredip/heroku-headless"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "heroku-headless"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = HerokuHeadless::VERSION
|
17
|
+
|
18
|
+
gem.add_runtime_dependency "heroku-api"
|
19
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
module HerokuHeadless
|
5
|
+
class Deployer
|
6
|
+
include DocumentsActions
|
7
|
+
include TalksToHeroku
|
8
|
+
|
9
|
+
def self.deploy(app_name)
|
10
|
+
new(app_name,CreatesUUIDs.generate_lowercase_uuid).deploy
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize( app_name, uid )
|
14
|
+
@app_name = app_name
|
15
|
+
@uid = uid
|
16
|
+
end
|
17
|
+
|
18
|
+
def deploy
|
19
|
+
prep_temp_dir
|
20
|
+
setup_ssh_key
|
21
|
+
do_action('push git to heroku'){ push_head_to_app }
|
22
|
+
|
23
|
+
ensure
|
24
|
+
cleanup
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def prep_temp_dir
|
30
|
+
@tmpdir = Pathname.new( Dir.tmpdir ).join('heroku-deployer').join(@uid)
|
31
|
+
@tmpdir.mkpath
|
32
|
+
end
|
33
|
+
|
34
|
+
def cleanup
|
35
|
+
do_action( 'removing ssh key' ){ remove_ssh_key }
|
36
|
+
do_action( 'removing temp dir' ){ remove_temp_dir }
|
37
|
+
end
|
38
|
+
|
39
|
+
def remove_temp_dir
|
40
|
+
@tmpdir.rmtree
|
41
|
+
end
|
42
|
+
|
43
|
+
def setup_ssh_key
|
44
|
+
do_action( 'creating ssh key' ){ create_ssh_key }
|
45
|
+
do_action( 'adding ssh key' ){ add_ssh_key }
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_ssh_key
|
49
|
+
`ssh-keygen -t rsa -N "" -C #{ssh_key_name} -f #{ssh_key_path}`
|
50
|
+
end
|
51
|
+
|
52
|
+
def ssh_key_path
|
53
|
+
@tmpdir.join('id_rsa')
|
54
|
+
end
|
55
|
+
|
56
|
+
def ssh_key_name
|
57
|
+
"deployer-#{@uid}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def public_ssh_key
|
61
|
+
ssh_key_path.sub_ext('.pub').read
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_ssh_key
|
65
|
+
heroku.post_key(public_ssh_key)
|
66
|
+
end
|
67
|
+
|
68
|
+
def remove_ssh_key
|
69
|
+
heroku.delete_key(ssh_key_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def push_head_to_app
|
73
|
+
setup_custom_git_ssh
|
74
|
+
push_git
|
75
|
+
end
|
76
|
+
|
77
|
+
def setup_custom_git_ssh
|
78
|
+
custom_git_ssh_path.open('w') do |f|
|
79
|
+
f.write <<-EOF
|
80
|
+
#!/bin/sh
|
81
|
+
exec ssh -o StrictHostKeychecking=no -o CheckHostIP=no -o UserKnownHostsFile=/dev/null -i #{ssh_key_path.expand_path} -- "$@"
|
82
|
+
EOF
|
83
|
+
end
|
84
|
+
custom_git_ssh_path.chmod( 0740 )
|
85
|
+
end
|
86
|
+
|
87
|
+
def push_git
|
88
|
+
system( {'GIT_SSH'=>custom_git_ssh_path.to_s}, "git push git@heroku.com:#{@app_name}.git HEAD:master" )
|
89
|
+
end
|
90
|
+
|
91
|
+
def custom_git_ssh_path
|
92
|
+
@tmpdir.join('git-ssh')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "heroku-headless/talks_to_heroku"
|
2
|
+
|
3
|
+
module HerokuHeadless
|
4
|
+
class DisposableAppDeleter
|
5
|
+
include TalksToHeroku
|
6
|
+
|
7
|
+
def self.delete_all
|
8
|
+
new.delete_all_apps
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete_all_apps
|
12
|
+
apps = heroku.get_apps.body.map{ |h| h['name'] }
|
13
|
+
disposable_apps = apps.select{ |x| x.start_with?( 'disposable' ) }
|
14
|
+
disposable_apps.each do |app|
|
15
|
+
puts "deleting #{app}"
|
16
|
+
heroku.delete_app app
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "heroku-headless"
|
2
|
+
|
3
|
+
module HerokuHeadless
|
4
|
+
class DisposableDeployer
|
5
|
+
include TalksToHeroku
|
6
|
+
include DocumentsActions
|
7
|
+
|
8
|
+
def go
|
9
|
+
source_secrets
|
10
|
+
do_deploy
|
11
|
+
rescue
|
12
|
+
cleanup_after_failure
|
13
|
+
raise
|
14
|
+
ensure
|
15
|
+
cleanup
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def do_deploy
|
21
|
+
do_action('creating app'){ create_app }
|
22
|
+
puts "created http://#{@app_name}.herokuapp.com"
|
23
|
+
|
24
|
+
deploy_app
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_app
|
29
|
+
app_name = "disposable-#{deploy_uuid}"[0,30]
|
30
|
+
heroku.post_app( name: app_name )
|
31
|
+
@app_name = app_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def deploy_app
|
35
|
+
Deployer.new(@app_name,deploy_uuid).deploy
|
36
|
+
end
|
37
|
+
|
38
|
+
def cleanup
|
39
|
+
# nothing to be done for now
|
40
|
+
end
|
41
|
+
|
42
|
+
def cleanup_after_failure
|
43
|
+
destroy_app
|
44
|
+
end
|
45
|
+
|
46
|
+
def destroy_app
|
47
|
+
heroku.delete_app( @app_name ) if @app_name
|
48
|
+
end
|
49
|
+
|
50
|
+
def deploy_uuid
|
51
|
+
@deploy_uuid ||= CreatesUUIDs.generate_lowercase_uuid
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: heroku-headless
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pete Hodgson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: heroku-api
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Push from your git repo to a heroku app without any external configuration.
|
31
|
+
email:
|
32
|
+
- phodgson@thoughtworks.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- heroku-headless.gemspec
|
43
|
+
- lib/heroku-headless.rb
|
44
|
+
- lib/heroku-headless/creates_uuids.rb
|
45
|
+
- lib/heroku-headless/deployer.rb
|
46
|
+
- lib/heroku-headless/disposable_app_deleter.rb
|
47
|
+
- lib/heroku-headless/disposable_deployer.rb
|
48
|
+
- lib/heroku-headless/documents_actions.rb
|
49
|
+
- lib/heroku-headless/talks_to_heroku.rb
|
50
|
+
- lib/heroku-headless/version.rb
|
51
|
+
homepage: https://github.com/moredip/heroku-headless
|
52
|
+
licenses: []
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.8.24
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Heroku's workflow is geared towards pushing to a heroku app from a dev workstation.
|
75
|
+
This gem makes it easy to push to a heroku app as part of a CI/CD setup.
|
76
|
+
test_files: []
|
77
|
+
has_rdoc:
|