depl 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/LICENSE.md +21 -0
- data/README.md +34 -0
- data/Rakefile +10 -0
- data/bin/depl +89 -0
- data/depl.gemspec +24 -0
- data/lib/depl.rb +3 -0
- data/lib/depl/main.rb +83 -0
- data/lib/depl/remote.rb +18 -0
- data/lib/depl/version.rb +3 -0
- data/spec/depl/main_spec.rb +52 -0
- data/spec/spec_helper.rb +2 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 68f043ef8f3eee4c482df1aeb3d01a3260591faf
|
4
|
+
data.tar.gz: 7931ea5e765b4dc6b669c7dd475f3f44fe8b407e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9cc658d19daabfa9c1b24e3d693eaffc7787e72a340cb0ad41f835b24772d8864e1310eebb9f6449183e3a6e28fd62b979e77408b43f61c1312ddd1e5f4971fe
|
7
|
+
data.tar.gz: 35a5440ae2c9bd56e30f10e6c1efce23813d38275668d63c3c9303c01ad7a7f69327521f8e1b6d165a4d3c08e73feff6c738f5051975e33310343dec9d2453b9
|
data/.gitignore
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Stefan Penner and ember-cli contributors
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# depl
|
2
|
+
|
3
|
+
depl evolved out of Movable Ink's deployments, which typically involved capistrano. Over time, the capistrano scripts got heavier and multiple datacenters were added, each with dozens of machines. We used Chef for provisioning, and found that it was impossible to keep capistrano up-to-date with the comings and goings of new machines. A separation was needed.
|
4
|
+
|
5
|
+
## The depl workflow
|
6
|
+
|
7
|
+
The goal of depl is to separate deployment into two parts: specifying that a new version of code should be deployed, and actually deploying that code to the machines that need it.
|
8
|
+
|
9
|
+
A typical deployment would look like this:
|
10
|
+
|
11
|
+
» depl production
|
12
|
+
Attempting to deploy d836d33
|
13
|
+
|
14
|
+
Difference of 6 new commit(s) between de0aed0 and d836d33:
|
15
|
+
|
16
|
+
d836d33 Michael Nutt 8 minutes ago ignore our own .deploy
|
17
|
+
9046842 Michael Nutt 8 minutes ago make bin executable
|
18
|
+
b2b4038 Michael Nutt 8 minutes ago clean up gemspec
|
19
|
+
e57b428 Michael Nutt 18 minutes ago refactoring
|
20
|
+
4fba6fa Michael Nutt 26 minutes ago add commit comparisons
|
21
|
+
349c4ce Michael Nutt 76 minutes ago first pass at sending to s3
|
22
|
+
|
23
|
+
Deploy? ([y]es / [n]o / [g]ithub) : y
|
24
|
+
Deployed d836d33
|
25
|
+
|
26
|
+
Movable Ink uses Chef to push out new code, and Chef is set up to use environment-based branches for its deployment. This allows newly provisioned machines to get the latest deployed version while not requiring changes to the provisioning system every time the project is updated.
|
27
|
+
|
28
|
+
## History
|
29
|
+
|
30
|
+
* _0.0.1_ - Forked from deploy_s3; initial release.
|
31
|
+
|
32
|
+
## License
|
33
|
+
|
34
|
+
The MIT License. See LICENSE.md.
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
# Default directory to look in is `/specs`
|
5
|
+
# Run with `rake spec`
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
7
|
+
task.rspec_opts = ['--color', '--format', 'nested']
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :spec
|
data/bin/depl
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'depl'
|
5
|
+
rescue LoadError
|
6
|
+
require 'rubygems'
|
7
|
+
require 'depl'
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'optparse'
|
11
|
+
require 'highline/import'
|
12
|
+
require 'colorize'
|
13
|
+
|
14
|
+
options = {}
|
15
|
+
|
16
|
+
options[:environment] = ARGV.shift
|
17
|
+
|
18
|
+
options[:rev] = ENV['REV']
|
19
|
+
|
20
|
+
optparse = OptionParser.new do |opts|
|
21
|
+
opts.banner = "Usage: depl [environment] [options]"
|
22
|
+
|
23
|
+
opts.on("-c", "--config=CONFIG", String, "Location of .deploy configuration file") do |c|
|
24
|
+
options[:config_file] = c
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-r", "--revision=REVISION", String, "Revision to deploy (can be sha, branch, etc)") do |r|
|
28
|
+
options[:rev] = r
|
29
|
+
end
|
30
|
+
end
|
31
|
+
optparse.parse!
|
32
|
+
|
33
|
+
unless options[:environment]
|
34
|
+
puts "Error: environment required"
|
35
|
+
puts optparse
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
deploy = Depl::Main.new(options)
|
40
|
+
|
41
|
+
if deploy.up_to_date
|
42
|
+
puts "Everything up-to-date (#{deploy.environment.green}: #{deploy.remote_sha.green})"
|
43
|
+
exit 0
|
44
|
+
end
|
45
|
+
|
46
|
+
if deploy.remote_sha.nil?
|
47
|
+
puts "New deployment: #{deploy.local_sha}"
|
48
|
+
else
|
49
|
+
puts "Attempting to deploy #{deploy.local_sha.bold}", ""
|
50
|
+
|
51
|
+
commits = "#{deploy.commit_count} new commit(s)".green
|
52
|
+
puts "Difference of #{commits} between #{deploy.remote_sha} and #{deploy.local_sha}:", ""
|
53
|
+
|
54
|
+
if deploy.commit_count > 0
|
55
|
+
puts deploy.diff.yellow, ""
|
56
|
+
else
|
57
|
+
puts " There are no new commits.", ""
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if deploy.older_local_sha
|
62
|
+
puts "WARNING: The commit you are deploying is older than what is currently on #{deploy.environment}. Missing commits: ".bold, ""
|
63
|
+
puts deploy.reverse_diff.red
|
64
|
+
puts ""
|
65
|
+
end
|
66
|
+
|
67
|
+
confirm = ask("Deploy #{deploy.environment}? ([y]es / [n]o / [g]ithub) : ") { |yn| yn.limit = 1, yn.validate = /([yng]|yes|no|github)/i }
|
68
|
+
|
69
|
+
case confirm.downcase
|
70
|
+
when 'y', 'yes'
|
71
|
+
deploy.run!
|
72
|
+
|
73
|
+
puts "Deployed #{deploy.remote_sha}"
|
74
|
+
when 'g', 'github'
|
75
|
+
url = Depl::Remote.comparison(deploy.remote_sha, deploy.local_sha)
|
76
|
+
if url
|
77
|
+
if `which open`.size > 0
|
78
|
+
`open #{url}`
|
79
|
+
else
|
80
|
+
puts " Github: #{url}"
|
81
|
+
end
|
82
|
+
else
|
83
|
+
puts "Unrecognized repository; can't open github"
|
84
|
+
puts "(try `git config --get remote.origin.url`)"
|
85
|
+
exit 1
|
86
|
+
end
|
87
|
+
when 'n', 'no'
|
88
|
+
puts "Bye."
|
89
|
+
end
|
data/depl.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "depl/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "depl"
|
6
|
+
s.version = Depl::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Michael Nutt"]
|
9
|
+
s.email = ["michael@movableink.com"]
|
10
|
+
s.homepage = "https://github.com/movableink/depl"
|
11
|
+
s.summary = %q{Writes project deployment hash to s3 file}
|
12
|
+
s.licenses = "MIT"
|
13
|
+
s.description = %q{Separate out the deployment concerns from your application by using depl to write your latest deployed git hash to s3. Then let your provisioning system (for instance, chef + deploy_revision provider) take care of actually deploying new code. depl shows diffs between your current branch and the deployed revision.}
|
14
|
+
|
15
|
+
s.add_runtime_dependency "highline", "~> 1.6"
|
16
|
+
s.add_runtime_dependency "colorize", "~> 0.7"
|
17
|
+
|
18
|
+
s.add_development_dependency "rspec", "~> 2.5"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/lib/depl.rb
ADDED
data/lib/depl/main.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
module Depl
|
2
|
+
class Main
|
3
|
+
def initialize(options)
|
4
|
+
config_path = options[:config_file] || "./.deploy"
|
5
|
+
@config = options[:config]
|
6
|
+
|
7
|
+
if File.exist? config_path
|
8
|
+
@config ||= YAML::load_file(config_path)
|
9
|
+
else
|
10
|
+
@config ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def environment
|
17
|
+
@options[:environment]
|
18
|
+
end
|
19
|
+
|
20
|
+
def prefix
|
21
|
+
@config[:prefix] || "deploy-"
|
22
|
+
end
|
23
|
+
|
24
|
+
def deploy_branch
|
25
|
+
"#{prefix}#{environment}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def save_sha
|
29
|
+
execute("git push --force origin #{local_sha}:refs/heads/#{deploy_branch}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def run!
|
33
|
+
if @config['before_hook']
|
34
|
+
`#{@config['before_hook']}`
|
35
|
+
end
|
36
|
+
|
37
|
+
save_sha
|
38
|
+
|
39
|
+
if @config['after_hook']
|
40
|
+
`#{@config['after_hook']}`
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def remote_sha
|
45
|
+
`git fetch origin`
|
46
|
+
sha = execute("git rev-parse -q --verify origin/#{deploy_branch}").chomp
|
47
|
+
sha if sha != ""
|
48
|
+
end
|
49
|
+
|
50
|
+
def up_to_date
|
51
|
+
local_sha == remote_sha
|
52
|
+
end
|
53
|
+
|
54
|
+
def local_sha
|
55
|
+
rev = @options[:rev] || @config[:branch] || 'head'
|
56
|
+
sha = execute("git rev-parse -q --verify #{rev}").chomp
|
57
|
+
sha if sha != ""
|
58
|
+
end
|
59
|
+
|
60
|
+
def diff
|
61
|
+
execute "git log --pretty=format:' %h %<(20)%an %ar\t %s' -10 #{remote_sha}..#{local_sha}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def reverse_diff
|
65
|
+
execute "git log --pretty=format:' %h %<(20)%an %ar\t %s' -10 #{local_sha}..#{remote_sha}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def older_local_sha
|
69
|
+
return false unless remote_sha
|
70
|
+
execute("git merge-base --is-ancestor #{local_sha} #{remote_sha}") && $?.exitstatus == 0
|
71
|
+
end
|
72
|
+
|
73
|
+
def commit_count
|
74
|
+
diff.split("\n").size
|
75
|
+
end
|
76
|
+
|
77
|
+
protected
|
78
|
+
|
79
|
+
def execute(cmd)
|
80
|
+
`#{cmd}`
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/depl/remote.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Depl
|
2
|
+
class Remote
|
3
|
+
def self.comparison(from, to)
|
4
|
+
origin_url = `git config --get remote.origin.url`.chomp
|
5
|
+
|
6
|
+
github_url = self.github_from_url origin_url
|
7
|
+
"#{github_url}/compare/#{from}...#{to}" if github_url
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.github_from_url(url)
|
11
|
+
if url =~ /git@github.com:(.*?).git/
|
12
|
+
"https://github.com/#{$1}"
|
13
|
+
elsif url =~ /(.*?):\/\/github.com\/(.*?).git/
|
14
|
+
"https://github.com/#{$1}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/depl/version.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Depl::Main do
|
4
|
+
let(:deploy) {
|
5
|
+
Depl::Main.new(:environment => 'production',
|
6
|
+
:config => {'s3' => 'my-bucket/deployments/foo'})
|
7
|
+
}
|
8
|
+
|
9
|
+
describe '#environment' do
|
10
|
+
it 'uses the passed environment' do
|
11
|
+
expect(deploy.environment).to eq('production')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#filename' do
|
16
|
+
it 'computes the filename' do
|
17
|
+
expect(deploy.filename).to eql('production.sha')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#key' do
|
22
|
+
it 'computes the key' do
|
23
|
+
expect(deploy.key).to eq('deployments/foo/production.sha')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#diff' do
|
28
|
+
it 'uses git to find the commits between two shas' do
|
29
|
+
deploy.should_receive(:remote_sha).and_return("remote")
|
30
|
+
deploy.should_receive(:local_sha).and_return("local")
|
31
|
+
|
32
|
+
cmd = "git log --pretty=format:' %h %<(20)%an %ar\t %s' -10 remote..local"
|
33
|
+
deploy.should_receive(:execute).with(cmd)
|
34
|
+
|
35
|
+
deploy.diff
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#up_to_date' do
|
40
|
+
it 'returns true when shas match' do
|
41
|
+
deploy.should_receive(:remote_sha).and_return("same")
|
42
|
+
deploy.should_receive(:local_sha).and_return("same")
|
43
|
+
expect(deploy.up_to_date).to be_true
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns true when shas differ' do
|
47
|
+
deploy.should_receive(:remote_sha).and_return("remote")
|
48
|
+
deploy.should_receive(:local_sha).and_return("local")
|
49
|
+
expect(deploy.up_to_date).to be_false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: depl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Nutt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: highline
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colorize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.5'
|
55
|
+
description: Separate out the deployment concerns from your application by using depl
|
56
|
+
to write your latest deployed git hash to s3. Then let your provisioning system
|
57
|
+
(for instance, chef + deploy_revision provider) take care of actually deploying
|
58
|
+
new code. depl shows diffs between your current branch and the deployed revision.
|
59
|
+
email:
|
60
|
+
- michael@movableink.com
|
61
|
+
executables:
|
62
|
+
- depl
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files: []
|
65
|
+
files:
|
66
|
+
- ".gitignore"
|
67
|
+
- LICENSE.md
|
68
|
+
- README.md
|
69
|
+
- Rakefile
|
70
|
+
- bin/depl
|
71
|
+
- depl.gemspec
|
72
|
+
- lib/depl.rb
|
73
|
+
- lib/depl/main.rb
|
74
|
+
- lib/depl/remote.rb
|
75
|
+
- lib/depl/version.rb
|
76
|
+
- spec/depl/main_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
homepage: https://github.com/movableink/depl
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 2.4.8
|
99
|
+
signing_key:
|
100
|
+
specification_version: 4
|
101
|
+
summary: Writes project deployment hash to s3 file
|
102
|
+
test_files:
|
103
|
+
- spec/depl/main_spec.rb
|
104
|
+
- spec/spec_helper.rb
|