Skip to content
Snippets Groups Projects
Select Git revision
  • gitkeep
  • dev protected
  • master default protected
  • Hotfix/2562-organizations
  • Issue/2518-docs
  • Sprint/2022-01
  • Sprint/2021-19
  • Issues/0028-maxQuotaFix
  • Sprint/2021-08
  • Product/1414-fhPrivileges
  • Topic/1425-fhPrivileges
  • Sprint/2020-20
  • Product/704-basicReporting
  • Topic/1051-basicReporting protected
  • Hotfix/986-fixOrganizationParserPipeline
  • Hotfix/953-fileNameWithSpace
  • Sprint/2020-13
  • Product/754-automatedImport
  • Topic/888-automatedImport protected
  • v1.5.0
  • v1.4.0
  • v1.3.2
  • v1.3.1
  • v1.3.0
  • v1.2.0
  • v1.1.2
  • v1.1.1
  • v1.1.0
28 results

build.cake

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    build.cake 11.86 KiB
    #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=6.0.1
    #addin nuget:https://api.nuget.org/v3/index.json?package=Newtonsoft.Json&version=11.0.2
    #addin nuget:https://api.nuget.org/v3/index.json?package=Cake.FileHelpers&version=4.0.1
    
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    
    // Commandline arguments
    var target = Argument("target", "Default");
    var configuration = Argument("configuration", "Release");
    var nugetApiKey = Argument<string>("nugetApiKey", null);
    var version = Argument("nugetVersion", "");
    var gitlabProjectPath = Argument("gitlabProjectPath", "");
    var gitlabProjectId = Argument("gitlabProjectId", "");
    var gitlabToken = Argument("gitlabToken", "");
    var branch = Argument("branch", "");
    var gitAuthorEmail = Argument("gitAuthorEmail", "");
    var gitAuthorName = Argument("gitAuthorName", "");
    
    // Define directories
    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";
    var assemblyInfoSubPath = "Properties/AssemblyInfo.cs";
    var semanticVersion = "";
    string localNugetFeed;
    
    // get latest MSBuild version
    var vsLatest  = VSWhereLatest();	
    var msBuildPathX64 = (vsLatest == null) ? null : vsLatest.CombineWithFilePath("./MSBuild/Current/Bin/MSBuild.exe");
    
    Setup(context =>{
    	nupkgDir = $"{artifactsDir.ToString()}/nupkg";
    	var branch = GitVersion(new GitVersionSettings {
    			UpdateAssemblyInfo = false
    		}).BranchName.Replace("/", "-");
    
    	localNugetFeed = $"C:\\coscine\\LocalNugetFeeds\\{branch}";
    	Information("{0}", branch);
    	Information("Started at {0}", DateTime.Now);
    });
    
    Teardown(context =>{
    	Information("Finished at {0}", DateTime.Now);
    });
    
    Task("Clean")
    .Description("Cleans all build and artifacts directories")
    .Does(() =>{
    	var settings = new DeleteDirectorySettings {
    		Recursive = true,
    		Force = true
    	};
    	
    	var directoriesToClean = new List<DirectoryPath>();
    	
    	foreach(var project in projects) {
    		directoriesToClean.Add(Directory($"{project.GetDirectory()}/obj"));
    		directoriesToClean.Add(Directory($"{project.GetDirectory()}/bin"));
    	}
    	
    	directoriesToClean.Add(artifactsDir);
    
    	foreach(var dir in directoriesToClean) {
    		Information("Cleaning {0}", dir.ToString());
    		if (DirectoryExists(dir)) {
    			DeleteDirectory(dir, settings);
    			CreateDirectory(dir);
    		} else {
    			CreateDirectory(dir);
    		}
    	}
    });
    
    Task("Restore")
    .Does(() =>{
    	NuGetRestore(solutionFile, new NuGetRestoreSettings {
    		NoCache = true,
    		FallbackSource = new List<string>{ localNugetFeed },
    	});
    });
    
    Task("Test")
    .IsDependentOn("Build")
    .Does(() =>{
    	NUnit3($"./src/**/bin/{configuration}/*.Tests.dll", new NUnit3Settings {
    		// generate the xml file
    		NoResults = false,
    		Results = new NUnit3Result[] {
    			new NUnit3Result() {
    				FileName = $"{artifactsDir}/TestResults.xml",
    				Transform = $"{Context.Environment.WorkingDirectory}/nunit3-junit.xslt"
    			}
    		}
    	});
    });
    
    Task("GitVersion")
    .Does(() => {
    	if(string.IsNullOrWhiteSpace(version)) {
    		version = GitVersion(new GitVersionSettings {
    			UpdateAssemblyInfo = false
    		}).NuGetVersionV2;
    	}
    	var index = version.IndexOf("-");
    	semanticVersion = index > 0 ? version.Substring(0, index) : version;
    	Information("Version: {0}, SemanticVersion: {1}", version, semanticVersion);
    });
    
    Task("UpdateAssemblyInfo")
    .Does(() =>{
    	var index = version.IndexOf("-");
    	var semanticVersion = index > 0 ? version.Substring(0, index) : version;
    
    	foreach(var project in projects) {
    		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."
    		});
    	}
    });
    
    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.");
    	}
    
    	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();
    
    	var url = $"https://git.rwth-aachen.de/{gitlabProjectPath}";
    	
    	if(url.EndsWith(".git")) {
    		url = url.Substring(0, url.Length - ".git".Length);
    	}
    
    	if(url.EndsWith("/")) {
    		url = url.Substring(0, url.Length - 1);
    	}
    
    	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";
    	} else {
    		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;
    		}
    
    		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.");
    	}
    });
    
    Task("Build")
    .IsDependentOn("Clean")
    .IsDependentOn("GitVersion")
    .IsDependentOn("UpdateAssemblyInfo")
    .IsDependentOn("Restore")
    .Does(() =>{
    		var frameworkSettingsWindows = new MSBuildSettings {
    			Configuration = configuration
    		};
    		
    		frameworkSettingsWindows.ToolPath = msBuildPathX64;
    		frameworkSettingsWindows.WorkingDirectory = Context.Environment.WorkingDirectory;
    
    		if (configuration.Equals("Release")) {
    			frameworkSettingsWindows.WithProperty("DebugSymbols", "false");
    			frameworkSettingsWindows.WithProperty("DebugType", "None");
    		}
    
    		// Use MSBuild
    		Information("Building {0}", solutionFile);
    		MSBuild(solutionFile, frameworkSettingsWindows);
    });
    
    Task("NugetPack")
    .IsDependentOn("Build")
    .Does(() =>{
    	foreach(var project in projects) {
    			var nuspec = $"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec";
    			if(!project.ToString().EndsWith(".Tests") && FileExists(nuspec))
    			{
    				var settings = new NuGetPackSettings 
    				{
    					OutputDirectory = nupkgDir,
    					Version = version,
    					Properties = new Dictionary<string, string>
    					{
    						{ "Configuration", configuration}
    					}
    				};				
    				NuGetPack(project.ToString(), settings);
    			}
    		}
    });
    
    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.");
    	}
    });
    
    Task("CopyToArtifacts")
    .Does(() =>{
    	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);
    		}
    	}
    });
    
    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()}");
    	}
    });
    
    Task("PushToGit")
    .Does(() =>{
    	if(FileExists($"{artifactsDir}/index.ttl"))
    	{
    
    		var client = new HttpClient();
    		var content = FileReadText($"{artifactsDir}/index.ttl");
    		var request = new HttpRequestMessage
    		{
    			Method = HttpMethod.Put,
    			RequestUri = new Uri("https://git.rwth-aachen.de/api/v4/projects/47542/repository/files/index.ttl"),
    			Headers =
    			{
    				{ "private-token", gitlabToken },
    			},
    			Content = new StringContent($"{{\"branch\": \"{branch}\", \"author_email\":\"{gitAuthorEmail}\", \"author_name\": \"{gitAuthorName}\", \"content\": \"{content.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\"", "\\\"")}\", \"commit_message\": \"update file\"}}")
    			{
    				Headers =
    				{
    					ContentType = new MediaTypeHeaderValue("application/json")
    				}
    			}
    		};
    		using (var response = client.SendAsync(request).Result)
    		{
    			var body = response.Content.ReadAsStringAsync().Result;
    			Information("IsSuccess: {0}", response.IsSuccessStatusCode);
    			Information("StatusCode: {0}", response.StatusCode);
    			Information("Response: {0}", response.Content.ReadAsStringAsync().Result);
    			response.EnsureSuccessStatusCode();
    		}		
    	} else {
    		Information("No index ttl found. Nothing to do.");
    	}
    });
    
    Task("Prerelease")
    .IsDependentOn("Build")
    .IsDependentOn("CopyToArtifacts")
    .IsDependentOn("NugetPushLocal");
    
    Task("Release")
    .IsDependentOn("NugetPack")
    .IsDependentOn("CopyToArtifacts")
    .IsDependentOn("NugetPushLocal")
    .IsDependentOn("NugetPush");
    
    Task("Default")
    .IsDependentOn("Test");
    
    RunTarget(target);