-
Notifications
You must be signed in to change notification settings - Fork 759
/
Copy pathcreate_release.rake
165 lines (129 loc) · 6.04 KB
/
create_release.rake
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
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
# frozen_string_literal: true
require "English"
desc("Releases both the gem and node package using the given version.
IMPORTANT: the gem version must be in valid rubygem format (no dashes).
It will be automatically converted to a valid yarn semver by the rake task
for the node package version. This only makes a difference for pre-release
versions such as `3.0.0.beta.1` (yarn version would be `3.0.0-beta.1`).
This task depends on the gem-release (ruby gem) and release-it (node package)
which are installed via `bundle install` and `yarn global add release-it`
1st argument: The new version in rubygem format (no dashes). Pass no argument to
automatically perform a patch version bump.
2nd argument: Perform a dry run by passing 'true' as a second argument.
Note, accept defaults for npmjs options. Script will pause to get 2FA tokens.
Example: `rake release[2.1.0,false]`")
task :create_release, %i[gem_version dry_run] do |_t, args|
args_hash = args.to_hash
is_dry_run = Release.object_to_boolean(args_hash[:dry_run])
puts "is_dry_run: #{is_dry_run}" if is_dry_run
gem_version = args_hash.fetch(:gem_version, "").strip
npm_version = gem_version.empty? ? "" : Release.convert_rubygem_to_npm_version(gem_version)
Release.update_the_local_project
Release.ensure_there_is_nothing_to_commit
# Preparing for release
# Updating the pre-bundled react
puts "Updating react"
Rake::Task["react:update"].invoke
# Updating ReactRailsUJS
puts "Updating ujs:update"
Rake::Task["ujs:update"].invoke
Release.make_sure_react_and_ujs_are_updated_and_commited
Release.bump_gem_version(gem_version, is_dry_run)
Release.release_the_new_npm_version(npm_version, is_dry_run)
Release.release_the_new_gem_version(is_dry_run)
Release.push
end
# A collection of helper functions for gem and npm release
module Release
extend FileUtils
class << self
def gem_root
File.expand_path("..", __dir__)
end
# Executes a string or an array of strings in a shell in the given directory in an unbundled environment
def sh_in_dir(dir, *shell_commands)
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
puts "sh_in_dir, shell_commands = #{shell_commands}"
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
shell_commands.flatten.compact.each { |shell_command| sh %(cd #{dir} && #{shell_command.strip}) }
end
def commit_the_changes(message)
sh_in_dir(gem_root, "git commit -am '#{Shellwords.escape(message)}'") unless nothing_to_commit?
end
def nothing_to_commit?
status = `git status --porcelain`
$CHILD_STATUS.success? && status == ""
end
def ensure_there_is_nothing_to_commit
status = `git status --porcelain`
return if $CHILD_STATUS.success? && status == ""
error = if $CHILD_STATUS.success?
"You have uncommitted code. Please commit or stash your changes before continuing"
else
"You do not have Git installed. Please install Git, and commit your changes before continuing"
end
raise(error)
end
def make_sure_react_and_ujs_are_updated_and_commited
status = `git status --porcelain`
return if $CHILD_STATUS.success? && status == ""
error = if $CHILD_STATUS.success?
<<-MSG
Running react:update and ujs:update resulted in uncommitted changes.
Please commit those changes & confirm that CI passes before continuing.
MSG
else
"You do not have Git installed. Please install Git, and commit your changes before continuing"
end
raise(error)
end
def object_to_boolean(value)
[true, "true", "yes", 1, "1", "t"].include?(value.instance_of?(String) ? value.downcase : value)
end
def convert_rubygem_to_npm_version(gem_version)
regex_match = gem_version.match(/(\d+\.\d+\.\d+)[.-]?(.+)?/)
return "#{regex_match[1]}-#{regex_match[2]}" if regex_match[2]
regex_match[1].to_s
end
def update_the_local_project
puts "Pulling latest commits from remote repository"
sh_in_dir(gem_root, "git pull --rebase")
sh_in_dir(gem_root, "bundle")
sh_in_dir(gem_root, "yarn")
sh_in_dir(File.join(gem_root, "react-builds"), "yarn")
raise "Failed in pulling latest changes from default remore repository." unless $CHILD_STATUS.success?
rescue Errno::ENOENT
raise "Ensure you have Git and Bundler installed before continuing."
end
def bump_gem_version(gem_version, is_dry_run)
puts "Bumping gem version"
Release.sh_in_dir(
gem_root,
"gem bump --no-commit #{gem_version == '' ? '' : %(--version #{gem_version})}",
"bundle install",
(is_dry_run ? nil : commit_the_changes("Bump version to #{gem_version}"))
)
end
def release_the_new_gem_version(is_dry_run)
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
puts "Use the OTP for RubyGems!"
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
sh_in_dir(gem_root, "gem release --push --tag") unless is_dry_run
end
def release_the_new_npm_version(npm_version, is_dry_run)
puts "Making npm release, #{is_dry_run ? 'dry run' : 'real run'}"
# Will bump the yarn version, commit, tag the commit, push to repo, and release on yarn
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
puts "Use the OTP for NPM!"
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
release_it_command = +"release-it"
release_it_command << " #{npm_version}" unless npm_version == ""
release_it_command << " --npm.publish --no-git.requireCleanWorkingDir"
release_it_command << " --dry-run --verbose" if is_dry_run
sh_in_dir(gem_root, release_it_command)
end
def push
sh_in_dir(gem_root, "git push")
end
end
end