build.cake 10.5 KB
Newer Older
RWTH App's avatar
RWTH App committed
1
2
3
4
5
6
#tool nuget:?package=NUnit.ConsoleRunner&version=3.10.0
#tool nuget:?package=vswhere&version=2.8.4
#tool nuget:?package=GitVersion.CommandLine&version=5.1.3

#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.Json&version=4.0.0
#addin nuget:https://api.nuget.org/v3/index.json?package=Newtonsoft.Json&version=11.0.2
RWTH App's avatar
RWTH App committed
7
#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.FileHelpers&version=3.2.1
RWTH App's avatar
RWTH App committed
8
9
10
11
12

using System.Net;
using System.Net.Http;

// Commandline arguments
RWTH App's avatar
RWTH App committed
13
14
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
RWTH App's avatar
RWTH App committed
15
var nugetApiKey = Argument<string>("nugetApiKey", null);
RWTH App's avatar
RWTH App committed
16
17
18
19
var version = Argument("nugetVersion", "");
var gitlabProjectPath = Argument("gitlabProjectPath", "");
var gitlabProjectId = Argument("gitlabProjectId", "");
var gitlabToken = Argument("gitlabToken", "");
RWTH App's avatar
RWTH App committed
20

RWTH App's avatar
RWTH App committed
21
// Define directories
RWTH App's avatar
RWTH App committed
22
23
24
25
26
27
var projects = GetFiles("./**/*.csproj");
var artifactsDir = Directory("./Artifacts");
string nupkgDir;
var solutionFile = GetFiles("./**/*.sln").First();
var projectName = solutionFile.GetFilenameWithoutExtension().ToString();
var nugetSource = "https://api.nuget.org/v3/index.json";
RWTH App's avatar
RWTH App committed
28
29
30
var assemblyInfoSubPath = "Properties/AssemblyInfo.cs";
var semanticVersion = "";
string localNugetFeed;
RWTH App's avatar
RWTH App committed
31
32
33
34

// get latest MSBuild version
var vsLatest  = VSWhereLatest();	
var msBuildPathX64 = (vsLatest == null) ? null : vsLatest.CombineWithFilePath("./MSBuild/Current/Bin/MSBuild.exe");
RWTH App's avatar
RWTH App committed
35

RWTH App's avatar
RWTH App committed
36
37
Setup(context =>{
	nupkgDir = $"{artifactsDir.ToString()}/nupkg";
RWTH App's avatar
RWTH App committed
38
39
40
41
42
43
44
	var branch = GitVersion(new GitVersionSettings {
			UpdateAssemblyInfo = false
		}).BranchName.Replace("/", "-");

	localNugetFeed = $"C:\\coscine\\LocalNugetFeeds\\{branch}";
	Information("{0}", branch);
	Information("Started at {0}", DateTime.Now);
RWTH App's avatar
RWTH App committed
45
});
RWTH App's avatar
RWTH App committed
46

RWTH App's avatar
RWTH App committed
47
Teardown(context =>{
RWTH App's avatar
RWTH App committed
48
	Information("Finished at {0}", DateTime.Now);
RWTH App's avatar
RWTH App committed
49
});
RWTH App's avatar
RWTH App committed
50

RWTH App's avatar
RWTH App committed
51
52
53
54
55
56
57
Task("Clean")
.Description("Cleans all build and artifacts directories")
.Does(() =>{
	var settings = new DeleteDirectorySettings {
		Recursive = true,
		Force = true
	};
RWTH App's avatar
RWTH App committed
58
	
RWTH App's avatar
RWTH App committed
59
	var directoriesToClean = new List<DirectoryPath>();
RWTH App's avatar
RWTH App committed
60
	
RWTH App's avatar
RWTH App committed
61
	foreach(var project in projects) {
RWTH App's avatar
RWTH App committed
62
63
		directoriesToClean.Add(Directory($"{project.GetDirectory()}/obj"));
		directoriesToClean.Add(Directory($"{project.GetDirectory()}/bin"));
RWTH App's avatar
RWTH App committed
64
	}
RWTH App's avatar
RWTH App committed
65
	
RWTH App's avatar
RWTH App committed
66
	directoriesToClean.Add(artifactsDir);
RWTH App's avatar
RWTH App committed
67

RWTH App's avatar
RWTH App committed
68
69
	foreach(var dir in directoriesToClean) {
		Information("Cleaning {0}", dir.ToString());
RWTH App's avatar
RWTH App committed
70
71
		if (DirectoryExists(dir)) {
			DeleteDirectory(dir, settings);
RWTH App's avatar
RWTH App committed
72
73
74
			CreateDirectory(dir);
		} else {
			CreateDirectory(dir);
RWTH App's avatar
RWTH App committed
75
76
		}
	}
RWTH App's avatar
RWTH App committed
77
78
});

RWTH App's avatar
RWTH App committed
79
80
81
Task("Restore")
.Does(() =>{
	NuGetRestore(solutionFile, new NuGetRestoreSettings {
RWTH App's avatar
RWTH App committed
82
83
		NoCache = true,
		FallbackSource = new List<string>{ localNugetFeed },
RWTH App's avatar
RWTH App committed
84
85
86
87
	});
});

Task("Test")
RWTH App's avatar
RWTH App committed
88
.IsDependentOn("Build")
RWTH App's avatar
RWTH App committed
89
90
91
92
93
94
95
.Does(() =>{
	NUnit3($"./src/**/bin/{configuration}/*.Tests.dll", new NUnit3Settings {
		// generate the xml file
		NoResults = false,
		Results = new NUnit3Result[] {
			new NUnit3Result() {
				FileName = $"{artifactsDir}/TestResults.xml",
RWTH App's avatar
RWTH App committed
96
				Transform = $"{Context.Environment.WorkingDirectory}/nunit3-junit.xslt"
RWTH App's avatar
RWTH App committed
97
98
99
			}
		}
	});
RWTH App's avatar
RWTH App committed
100
101
});

RWTH App's avatar
RWTH App committed
102
103
104
105
106
107
Task("GitVersion")
.Does(() => {
	if(string.IsNullOrWhiteSpace(version)) {
		version = GitVersion(new GitVersionSettings {
			UpdateAssemblyInfo = false
		}).NuGetVersionV2;
RWTH App's avatar
RWTH App committed
108
	}
RWTH App's avatar
RWTH App committed
109
110
111
	var index = version.IndexOf("-");
	semanticVersion = index > 0 ? version.Substring(0, index) : version;
	Information("Version: {0}, SemanticVersion: {1}", version, semanticVersion);
RWTH App's avatar
RWTH App committed
112
});
RWTH App's avatar
RWTH App committed
113

RWTH App's avatar
RWTH App committed
114
Task("UpdateAssemblyInfo")
RWTH App's avatar
RWTH App committed
115
.Does(() =>{
RWTH App's avatar
RWTH App committed
116
117
118
	var index = version.IndexOf("-");
	var semanticVersion = index > 0 ? version.Substring(0, index) : version;

RWTH App's avatar
RWTH App committed
119
	foreach(var project in projects) {
RWTH App's avatar
RWTH App committed
120
121
122
123
124
125
126
127
128
129
130
		CreateAssemblyInfo($"{project.GetDirectory()}/{assemblyInfoSubPath}", new AssemblyInfoSettings {
			Product = project.GetFilenameWithoutExtension().ToString(),
			Title = project.GetFilenameWithoutExtension().ToString(),
			Company = "IT Center, RWTH Aachen University",
			Version = semanticVersion,
			FileVersion = semanticVersion,
			InformationalVersion = version,
			Copyright = $"{DateTime.Now.Year} IT Center, RWTH Aachen University",
			Description = $"{project.GetFilenameWithoutExtension().ToString()} is a part of the CoScInE group."
		});
	}
RWTH App's avatar
RWTH App committed
131
});
RWTH App's avatar
RWTH App committed
132

RWTH App's avatar
RWTH App committed
133
134
135
136
137
138
139
140
141
142
143
Task("GitlabRelease")
.IsDependentOn("GitVersion")
.Does(() => {
	var client = new HttpClient();
	client.DefaultRequestHeaders.Add("PRIVATE-TOKEN", gitlabToken);
	
	// get the latest tag
	var result = client.GetAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/repository/tags").Result;
	if(!result.IsSuccessStatusCode) {
		throw new Exception("Tag query failed.");
	}
RWTH App's avatar
RWTH App committed
144

RWTH App's avatar
RWTH App committed
145
146
147
148
	var tagList = result.Content.ReadAsStringAsync().Result;
	var jArray = JArray.Parse(tagList);
	// null if not tags exists yet
	var lastTag = jArray.Select(x => x["name"]).FirstOrDefault();
RWTH App's avatar
RWTH App committed
149

RWTH App's avatar
RWTH App committed
150
151
152
153
154
	var url = $"https://git.rwth-aachen.de/{gitlabProjectPath}";
	
	if(url.EndsWith(".git")) {
		url = url.Substring(0, url.Length - ".git".Length);
	}
RWTH App's avatar
RWTH App committed
155

RWTH App's avatar
RWTH App committed
156
157
158
	if(url.EndsWith("/")) {
		url = url.Substring(0, url.Length - 1);
	}
RWTH App's avatar
RWTH App committed
159

RWTH App's avatar
RWTH App committed
160
161
162
163
164
	var description = "";
	// First line of description
	// Gitlab compare url, if something can be compared
	if(lastTag == null) {
		description = $"# {semanticVersion} ({DateTime.Now.Year}-{DateTime.Now.Month}-{DateTime.Now.Day})\n\n\n";
RWTH App's avatar
RWTH App committed
165
	} else {
RWTH App's avatar
RWTH App committed
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
		description = $"# [{semanticVersion}]({url}/compare/{lastTag}...v{semanticVersion}) ({DateTime.Now.Year}-{DateTime.Now.Month}-{DateTime.Now.Day})\n\n\n";
	}

	// From when will messages be parsed, null results in all messages
	var logParam = "";
	if(lastTag != null) {
		logParam = $"{lastTag}..Head";
	}

	Information(lastTag);

	IEnumerable<string> redirectedStandardOutput;
	var exitCodeWithArgument =
		StartProcess(
			"git",
			new ProcessSettings {
				Arguments = $"log {logParam} --pretty=format:HASH%h:%B",
				RedirectStandardOutput = true
			},
			out redirectedStandardOutput
		);

	var prefixList = new Dictionary<string, List<string>>{
		{"Fix", new List<string>()},
		{"Update", new List<string>()},
		{"New", new List<string>()},
		{"Breaking", new List<string>()},
		{"Docs", new List<string>()},
		{"Build", new List<string>()},
		{"Upgrade", new List<string>()},
		{"Chore", new List<string>()},
	};

	var currentHash = "";
	// Output last line of process output.
	foreach(var line in redirectedStandardOutput) {
		var commitMessage = "";
		if(line.StartsWith("HASH")) {
			currentHash = line.Substring("HASH".Length);
			currentHash = currentHash.Substring(0, currentHash.IndexOf(":"));
			commitMessage = line.Substring(currentHash.Length + line.IndexOf(currentHash) + 1);
		} else {
			commitMessage = line;
RWTH App's avatar
RWTH App committed
209
		}
RWTH App's avatar
RWTH App committed
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

		foreach(var kv in prefixList) {
			if(commitMessage.StartsWith($"{kv.Key}:")) {
				kv.Value.Add($"* {commitMessage.Substring(kv.Key.Length + 1).Trim()} {currentHash}");
				break;
			}
		};
	}
	
	foreach(var kv in prefixList) {
		if(kv.Value.Any()) {
			description += $" ### {kv.Key}\n\n";
			foreach(var line in kv.Value) {
				description += $"{line}\n";
			}
			description += "\n";
		}
	}
	// correctly escape the json newlines
	description = description.Replace("\n", "\\n");
	Information("Description: {0}", description);

	// create tag
	result = client.PostAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/repository/tags?tag_name=v{semanticVersion}&ref=master", null).Result;
	Information("Create tag: {0}", result.Content.ReadAsStringAsync().Result);
	if(!result.IsSuccessStatusCode) {
		throw new Exception("Tag creation failed.");
	}

	// create release
	var json = $"{{\"name\": \"v{semanticVersion}\", \"tag_name\": \"v{semanticVersion}\", \"description\": \"{description}\"}}";
	var content = new StringContent(json, Encoding.UTF8, "application/json");
	result = client.PostAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/releases", content).Result;
	Information("Create release: {0}", result.Content.ReadAsStringAsync().Result);
	if(!result.IsSuccessStatusCode) {
		throw new Exception("Release creation failed.");
RWTH App's avatar
RWTH App committed
246
	}
RWTH App's avatar
RWTH App committed
247
248
249
});

Task("Build")
RWTH App's avatar
RWTH App committed
250
.IsDependentOn("Clean")
RWTH App's avatar
RWTH App committed
251
252
.IsDependentOn("GitVersion")
.IsDependentOn("UpdateAssemblyInfo")
RWTH App's avatar
RWTH App committed
253
254
255
.IsDependentOn("Restore")
.Does(() =>{
		var frameworkSettingsWindows = new MSBuildSettings {
RWTH App's avatar
RWTH App committed
256
			Configuration = configuration
RWTH App's avatar
RWTH App committed
257
258
259
260
261
262
263
264
265
		};
		
		frameworkSettingsWindows.ToolPath = msBuildPathX64;
		frameworkSettingsWindows.WorkingDirectory = Context.Environment.WorkingDirectory;

		if (configuration.Equals("Release")) {
			frameworkSettingsWindows.WithProperty("DebugSymbols", "false");
			frameworkSettingsWindows.WithProperty("DebugType", "None");
		}
RWTH App's avatar
RWTH App committed
266

RWTH App's avatar
RWTH App committed
267
		// Use MSBuild
RWTH App's avatar
RWTH App committed
268
		Information("Building {0}", solutionFile);
RWTH App's avatar
RWTH App committed
269
		MSBuild(solutionFile, frameworkSettingsWindows);
RWTH App's avatar
RWTH App committed
270
});
RWTH App's avatar
RWTH App committed
271

RWTH App's avatar
RWTH App committed
272
273
274
275
276
277
Task("NugetPack")
.IsDependentOn("Build")
.Does(() =>{
	foreach(var project in projects) {
			var nuspec = $"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec";
			if(!project.ToString().EndsWith(".Tests") && FileExists(nuspec))
RWTH App's avatar
RWTH App committed
278
			{
RWTH App's avatar
RWTH App committed
279
280
281
282
283
284
285
286
287
288
				var settings = new NuGetPackSettings 
				{
					OutputDirectory = nupkgDir,
					Version = version,
					Properties = new Dictionary<string, string>
					{
						{ "Configuration", configuration}
					}
				};				
				NuGetPack(project.ToString(), settings);
RWTH App's avatar
RWTH App committed
289
290
			}
		}
RWTH App's avatar
RWTH App committed
291
});
RWTH App's avatar
RWTH App committed
292

RWTH App's avatar
RWTH App committed
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
Task("NugetPush")
.IsDependentOn("NugetPack")
.Does(() =>{
	var nupkgs = GetFiles($"{nupkgDir}/*.nupkg");
	Information("Need to push {0} packages", nupkgs.Count);
	if(!String.IsNullOrWhiteSpace(nugetApiKey)) {
		foreach(var nupkg in nupkgs) {
			Information("Pushing {0}", nupkg);
			NuGetPush(nupkg, new NuGetPushSettings {
				Source = nugetSource,
				ApiKey = nugetApiKey
			});
		}
	} else {
		Information("NugetApiKey is not set. Can't push.");
		throw new Exception("NugetApiKey is not set. Can't push.");
	}
RWTH App's avatar
RWTH App committed
310
311
});

RWTH App's avatar
RWTH App committed
312
Task("CopyToArtifacts")
RWTH App's avatar
RWTH App committed
313
.Does(() =>{
RWTH App's avatar
RWTH App committed
314
315
316
317
318
319
320
321
322
	foreach(var project in projects) {
		if(!project.GetDirectory().ToString().EndsWith(".Tests")
		&& !FileExists($"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec")
		&& DirectoryExists(project.GetDirectory()))
		{
			Information("Copying {0}/* to {1}", $"{project.GetDirectory()}/bin/{configuration}", artifactsDir);
			CopyDirectory($"{project.GetDirectory()}/bin/{configuration}/", artifactsDir);
		}
	}
RWTH App's avatar
RWTH App committed
323
324
});

RWTH App's avatar
RWTH App committed
325
326
327
328
329
330
331
332
333
334
335
Task("NugetPushLocal")
.IsDependentOn("NugetPack")
.Does(() =>{	
	var nupkgs = GetFiles($"{nupkgDir}/*.nupkg");
	foreach(var nupkg in nupkgs) {
		if(!DirectoryExists(localNugetFeed)) {
			CreateDirectory(localNugetFeed);
		}
		CopyFile(nupkg.ToString(), $"{localNugetFeed}\\{nupkg.GetFilename()}");
	}
});
RWTH App's avatar
RWTH App committed
336

RWTH App's avatar
RWTH App committed
337
338
339
340
341
342
343
344
345
346
Task("Prerelease")
.IsDependentOn("Build")
.IsDependentOn("CopyToArtifacts")
.IsDependentOn("NugetPushLocal");

Task("Release")
.IsDependentOn("NugetPack")
.IsDependentOn("CopyToArtifacts")
.IsDependentOn("NugetPushLocal")
.IsDependentOn("NugetPush");
RWTH App's avatar
RWTH App committed
347
348

Task("Default")
RWTH App's avatar
RWTH App committed
349
.IsDependentOn("Test");
RWTH App's avatar
RWTH App committed
350
351

RunTarget(target);