lib/hu/deploy.rb in hu-1.2.5 vs lib/hu/deploy.rb in hu-1.3.0
- old
+ new
@@ -10,10 +10,11 @@
require 'awesome_print'
require 'chronic_duration'
require 'tempfile'
require 'thread_safe'
require 'io/console'
+require 'rugged'
module Hu
class Cli < Optix::Cli
class Deploy < Optix::Cli
@@shutting_down = false
@@ -33,36 +34,70 @@
end
def deploy(cmd, opts, argv)
trap('INT') { shutdown; safe_abort; exit 1 }
at_exit {
- if 130 == $!.status
+ if $!.class == SystemExit && 130 == $!.status
shutdown
puts
safe_abort
- exit $!.status
end
}
- unless File.exists? '.git'
+ begin
+ @git = Rugged::Repository.discover('.')
+ rescue Rugged::RepositoryError => e
puts
- puts "You need to be inside the working directory of the app that you wish to deploy.".color(:red)
+ puts "Git error: #{e}".color(:red)
+ puts "You need to be inside the working copy of the app that you wish to deploy.".color(:red)
puts
safe_abort
print TTY::Cursor.prev_line
exit 1
end
+ Dir.chdir(@git.workdir)
+
+ if @git.config['branch.master.remote'] != 'origin'
+ puts
+ puts "ERROR: Remote of branch 'master' does not point to 'origin'.".color(:red)
+ puts
+ puts " Sorry, we need an origin here. We really do."
+ puts
+ exit 1
+ end
+
+ if @git.config['gitflow.branch.master'].nil?
+ puts
+ puts "ERROR: This repository doesn't seem to be git-flow enabled.".color(:red)
+ puts
+ puts " Please run 'git flow init'."
+ puts
+ exit 1
+ end
+
+ unless @git.config['gitflow.prefix.versiontag'].nil? ||
+ @git.config['gitflow.prefix.versiontag'].empty?
+ puts
+ puts "ERROR: git-flow version prefix configured.".color(:red)
+ puts
+ puts " Please use this command to remove the prefix:"
+ puts
+ puts " git config --add gitflow.prefix.versiontag ''".bright
+ puts
+ exit 1
+ end
+
push_url = get_heroku_git_remote
wc_update = Thread.new { update_working_copy }
app = heroku_app_by_git(push_url)
if app.nil?
puts
- puts "FATAL: Found no heroku app for git remote #{push_url}".color(:red)
+ puts "ERROR: Found no heroku app for git remote #{push_url}".color(:red)
puts " Are you logged into the right heroku account?".color(:red)
puts
puts " Please run 'git remote rm heroku'. Then run 'hu deploy' again to select a new remote."
puts
exit 1
@@ -70,11 +105,11 @@
pipeline_name, stag_app_id, prod_app_id = heroku_pipeline_details(app)
if app['id'] != stag_app_id
puts
- puts "FATAL: The git remote 'heroku' points to app '#{app['name']}'".color(:red)
+ puts "ERROR: The git remote 'heroku' points to app '#{app['name']}'".color(:red)
puts " which is not in stage 'staging'".color(:red)+
" of pipeline '#{pipeline_name}'.".color(:red)
puts
puts " The referenced app MUST be the staging member of the pipeline."
@@ -92,13 +127,38 @@
busy 'update working copy', :dots
wc_update.join
unbusy
highest_version = find_highest_version_tag
- tiny_bump = Versionomy.parse(highest_version).bump(:tiny).to_s
- minor_bump = Versionomy.parse(highest_version).bump(:minor).to_s
- major_bump = Versionomy.parse(highest_version).bump(:major).to_s
+ begin
+ highest_versionomy = Versionomy.parse(highest_version)
+ rescue
+ highest_versionomy = Versionomy.parse('v0.0.0')
+ end
+
+ all_tags = Set.new(@git.references.to_a("refs/tags/*").collect{|e| e.target.name})
+
+ tiny_bump = highest_versionomy.dup
+ minor_bump = highest_versionomy.dup
+ major_bump = highest_versionomy.dup
+
+ loop do
+ tiny_bump = tiny_bump.bump(:tiny)
+ break unless all_tags.include? tiny_bump.to_s
+ end
+ loop do
+ minor_bump = minor_bump.bump(:minor)
+ break unless all_tags.include? minor_bump.to_s
+ end
+ loop do
+ major_bump = major_bump.bump(:major)
+ break unless all_tags.include? tiny_bump.to_s
+ end
+ tiny_bump = tiny_bump.to_s
+ minor_bump = minor_bump.to_s
+ major_bump = major_bump.to_s
+
likely_next_version = tiny_bump
release_tag, branch_already_exists = prompt_for_release_tag(likely_next_version, likely_next_version, true)
prompt = TTY::Prompt.new
@@ -112,11 +172,15 @@
release_branch_exists = branch_exists?("release/#{release_tag}")
if release_branch_exists
puts "\nThis release will be "+release_tag.color(:red).bright
unless highest_version == 'v0.0.0'
- changelog=`git log --pretty=format:" - %s" #{highest_version}..HEAD 2>/dev/null` unless highest_version == 'v0.0.0'
+ env = {
+ 'PREVIOUS_TAG' => highest_version,
+ 'RELEASE_TAG' => release_tag
+ }
+ changelog=create_changelog(env) unless highest_version == 'v0.0.0'
unless changelog.empty?
puts "\nChanges since "+highest_version.bright+":"
puts changelog
end
end
@@ -164,20 +228,23 @@
old_editor = ENV['EDITOR']
tf = Tempfile.new('hu-tag')
tf.write "#{release_tag}\n#{changelog}"
tf.close
ENV['EDITOR'] = "cp #{tf.path}"
- unless 0 == finish_release(release_tag)
+ env = {
+ 'PREVIOUS_TAG' => highest_version,
+ 'RELEASE_TAG' => release_tag
+ }
+ unless 0 == finish_release(release_tag, env)
abort_merge
puts "*** ERROR! Push did not complete. *** ".color(:red)
end
ENV['EDITOR'] = old_editor
anykey
when :push_to_staging
push_command = "git push #{push_url} release/#{release_tag}:master -f"
`#{push_command}`
- puts
anykey
when :abort_ask
puts if delete_branch("release/#{release_tag}")
exit 0
when :bump_tiny
@@ -535,11 +602,19 @@
# Push develop to origin
git push origin develop
EOS
end
- def finish_release(release_tag)
+ def finish_release(release_tag, env)
+ env.each { |k,v| ENV[k] = v }
+ if File.executable? '.hu/hooks/pre_release'
+ run_each <<-EOS.strip_heredoc
+ # Run pre-release hook
+ .hu/hooks/pre_release
+ EOS
+ end
+
run_each <<-EOS.strip_heredoc
:return
# Finish release
git flow release finish #{release_tag}
@@ -561,10 +636,19 @@
# Abort failed merge
git merge --abort
EOS
end
+ def create_changelog(env)
+ if File.executable? '.hu/hooks/changelog'
+ env.each { |k,v| ENV[k] = v }
+ `.hu/hooks/changelog`
+ else
+ `git log --pretty=format:" - %s" #{env['PREVIOUS_TAG']}..HEAD 2>/dev/null`
+ end
+ end
+
def shutdown
@@shutting_down = true
unbusy
end
@@ -575,11 +659,11 @@
@@spinner = TTY::Spinner.new("\e[0;1m#{msg}#{msg.empty? ? '' : ' '}\e[0m\e[32;1m:spinner\e[0m", options)
@@spinner.start
end
def unbusy
- @@spinner.stop
+ @@spinner&.stop
printf "\e[?25h"
end
def with_spinner(msg='', format=:classic, &block)
busy(msg, format)
@@ -587,10 +671,10 @@
unbusy
end
def anykey
puts TTY::Cursor.hide
- print "--- Press any key to continue ---".color(:cyan).inverse
+ print "--- Press any key ---".color(:cyan)
STDIN.getch
print TTY::Cursor.clear_line + TTY::Cursor.show
end
def dp(label, *args)