redmine_stagecoach 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +39 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +69 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/bin/stagecoach +270 -0
- data/lib/.DS_Store +0 -0
- data/lib/githooks/commit-msg +99 -0
- data/lib/stagecoach.rb +7 -0
- data/lib/stagecoach/capistrano.rb +11 -0
- data/lib/stagecoach/command_line.rb +84 -0
- data/lib/stagecoach/config.rb +125 -0
- data/lib/stagecoach/git.rb +123 -0
- data/lib/stagecoach/redmine.rb +27 -0
- data/redmine_stagecoach.gemspec +78 -0
- data/test/helper.rb +18 -0
- data/test/test_stagecoach.rb +7 -0
- metadata +149 -0
data/.document
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create ruby-1.9.2-p290@stagecoach
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'ghi'
|
4
|
+
gem 'trollop'
|
5
|
+
gem 'capistrano'
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "shoulda", ">= 0"
|
11
|
+
gem "bundler", "~> 1.0.0"
|
12
|
+
gem "jeweler", "~> 1.6.4"
|
13
|
+
gem "rcov", ">= 0"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
capistrano (2.9.0)
|
5
|
+
highline
|
6
|
+
net-scp (>= 1.0.0)
|
7
|
+
net-sftp (>= 2.0.0)
|
8
|
+
net-ssh (>= 2.0.14)
|
9
|
+
net-ssh-gateway (>= 1.1.0)
|
10
|
+
ghi (0.3.0)
|
11
|
+
git (1.2.5)
|
12
|
+
highline (1.6.9)
|
13
|
+
jeweler (1.6.4)
|
14
|
+
bundler (~> 1.0)
|
15
|
+
git (>= 1.2.5)
|
16
|
+
rake
|
17
|
+
net-scp (1.0.4)
|
18
|
+
net-ssh (>= 1.99.1)
|
19
|
+
net-sftp (2.0.5)
|
20
|
+
net-ssh (>= 2.0.9)
|
21
|
+
net-ssh (2.3.0)
|
22
|
+
net-ssh-gateway (1.1.0)
|
23
|
+
net-ssh (>= 1.99.1)
|
24
|
+
rake (0.9.2.2)
|
25
|
+
rcov (0.9.11)
|
26
|
+
shoulda (2.11.3)
|
27
|
+
trollop (1.16.2)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
bundler (~> 1.0.0)
|
34
|
+
capistrano
|
35
|
+
ghi
|
36
|
+
jeweler (~> 1.6.4)
|
37
|
+
rcov
|
38
|
+
shoulda
|
39
|
+
trollop
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Oli Barnett
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
= Stagecoach
|
2
|
+
stagecoach works in two stages, init and deploy. The init stage creates a branch based on a redmine/planio issue, and the deploy stage pushes, merges and (yes!) deploys it.
|
3
|
+
|
4
|
+
*You should always run stagecoach from the root directory of your repo*
|
5
|
+
Otherwise it may (will) break.
|
6
|
+
|
7
|
+
The first time you run stagecoach it will ask you for some information, namely your redmine/planio repo URL and your API key for this repo.
|
8
|
+
It will also install a custom commit-msg git hook (if you ask it to) - for more information, see below.
|
9
|
+
|
10
|
+
All stagecoach config is saved in /path/to/your/repo/.stagecoach which is created at initial setup and added to your global .gitignore. This is a yaml file with fairly obvious syntax
|
11
|
+
so if you need to remove a branch or edit the issue number that a branch points to, it is possible (although not necessarily recommended) to edit it.
|
12
|
+
|
13
|
+
Init Stage
|
14
|
+
==========
|
15
|
+
stagecoach -p[lanio] 4115 (OR) -g[ithub] 525 -b[ranch] my_new_branch
|
16
|
+
|
17
|
+
You can also just run stagecoach without any flags and it will allow you to enter this stuff manually.
|
18
|
+
|
19
|
+
To get started, all stagecoach needs from you is the issue number you are working on (redmine/planio or github) and a new branch name. You /can/ use an existing branch if it
|
20
|
+
is up to date with your master branch. If it is not, stagecoach will squawk and die and you will have to bring the branch up to date, or use a new one.
|
21
|
+
|
22
|
+
If you are working from a redmine/planio issue, stagecoach sets the issue to 'In Progress'. Currently it does not assign the issue to you, but you have the option to view the issue
|
23
|
+
in your browser and do this manually. It also sets up a git issue for you to reference in your commits (see commit-msg githook).
|
24
|
+
|
25
|
+
If you are working from a github issue, we can all get on with our lives.
|
26
|
+
|
27
|
+
Coding Stage
|
28
|
+
============
|
29
|
+
Future versions of stagecoach may do the coding for you, but at the moment you have to do this part manually.
|
30
|
+
Just code and commit, code and commit until your feature or fix is ready.
|
31
|
+
|
32
|
+
Commit-msg githook
|
33
|
+
------------------
|
34
|
+
If you opt to install the commit-msg githook during initial setup (stagecoach -s) then your commit messages will be automatically referenced to the github issue of the branch you are in
|
35
|
+
(this only applies to branches created or registered in Stagecoach).
|
36
|
+
|
37
|
+
- to reference a different issue from a commit, simply refer to it as normal with #xxx in the commit message. The git-hook will leave your message alone.
|
38
|
+
- to make no reference at all, you can use the #noref tag in the commit message. The git-hook
|
39
|
+
- to close an issue with a commit, use the #closes tag.
|
40
|
+
|
41
|
+
For more information, see
|
42
|
+
- the githook itself at /path/to/your/repo/.git/hooks/commit-msg
|
43
|
+
- http://book.git-scm.com/5_git_hooks.html
|
44
|
+
|
45
|
+
Deploy Stage
|
46
|
+
============
|
47
|
+
stagecoach -d[eploy]
|
48
|
+
|
49
|
+
This automates the entire deploy workflow for you as follows:
|
50
|
+
|
51
|
+
git push origin new_branch_name
|
52
|
+
git checkout staging
|
53
|
+
git pull
|
54
|
+
git merge task_name
|
55
|
+
git push origin staging
|
56
|
+
cap staging deploy
|
57
|
+
set redmine/planio ticket to 'feedback' status (if applicable)
|
58
|
+
|
59
|
+
Sample usage:
|
60
|
+
stagecoach -p 4115 -b new_branch_name
|
61
|
+
[code, commit until feature or fix is complete]
|
62
|
+
stagecoach -d
|
63
|
+
|
64
|
+
Flags
|
65
|
+
--branch, -b: Enter your new branch name here, eg. stagecoach -b new_branch (optional)
|
66
|
+
--planio, -p: Enter your planio issue number here, eg. stagecoach -p 1234 (optional)
|
67
|
+
--github, -g: Enter your github issue number here, eg. stagecoach -g 1234 (optional)
|
68
|
+
--deploy, -d: Use this option to skip straight to push & deploy if you have already pulled from master and created your new branch
|
69
|
+
--setup, -s: Use this the first time you run stagecoach to save your redmine repository/api key and install the commit-msg githook if desired
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "redmine_stagecoach"
|
18
|
+
gem.homepage = "http://github.com/omnikron/stagecoach"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Stagecoach is in ur Redmine, automating ur Git workflow.}
|
21
|
+
gem.description = %Q{Git/capistrano workflow automation script with Redmine & Github issue integration}
|
22
|
+
gem.email = "o.barnett@digitaleseiten.de"
|
23
|
+
gem.authors = ["Oli Barnett"]
|
24
|
+
gem.executables = ['stagecoach']
|
25
|
+
# dependencies defined in Gemfile
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'test'
|
39
|
+
test.pattern = 'test/**/test_*.rb'
|
40
|
+
test.verbose = true
|
41
|
+
test.rcov_opts << '--exclude "gems/*"'
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => :test
|
45
|
+
|
46
|
+
require 'rake/rdoctask'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "stagecoach #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.5.0
|
data/bin/stagecoach
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
require File.dirname(__FILE__) + '/../lib/stagecoach.rb'
|
4
|
+
|
5
|
+
CONFIG_FILE = `pwd`.chomp + '/.stagecoach'
|
6
|
+
|
7
|
+
module Stagecoach
|
8
|
+
staging = 'staging'
|
9
|
+
master = 'master'
|
10
|
+
|
11
|
+
# Command line options courtesy of the Trollop gem.
|
12
|
+
opts = CommandLine.trollop
|
13
|
+
|
14
|
+
# Initial setup with -s flag.
|
15
|
+
if opts[:setup]
|
16
|
+
Config.setup
|
17
|
+
end
|
18
|
+
|
19
|
+
# Initial setup without -s flag.
|
20
|
+
unless File.exist?(CONFIG_FILE)
|
21
|
+
Config.setup
|
22
|
+
end
|
23
|
+
|
24
|
+
# Load config file to a hash.
|
25
|
+
config = Config.yaml_to_hash
|
26
|
+
|
27
|
+
# Checks validity of argument variables.
|
28
|
+
# Ignore these checks with -t flag.
|
29
|
+
unless opts[:testing_given]
|
30
|
+
Config.setup if config["redmine_site"] == "none"
|
31
|
+
Config.setup if config["redmine_api"] == "none"
|
32
|
+
|
33
|
+
# Checks that command-line args are present and correct.
|
34
|
+
Trollop::die :planio, "issue number can only contain digits" if opts[:planio] && opts[:planio][/\D/]
|
35
|
+
Trollop::die :github, "issue number can only contain digits" if opts[:github] && opts[:github][/\D/]
|
36
|
+
Trollop::die :branch, "name must be longer than 1 character" if opts[:branch] && opts[:branch].length <= 1
|
37
|
+
|
38
|
+
# You can't give a planio and a github issue number (for the moment)
|
39
|
+
if opts[:github] && opts[:planio]
|
40
|
+
puts "You can't enter a github issue at the same time as a planio issue at the moment. Make up your mind!\nExiting..."
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Set up redmine client config.
|
46
|
+
RedmineApi::Client.instance_eval do
|
47
|
+
self.site = config["redmine_site"]
|
48
|
+
self.user = config["redmine_api_key"]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Checks for uncommitted/unstashed changes and aborts if present.
|
52
|
+
if Git.changes != ''
|
53
|
+
puts "You have uncommitted changes:".red
|
54
|
+
puts Git.changes
|
55
|
+
puts "Please commit or stash these changes before running Stagecoach. -h for help."
|
56
|
+
puts "Exiting..."
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
|
60
|
+
# Initial stage - set up branch and git issue.
|
61
|
+
|
62
|
+
unless opts[:deploy]
|
63
|
+
|
64
|
+
# If no issue argument has been given.
|
65
|
+
if opts[:github].nil? && opts[:planio].nil?
|
66
|
+
print "Are you working on a [P]lanio or a [G]ithub issue: "
|
67
|
+
case STDIN.gets.chomp
|
68
|
+
when 'P'
|
69
|
+
print "Please enter your Planio issue number: "
|
70
|
+
opts[:planio] = gets.chomp
|
71
|
+
when 'G'
|
72
|
+
print "Please enter your Github issue number: "
|
73
|
+
opts[:github] = gets.chomp
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Check that the planio issue is not already assigned.
|
78
|
+
if opts[:planio]
|
79
|
+
planio_issue_number = opts[:planio]
|
80
|
+
planio_issue = Redmine.issue(planio_issue_number)
|
81
|
+
if planio_issue.status.id != '1'
|
82
|
+
puts "Warning!".red
|
83
|
+
puts "This issue is in status '#{planio_issue.status.name}'"
|
84
|
+
begin
|
85
|
+
puts "It is assigned to #{planio_issue.assigned_to.name}"
|
86
|
+
rescue
|
87
|
+
puts "But it is not assigned to anybody yet."
|
88
|
+
end
|
89
|
+
print "Continue? [Y]es or [Q]uit: "
|
90
|
+
case STDIN.gets.chomp
|
91
|
+
when 'Y'
|
92
|
+
when 'Q'
|
93
|
+
exit
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set the planio issue status to 'In Bearbeitung'
|
98
|
+
planio_issue.status_id = 2
|
99
|
+
planio_issue.save
|
100
|
+
end
|
101
|
+
|
102
|
+
# TODO: Check that the github issue is not already assigned.
|
103
|
+
|
104
|
+
CommandLine.line_break
|
105
|
+
puts "Stagecoach: initial stage"
|
106
|
+
|
107
|
+
# Change to master, pull changes, and create a new branch.
|
108
|
+
CommandLine.line_break
|
109
|
+
puts "Switching to master branch"
|
110
|
+
#
|
111
|
+
# TODO if there is a file that has been git added but not git committed, it
|
112
|
+
# will pop up at this point looking confusing (eg. "A test_file").
|
113
|
+
# Handle this better?
|
114
|
+
#
|
115
|
+
Git.checkout(master)
|
116
|
+
puts "Pulling changes:"
|
117
|
+
Git.pull
|
118
|
+
if opts[:branch]
|
119
|
+
new_branch = opts[:branch]
|
120
|
+
else
|
121
|
+
print "Please enter a new git branch name for your changes (branch will be created): "
|
122
|
+
new_branch = STDIN.gets.chomp
|
123
|
+
end
|
124
|
+
|
125
|
+
# Check that the new branch isn't master, because that would be silly
|
126
|
+
case new_branch
|
127
|
+
when 'master', 'Master'
|
128
|
+
puts "You can't use stagecoach to deploy your master branch.\nExiting..."
|
129
|
+
exit
|
130
|
+
end
|
131
|
+
|
132
|
+
# Make sure new local branch does not already exist.
|
133
|
+
if Git.branch_exist?(new_branch)
|
134
|
+
puts "There is already a local branch called #{new_branch}."
|
135
|
+
if Git.diff(master, new_branch) == ""
|
136
|
+
print "#{new_branch} is up to date with master. [U]se or [Q]uit: "
|
137
|
+
else
|
138
|
+
puts "#{new_branch} is not up to date with master. Please use a different branch or update this one.".red
|
139
|
+
puts "Exiting..."
|
140
|
+
CommandLine.line_break
|
141
|
+
puts "The following files in branch '#{new_branch}' differ from their master branch versions:"
|
142
|
+
puts Git.diff(master, new_branch)
|
143
|
+
CommandLine.line_break
|
144
|
+
exit
|
145
|
+
end
|
146
|
+
case STDIN.gets.chomp
|
147
|
+
when 'U'
|
148
|
+
Git.change_to_branch(new_branch)
|
149
|
+
when 'Q'
|
150
|
+
exit
|
151
|
+
end
|
152
|
+
else
|
153
|
+
Git.new_branch(new_branch)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Ugly code, pretty output...
|
157
|
+
CommandLine.line_break
|
158
|
+
|
159
|
+
# Issue handling.
|
160
|
+
if opts[:github]
|
161
|
+
config[Git.current_branch] = {:github_issue => opts[:github]}
|
162
|
+
#TODO check that github issue is not assigned to somebody already
|
163
|
+
elsif opts[:planio]
|
164
|
+
config[Git.current_branch] = {:planio_issue => planio_issue_number}
|
165
|
+
end
|
166
|
+
|
167
|
+
issue = config[Git.current_branch]
|
168
|
+
|
169
|
+
# Set up the related issue for this branch.
|
170
|
+
if planio_issue = issue[:planio_issue]
|
171
|
+
begin
|
172
|
+
puts "Searching for issue number #{planio_issue}..."
|
173
|
+
redmine_issue = Redmine.issue(planio_issue)
|
174
|
+
rescue ActiveResource::ResourceNotFound => e
|
175
|
+
puts e.message
|
176
|
+
exit
|
177
|
+
end
|
178
|
+
puts "Issue found: #{redmine_issue.subject}\n"
|
179
|
+
|
180
|
+
# Create a Github issue referencing the planio issue.
|
181
|
+
puts "Creating Git issue with subject: " + redmine_issue.subject
|
182
|
+
body = "Planio issue: #{Redmine.issue_url(redmine_issue)} \n\n #{redmine_issue.description}"
|
183
|
+
|
184
|
+
# Create a Git issue.
|
185
|
+
github_issue = Git.new_issue(redmine_issue.subject, body)
|
186
|
+
github_issue_id = github_issue[/\d+/]
|
187
|
+
|
188
|
+
# Save it so we can reference it in commits using the magic of git hooks!
|
189
|
+
config[Git.current_branch] = {:github_issue => github_issue_id, :planio_issue => planio_issue}
|
190
|
+
|
191
|
+
print "Would you like to edit the issue on Github? [Y]es or anything else to continue: "
|
192
|
+
|
193
|
+
if STDIN.gets.chomp == 'Y'
|
194
|
+
Git.view_issue(github_issue_id)
|
195
|
+
else
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Github issues are easier.
|
200
|
+
if issue[:github]
|
201
|
+
#TODO what happens if no github issue is found?
|
202
|
+
puts "Searching for github issue number #{issue[:number]}..."
|
203
|
+
github_issue = Git.issue(issue[:number])
|
204
|
+
puts "Issue found: #{github_issue} \n"
|
205
|
+
end
|
206
|
+
|
207
|
+
# Saves the branch-specific details for later.
|
208
|
+
Config.save(config)
|
209
|
+
puts "Happy coding! Run stagecoach -d when you're ready to deploy."
|
210
|
+
end
|
211
|
+
|
212
|
+
# ------------------------------------------------------------------
|
213
|
+
# Deploy stage.
|
214
|
+
if opts[:deploy]
|
215
|
+
|
216
|
+
# Get the current git branch
|
217
|
+
branch = Git.current_branch
|
218
|
+
|
219
|
+
# There's no point in deploying without any commits
|
220
|
+
unless Git.branch_has_commits?(branch)
|
221
|
+
puts "You don't have any uncommitted changes on branch #{branch}. Please make some commits before running stagecoach!\nExiting..."
|
222
|
+
exit
|
223
|
+
end
|
224
|
+
|
225
|
+
# You never know! Display git status in case there are any nasty surprises.
|
226
|
+
unless Git.status =~ /nothing to commit/
|
227
|
+
CommandLine.line_break
|
228
|
+
puts "You have a dirty git branch:\n".red
|
229
|
+
puts Git.status
|
230
|
+
CommandLine.line_break
|
231
|
+
print "[D]eploy anyway".red
|
232
|
+
print " or "
|
233
|
+
print "[anything else] to cancel: ".green
|
234
|
+
case STDIN.gets.chomp
|
235
|
+
when "D"
|
236
|
+
CommandLine.line_break
|
237
|
+
puts "DEPLOYING:"
|
238
|
+
CommandLine.line_break
|
239
|
+
else
|
240
|
+
puts "Exiting..."
|
241
|
+
exit
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
# Stop anybody deploying master to staging...
|
247
|
+
case branch
|
248
|
+
when 'master', 'Master'
|
249
|
+
puts "You can't use stagecoach to deploy your master branch.\nExiting..."
|
250
|
+
exit
|
251
|
+
end
|
252
|
+
|
253
|
+
# Finally, push, merge and deploy!
|
254
|
+
Git.push(branch)
|
255
|
+
Git.merge(staging, branch)
|
256
|
+
Git.push(staging)
|
257
|
+
Capistrano.deploy(staging)
|
258
|
+
Git.change_to_branch(master)
|
259
|
+
|
260
|
+
# Planio issue to feedback status
|
261
|
+
if planio_issue_number = config[branch][:planio_issue]
|
262
|
+
CommandLine.line_break
|
263
|
+
puts "Attempting to change Planio ticket status to 'Feedback' for you:"
|
264
|
+
issue = Redmine.issue(planio_issue_number)
|
265
|
+
issue.status_id = 4
|
266
|
+
issue.save
|
267
|
+
Redmine.view_issue(issue)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Git commit-msg hook. If your branch name is in the form "t123", automatically
|
4
|
+
# adds "Refs #123." to commit messages unless they mention "#123" already.
|
5
|
+
# Include "#close" or "#finish" to add "Closes #123."
|
6
|
+
#
|
7
|
+
# For Pivotal Tracker, branch names like "s123" adds "[#123]".
|
8
|
+
# Include "#close" or "#finish" to add "[Finishes #123]".
|
9
|
+
#
|
10
|
+
# If you include "#noref" in the commit message, nothing will be added to
|
11
|
+
# the commit message, and the "#noref" itself will be stripped.
|
12
|
+
#
|
13
|
+
# By Henrik Nyh <http://henrik.nyh.se> 2009-09-10 under the MIT License.
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# Install:
|
17
|
+
#
|
18
|
+
# cd your_project
|
19
|
+
# stick it in .git/hooks/commit-msg && chmod u+x .git/hooks/commit-msg
|
20
|
+
#
|
21
|
+
# Or store it centrally and symlink in your projects:
|
22
|
+
# TODO Replace ~./.githooks etc with the file location in the gem
|
23
|
+
# ~/.githooks/commit-msg && chmod u+x ~/.githooks/commit-msg
|
24
|
+
# cd your_project
|
25
|
+
# ~/.githooks/commit-msg .git/hooks
|
26
|
+
|
27
|
+
require 'yaml'
|
28
|
+
|
29
|
+
# Custom method to check for installed redmine_stagecoach gem
|
30
|
+
def gem_available?(name)
|
31
|
+
Gem::Specification.find_by_name(name)
|
32
|
+
rescue Gem::LoadError
|
33
|
+
false
|
34
|
+
rescue
|
35
|
+
Gem.available?(name)
|
36
|
+
end
|
37
|
+
|
38
|
+
if gem_available?('redmine_stagecoach') == false
|
39
|
+
exit
|
40
|
+
else
|
41
|
+
config = YAML::load(File.open(File.dirname(__FILE__) + '/../../.stagecoach', 'r'))
|
42
|
+
end
|
43
|
+
|
44
|
+
# Find out what branch we are on
|
45
|
+
def branches
|
46
|
+
`git branch`.split("\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_branch
|
50
|
+
branches.each do |b|
|
51
|
+
if b =~ /\*/
|
52
|
+
return b[1..-1].strip
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
# And now the git hook stuff
|
59
|
+
|
60
|
+
FLAGS = [
|
61
|
+
NOREF = "noref",
|
62
|
+
UP_NOREF = "Noref",
|
63
|
+
CAPS_NOREF = "NOREF",
|
64
|
+
CLOSE = "close",
|
65
|
+
UP_CLOSE= "Close",
|
66
|
+
CAPS_CLOSE= "CLOSE"
|
67
|
+
]
|
68
|
+
|
69
|
+
NO_REFERENCE_FLAGS = [ NOREF, UP_NOREF, CAPS_NOREF ]
|
70
|
+
CLOSING_FLAGS = [ CLOSE, UP_CLOSE, CAPS_CLOSE ]
|
71
|
+
|
72
|
+
begin
|
73
|
+
ticket_number = config[current_branch][:github_issue]
|
74
|
+
rescue
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
finish = "Closes #%s" % ticket_number
|
78
|
+
reference = "#%s" % ticket_number
|
79
|
+
|
80
|
+
message_file = ARGV[0]
|
81
|
+
message = File.read(message_file).strip
|
82
|
+
exit if message.include?("##{ticket_number}")
|
83
|
+
exit if message =~ /#\d+/
|
84
|
+
|
85
|
+
# Determine if any of the flags are included. Make a note of which and then remove it.
|
86
|
+
message.sub!(/(?:^|\s)#(#{Regexp.union(*FLAGS)})\b/, '')
|
87
|
+
flag = $1
|
88
|
+
|
89
|
+
message =
|
90
|
+
case flag
|
91
|
+
when *NO_REFERENCE_FLAGS
|
92
|
+
message
|
93
|
+
when *CLOSING_FLAGS
|
94
|
+
[ message, finish ].join(" ")
|
95
|
+
else
|
96
|
+
[ message, reference ].join(" ")
|
97
|
+
end
|
98
|
+
|
99
|
+
File.open(message_file, 'w') {|f| f.write message }
|
data/lib/stagecoach.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module Stagecoach
|
2
|
+
class CommandLine
|
3
|
+
def self.line_break
|
4
|
+
puts "\n"
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.trollop
|
8
|
+
require 'trollop'
|
9
|
+
# Command line options using Trollop.
|
10
|
+
Trollop::options do
|
11
|
+
banner <<-EOS
|
12
|
+
stagecoach works in two stages, init and deploy. The init stage creates a branch based on a redmine/planio issue, and the deploy stage pushes, merges and (yes!) deploys it.
|
13
|
+
|
14
|
+
#{"You should always run stagecoach from the root directory of your repo".red}
|
15
|
+
Otherwise it may (will) break.
|
16
|
+
|
17
|
+
The first time you run stagecoach it will ask you for some information, namely your redmine/planio repo URL and your API key for this repo.
|
18
|
+
It will also install a custom commit-msg git hook (if you ask it to) - for more information, see below.
|
19
|
+
|
20
|
+
All stagecoach config is saved in /path/to/your/repo/.stagecoach which is created at initial setup and added to your global .gitignore. This is a yaml file with fairly obvious syntax
|
21
|
+
so if you need to remove a branch or edit the issue number that a branch points to, it is possible (although not necessarily recommended) to edit it.
|
22
|
+
|
23
|
+
Init Stage
|
24
|
+
----------
|
25
|
+
stagecoach -p[lanio] 4115 (OR) -g[ithub] 525 -b[ranch] my_new_branch
|
26
|
+
|
27
|
+
You can also just run stagecoach without any flags and it will allow you to enter this stuff manually.
|
28
|
+
|
29
|
+
To get started, all stagecoach needs from you is the issue number you are working on (redmine/planio or github) and a new branch name. You /can/ use an existing branch if it
|
30
|
+
is up to date with your master branch. If it is not, stagecoach will squawk and die and you will have to bring the branch up to date, or use a new one.
|
31
|
+
|
32
|
+
If you are working from a redmine/planio issue, stagecoach sets the issue to 'In Progress'. Currently it does not assign the issue to you, but you have the option to view the issue
|
33
|
+
in your browser and do this manually. It also sets up a git issue for you to reference in your commits (see commit-msg githook).
|
34
|
+
|
35
|
+
If you are working from a github issue, we can all get on with our lives.
|
36
|
+
|
37
|
+
Coding Stage
|
38
|
+
------------
|
39
|
+
Future versions of stagecoach may do the coding for you, but at the moment you have to do this part manually.
|
40
|
+
Just code and commit, code and commit until your feature or fix is ready.
|
41
|
+
|
42
|
+
#{"commit-msg githook".green}
|
43
|
+
If you opt to install the commit-msg githook during initial setup (stagecoach -s) then your commit messages will be automatically referenced to the github issue of the branch you are in
|
44
|
+
(this only applies to branches created or registered in Stagecoach).
|
45
|
+
|
46
|
+
- to reference a different issue from a commit, simply refer to it as normal with #xxx in the commit message. The git-hook will leave your message alone.
|
47
|
+
- to make no reference at all, you can use the #noref tag in the commit message. The git-hook
|
48
|
+
- to close an issue with a commit, use the #closes tag.
|
49
|
+
|
50
|
+
For more information, see
|
51
|
+
- the githook itself at /path/to/your/repo/.git/hooks/commit-msg
|
52
|
+
- http://book.git-scm.com/5_git_hooks.html
|
53
|
+
|
54
|
+
Deploy Stage
|
55
|
+
------------
|
56
|
+
stagecoach -d[eploy]
|
57
|
+
|
58
|
+
This automates the entire deploy workflow for you as follows:
|
59
|
+
|
60
|
+
git push origin new_branch_name
|
61
|
+
git checkout staging
|
62
|
+
git pull
|
63
|
+
git merge task_name
|
64
|
+
git push origin staging
|
65
|
+
cap staging deploy
|
66
|
+
set redmine/planio ticket to 'feedback' status (if applicable)
|
67
|
+
|
68
|
+
#{"Sample usage:".green}
|
69
|
+
stagecoach -p 4115 -b new_branch_name
|
70
|
+
[code, commit until feature or fix is complete]
|
71
|
+
stagecoach -d
|
72
|
+
|
73
|
+
#{"Flags".red}
|
74
|
+
EOS
|
75
|
+
opt :branch, "Enter your new branch name here, eg. stagecoach -b new_branch (optional)", :type => :string
|
76
|
+
opt :planio, "Enter your planio issue number here, eg. stagecoach -p 1234 (optional)", :type => :string
|
77
|
+
opt :github, "Enter your github issue number here, eg. stagecoach -g 1234 (optional)", :type => :string
|
78
|
+
opt :deploy, "Use this option to skip straight to push & deploy if you have already pulled from master and created your new branch"
|
79
|
+
opt :setup, "Use this the first time you run stagecoach to save your redmine repository and api key"
|
80
|
+
opt :testing, "Dev testing tool"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'FileUtils'
|
3
|
+
|
4
|
+
module Stagecoach
|
5
|
+
class Config
|
6
|
+
class << self
|
7
|
+
def new
|
8
|
+
File.open(CONFIG_FILE, 'w') { |f| f.write("---\nredmine_site: none\nredmine_api_key: none")}
|
9
|
+
end
|
10
|
+
|
11
|
+
def open
|
12
|
+
File.open(CONFIG_FILE, 'r+')
|
13
|
+
end
|
14
|
+
|
15
|
+
def yaml_to_hash
|
16
|
+
YAML::load(Config.open)
|
17
|
+
end
|
18
|
+
|
19
|
+
def save(hash, config_file = Config.open)
|
20
|
+
config_file.write(hash.to_yaml)
|
21
|
+
end
|
22
|
+
|
23
|
+
def githook_install(source_dir, install_dir, file)
|
24
|
+
FileUtils.cp(source_dir + file, install_dir + file)
|
25
|
+
puts 'OK!'
|
26
|
+
puts 'Making githook executable (may require admin password)'
|
27
|
+
FileUtils.chmod(0711, ( install_dir + file ))
|
28
|
+
puts 'OK!'
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup
|
32
|
+
# Say hello
|
33
|
+
CommandLine.line_break
|
34
|
+
puts "Stagecoach Initial Setup"
|
35
|
+
CommandLine.line_break
|
36
|
+
|
37
|
+
# Now scare everybody away again
|
38
|
+
puts "You are running stagecoach from #{FileUtils.pwd.green}. Is this the root directory of your repository?"
|
39
|
+
puts "Stagecoach may not work properly anywhere else! So proceed with caution"
|
40
|
+
CommandLine.line_break
|
41
|
+
print "[C]ontinue or [Q]uit: "
|
42
|
+
|
43
|
+
# Create a config file if necessary
|
44
|
+
case STDIN.gets.chomp
|
45
|
+
when 'C'
|
46
|
+
Config.new unless File.exist?(CONFIG_FILE)
|
47
|
+
when 'Q'
|
48
|
+
puts "Exiting..."
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
|
52
|
+
# Tell git to ignore the stagecoach config file
|
53
|
+
Git.global_ignore('.stagecoach')
|
54
|
+
|
55
|
+
# Install the commit-msg githook if it is not already there:
|
56
|
+
source_dir = (File.dirname(__FILE__) + '/../githooks/')
|
57
|
+
install_dir = FileUtils.pwd + '/.git/hooks/'
|
58
|
+
git_hook = 'commit-msg'
|
59
|
+
|
60
|
+
CommandLine.line_break
|
61
|
+
puts "Would you like to install the stagecoach #{"commit-msg githook".green}?"
|
62
|
+
puts "This automatically references stagecoach-created github issues from each commit you make"
|
63
|
+
puts "Note that this will only affect branches created in stagecoach. For more information run stagecoach -h"
|
64
|
+
CommandLine.line_break
|
65
|
+
print "[I]nstall or [S]kip this step: "
|
66
|
+
loop do
|
67
|
+
case STDIN.gets.chomp
|
68
|
+
when 'I'
|
69
|
+
if File.exist?(install_dir + git_hook)
|
70
|
+
case FileUtils.compare_file(source_dir + git_hook, install_dir + git_hook)
|
71
|
+
when true
|
72
|
+
puts 'The stagecoach githook is already installed in this repo. Skipping this step...'
|
73
|
+
break
|
74
|
+
when false
|
75
|
+
puts "You have a commit-msg githook already. Are you sure you want to install? This will #{'overwrite'.red} your current commit-msg githook."
|
76
|
+
print "Type [overwrite] to continue or anything else to skip installation: "
|
77
|
+
case STDIN.gets.chomp
|
78
|
+
when 'overwrite'
|
79
|
+
Config.githook_install(source_dir, install_dir, git_hook)
|
80
|
+
break
|
81
|
+
else
|
82
|
+
break
|
83
|
+
end
|
84
|
+
end
|
85
|
+
else
|
86
|
+
puts "Installing..."
|
87
|
+
Config.githook_install(source_dir, install_dir, git_hook)
|
88
|
+
break
|
89
|
+
end
|
90
|
+
when 'S'
|
91
|
+
puts 'Skipping Installation.'
|
92
|
+
break
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# TODO Some verification of the input at this stage, for example test the
|
97
|
+
# connection and have the user re-enter the details if necessary
|
98
|
+
# http://api.rubyonrails.org/classes/ActiveResource/Connection.html#method-i-head
|
99
|
+
loop do
|
100
|
+
CommandLine.line_break
|
101
|
+
print "Enter your redmine/planio repository, eg. https://digitaleseiten.plan.io: "
|
102
|
+
redmine_repo = STDIN.gets.chomp
|
103
|
+
print "Enter your API key for that repo: "
|
104
|
+
redmine_api_key = STDIN.gets.chomp
|
105
|
+
|
106
|
+
Config.save({"redmine_site" => redmine_repo, "redmine_api_key" => redmine_api_key})
|
107
|
+
|
108
|
+
CommandLine.line_break
|
109
|
+
puts "Settings saved OK:"
|
110
|
+
puts "Repository: " + redmine_repo
|
111
|
+
puts "API Key: " + redmine_api_key
|
112
|
+
CommandLine.line_break
|
113
|
+
puts "Exiting..."
|
114
|
+
exit
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class String
|
122
|
+
def red; colorize(self, "\e[1m\e[31m"); end
|
123
|
+
def green; colorize(self, "\e[32m"); end
|
124
|
+
def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
|
125
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Stagecoach
|
2
|
+
class Git
|
3
|
+
class << self
|
4
|
+
def branches
|
5
|
+
`git branch`.split("\n")
|
6
|
+
end
|
7
|
+
|
8
|
+
def global_ignore(filename)
|
9
|
+
gitignore = File.open(Dir.home + '/.gitignore', 'a+')
|
10
|
+
|
11
|
+
# Check if filename is ignored already and ignores it if not
|
12
|
+
unless File.read(gitignore) =~ /\.stagecoach/
|
13
|
+
gitignore.puts(filename)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def changes
|
18
|
+
`git diff-files --name-status -r --ignore-submodules`
|
19
|
+
end
|
20
|
+
|
21
|
+
def status
|
22
|
+
`git status`
|
23
|
+
end
|
24
|
+
|
25
|
+
def current_branch
|
26
|
+
branches.each do |b|
|
27
|
+
if b =~ /\*/
|
28
|
+
return b[1..-1].strip
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def correct_branch?
|
34
|
+
CommandLine.line_break
|
35
|
+
print "You are currently in local branch: #{Git.current_branch.red} \nAre these details correct? ([Y]es or [Q]uit): "
|
36
|
+
case STDIN.gets.chomp
|
37
|
+
when "Y"
|
38
|
+
when "Q"
|
39
|
+
exit
|
40
|
+
else
|
41
|
+
puts "Please enter Y to continue or Q to quit."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def new_branch(branch)
|
46
|
+
CommandLine.line_break
|
47
|
+
`git checkout -b #{branch}`
|
48
|
+
end
|
49
|
+
|
50
|
+
def change_to_branch(branch)
|
51
|
+
CommandLine.line_break
|
52
|
+
puts "Changing to branch '#{branch}'"
|
53
|
+
if branch_exist?(branch)
|
54
|
+
`git checkout #{branch}`
|
55
|
+
else
|
56
|
+
print "Branch '#{branch}' does not exist. [C]reate or [Q]uit: "
|
57
|
+
case STDIN.gets.chomp
|
58
|
+
when 'C'
|
59
|
+
new_branch(branch)
|
60
|
+
when 'Q'
|
61
|
+
exit
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def diff(branch1, branch2)
|
67
|
+
diff = `git diff --name-status #{branch1}..#{branch2}`
|
68
|
+
return diff
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def merge(to_branch, from_branch)
|
73
|
+
CommandLine.line_break
|
74
|
+
puts "Merging into #{to_branch} (after pulling updates)"
|
75
|
+
Git.change_to_branch(to_branch)
|
76
|
+
puts `git pull origin #{to_branch}`
|
77
|
+
puts `git merge #{from_branch}`
|
78
|
+
raise 'merge failed' if $?.exitstatus != 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def push(branch)
|
82
|
+
CommandLine.line_break
|
83
|
+
puts "Pushing your changes to branch '#{branch}'"
|
84
|
+
puts `git push origin #{branch}`
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def checkout(branch)
|
89
|
+
puts `git checkout #{branch}`
|
90
|
+
end
|
91
|
+
|
92
|
+
def pull
|
93
|
+
puts `git pull`
|
94
|
+
end
|
95
|
+
|
96
|
+
def branch_exist?(branch)
|
97
|
+
branches.find { |e| /#{branch}/ =~ e }
|
98
|
+
end
|
99
|
+
|
100
|
+
def new_issue(title, description)
|
101
|
+
`ghi -o "#{title}" -m "#{description}"`
|
102
|
+
end
|
103
|
+
|
104
|
+
def branch_has_commits?(branch)
|
105
|
+
log = `git log --branches --not --remotes --simplify-by-decoration --decorate --oneline`
|
106
|
+
if log.include? branch
|
107
|
+
return true
|
108
|
+
else
|
109
|
+
return false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def view_issue(github_issue)
|
114
|
+
issue_url = `ghi -u#{github_issue}`
|
115
|
+
`open #{issue_url}`
|
116
|
+
end
|
117
|
+
|
118
|
+
def issue(id)
|
119
|
+
`ghi -l #{id}`
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_resource'
|
3
|
+
|
4
|
+
module RedmineApi
|
5
|
+
class Client < ActiveResource::Base; end
|
6
|
+
class Issue < RedmineApi::Client; end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Stagecoach
|
10
|
+
class Redmine
|
11
|
+
def self.issue(issue_number)
|
12
|
+
return RedmineApi::Issue.find(issue_number)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.issue_url(issue)
|
16
|
+
RedmineApi::Client.site + "/issues/" + issue.id
|
17
|
+
end
|
18
|
+
|
19
|
+
# Open the issue in a browser.
|
20
|
+
def self.view_issue(issue)
|
21
|
+
issue_url = Redmine.issue_url(issue)
|
22
|
+
print "Open planio issue in browser? [Y]es or anything else to exit: "
|
23
|
+
`open #{issue_url.to_s}` if gets.chomp == "Y"
|
24
|
+
puts "Staging completed! Exiting..."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "redmine_stagecoach"
|
8
|
+
s.version = "0.5.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Oli Barnett"]
|
12
|
+
s.date = "2012-01-24"
|
13
|
+
s.description = "Git/capistrano workflow automation script with Redmine & Github issue integration"
|
14
|
+
s.email = "o.barnett@digitaleseiten.de"
|
15
|
+
s.executables = ["stagecoach"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE.txt",
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".document",
|
22
|
+
".rvmrc",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"bin/stagecoach",
|
30
|
+
"lib/.DS_Store",
|
31
|
+
"lib/githooks/commit-msg",
|
32
|
+
"lib/stagecoach.rb",
|
33
|
+
"lib/stagecoach/capistrano.rb",
|
34
|
+
"lib/stagecoach/command_line.rb",
|
35
|
+
"lib/stagecoach/config.rb",
|
36
|
+
"lib/stagecoach/git.rb",
|
37
|
+
"lib/stagecoach/redmine.rb",
|
38
|
+
"redmine_stagecoach.gemspec",
|
39
|
+
"test/helper.rb",
|
40
|
+
"test/test_stagecoach.rb"
|
41
|
+
]
|
42
|
+
s.homepage = "http://github.com/omnikron/stagecoach"
|
43
|
+
s.licenses = ["MIT"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = "1.8.15"
|
46
|
+
s.summary = "Stagecoach is in ur Redmine, automating ur Git workflow."
|
47
|
+
|
48
|
+
if s.respond_to? :specification_version then
|
49
|
+
s.specification_version = 3
|
50
|
+
|
51
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
52
|
+
s.add_runtime_dependency(%q<ghi>, [">= 0"])
|
53
|
+
s.add_runtime_dependency(%q<trollop>, [">= 0"])
|
54
|
+
s.add_runtime_dependency(%q<capistrano>, [">= 0"])
|
55
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
56
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
58
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<ghi>, [">= 0"])
|
61
|
+
s.add_dependency(%q<trollop>, [">= 0"])
|
62
|
+
s.add_dependency(%q<capistrano>, [">= 0"])
|
63
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
64
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
65
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
66
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
67
|
+
end
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<ghi>, [">= 0"])
|
70
|
+
s.add_dependency(%q<trollop>, [">= 0"])
|
71
|
+
s.add_dependency(%q<capistrano>, [">= 0"])
|
72
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
73
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
74
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
75
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'stagecoach'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: redmine_stagecoach
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Oli Barnett
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ghi
|
16
|
+
requirement: &70166234091840 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70166234091840
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: trollop
|
27
|
+
requirement: &70166234091360 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70166234091360
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: capistrano
|
38
|
+
requirement: &70166234090880 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70166234090880
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: shoulda
|
49
|
+
requirement: &70166234090400 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70166234090400
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: bundler
|
60
|
+
requirement: &70166234089920 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.0.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70166234089920
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: jeweler
|
71
|
+
requirement: &70166234089440 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.6.4
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70166234089440
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rcov
|
82
|
+
requirement: &70166234088960 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70166234088960
|
91
|
+
description: Git/capistrano workflow automation script with Redmine & Github issue
|
92
|
+
integration
|
93
|
+
email: o.barnett@digitaleseiten.de
|
94
|
+
executables:
|
95
|
+
- stagecoach
|
96
|
+
extensions: []
|
97
|
+
extra_rdoc_files:
|
98
|
+
- LICENSE.txt
|
99
|
+
- README.rdoc
|
100
|
+
files:
|
101
|
+
- .document
|
102
|
+
- .rvmrc
|
103
|
+
- Gemfile
|
104
|
+
- Gemfile.lock
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.rdoc
|
107
|
+
- Rakefile
|
108
|
+
- VERSION
|
109
|
+
- bin/stagecoach
|
110
|
+
- lib/.DS_Store
|
111
|
+
- lib/githooks/commit-msg
|
112
|
+
- lib/stagecoach.rb
|
113
|
+
- lib/stagecoach/capistrano.rb
|
114
|
+
- lib/stagecoach/command_line.rb
|
115
|
+
- lib/stagecoach/config.rb
|
116
|
+
- lib/stagecoach/git.rb
|
117
|
+
- lib/stagecoach/redmine.rb
|
118
|
+
- redmine_stagecoach.gemspec
|
119
|
+
- test/helper.rb
|
120
|
+
- test/test_stagecoach.rb
|
121
|
+
homepage: http://github.com/omnikron/stagecoach
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: 2500404004806684746
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 1.8.15
|
146
|
+
signing_key:
|
147
|
+
specification_version: 3
|
148
|
+
summary: Stagecoach is in ur Redmine, automating ur Git workflow.
|
149
|
+
test_files: []
|