deployment 0.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,2 @@
1
- require "deployment/version"
2
-
3
1
  module Deployment
4
- # Your code goes here...
5
2
  end
@@ -0,0 +1,156 @@
1
+ Capistrano::Configuration.instance(:must_exist).load do
2
+
3
+ ## Define the roles
4
+ role :app
5
+ role :storage
6
+
7
+ ## Server configuration
8
+ set :user, `whoami`.chomp
9
+ set :ssh_options, {:forward_agent => true, :port => 22}
10
+
11
+ ## Set the `current_revision`
12
+ set(:current_revision) { capture("cd #{deploy_to} && git log --pretty=%H -n 1", :except => { :no_release => true }).chomp }
13
+
14
+ ## Return the deployment path
15
+ def deploy_to
16
+ fetch(:deploy_to, nil) || "/opt/apps/#{fetch(:application)}"
17
+ end
18
+
19
+ ## Return an array of all environments which should be deployed
20
+ def environments
21
+ fetch(:environments, nil) || [fetch(:environment, 'production')]
22
+ end
23
+
24
+ ## Deployment namespace
25
+ namespace :deploy do
26
+ desc 'Deploy the latest revision of the application'
27
+ task :default do
28
+ update_code
29
+ restart
30
+ end
31
+
32
+ desc 'Deploy and migrate the database before restart'
33
+ task :migrations do
34
+ set :run_migrations, true
35
+ default
36
+ end
37
+
38
+ task :update_code, :roles => [:app, :storage] do
39
+ ## Create a branch for previous (pre-deployment)
40
+ run "cd #{deploy_to} && git branch -d rollback && git branch rollback"
41
+ ## Update remote repository and merge deploy branch into current branch
42
+ run "cd #{deploy_to} && git fetch origin && git reset --hard origin/#{fetch(:branch)}"
43
+ finalise
44
+ end
45
+
46
+ task :finalise, :roles => [:app, :storage] do
47
+ execute = Array.new
48
+ execute << "cd #{deploy_to}"
49
+ execute << "git submodule init"
50
+ execute << "git submodule sync"
51
+ execute << "git submodule update --recursive"
52
+ run execute.join(' && ')
53
+
54
+ run "cd #{deploy_to} && bundle --deployment --quiet"
55
+ migrate if fetch(:run_migrations, false)
56
+ end
57
+
58
+ desc 'Setup the repository on the remote server for the first time'
59
+ task :setup, :roles => [:app, :storage] do
60
+ run "rm -rf #{deploy_to}"
61
+ run "git clone -n #{fetch(:repository)} #{deploy_to} --branch #{fetch(:branch)}"
62
+ run "cd #{deploy_to} && git branch rollback && git checkout -b deploy && git branch -d #{fetch(:branch)}"
63
+ upload_db_config
64
+ update_code
65
+ end
66
+
67
+ desc 'Upload the database configuration file'
68
+ task :upload_db_config, :roles => [:app, :storage] do
69
+ put "production:\n adapter: mysql2\n encoding: utf8\n reconnect: true\n database: #{fetch(:application, 'databasename')}\n pool: 5\n username: #{fetch(:application, 'dbusernmae')}\n password: #{ENV['DBPASS'] || 'xxxx'}\n host: #{fetch(:database_host, 'db-a-vip.cloud.atechmedia.net')}\n", File.join(deploy_to, 'config', 'database.yml')
70
+ end
71
+ end
72
+
73
+ ## ==================================================================
74
+ ## Database
75
+ ## ==================================================================
76
+ desc 'Run database migrations on the remote'
77
+ task :migrate, :roles => :app, :only => {:database_ops => true} do
78
+ for environment in environments
79
+ run "cd #{deploy_to} && RAILS_ENV=#{environment} bundle exec rake db:migrate"
80
+ end
81
+ end
82
+
83
+ ## ==================================================================
84
+ ## Rollback
85
+ ## ==================================================================
86
+ desc 'Rollback to the previous deployment'
87
+ task :rollback, :roles => [:app, :storage] do
88
+ run "cd #{deploy_to} && git reset --hard rollback"
89
+ deploy.finalise
90
+ deploy.restart
91
+ end
92
+
93
+ ## ==================================================================
94
+ ## Test
95
+ ## ==================================================================
96
+ desc 'Test the deployment connection'
97
+ task :testing do
98
+ run "whoami"
99
+ end
100
+
101
+ ## ==================================================================
102
+ ## init
103
+ ## ==================================================================
104
+ desc 'Restart the whole remote application'
105
+ task :restart, :roles => :app do
106
+ unicorn.restart unless fetch(:skip_unicorn, false)
107
+ workers.restart if respond_to?(:workers)
108
+ end
109
+
110
+ desc 'Stop the whole remote application'
111
+ task :stop, :roles => :app do
112
+ unicorn.stop unless fetch(:skip_unicorn, false)
113
+ workers.stop if respond_to?(:workers)
114
+ end
115
+
116
+ desc 'Start the whole remote application'
117
+ task :start, :roles => :app do
118
+ unicorn.start unless fetch(:skip_unicorn, false)
119
+ workers.start if respond_to?(:workers)
120
+ end
121
+
122
+ ## ==================================================================
123
+ ## Unicorn Management
124
+ ## ==================================================================
125
+ namespace :unicorn do
126
+ task :start, :roles => :app do
127
+ upload_config
128
+ for environment in environments
129
+ run "sudo -u app sh -c \"umask 002 && cd #{deploy_to} && bundle exec unicorn_rails -E #{environment} -c #{deploy_to}/config/unicorn.rb -D\""
130
+ end
131
+ end
132
+
133
+ task :stop, :roles => :app do
134
+ for environment in environments
135
+ run "sudo -u app sh -c \"kill `cat #{deploy_to}/tmp/pids/unicorn.#{environment}.pid`\""
136
+ end
137
+ end
138
+
139
+ task :restart, :roles => :app do
140
+ upload_config
141
+ for environment in environments
142
+ run "sudo -u app sh -c \"kill -USR2 `cat #{deploy_to}/tmp/pids/unicorn.#{environment}.pid`\""
143
+ end
144
+ end
145
+
146
+ task :upload_config, :roles => :app do
147
+ unless fetch(:skip_unicorn_config, false)
148
+ template_config = File.read(File.expand_path('../unicorn.rb', __FILE__))
149
+ template_config.gsub!('$WORKER_PROCESSES', fetch(:unicorn_workers, 4).to_s)
150
+ template_config.gsub!('$TIMEOUT', fetch(:unicorn_timeout, 30).to_s)
151
+ put template_config, File.join(deploy_to, 'config', 'unicorn.rb')
152
+ end
153
+ end
154
+ end
155
+
156
+ end
@@ -0,0 +1,53 @@
1
+ rails_env = ENV['RAILS_ENV'] || 'production'
2
+
3
+ ## Directory to use for stuff
4
+ rails_root = File.expand_path('../../', __FILE__)
5
+ FileUtils.mkdir_p(File.join(rails_root, 'tmp', 'sockets'))
6
+ FileUtils.mkdir_p(File.join(rails_root, 'tmp', 'pids'))
7
+ FileUtils.mkdir_p(File.join(rails_root, 'log'))
8
+
9
+ ## Set the number of worker processes which can be spawned
10
+ worker_processes $WORKER_PROCESSES
11
+
12
+ ## Preload the application into master for fast worker spawn
13
+ ## times.
14
+ preload_app true
15
+
16
+ ## Restart any workers which haven't responded for 30 seconds.
17
+ timeout $TIMEOUT
18
+
19
+ ## Store the pid file safely away in the pids folder
20
+ logger Logger.new(File.join(rails_root, 'log', "unicorn.#{rails_env}.log"))
21
+ pid File.join(rails_root, 'tmp', 'pids', "unicorn.#{rails_env}.pid")
22
+
23
+ ## Listen on a unix data socket
24
+ listen File.join(rails_root, 'tmp', 'sockets', "unicorn.#{rails_env}.sock")
25
+
26
+ before_fork do |server, worker|
27
+ # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
28
+ # immediately start loading up a new version of itself (loaded with a new
29
+ # version of our app). When this new Unicorn is completely loaded
30
+ # it will begin spawning workers. The first worker spawned will check to
31
+ # see if an .oldbin pidfile exists. If so, this means we've just booted up
32
+ # a new Unicorn and need to tell the old one that it can now die. To do so
33
+ # we send it a QUIT.
34
+ #
35
+ # Using this method we get 0 downtime deploys.
36
+
37
+ old_pid = File.join(rails_root, 'tmp', 'pids', "unicorn.#{rails_env}.pid.oldbin")
38
+ if File.exists?(old_pid) && server.pid != old_pid
39
+ begin
40
+ Process.kill("QUIT", File.read(old_pid).to_i)
41
+ rescue Errno::ENOENT, Errno::ESRCH
42
+ # someone else did our job for us
43
+ end
44
+ end
45
+ end
46
+
47
+ after_fork do |server, worker|
48
+ # Unicorn master loads the app then forks off workers - because of the way
49
+ # Unix forking works, we need to make sure we aren't using any of the parent's
50
+ # sockets, e.g. db connection
51
+ ActiveRecord::Base.establish_connection
52
+ srand
53
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deployment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,24 +9,18 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-22 00:00:00.000000000 Z
12
+ date: 2013-01-29 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: Gem to make deployments with Capistrano easier.
15
- email:
16
- - danq@atechmedia.com
14
+ description:
15
+ email: danq@keeptrack.co
17
16
  executables: []
18
17
  extensions: []
19
18
  extra_rdoc_files: []
20
19
  files:
21
- - .gitignore
22
- - Gemfile
23
- - LICENSE.txt
24
- - README.md
25
- - Rakefile
26
- - deployment.gemspec
20
+ - lib/deployment/deploy.rb
21
+ - lib/deployment/unicorn.rb
27
22
  - lib/deployment.rb
28
- - lib/deployment/version.rb
29
- homepage: ''
23
+ homepage: http://keeptrack.co
30
24
  licenses: []
31
25
  post_install_message:
32
26
  rdoc_options: []
@@ -49,5 +43,5 @@ rubyforge_project:
49
43
  rubygems_version: 1.8.23
50
44
  signing_key:
51
45
  specification_version: 3
52
- summary: Placeholder for now.
46
+ summary: Gem to make deployments with Capistrano easier.
53
47
  test_files: []
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in deployment.gemspec
4
- gemspec
@@ -1,22 +0,0 @@
1
- Copyright (c) 2013 Dan Quinney
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 DELETED
@@ -1,29 +0,0 @@
1
- # Deployment
2
-
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'deployment'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install deployment
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
data/Rakefile DELETED
@@ -1 +0,0 @@
1
- require "bundler/gem_tasks"
@@ -1,19 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'deployment/version'
5
-
6
- Gem::Specification.new do |gem|
7
- gem.name = "deployment"
8
- gem.version = Deployment::VERSION
9
- gem.authors = ["Dan Quinney"]
10
- gem.email = ["danq@atechmedia.com"]
11
- gem.description = "Gem to make deployments with Capistrano easier."
12
- gem.summary = "Placeholder for now."
13
- gem.homepage = ""
14
-
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ["lib"]
19
- end
@@ -1,3 +0,0 @@
1
- module Deployment
2
- VERSION = "0.0.2"
3
- end