Skip to content

Commit

Permalink
Merge pull request #71 from feelobot/release_notes
Browse files Browse the repository at this point in the history
add release notes ability
  • Loading branch information
feelobot committed Jun 18, 2015
2 parents d54ea1f + d234711 commit d17b51c
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 57 deletions.
1 change: 1 addition & 0 deletions lib/gantree/deploy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'colorize'
require 'librato/metrics'
require_relative 'release_notes'
require_relative 'wiki'
require_relative 'notification'

module Gantree
Expand Down
108 changes: 67 additions & 41 deletions lib/gantree/release_notes.rb
Original file line number Diff line number Diff line change
@@ -1,57 +1,83 @@
require 'aws-sdk'

module Gantree
class ReleaseNotes
def initialize wiki, app, hash
@application = app
@new_hash = hash
@wiki_url = wiki
end
attr_reader :current_sha
attr_writer :beanstalk
def initialize wiki, env_name, current_sha
@env_name = env_name
@wiki = wiki
@org = wiki.split("/")[0..-2].join("/")
@current_sha = current_sha
end

def create
get_release_notes
write_release_notes
commit_release_notes
def beanstalk
return @beanstalk if @beanstalk
@beanstalk = Aws::ElasticBeanstalk::Client.new(
:region => ENV['AWS_REGION'] || "us-east-1"
)
end

def get_release_notes
rl_dir = "/tmp/wiki_release_notes"
FileUtils.rm_rf(rl_dir) if File.directory? rl_dir
`git clone #{@wiki_url} /tmp/wiki_release_notes/`

def environment
beanstalk.describe_environments(:environment_names => [@env_name]).environments.first
end

def write_release_notes
wiki_dir = "/tmp/wiki_release_notes/"
release_notes_file = "Release-notes-br-#{@application}.md"
path_to_wiki_file = "#{wiki_dir}#{release_notes_file}"
`touch #{path_to_wiki_file}` unless File.exist? "#{path_to_wiki_file}"
`printf "#{release_notes}\n\n" | cat - #{path_to_wiki_file} > #{path_to_wiki_file}.tmp && mv #{path_to_wiki_file}.tmp #{path_to_wiki_file}`

def previous_tag
environment.version_label
end

def release_notes
time = Time.now.strftime("%a, %e %b %Y %H:%M:%S %z")
"#{time} [#{last_deployed_hash}...#{@new_hash}](https://github.com/br/#{@application}/compare/#{last_deployed_hash}...#{@new_hash})"
def previous_sha
previous_tag.split("-")[2]
end

def last_deployed_hash
get_latest_tag.split("-").last
def app_name
name = environment.application_name
name.include?("-") ? name.split("-")[1] : name # TODO: business logic
end

def get_latest_tag
Aws.config[:credentials]
beanstalk = Aws::ElasticBeanstalk::Client.new
resp = beanstalk.describe_application_versions(
application_name: @application,
)
label = resp["application_versions"].select {|version| version["version_label"].include?("br-master") }.first
if label
label["version_label"].split("-")[0..2].join('-')
else
raise "No Master Tags Deployed:\n #{resp["application_versions"].inspect}"
500
def now
@now ||= Time.now.strftime("%a, %e %b %Y %H:%M:%S %z")
end

def commits
return @commits if @commits
# Get commits for this release
commits = git_log
commits = commits.split("COMMIT_SEPARATOR")
commits = commits.collect { |x| x.strip }
# only grab the line with the lighthouse info
# or the first line if no lighthouse info
commits = commits.collect do |x|
lines = x.split("\n")
lines.select { |y| y =~ /\[#\d+/ }.first || lines.first
end.compact
# rid of clean up ticket format [#1234 state:xxx]
commits = commits.map do |x|
x.gsub(/\[#(\d+)(.*)\]/, '\1')
end
@commits = commits.uniq.sort
end
def commit_release_notes
`cd /tmp/wiki_release_notes && git add . && git commit -am "Updated release notes" && git push origin master`

def git_log
execute("git log --no-merges --pretty=format:'%B COMMIT_SEPARATOR' #{@left}..#{@right}").strip
end

def execute(cmd)
`#{cmd}`
end

def notes
compare = "#{previous_sha}...#{current_sha}"
notes = <<-EOL
"#{@env_name} #{now} [compare](#{@org}/#{app_name}/compare/#{compare})"
#{commits.collect{|x| "* #{x}" }.join("\n")}
EOL
end

def create
filename = "Release-notes-br-#{app_name}.md" # business logic
Gantree::Wiki.new(notes, filename, @wiki).update
end
end
end
end
57 changes: 57 additions & 0 deletions lib/gantree/wiki.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module Gantree
class Wiki
attr_reader :wiki_path
attr_accessor :file_path
def initialize(notes, filename, wiki_url, path='/tmp/')
@notes = notes
@wiki_url = wiki_url
wiki_path = wiki_url.split("/").last.sub(".git","")
@wiki_path = "#{path}#{wiki_path}"
@file_path = "#{@wiki_path}/#{filename}"
end

def update
pull
added = add_to_top
push if added
end

def pull
puts "Updating wiki cached repo".colorize(:yellow)
if File.exist?(@wiki_path)
Dir.chdir(@wiki_path) do
execute("git checkout master") unless execute("git branch").include?("* master")
execute("git pull origin master")
end
else
dirname = File.dirname(@wiki_path)
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
cmd = "cd #{dirname} && git clone #{@wiki_url}"
execute(cmd)
end
end

def add_to_top
data = IO.read(@file_path) if File.exist?(@file_path)
File.open(@file_path, "w") do |file|
file.write(@notes)
file.write("\n\n")
file.write(data) if data
end
true
end

def push
Dir.chdir(@wiki_path) do
basename = File.basename(@file_path)
execute("git add #{basename}")
execute(%Q|git commit -m "Update release notes"|)
execute("git push origin master")
end
end

def execute(cmd)
`#{cmd}`
end
end
end
57 changes: 42 additions & 15 deletions spec/lib/gantree/1_release_notes_spec.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,52 @@

require "spec_helper"
require "pry"

describe Gantree::ReleaseNotes do
before(:all) do
@app = "cms"
@hash = "9ef330b"
@wiki = "git@github.com:br/dev.wiki.git"
@release_notes = Gantree::ReleaseNotes.new(@wiki,@app,@hash)
@release_notes.instance_variable_set("@beanstalk", Aws::ElasticBeanstalk::Client.new(stub_responses: true))
@wiki = "https://github.com/br/dev.wiki.git"
@env_name = "stag-rails-app-s1"
@current_sha = "d961c96"
@rn = Gantree::ReleaseNotes.new(@wiki, @env_name, @current_sha)
@rn.beanstalk = Aws::ElasticBeanstalk::Client.new(stub_responses: true)
end

def mock_environment
double(
version_label: "br-master-fb3e1cd-23.zip",
application_name: "rails"
)
end

it "can retrieve the latest deployed master tag" do
expect(@release_notes.send(:get_latest_tag)).to include "br-master"
allow(@rn).to receive(:environment).and_return(mock_environment)
expect(@rn.previous_tag).to include "br-master"
end

it "can get the last deployed hash" do
expect(@release_notes.send(:last_deployed_hash).length).to eq 7

it "can retrieve the latest deployed sha from the master tag" do
allow(@rn).to receive(:environment).and_return(mock_environment)
expect(@rn.previous_sha).to eq "fb3e1cd"
end

it "can show release notes" do
expect(@release_notes.send(:release_notes)).to include "github.com/br/#{@app}/compare/#{@release_notes.send(:last_deployed_hash)}..."

it "can retrieve the current sha" do
expect(@rn.current_sha).to eq @current_sha
end

it "should generate notes" do
allow(@rn).to receive(:environment).and_return(mock_environment)
allow(@rn).to receive(:git_log).and_return(git_log_mock)
notes = @rn.notes
puts notes if ENV['DEBUG']
expect(notes).to include(@env_name)
expect(notes).to include(@rn.now)
expect(notes).to include("compare")
expect(notes).to include("test up controller")
end

it "should grab commit messages" do
allow(@rn).to receive(:git_log).and_return(git_log_mock)
commits = @rn.commits
p commits if ENV['DEBUG']
expect(commits).to be_a(Array)
expect(commits).to include("commit 1")
expect(commits).to include("commit 2")
end
end
end
49 changes: 49 additions & 0 deletions spec/lib/gantree/wiki_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require "spec_helper"

describe Gantree::Wiki do
before(:all) do
@notes = "fake_release_notes"
filename = "Release-notes-br-rails.md"
wiki = "git@github.com:br/dev.wiki.git"
@wiki = Gantree::Wiki.new(@notes, filename, wiki, "tmp/")
end

def fake_clone_dir
FileUtils.mkdir_p(@wiki.wiki_path)
end

it "should clone and pull" do
FileUtils.rm_rf(@wiki.wiki_path) if ENV['CLEAN']
allow(@wiki).to receive(:execute).and_return(fake_clone_dir)
@wiki.pull
folder_created = File.exist?(@wiki.wiki_path)
# puts "@wiki.wiki_path #{@wiki.wiki_path.inspect}"
expect(folder_created).to be true
@wiki.pull
end

it "should add notes to the top" do
FileUtils.mkdir("tmp") unless File.exist?("tmp")
@wiki.file_path = "tmp/Release-notes-br-rails.md"
FileUtils.rm_f(@wiki.file_path)
@wiki.add_to_top
notes = IO.read(@wiki.file_path)
expect(notes).to eq "#{@notes}\n\n"

@wiki.add_to_top
notes = IO.read(@wiki.file_path)
expect(notes).to eq "#{@notes}\n\n#{@notes}\n\n"
end

it "should push" do
allow(@wiki).to receive(:execute).and_return(fake_clone_dir)
@wiki.push
end

it "should update" do
allow(@wiki).to receive(:pull)
allow(@wiki).to receive(:add_to_top).and_return(true)
allow(@wiki).to receive(:push)
@wiki.update
end
end
23 changes: 22 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,31 @@ module Helpers
def execute(cmd)
puts "Running: #{cmd}" if ENV['DEBUG']
out = `#{cmd}`
raise "Stack Trance Found: \n #{out}" if out.include? "Error"
raise "Stack Trace Found: \n #{out}" if out.include? "Error"
puts out if ENV['DEBUG']
out
end

def git_log_mock
<<-EOL
commit 1
COMMIT_SEPARATOR
commit 2
COMMIT_SEPARATOR
test up controller
COMMIT_SEPARATOR
commit 4
COMMIT_SEPARATOR
add to test
note with newlie
COMMIT_SEPARATOR
fix bug
COMMIT_SEPARATOR
whatever
COMMIT_SEPARATOR
EOL
end

end

RSpec.configure do |c|
Expand Down

0 comments on commit d17b51c

Please sign in to comment.