Module: ReleaseTagger

Defined in:
lib/release_tagger.rb,
lib/release_tagger/version.rb

Defined Under Namespace

Classes: Version

Constant Summary collapse

VERSION =
File.read(
  File.join(File.dirname(__FILE__), "..", "..", "VERSION")
).strip

Class Method Summary collapse

Class Method Details

.behind_origin?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/release_tagger.rb', line 68

def behind_origin?
  %x{git fetch origin >/dev/null 2>&1; git diff --stat HEAD...@{u}}.strip != ""
end

.changelog(old_version) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/release_tagger.rb', line 80

def changelog(old_version)
  commits = %x{git log --pretty="format:* %s" v#{old_version}..HEAD}
  unless $?.success?
    raise RuntimeError, "Error getting changelog!"
  end
  commits
end

.color_terminal?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/release_tagger.rb', line 28

def color_terminal?
  ENV["TERM"] =~ /color/
end

.dirty_working_tree?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/release_tagger.rb', line 72

def dirty_working_tree?
  %x{git status --porcelain 2>/dev/null | egrep "^(M| M)"}.strip != ""
end

.err(message) ⇒ Object



52
53
54
# File 'lib/release_tagger.rb', line 52

def err(message)
  $stderr.puts(red(message))
end

.green(string) ⇒ Object



32
33
34
35
36
37
38
# File 'lib/release_tagger.rb', line 32

def green(string)
  if color_terminal?
    "\x1b[0;32m#{string}\x1b[0m"
  else
    string
  end
end

.log(message) ⇒ Object



48
49
50
# File 'lib/release_tagger.rb', line 48

def log(message)
  $stdout.puts(green(message))
end

.on_master_branch?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/release_tagger.rb', line 64

def on_master_branch?
  `git rev-parse --abbrev-ref HEAD`.strip == "master"
end

.red(string) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/release_tagger.rb', line 40

def red(string)
  if color_terminal?
    "\x1b[0;31m#{string}\x1b[0m"
  else
    string
  end
end

.release_message(version) ⇒ Object



76
77
78
# File 'lib/release_tagger.rb', line 76

def release_message(version)
  "Release v#{version}"
end

.run!Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/release_tagger.rb', line 88

def run!
  if ARGV.length != 1
    usage
    exit 1
  end

  release_type = ARGV.first

  if !valid_release_type?(release_type)
    usage
    exit 1
  end

  if !on_master_branch?
    err "You must be on the master branch to make a release"
    exit 1
  end

  if behind_origin?
    err "You are behind the origin/master branch - please pull before releasing."
    exit 1
  end

  if dirty_working_tree?
    err "There are uncommitted changes in the working directory."
    err "Please commit or stash all changes before making a release."
    exit 1
  end

  version_file = Pathname.getwd.join("VERSION")

  if !version_file.exist?
    err "Could not find VERSION file - this must be present to make a release"
    exit 1
  end

  old_version_string = version_file.read.strip
  old_version_parts  = old_version_string.split(".").map(&:to_i)
  old_version        = Version.new(*old_version_parts)
  new_version        = old_version.bump(release_type)

  $stderr.write "This will release version #{new_version}. Are you sure? [y/N]: "
  unless STDIN.gets.strip == "y"
    err "Exiting."
    exit 1
  end

  if !version_file.writable?
    err "Could not write to VERSION file - please check you have write permissions"
    exit 1
  end

  log "Updating VERSION file to #{new_version}"
  version_file.open("w") do |f|
    f.write(new_version.to_s)
  end

  log "Creating release commit"
  commits = changelog(old_version)
  commit_output = %x{git add -u . && git commit -m "#{release_message(new_version)}\n\n#{commits}" 2>&1}
  unless $?.success?
    err "Error committing VERSION update:"
    err commit_output
    exit 1
  end

  log "Adding release tag"
  tag_output = %x{git tag v#{new_version} 2>&1}
  unless $?.success?
    err "Error adding version tag v#{new_version}:"
    err tag_output
    exit 1
  end

  log "Pushing release to origin"
  # Separate `push` and `push --tags` here, because only relatively recent
  # versions of git push both refs and tags with the single command.
  push_output = %x{git push 2>&1 && git push --tags 2>&1}
  unless $?.success?
    err "Error pushing release tag to origin:"
    err push_output
    exit 1
  end
end

.usageObject



56
57
58
# File 'lib/release_tagger.rb', line 56

def usage
  puts "Usage: #{File.basename($0)} (major|minor|patch)"
end

.valid_release_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/release_tagger.rb', line 60

def valid_release_type?(type)
  %w{ major minor patch }.include?(type)
end