recap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in recap.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Tom Ward
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ [recap](http://github.com/freerange/recap) is a simple, EXPERIMENTAL, opinionated set of capistrano deployment recipes, using git's strengths to deploy applications in a fast and simple manner.
2
+
3
+ It started as a playaround with git, and is slowly evolving into something useful (though it isn't there) yet. There are lots of gaps, and half-thought-through ideas. Also, it needs a proper name.
4
+
5
+ The main documentation can be found at [http://code.gofreerange.com/recap](http://code.gofreerange.com/recap), while the code is available [on github](https://github.com/freerange/recap) and released under the [MIT License](https://github.com/freerange/recap/blob/master/LICENSE).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rocco/tasks'
3
+
4
+ desc 'build docs'
5
+ Rocco::Task.new :rocco, 'doc/', ['index.rb', 'lib/**/*.rb']
6
+
7
+ desc 'publish docs'
8
+ task :publish do
9
+ sha = `git ls-tree -d HEAD doc | awk '{print $3}'`.strip
10
+ commit = `echo "Publishing docs from master branch" | git commit-tree #{sha} -p refs/heads/gh-pages`.strip
11
+ `git update-ref refs/heads/gh-pages #{commit}`
12
+ end
@@ -0,0 +1,3 @@
1
+ require 'recap/cli'
2
+ Recap::CLI.start
3
+
data/doc/index.html ADDED
@@ -0,0 +1,216 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
+ <title>index.rb</title>
6
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
+ </head>
8
+ <body>
9
+ <div id='container'>
10
+ <div id="background"></div>
11
+ <div id="jump_to">
12
+ Jump To &hellip;
13
+ <div id="jump_wrapper">
14
+ <div id="jump_page">
15
+ <a class="source" href="index.html">index.rb</a>
16
+ <a class="source" href="lib/recap/bundler.html">bundler.rb</a>
17
+ <a class="source" href="lib/recap/capistrano_extensions.html">capistrano_extensions.rb</a>
18
+ <a class="source" href="lib/recap/cli.html">cli.rb</a>
19
+ <a class="source" href="lib/recap/compatibility.html">compatibility.rb</a>
20
+ <a class="source" href="lib/recap/deploy.html">deploy.rb</a>
21
+ <a class="source" href="lib/recap/env.html">env.rb</a>
22
+ <a class="source" href="lib/recap/foreman.html">foreman.rb</a>
23
+ <a class="source" href="lib/recap/preflight.html">preflight.rb</a>
24
+ <a class="source" href="lib/recap/rails.html">rails.rb</a>
25
+ <a class="source" href="lib/recap/version.html">version.rb</a>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ <table cellspacing=0 cellpadding=0>
30
+ <thead>
31
+ <tr>
32
+ <th class=docs><h1>index.rb</h1></th>
33
+ <th class=code></th>
34
+ </tr>
35
+ </thead>
36
+ <tbody>
37
+ <tr id='section-1'>
38
+ <td class=docs>
39
+ <div class="pilwrap">
40
+ <a class="pilcrow" href="#section-1">&#182;</a>
41
+ </div>
42
+ <p>This is the annotated source code and documentation for
43
+ <a href="http://github.com/freerange/recap">recap</a>, a simple, opinionated set of capistrano
44
+ deployment recipes. Inspired by
45
+ <a href="https://github.com/blog/470-deployment-script-spring-cleaning">this blog post</a>, these recipes use
46
+ git&rsquo;s strengths to deploy applications in a faster, simpler manner than a standard capistrano
47
+ deployment. Using git to manage release versions means apps can be deployed to a single directory.
48
+ There&rsquo;s no need for <code>releases</code>, <code>shared</code> or <code>current</code> folders, and no symlinking.</p>
49
+ </td>
50
+ <td class=code>
51
+ <div class='highlight'><pre></pre></div>
52
+ </td>
53
+ </tr>
54
+ <tr id='section-Goals'>
55
+ <td class=docs>
56
+ <div class="pilwrap">
57
+ <a class="pilcrow" href="#section-Goals">&#182;</a>
58
+ </div>
59
+ <h3>Goals</h3>
60
+ </td>
61
+ <td class=code>
62
+ <div class='highlight'><pre></pre></div>
63
+ </td>
64
+ </tr>
65
+ <tr id='section-3'>
66
+ <td class=docs>
67
+ <div class="pilwrap">
68
+ <a class="pilcrow" href="#section-3">&#182;</a>
69
+ </div>
70
+ <p>These deployment recipes try to do the following:</p>
71
+ </td>
72
+ <td class=code>
73
+ <div class='highlight'><pre></pre></div>
74
+ </td>
75
+ </tr>
76
+ <tr id='section-4'>
77
+ <td class=docs>
78
+ <div class="pilwrap">
79
+ <a class="pilcrow" href="#section-4">&#182;</a>
80
+ </div>
81
+ <p>Run all commands as the <code>application_user</code>, loading the full user environment. The only
82
+ exceptions are <code>git</code> commands (which often rely on SSH agent forwarding for authentication), and anything
83
+ that requires <code>sudo</code>.</p>
84
+ </td>
85
+ <td class=code>
86
+ <div class='highlight'><pre></pre></div>
87
+ </td>
88
+ </tr>
89
+ <tr id='section-5'>
90
+ <td class=docs>
91
+ <div class="pilwrap">
92
+ <a class="pilcrow" href="#section-5">&#182;</a>
93
+ </div>
94
+ <p>Use <code>git</code> to avoid unecessary work. If the <code>Gemfile.lock</code> hasn&rsquo;t changed, there&rsquo;s no need to run
95
+ <code>bundle install</code>. Similarly if there are no new migrations, why do <code>rake db:migrate</code>. Faster deploys
96
+ mean more frequent deploys, which in our experience leads to better applications.</p>
97
+ </td>
98
+ <td class=code>
99
+ <div class='highlight'><pre></pre></div>
100
+ </td>
101
+ </tr>
102
+ <tr id='section-6'>
103
+ <td class=docs>
104
+ <div class="pilwrap">
105
+ <a class="pilcrow" href="#section-6">&#182;</a>
106
+ </div>
107
+ <p>Avoid the use of <code>sudo</code> (other than to change to the <code>application_user</code>). As much as possible, <code>sudo</code>
108
+ is only used to <code>su</code> to the <code>application_user</code> before running a command. To avoid typing a password
109
+ to perform the majority of deployment tasks, this code can be added to
110
+ <code>/etc/sudoers.d/application</code> (change <code>application</code> to the name of your app).</p>
111
+ </td>
112
+ <td class=code>
113
+ <div class='highlight'><pre><span class="o">%</span><span class="n">application</span> <span class="no">ALL</span><span class="o">=</span><span class="no">NOPASSWD</span><span class="p">:</span><span class="sr"> /sbin/s</span><span class="n">tart</span> <span class="n">application</span><span class="o">*</span>
114
+ <span class="o">%</span><span class="n">application</span> <span class="no">ALL</span><span class="o">=</span><span class="no">NOPASSWD</span><span class="p">:</span><span class="sr"> /sbin/s</span><span class="n">top</span> <span class="n">application</span><span class="o">*</span>
115
+ <span class="o">%</span><span class="n">application</span> <span class="no">ALL</span><span class="o">=</span><span class="no">NOPASSWD</span><span class="p">:</span><span class="sr"> /sbin/</span><span class="n">restart</span> <span class="n">application</span><span class="o">*</span>
116
+ <span class="o">%</span><span class="n">application</span> <span class="no">ALL</span><span class="o">=</span><span class="no">NOPASSWD</span><span class="p">:</span><span class="sr"> /bin/su</span> <span class="o">-</span> <span class="n">application</span><span class="o">*</span>
117
+ <span class="o">%</span><span class="n">application</span> <span class="no">ALL</span><span class="o">=</span><span class="no">NOPASSWD</span><span class="p">:</span><span class="sr"> /bin/su</span> <span class="n">application</span><span class="o">*</span></pre></div>
118
+ </td>
119
+ </tr>
120
+ <tr id='section-Code_layout'>
121
+ <td class=docs>
122
+ <div class="pilwrap">
123
+ <a class="pilcrow" href="#section-Code_layout">&#182;</a>
124
+ </div>
125
+ <h3>Code layout</h3>
126
+ </td>
127
+ <td class=code>
128
+ <div class='highlight'><pre></pre></div>
129
+ </td>
130
+ </tr>
131
+ <tr id='section-8'>
132
+ <td class=docs>
133
+ <div class="pilwrap">
134
+ <a class="pilcrow" href="#section-8">&#182;</a>
135
+ </div>
136
+ <p>The main deployment tasks are defined in <a href="lib/recap.html">recap.rb</a>. Automatic
137
+ checks to ensure servers are correctly setup are in
138
+ <a href="lib/recap/preflight.html">recap/preflight.rb</a>.</p>
139
+ </td>
140
+ <td class=code>
141
+ <div class='highlight'><pre></pre></div>
142
+ </td>
143
+ </tr>
144
+ <tr id='section-9'>
145
+ <td class=docs>
146
+ <div class="pilwrap">
147
+ <a class="pilcrow" href="#section-9">&#182;</a>
148
+ </div>
149
+ <p>In addition, there are extensions for <a href="lib/recap/bundler.html">bundler</a> and
150
+ <a href="lib/recap/foreman.html">foreman</a>.</p>
151
+ </td>
152
+ <td class=code>
153
+ <div class='highlight'><pre></pre></div>
154
+ </td>
155
+ </tr>
156
+ <tr id='section-10'>
157
+ <td class=docs>
158
+ <div class="pilwrap">
159
+ <a class="pilcrow" href="#section-10">&#182;</a>
160
+ </div>
161
+ <p>For (limited) compatability with other existing recipes, see
162
+ <a href="lib/recap/compatibility.html">compatibility</a></p>
163
+ </td>
164
+ <td class=code>
165
+ <div class='highlight'><pre></pre></div>
166
+ </td>
167
+ </tr>
168
+ <tr id='section-Deployment_target'>
169
+ <td class=docs>
170
+ <div class="pilwrap">
171
+ <a class="pilcrow" href="#section-Deployment_target">&#182;</a>
172
+ </div>
173
+ <h3>Deployment target</h3>
174
+ </td>
175
+ <td class=code>
176
+ <div class='highlight'><pre></pre></div>
177
+ </td>
178
+ </tr>
179
+ <tr id='section-12'>
180
+ <td class=docs>
181
+ <div class="pilwrap">
182
+ <a class="pilcrow" href="#section-12">&#182;</a>
183
+ </div>
184
+ <p>These recipes have been run successful against Ubuntu.</p>
185
+ </td>
186
+ <td class=code>
187
+ <div class='highlight'><pre></pre></div>
188
+ </td>
189
+ </tr>
190
+ <tr id='section-13'>
191
+ <td class=docs>
192
+ <div class="pilwrap">
193
+ <a class="pilcrow" href="#section-13">&#182;</a>
194
+ </div>
195
+ <p>The application should be run as the application user; if using Apache and Passenger, you should set the <code>PassengerDefaultUser</code> directive to be the same as the <code>application_user</code>.</p>
196
+ </td>
197
+ <td class=code>
198
+ <div class='highlight'><pre></pre></div>
199
+ </td>
200
+ </tr>
201
+ <tr id='section-14'>
202
+ <td class=docs>
203
+ <div class="pilwrap">
204
+ <a class="pilcrow" href="#section-14">&#182;</a>
205
+ </div>
206
+ <p>The code is available <a href="http://github.com/freerange/recap">on github</a> and released under the
207
+ <a href="https://github.com/freerange/recap/blob/master/LICENSE">MIT License</a></p>
208
+
209
+ </td>
210
+ <td class=code>
211
+ <div class='highlight'><pre></pre></div>
212
+ </td>
213
+ </tr>
214
+ </table>
215
+ </div>
216
+ </body>
@@ -0,0 +1,151 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
+ <title>bundler.rb</title>
6
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
+ </head>
8
+ <body>
9
+ <div id='container'>
10
+ <div id="background"></div>
11
+ <div id="jump_to">
12
+ Jump To &hellip;
13
+ <div id="jump_wrapper">
14
+ <div id="jump_page">
15
+ <a class="source" href="../../index.html">index.rb</a>
16
+ <a class="source" href="bundler.html">bundler.rb</a>
17
+ <a class="source" href="capistrano_extensions.html">capistrano_extensions.rb</a>
18
+ <a class="source" href="cli.html">cli.rb</a>
19
+ <a class="source" href="compatibility.html">compatibility.rb</a>
20
+ <a class="source" href="deploy.html">deploy.rb</a>
21
+ <a class="source" href="env.html">env.rb</a>
22
+ <a class="source" href="foreman.html">foreman.rb</a>
23
+ <a class="source" href="preflight.html">preflight.rb</a>
24
+ <a class="source" href="rails.html">rails.rb</a>
25
+ <a class="source" href="version.html">version.rb</a>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ <table cellspacing=0 cellpadding=0>
30
+ <thead>
31
+ <tr>
32
+ <th class=docs><h1>bundler.rb</h1></th>
33
+ <th class=code></th>
34
+ </tr>
35
+ </thead>
36
+ <tbody>
37
+ <tr id='section-1'>
38
+ <td class=docs>
39
+ <div class="pilwrap">
40
+ <a class="pilcrow" href="#section-1">&#182;</a>
41
+ </div>
42
+ <p>The bundler recipe ensures that the application bundle is installed whenever the code is updated.</p>
43
+ </td>
44
+ <td class=code>
45
+ <div class='highlight'><pre><span class="no">Capistrano</span><span class="o">::</span><span class="no">Configuration</span><span class="o">.</span><span class="n">instance</span><span class="p">(</span><span class="ss">:must_exist</span><span class="p">)</span><span class="o">.</span><span class="n">load</span> <span class="k">do</span></pre></div>
46
+ </td>
47
+ </tr>
48
+ <tr id='section-2'>
49
+ <td class=docs>
50
+ <div class="pilwrap">
51
+ <a class="pilcrow" href="#section-2">&#182;</a>
52
+ </div>
53
+ <p>Each bundle is declared in a <code>Gemfile</code>, by default in the root of the application directory</p>
54
+ </td>
55
+ <td class=code>
56
+ <div class='highlight'><pre> <span class="n">set</span><span class="p">(</span><span class="ss">:bundle_gemfile</span><span class="p">)</span> <span class="p">{</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">deploy_to</span><span class="si">}</span><span class="s2">/Gemfile&quot;</span> <span class="p">}</span></pre></div>
57
+ </td>
58
+ </tr>
59
+ <tr id='section-3'>
60
+ <td class=docs>
61
+ <div class="pilwrap">
62
+ <a class="pilcrow" href="#section-3">&#182;</a>
63
+ </div>
64
+ <p>As well as a <code>Gemfile</code>, application repositories should also contain a <code>Gemfile.lock</code>.</p>
65
+ </td>
66
+ <td class=code>
67
+ <div class='highlight'><pre> <span class="n">set</span><span class="p">(</span><span class="ss">:bundle_gemfile_lock</span><span class="p">)</span> <span class="p">{</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">bundle_gemfile</span><span class="si">}</span><span class="s2">.lock&quot;</span> <span class="p">}</span></pre></div>
68
+ </td>
69
+ </tr>
70
+ <tr id='section-4'>
71
+ <td class=docs>
72
+ <div class="pilwrap">
73
+ <a class="pilcrow" href="#section-4">&#182;</a>
74
+ </div>
75
+ <p>An application&rsquo;s gems are installed within the application directory. By default they are
76
+ places under <code>.bundle/gems</code>.</p>
77
+ </td>
78
+ <td class=code>
79
+ <div class='highlight'><pre> <span class="n">set</span><span class="p">(</span><span class="ss">:bundle_dir</span><span class="p">)</span> <span class="p">{</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">deploy_to</span><span class="si">}</span><span class="s2">/.bundle/gems&quot;</span> <span class="p">}</span></pre></div>
80
+ </td>
81
+ </tr>
82
+ <tr id='section-5'>
83
+ <td class=docs>
84
+ <div class="pilwrap">
85
+ <a class="pilcrow" href="#section-5">&#182;</a>
86
+ </div>
87
+ <p>Not all gems are needed for production environments, so by default the <code>development</code>, <code>test</code> and
88
+ <code>assets</code> groups are skipped.</p>
89
+ </td>
90
+ <td class=code>
91
+ <div class='highlight'><pre> <span class="n">set</span><span class="p">(</span><span class="ss">:bundle_without</span><span class="p">)</span> <span class="p">{</span> <span class="s2">&quot;development test assets&quot;</span> <span class="p">}</span>
92
+
93
+ <span class="n">namespace</span> <span class="ss">:bundle</span> <span class="k">do</span>
94
+ <span class="n">namespace</span> <span class="ss">:install</span> <span class="k">do</span></pre></div>
95
+ </td>
96
+ </tr>
97
+ <tr id='section-6'>
98
+ <td class=docs>
99
+ <div class="pilwrap">
100
+ <a class="pilcrow" href="#section-6">&#182;</a>
101
+ </div>
102
+ <p>After cloning or updating the code, we only install the bundle if the <code>Gemfile</code> has changed.</p>
103
+ </td>
104
+ <td class=code>
105
+ <div class='highlight'><pre> <span class="n">desc</span> <span class="s2">&quot;Install the latest gem bundle only if Gemfile.lock has changed&quot;</span>
106
+ <span class="n">task</span> <span class="ss">:if_changed</span> <span class="k">do</span>
107
+ <span class="k">if</span> <span class="n">deployed_file_changed?</span><span class="p">(</span><span class="n">bundle_gemfile_lock</span><span class="p">)</span>
108
+ <span class="n">top</span><span class="o">.</span><span class="n">bundle</span><span class="o">.</span><span class="n">install</span><span class="o">.</span><span class="n">default</span>
109
+ <span class="k">end</span>
110
+ <span class="k">end</span></pre></div>
111
+ </td>
112
+ </tr>
113
+ <tr id='section-7'>
114
+ <td class=docs>
115
+ <div class="pilwrap">
116
+ <a class="pilcrow" href="#section-7">&#182;</a>
117
+ </div>
118
+ <p>Occassionally it&rsquo;s useful to force an install (such as if something has gone wrong in
119
+ a previous deployment)</p>
120
+ </td>
121
+ <td class=code>
122
+ <div class='highlight'><pre> <span class="n">desc</span> <span class="s2">&quot;Install the latest gem bundle&quot;</span>
123
+ <span class="n">task</span> <span class="ss">:default</span> <span class="k">do</span>
124
+ <span class="k">if</span> <span class="n">deployed_file_exists?</span><span class="p">(</span><span class="n">bundle_gemfile</span><span class="p">)</span>
125
+ <span class="n">bundler</span> <span class="s2">&quot;install --gemfile </span><span class="si">#{</span><span class="n">bundle_gemfile</span><span class="si">}</span><span class="s2"> --path </span><span class="si">#{</span><span class="n">bundle_dir</span><span class="si">}</span><span class="s2"> --deployment --quiet --binstubs --without </span><span class="si">#{</span><span class="n">bundle_without</span><span class="si">}</span><span class="s2">&quot;</span>
126
+ <span class="k">else</span>
127
+ <span class="nb">puts</span> <span class="s2">&quot;Skipping bundle:install as no Gemfile found&quot;</span>
128
+ <span class="k">end</span>
129
+ <span class="k">end</span>
130
+ <span class="k">end</span>
131
+ <span class="k">end</span></pre></div>
132
+ </td>
133
+ </tr>
134
+ <tr id='section-8'>
135
+ <td class=docs>
136
+ <div class="pilwrap">
137
+ <a class="pilcrow" href="#section-8">&#182;</a>
138
+ </div>
139
+ <p>To install the bundle automatically each time the code is updated or cloned, hooks are added to
140
+ the <code>deploy:clone_code</code> and <code>deploy:update_code</code> tasks.</p>
141
+
142
+ </td>
143
+ <td class=code>
144
+ <div class='highlight'><pre> <span class="n">after</span> <span class="s1">&#39;deploy:clone_code&#39;</span><span class="p">,</span> <span class="s1">&#39;bundle:install:if_changed&#39;</span>
145
+ <span class="n">after</span> <span class="s1">&#39;deploy:update_code&#39;</span><span class="p">,</span> <span class="s1">&#39;bundle:install:if_changed&#39;</span>
146
+ <span class="k">end</span></pre></div>
147
+ </td>
148
+ </tr>
149
+ </table>
150
+ </div>
151
+ </body>