phase 0.0.17 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/phase/cli/build.rb +2 -3
- data/lib/phase/cli/ssh.rb +10 -3
- data/lib/phase/config/deploy.rb +6 -0
- data/lib/phase/kit/deploy/build.rb +64 -17
- data/lib/phase/util/console.rb +0 -1
- data/lib/phase/util/shell.rb +10 -3
- data/lib/phase/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9418e0cabac33009818c8d089c896b5b4cb81004
|
4
|
+
data.tar.gz: b7346fdc18bcad141314d0e96247e6bb9e3aaf55
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94f9716929b4f0b402104f6c9012300664dde3c1e35df93bd914aa84ed4fbd236f59534f062648a56bc768e745369ea0d3ea0fefcd8dd6aeaaa8ee7eb1860026
|
7
|
+
data.tar.gz: 15248f3be2d0e843db4f9778421715204d965af8d1822113f104aea05f081c7304808f96e0d95a6d9221084aeaba267baf8a885064ba8d592b0fa89726da372f
|
data/lib/phase/cli/build.rb
CHANGED
@@ -27,9 +27,8 @@ module Phase
|
|
27
27
|
|
28
28
|
def run
|
29
29
|
version_number = get_next_version_number
|
30
|
-
::Phase::Deploy::Version.update(version_number) if clean_build
|
31
30
|
|
32
|
-
build = ::Phase::Deploy::Build.new(version_number,
|
31
|
+
build = ::Phase::Deploy::Build.new(version_number, clean_build: clean_build)
|
33
32
|
build.execute!
|
34
33
|
end
|
35
34
|
|
@@ -41,7 +40,7 @@ module Phase
|
|
41
40
|
log "Last release was version #{ current_version.magenta }." if current_version
|
42
41
|
|
43
42
|
input = ask "New version number:"
|
44
|
-
fail "
|
43
|
+
fail "Version number is required" if input.blank?
|
45
44
|
input
|
46
45
|
end
|
47
46
|
|
data/lib/phase/cli/ssh.rb
CHANGED
@@ -2,7 +2,7 @@ module Phase
|
|
2
2
|
module CLI
|
3
3
|
class SSH < Command
|
4
4
|
command :ssh do |c|
|
5
|
-
c.syntax = "phase ssh [-i instance_id] [-n instance_name] [-r instance_role] [-u user] [-c conn_str] [username@instance_name|instance_id]"
|
5
|
+
c.syntax = "phase ssh [-i instance_id] [-n instance_name] [-r instance_role] [-u user] [-c conn_str] [username@instance_name|instance_id] [command...]"
|
6
6
|
|
7
7
|
c.option "-i", "--id instance_id", String, "Connects to the instance with this ID."
|
8
8
|
c.option "-n", "--name instance_name", String, "Connects to the instance with this 'Name' tag."
|
@@ -21,8 +21,15 @@ module Phase
|
|
21
21
|
|
22
22
|
def run
|
23
23
|
parse_connection_string
|
24
|
-
|
25
|
-
|
24
|
+
ssh_command = args.last if args.count > 1
|
25
|
+
|
26
|
+
if ssh_command
|
27
|
+
log "running on instance #{ instance.resource.id }: `#{ ssh_command }'"
|
28
|
+
exec "#{ options.conn } #{ username }@#{ instance.resource.dns_name } #{ ssh_command }"
|
29
|
+
else
|
30
|
+
log "connecting to instance #{ instance.resource.id }..."
|
31
|
+
exec "#{ options.conn } #{ username }@#{ instance.resource.dns_name }"
|
32
|
+
end
|
26
33
|
end
|
27
34
|
|
28
35
|
private
|
data/lib/phase/config/deploy.rb
CHANGED
@@ -19,6 +19,12 @@ module Phase
|
|
19
19
|
attr_accessor :version_lockfile
|
20
20
|
|
21
21
|
|
22
|
+
# @return [String] the cloud storage bucket ("directory") for storing compiled assets
|
23
|
+
# @example Sample settings
|
24
|
+
# config.deploy.docker_repository = "static-assets"
|
25
|
+
attr_accessor :asset_bucket
|
26
|
+
|
27
|
+
|
22
28
|
def initialize
|
23
29
|
@environments = []
|
24
30
|
@version_lockfile = "VERSION"
|
@@ -4,13 +4,13 @@ module Phase
|
|
4
4
|
class Build
|
5
5
|
include ::Phase::Util::Shell
|
6
6
|
|
7
|
-
attr_reader :build_dir, :
|
7
|
+
attr_reader :build_dir, :clean_build, :version_tag
|
8
8
|
|
9
9
|
def initialize(version_tag, options = {})
|
10
|
-
@
|
10
|
+
@clean_build = options.fetch(:clean_build, true)
|
11
11
|
@version_tag = version_tag
|
12
12
|
|
13
|
-
if
|
13
|
+
if clean_build
|
14
14
|
@build_dir = ::Pathname.new( options.fetch(:build_dir, "build") )
|
15
15
|
else
|
16
16
|
@build_dir = ::Pathname.new(".")
|
@@ -18,29 +18,45 @@ module Phase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def execute!
|
21
|
-
|
21
|
+
prepare_environment
|
22
|
+
build_assets
|
23
|
+
commit_new_version!
|
22
24
|
build_image
|
23
|
-
# tag_image
|
24
25
|
push
|
25
26
|
end
|
26
27
|
|
27
28
|
private
|
28
29
|
|
30
|
+
def build_assets
|
31
|
+
precompile_assets
|
32
|
+
sync_assets
|
33
|
+
end
|
34
|
+
|
29
35
|
def build_image
|
30
|
-
prepare_clean_build if
|
36
|
+
prepare_clean_build if clean_build
|
31
37
|
|
32
|
-
shell("docker build -t #{
|
38
|
+
shell("docker build -t #{docker_repo}:#{version_tag} #{build_dir}") do |status|
|
33
39
|
fail "Couldn't build Docker image"
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
37
|
-
def
|
43
|
+
def commit_new_version!
|
44
|
+
::Phase::Deploy::Version.update(version_tag)
|
45
|
+
shell("git add -f public/assets/*manifest* #{::Phase.config.deploy.version_lockfile}", allow_failure: true)
|
46
|
+
shell("git commit -m 'Built v#{version_tag}'", allow_failure: true)
|
47
|
+
end
|
48
|
+
|
49
|
+
def prepare_environment
|
50
|
+
raise_on_dirty_index!
|
51
|
+
|
38
52
|
shell("docker ps > /dev/null 2>&1") do |status|
|
39
53
|
fail <<-EOS.strip_heredoc
|
40
54
|
Docker isn't responding. Is boot2docker running? Try:
|
41
55
|
boot2docker start && $(boot2docker shellinit)
|
42
56
|
EOS
|
43
57
|
end
|
58
|
+
|
59
|
+
pull_latest_build
|
44
60
|
end
|
45
61
|
|
46
62
|
def clone_local_git_repo
|
@@ -50,40 +66,62 @@ module Phase
|
|
50
66
|
end
|
51
67
|
end
|
52
68
|
|
69
|
+
def docker_repo
|
70
|
+
::Phase.config.deploy.docker_repository
|
71
|
+
end
|
72
|
+
|
53
73
|
def last_committed_mtime_for_file(file_path)
|
54
74
|
rev_hash = `git rev-list HEAD "#{file_path}" | head -n 1`.chomp
|
55
75
|
time_str = `git show --pretty=format:%ai --abbrev-commit #{rev_hash} | head -n 1`.chomp
|
56
76
|
::DateTime.parse(time_str).to_time
|
57
77
|
end
|
58
78
|
|
79
|
+
# FIXME: This approach isn't ideal because it compiles assets in the *working* git
|
80
|
+
# directory rather than building in a clean, committed environment. This could lead
|
81
|
+
# to errors in the compiled assets.
|
82
|
+
def precompile_assets
|
83
|
+
shell("RAILS_GROUPS=assets rake assets:precompile") do |status|
|
84
|
+
fail "Couldn't precompile assets"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
59
88
|
def prepare_clean_build
|
60
89
|
remove_stale_build_dir!
|
61
90
|
clone_local_git_repo
|
62
91
|
set_file_modification_timestamps
|
63
92
|
end
|
64
93
|
|
94
|
+
# This needs to run *before* the version gets updated so we know which version
|
95
|
+
# number to pull from the registry.
|
96
|
+
def pull_latest_build
|
97
|
+
shell("docker pull #{docker_repo}:#{::Phase::Deploy::Version.current}")
|
98
|
+
end
|
99
|
+
|
65
100
|
def push
|
66
|
-
shell("docker push #{
|
67
|
-
fail "Couldn't push #{
|
101
|
+
shell("docker push #{docker_repo}:#{version_tag}") do |status|
|
102
|
+
fail "Couldn't push #{docker_repo}:#{version_tag}"
|
68
103
|
end
|
69
104
|
end
|
70
105
|
|
71
|
-
def
|
72
|
-
|
106
|
+
def raise_on_dirty_index!
|
107
|
+
shell('git diff-index --quiet --cached HEAD') do |status|
|
108
|
+
fail "Other changes are already staged. Commit or stash them first"
|
109
|
+
end
|
73
110
|
end
|
74
111
|
|
75
|
-
def
|
76
|
-
::
|
112
|
+
def remove_stale_build_dir!
|
113
|
+
::FileUtils.rm_rf(build_dir)
|
77
114
|
end
|
78
115
|
|
79
116
|
def set_file_modification_timestamps
|
80
|
-
log
|
117
|
+
log("Preparing docker cache...")
|
81
118
|
|
119
|
+
# Threadsafe queue for multiple threads to pull from
|
82
120
|
queue = ::Queue.new
|
83
121
|
|
84
122
|
::FileUtils.cd(build_dir) do
|
85
|
-
# Sets consistent mtime on directories because docker cares about that
|
86
|
-
|
123
|
+
# Sets consistent mtime on directories because docker cares about that too
|
124
|
+
shell("find . -type d | xargs touch -t 7805200000")
|
87
125
|
|
88
126
|
files = `git ls-files`.split
|
89
127
|
files.each { |f| queue.push(f) }
|
@@ -106,6 +144,15 @@ module Phase
|
|
106
144
|
bar.finish
|
107
145
|
end
|
108
146
|
end
|
147
|
+
|
148
|
+
def sync_assets
|
149
|
+
bucket = ::Phase.config.deploy.asset_bucket
|
150
|
+
return log("Set `deploy.asset_bucket` in Phasefile to enable asset syncing") if bucket.blank?
|
151
|
+
|
152
|
+
shell("RAILS_GROUPS=assets FOG_DIRECTORY=#{bucket} rake assets:sync") do |status|
|
153
|
+
fail "Couldn't sync assets to The Clouds"
|
154
|
+
end
|
155
|
+
end
|
109
156
|
end
|
110
157
|
|
111
158
|
end
|
data/lib/phase/util/console.rb
CHANGED
data/lib/phase/util/shell.rb
CHANGED
@@ -4,10 +4,17 @@ module Phase
|
|
4
4
|
include Console
|
5
5
|
|
6
6
|
def shell(*args)
|
7
|
+
options = args.extract_options!
|
8
|
+
options.reverse_merge({
|
9
|
+
allow_failure: false
|
10
|
+
})
|
11
|
+
|
7
12
|
log "running: #{args.join(' ')}"
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
succeeded = !!system(*args) || options[:allow_failure]
|
14
|
+
|
15
|
+
yield $? unless succeeded
|
16
|
+
|
17
|
+
succeeded
|
11
18
|
end
|
12
19
|
|
13
20
|
end
|
data/lib/phase/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 1.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piers Mainwaring
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-06-
|
12
|
+
date: 2015-06-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: commander
|
@@ -256,9 +256,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
256
256
|
version: '2.0'
|
257
257
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
258
258
|
requirements:
|
259
|
-
- - "
|
259
|
+
- - ">"
|
260
260
|
- !ruby/object:Gem::Version
|
261
|
-
version:
|
261
|
+
version: 1.3.1
|
262
262
|
requirements: []
|
263
263
|
rubyforge_project:
|
264
264
|
rubygems_version: 2.2.3
|