This repository has been archived by the owner on Dec 24, 2019. It is now read-only.
/
release.rb
89 lines (80 loc) · 2.69 KB
/
release.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
meta :release do
def repo
@repo ||= Babushka::GitRepo.new('.')
end
def release_tag
version.to_s.sub(/^(?!v)/, 'v')
end
def git_log from, to
log shell("git log --graph --date-order --pretty='format:%C(yellow)%h%Cblue%d%Creset %s %C(white) %an, %ar%Creset' #{from}..#{to}")
end
def latest_tag
version = shell('git tag').lines.map(&:to_version).max
"v#{version}"
end
end
dep 'release', :version, :version_file, :template => 'release' do
requires 'release exists'.with(version, version_file)
setup {
if latest_tag > release_tag
log_warn "There is already a newer release than #{release_tag} (#{latest_tag})."
end
}
met? {
shell("git ls-remote --tags origin").split("\n").grep(%r{refs/tags/#{release_tag}$}).any?
}
meet {
log_block "Pushing #{release_tag} to origin" do
shell! 'git push origin'
shell! 'git push origin --tags'
end
}
end
# This is the messy one.
dep 'release exists', :version, :version_file, :template => 'release' do
version_file.default!('./lib/babushka.rb')
def update_version!
sed_expression = %q{s/^(\s+VERSION\s+=\s+).*/\1'%s'/} % version
shell! 'sed', '-i.bak', '-E', sed_expression, version_file
shell! 'rm', "#{version_file}.bak"
end
requires 'repo on master'
requires_when_unmet 'repo clean', 'descendant of last release', 'build passing'
met? {
repo.resolve(release_tag)
}
meet {
git_log "#{latest_tag}", 'HEAD'
confirm "Create #{release_tag} from #{latest_tag} + this changeset?" do
log_block("Writing version to #{version_file}") { update_version! }
log_shell "Committing", "git commit #{version_file} --message '#{release_tag} - ' --edit"
log_shell "Tagging", "git tag '#{release_tag}'"
end
}
end
dep 'repo on master', :template => 'release' do
met? {
repo.current_branch == 'master' || unmeetable!("Releases have to be made from master.")
}
end
dep 'repo clean', :template => 'release' do
met? {
repo.repo_shell("git diff") # Clear git's internal cache, which sometimes says the repo is dirty when it isn't.
repo.clean? || unmeetable!("The remote repo has local changes.")
}
end
dep 'build passing' do
met? {
log_shell("Running specs", "bundle exec rspec --format documentation") ||
unmeetable!("Can't make a release when the build is broken.")
}
end
dep 'descendant of last release', :template => 'release' do
met? {
if shell?("git rev-list HEAD | grep #{repo.resolve(latest_tag)}")
log_ok "The most recent version (#{latest_tag} / #{repo.resolve(latest_tag)}) is a parent of HEAD."
else
unmeetable!("The most recent version (#{latest_tag} / #{repo.resolve(latest_tag)}) isn't a parent of HEAD.")
end
}
end