forked from FakeItEasy/FakeItEasy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rakefile.rb
295 lines (241 loc) · 9.12 KB
/
rakefile.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
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
require 'albacore'
require 'fileutils'
nuget_command = "Source/packages/NuGet.CommandLine.2.8.0/tools/NuGet.exe"
nunit_command = "Source/packages/NUnit.Runners.2.6.3/tools/nunit-console.exe"
mspec_command = "Source/packages/Machine.Specifications.0.8.0/tools/mspec-clr4.exe"
solution = "Source/FakeItEasy.sln"
assembly_info = "Source/CommonAssemblyInfo.cs"
version = IO.read(assembly_info)[/AssemblyInformationalVersion\("([^"]+)"\)/, 1]
nuspec = "Source/FakeItEasy.nuspec"
output_folder = "Build"
unit_tests = [
"Source/FakeItEasy.Net35.Tests/bin/Release/FakeItEasy.Net35.Tests.dll",
"Source/FakeItEasy.Tests/bin/Release/FakeItEasy.Tests.dll",
"Source/FakeItEasy-SL.Tests/Bin/Release/FakeItEasy-SL.Tests.dll"
]
integration_tests = [
"Source/FakeItEasy.IntegrationTests/bin/Release/FakeItEasy.IntegrationTests.dll",
"Source/FakeItEasy.IntegrationTests.VB/bin/Release/FakeItEasy.IntegrationTests.VB.dll"
]
specs = [
"Source/FakeItEasy.Specs/bin/Release/FakeItEasy.Specs.dll"
]
repo = 'FakeItEasy/FakeItEasy'
release_issue_labels = ['0 - Backlog', 'P2', 'build', 'documentation']
release_issue_body = <<-eos
**Ready** when all other issues forming part of the release are **Done**.
- [ ] run code analysis in VS in *Release* mode and address violations (send a regular PR which must be merged before continuing)
- [ ] check build
- edit draft release in [GitHub UI](https://github.com/FakeItEasy/FakeItEasy/releases):
- [ ] complete release notes, mentioning non-owner contributors, if any
- [ ] attach nupkg
- [ ] publish the release
- [ ] push NuGet package
- [ ] copy release notes from GitHub to NuGet
- [ ] de-list pre-release NuGet packages if present
- [ ] update website with contributors list (if in place)
- [ ] tweet, mentioning contributors and post link as comment here for easy retweeting ;-)
- [ ] post tweet in JabbR ([fakeiteasy][1] and [general-chat][2]) and Gitter ([FakeItEasy/FakeItEasy][3])
- [ ] post links to the NuGet and GitHub release in each issue in this milestone, with thanks to contributors
- [ ] use `rake set_version[new_version]` to
- create a new branch
- change CommonAssemblyInfo.cs to expected minor version (of form _xx.yy.zz_)
- push to origin
- create PR to upstream master
- [ ] use `rake create_milestone` to
- create a new milestone for the next release
- create new issue (like this one) for the next release, adding it to the new milestone
- create a new draft GitHub Release
- [ ] close all issues on this milestone
- [ ] close this milestone
[1]: https://jabbr.net/#/rooms/fakeiteasy
[2]: https://jabbr.net/#/rooms/general-chat
[3]: https://gitter.im/FakeItEasy/FakeItEasy
eos
release_body = <<-eos
* **Changed**: _<description>_ - _#<issue number>_
* **New**: _<description>_ - _#<issue number>_
* **Fixed**: _<description>_ - _#<issue number>_
With special thanks for contributions to this release from:
* _<user's actual name>_ - _@<github_userid>_
eos
ssl_cert_file_url = "http://curl.haxx.se/ca/cacert.pem"
Albacore.configure do |config|
config.log_level = :verbose
end
desc "Execute default tasks"
task :default => [ :vars, :unit, :integ, :spec, :pack ]
desc "Print all variables"
task :vars do
print_vars(local_variables.sort.map { |name| [name.to_s, (eval name.to_s)] })
end
desc "Restore NuGet packages"
exec :restore do |cmd|
cmd.command = nuget_command
cmd.parameters "restore #{solution}"
end
desc "Clean solution"
msbuild :clean do |msb|
FileUtils.rmtree output_folder
msb.properties = { :configuration => :Release }
msb.targets = [ :Clean ]
msb.solution = solution
end
desc "Update version number"
task :set_version, :new_version do |asm, args|
current_branch = `git rev-parse --abbrev-ref HEAD`.strip()
if current_branch != 'master'
fail("ERROR: Current branch is '#{current_branch}'. Must be on branch 'master' to set new version.")
end if
new_version = args.new_version
new_branch = "set-version-to-" + new_version
require 'octokit'
ssl_cert_file = get_temp_ssl_cert_file(ssl_cert_file_url)
client = Octokit::Client.new(:netrc => true)
puts "Creating branch '#{new_branch}'..."
`git checkout -b #{new_branch}`
puts "Created branch '#{new_branch}'."
puts "Setting version to '#{new_version}' in '#{assemblyinfo}'..."
Rake::Task["set_version_in_assemblyinfo"].invoke(new_version)
puts "Set version to '#{new_version}' in '#{assembly_info}'."
puts "Committing '#{assembly_info}'..."
`git commit -m "setting version to #{new_version}" #{assembly_info}`
puts "Committed '#{assembly_info}'."
puts "Pushing '#{new_branch}' to origin..."
`git push origin #{new_branch}"`
puts "Pushed '#{new_branch}' to origin."
puts "Creating pull request..."
pull_request = client.create_pull_request(
repo,
"master",
"#{client::user.login}:#{new_branch}",
"set version to #{new_version} for next release",
"preparing for #{new_version}"
)
puts "Created pull request \##{pull_request.number} '#{pull_request.title}'."
end
desc "Update assembly info"
assemblyinfo :set_version_in_assemblyinfo, :new_version do |asm, args|
new_version = args.new_version
net_version = new_version.split(/[^\d.]/, 2).first
# not using asm.version and asm.file_version due to StyleCop violations
asm.custom_attributes = {
:AssemblyVersion => net_version,
:AssemblyFileVersion => net_version,
:AssemblyInformationalVersion => new_version
}
asm.input_file = assembly_info
asm.output_file = assembly_info
end
desc "Build solution"
msbuild :build => [:clean, :restore] do |msb|
msb.properties = { :configuration => :Release }
msb.targets = [ :Build ]
msb.solution = solution
end
task :create_output_folder do
FileUtils.mkpath output_folder
end
desc "Execute unit tests"
nunit :unit => [:build, :create_output_folder] do |nunit|
nunit.command = nunit_command
nunit.assemblies unit_tests
nunit.options "/result=#{output_folder}/TestResult.Unit.xml"
end
desc "Execute integration tests"
nunit :integ => [:build, :create_output_folder] do |nunit|
nunit.command = nunit_command
nunit.assemblies integration_tests
nunit.options "/result=#{output_folder}/TestResult.Integration.xml"
end
desc "Execute specifications"
mspec :spec => [:build] do |mspec|
mspec.command = mspec_command
mspec.assemblies specs
end
desc "create the nuget package"
exec :pack => [:build, :create_output_folder] do |cmd|
cmd.command = nuget_command
cmd.parameters "pack #{nuspec} -Version #{version} -OutputDirectory #{output_folder}"
end
desc "create new milestone, release issue and release"
task :create_milestone do |t|
require 'octokit'
ssl_cert_file = get_temp_ssl_cert_file(ssl_cert_file_url)
client = Octokit::Client.new(:netrc => true)
release_description = version + ' release'
puts "Creating milestone '#{version}'..."
milestone = client.create_milestone(
repo,
version,
:description => release_description
)
puts "Created milestone '#{version}'."
puts "Creating issue '#{release_description}'..."
issue = client.create_issue(
repo,
release_description,
release_issue_body,
:labels => release_issue_labels,
:milestone => milestone.number
)
puts "Created issue \##{issue.number} '#{release_description}'."
puts "Creating release '#{version}'..."
client.create_release(
repo,
version,
:name => version,
:draft => true,
:body => release_body
)
puts "Created release '#{version}'."
end
def print_vars(variables)
scalars = []
vectors = []
variables.each { |name, value|
if value.respond_to?('each')
vectors << [name, value.map { |v| v.to_s }]
else
string_value = value.to_s
lines = string_value.lines
if lines.length > 1
vectors << [name, lines]
else
scalars << [name, string_value]
end
end
}
scalar_name_column_width = scalars.map { |s| s[0].length }.max
scalars.each { |name, value|
puts "#{name}:#{' ' * (scalar_name_column_width - name.length)} #{value}"
}
puts
vectors.each { |name, value|
puts "#{name}:"
puts value.map {|v| " " + v }
puts ""
}
end
# Get a temporary SSL cert file if necessary.
# If ENV["SSL_CERT_FILE"] is set, will return nil.
# Otherwise, attempts to download a known
# SSL cert file, sets ENV["SSL_CERT_FILE"]
# to point at it, and returns the file (mostly so it will
# stay in scope while it's needed).
def get_temp_ssl_cert_file(ssl_cert_file_url)
ssl_cert_file_path = ENV["SSL_CERT_FILE"]
if ssl_cert_file_path
return nil
end
puts "Environment variable SSL_CERT_FILE is not set. Downloading a cert file from '#{ssl_cert_file_url}'..."
require 'open-uri'
require 'tempfile'
file = Tempfile.new('ssl_cert_file')
file.binmode
file << open(ssl_cert_file_url).read
file.close
ENV["SSL_CERT_FILE"] = file.path
puts "Downloaded cert file to '#{ENV['SSL_CERT_FILE']}'."
return file
end