minicap 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENCE +1 -0
- data/README.md +23 -0
- data/lib/minicap.rb +71 -0
- metadata +72 -0
data/LICENCE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
BSD
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Minicap
|
2
|
+
|
3
|
+
Minicap replaces the stock [capistrano](http://capify.org) recipes with a small, git-centric deployment strategy that eschews the power and flexibility of capistrano's (excellent, btw) default recipes, and replaces them with something smaller, faster and easier to grok.
|
4
|
+
|
5
|
+
Minicap is formalization of some work we've been doing with side project deployments at [well.ca](http://well.ca), originally inspired by Chris Wanstrath's [take](http://github.com/blog/470-deployment-script-spring-cleaning) on the subject. I got tired of maintaining separate yet nearly identical `deploy.rb` files in every side project, and realized where there was commonality, there was an opportunity to factor some behaviour up into stock recipes. Now the project `deploy.rb` files just contain a bunch of `set` statements, and a few (very minor) amendments to the minicap recipes.
|
6
|
+
|
7
|
+
Minicap requires that you use git as a repository, and that `git` is present
|
8
|
+
on the server. Deployments are not atomic (but since they're based on `git reset --hard`, they're pretty damn close).
|
9
|
+
|
10
|
+
Minicap also has two features that the stock deployment recipes lack;
|
11
|
+
|
12
|
+
1. Better (or at least more transparent) support for shared files. Since your deployment is just a git repo, files that need to persist between deployments can just live right in your server's working copy. Minicap has an optional task (enabled by enabling `look_for_orphans`) which scans for untracked files on your remote repo. Since any shared files should probably be in your `.gitignore` anyway, this really just reinforces a best practice.
|
13
|
+
|
14
|
+
2. Checking for unpushed changes. If you enable `pedantic_remote`, deployments will fail if your local HEAD is newer than the branch pulled down on the remote server. This is usually indicative of your forgetting to do a `git push` before a `cap deploy`, and helps prevent those 'why didn't my deployment change anything?' moments.
|
15
|
+
|
16
|
+
## Using Minicap
|
17
|
+
|
18
|
+
The easiest way to start using minicap is to change the first line of your project's `Capfile` to `load 'minicap'`. Copy the contents of minicap's `examples/deploy.rb` as a jumping off point for your project's `deploy.rb`.
|
19
|
+
|
20
|
+
## Coming soon
|
21
|
+
|
22
|
+
* Better multistage support. This will probably just lean on cap's multistage support, but I may make it a little cleaner
|
23
|
+
* Transparent support for templated files. No more jumping through hoops to get a `database.yml` file up to production
|
data/lib/minicap.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'capistrano/recipes/deploy/scm'
|
2
|
+
|
3
|
+
default_run_options[:pty] = true # Needed for debian based servers
|
4
|
+
set :ssh_options, {:forward_agent => true}
|
5
|
+
|
6
|
+
namespace :deploy do
|
7
|
+
desc "Set up the deployment structure"
|
8
|
+
task :setup, :except => { :no_release => true } do
|
9
|
+
run "mkdir -p #{deploy_to}"
|
10
|
+
run_gregarious "[ -d #{deploy_to}/.git ] || git clone -q #{repository} #{deploy_to}"
|
11
|
+
unversioned_dirs.each { |d| run "mkdir -p #{deploy_to + '/' + d}" } if exists? :unversioned_dirs
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Update the deployed code"
|
15
|
+
task :default, :except => { :no_release => true } do
|
16
|
+
fetch
|
17
|
+
deploy.check_yr_head if fetch(:pedantic_remote, false) && branch !~ /HEAD/
|
18
|
+
update_code
|
19
|
+
orphans if fetch(:look_for_orphans, false)
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Fetches the latest from the repo"
|
23
|
+
task :fetch do
|
24
|
+
run_gregarious "cd #{deploy_to} ; git fetch -q origin"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Aborts if remote's HEAD is different than ours"
|
28
|
+
task :check_yr_head do
|
29
|
+
remote = capture("cd #{deploy_to} ; git show-ref origin/#{branch}").split[0]
|
30
|
+
local = `git show-ref #{branch}`.split[0]
|
31
|
+
abort "It looks like you haven't pushed your changes yet. Aborting
|
32
|
+
Your HEAD is #{local[0,7]}
|
33
|
+
Their HEAD is #{remote[0,7]}" if local != remote
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Does a git reset to get the repo looking like branch"
|
37
|
+
task :update_code do
|
38
|
+
run "cd #{deploy_to} ; git reset --hard origin/#{branch}"
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Reports back on remote files that didn't come from git, or aren't ignored by git"
|
42
|
+
task :orphans do
|
43
|
+
orphans = capture "cd #{deploy_to} ; git ls-files -o"
|
44
|
+
unless orphans.empty?
|
45
|
+
logger.important <<-EOF
|
46
|
+
The following files are present in the deployment, and are unaccounted for
|
47
|
+
You may want to manually slay them, or else add them to .gitignore
|
48
|
+
|
49
|
+
#{orphans}
|
50
|
+
EOF
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Rollback a single commit"
|
55
|
+
task :rollback, :except => { :no_release => true } do
|
56
|
+
set :branch, "HEAD^"
|
57
|
+
default
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Runs the given command via cap's wrapper, which handles things like ssh host
|
63
|
+
# key messages, passphrase prompts, and the like
|
64
|
+
#
|
65
|
+
def run_gregarious(cmd)
|
66
|
+
run cmd do |ch,stream,text|
|
67
|
+
ch[:state] ||= { :channel => ch }
|
68
|
+
output = Capistrano::Deploy::SCM.new(:git, self).handle_data(ch[:state], stream, text)
|
69
|
+
ch.send_data(output) if output
|
70
|
+
end
|
71
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minicap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mat Trudel
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-07-15 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: |-
|
23
|
+
Minicap provides a minimal yet functional set of git specific cap recipes.
|
24
|
+
Minicap's recipes roughly mimic those in the standard capistrano distribution, but are
|
25
|
+
much smaller and faster to understand'
|
26
|
+
email: mat@well.ca
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- LICENCE
|
36
|
+
- lib/minicap.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage:
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
hash: 3
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.7
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Minicap provides a minimal yet functional set of git specific cap recipes
|
71
|
+
test_files: []
|
72
|
+
|