diff --git a/.gitignore b/.gitignore index 7c2965eda294e35b644059bf493b44aa290aebb6..363c7b2ec0283c1fb1b2d1d239fe573caffc5663 100644 --- a/.gitignore +++ b/.gitignore @@ -262,5 +262,6 @@ __pycache__/ *.pyc #cake -tools/ -dist/ \ No newline at end of file +tools/* +!tools/packages.config +dist/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 50709f679a4c80a0c4af614eecdae531b7905e2b..70f41bc841fef797f60350032c50e96f2d99fe9b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,123 +1,65 @@ stages: - - build - test - docs - - update-assembly-info - - build-release - - semantic-release - release - - pre_release + - releasetrigger -build: - stage: build - script: - - PowerShell .\build.ps1 -Target Build -Configuration Debug - variables: - GIT_STRATEGY: clone - except: - variables: - - $GITLAB_USER_ID == $GIT_BOT_USER_ID - -test: +cake:Test: stage: test script: - - PowerShell .\build.ps1 -Target LinterAndTest -Configuration Debug + - PowerShell .\build.ps1 -Target Test -Configuration Debug variables: - GIT_STRATEGY: none - dependencies: - - build + GIT_STRATEGY: clone artifacts: reports: junit: "./Artifacts/TestResults.xml" paths: - "./Artifacts/*" except: - variables: - - $GITLAB_USER_ID == $GIT_BOT_USER_ID - -update-assembly-info: - stage: update-assembly-info - script: - - PowerShell .\build.ps1 -Target UpdateAssemblyInfo - variables: - GIT_STRATEGY: none - dependencies: - - test - only: - - master - except: - variables: - - $GITLAB_USER_ID == $GIT_BOT_USER_ID - -build-release: - stage: build-release - script: - - PowerShell .\build.ps1 -Target Build -Configuration Release - - PowerShell .\build.ps1 -Configuration Release -Target NugetPack - variables: - GIT_STRATEGY: none - dependencies: - - update-assembly-info - only: - master - except: - variables: - - $GITLAB_USER_ID == $GIT_BOT_USER_ID + - tags docs: stage: docs script: - .\publishDocs.ps1 $GITLAB_TOKEN variables: - GIT_STRATEGY: none - dependencies: - - test - only: - - master - except: - variables: - - $GITLAB_USER_ID == $GIT_BOT_USER_ID - -semantic-release: - stage: semantic-release - script: - - PowerShell .\build.ps1 -Target SemanticRelease - variables: - GIT_STRATEGY: none - dependencies: - - test + GIT_STRATEGY: clone only: - - master - except: - variables: - - $GITLAB_USER_ID == $GIT_BOT_USER_ID + - tags -release: - before_script: +cake:Release: stage: release script: - - PowerShell .\build.ps1 -Target Build -Configuration Release - - PowerShell .\build.ps1 -Configuration Release -Target NugetPack - - PowerShell .\build.ps1 -Configuration Release -Target NugetPush --nugetApiKey="$NUGET_API_KEY" + - PowerShell .\build.ps1 -Target Release -Configuration Release --nugetApiKey="${NUGET_API_KEY}" variables: GIT_STRATEGY: clone + dependencies: + - cake:Test artifacts: paths: - "./Artifacts/*" only: - tags -pre_release: - stage: pre_release +cake:Prerelease: + stage: release script: - - PowerShell .\build.ps1 -Target Build -Configuration Release + - PowerShell .\build.ps1 -Target Prerelease -Configuration Release variables: GIT_STRATEGY: clone + dependencies: + - cake:Test artifacts: paths: - "./Artifacts/*" - when: manual except: - tags - master - \ No newline at end of file + +cake:GitlabRelease: + stage: releasetrigger + script: + - PowerShell .\build.ps1 -Target GitlabRelease --GitlabProjectPath="${CI_PROJECT_PATH}" --gitlabProjectId="${CI_PROJECT_ID}" --gitlabToken="${GITLAB_TOKEN}" + only: + - master \ No newline at end of file diff --git a/GitVersion.yml b/GitVersion.yml new file mode 100644 index 0000000000000000000000000000000000000000..1bdc0fe219f5f35d8a024a66d9fd715f44539640 --- /dev/null +++ b/GitVersion.yml @@ -0,0 +1,7 @@ +mode: ContinuousDeployment +next-version: 1.0.0 +major-version-bump-message: 'Breaking:' +minor-version-bump-message: '(Update|New):' +patch-version-bump-message: 'Fix:' +no-bump-message: '.*' +commit-message-incrementing: Enabled \ No newline at end of file diff --git a/build.cake b/build.cake index 4827ab9efc72cf3b541ac20b05fa38295795369a..81648ff61bbee492e1bc7b4390eb8e0cc33d3056 100644 --- a/build.cake +++ b/build.cake @@ -1,65 +1,53 @@ -#tool nuget:?package=NUnit.ConsoleRunner&version=3.9.0 -#tool nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.3.4 -#tool nuget:?package=vswhere&version=2.6.7 - -#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.Npx&version=1.6.0 -#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.Issues&version=0.7.1 -#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.Issues.InspectCode&version=0.7.1 +#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 #addin nuget:https://api.nuget.org/v3/index.json?package=Cake.FileHelpers&version=3.2.1 -////////////////////////////////////////////////////////////////////// -// ARGUMENTS -////////////////////////////////////////////////////////////////////// + +using System.Net; +using System.Net.Http; + +// 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", ""); -////////////////////////////////////////////////////////////////////// -// PREPARATION -////////////////////////////////////////////////////////////////////// -// Define directories. +// Define directories var projects = GetFiles("./**/*.csproj"); var artifactsDir = Directory("./Artifacts"); string nupkgDir; var solutionFile = GetFiles("./**/*.sln").First(); var projectName = solutionFile.GetFilenameWithoutExtension().ToString(); -var assemblyInfoSubPath = "Properties/AssemblyInfo.cs"; 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"); -// Error rules for resharper -// Example: {"InconsistentNaming", "RedundantUsingDirective"}; -string[] resharperErrorRules = {}; -// Paths to exclude from dupFinder -List<string> dupFinderExcludePatterns = projects.Select( x => $"{x.GetDirectory().ToString()}/{assemblyInfoSubPath}").ToList(); -string[] dupFinderExcludeCodeRegionsByNameSubstring = { "DupFinder Exclusion" }; - -Action <NpxSettings> requiredSemanticVersionPackages = settings => - settings.AddPackage("semantic-release") - .AddPackage("@semantic-release/commit-analyzer") - .AddPackage("@semantic-release/release-notes-generator") - .AddPackage("@semantic-release/gitlab") - .AddPackage("@semantic-release/git") - .AddPackage("@semantic-release/exec") - .AddPackage("conventional-changelog-eslint"); - -/////////////////////////////////////////////////////////////////////////////// -// SETUP / TEARDOWN -/////////////////////////////////////////////////////////////////////////////// Setup(context =>{ nupkgDir = $"{artifactsDir.ToString()}/nupkg"; - Information("Running tasks..."); + 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 running tasks."); + Information("Finished at {0}", DateTime.Now); }); -////////////////////////////////////////////////////////////////////// -// TASKS -////////////////////////////////////////////////////////////////////// Task("Clean") .Description("Cleans all build and artifacts directories") .Does(() =>{ @@ -68,70 +56,36 @@ Task("Clean") Force = true }; - var directoriesToDelete = new List<DirectoryPath>(); + var directoriesToClean = new List<DirectoryPath>(); foreach(var project in projects) { - directoriesToDelete.Add(Directory($"{project.GetDirectory()}/obj")); - directoriesToDelete.Add(Directory($"{project.GetDirectory()}/bin")); + directoriesToClean.Add(Directory($"{project.GetDirectory()}/obj")); + directoriesToClean.Add(Directory($"{project.GetDirectory()}/bin")); } - directoriesToDelete.Add(artifactsDir); + directoriesToClean.Add(artifactsDir); - foreach(var dir in directoriesToDelete) { + foreach(var dir in directoriesToClean) { + Information("Cleaning {0}", dir.ToString()); if (DirectoryExists(dir)) { - Information($"Cleaning path {dir} ..."); DeleteDirectory(dir, settings); + CreateDirectory(dir); + } else { + CreateDirectory(dir); } } }); Task("Restore") .Does(() =>{ - // Restore all NuGet packages. - Information($"Restoring {solutionFile}..."); NuGetRestore(solutionFile, new NuGetRestoreSettings { - NoCache = true + NoCache = true, + FallbackSource = new List<string>{ localNugetFeed }, }); }); -Task("DupFinder") -.Description("Find duplicates in the code") -.Does(() =>{ - var settings = new DupFinderSettings() { - ShowStats = true, - ShowText = true, - OutputFile = $"{artifactsDir}/dupfinder.xml", - ExcludeCodeRegionsByNameSubstring = dupFinderExcludeCodeRegionsByNameSubstring, - ExcludePattern = dupFinderExcludePatterns.ToArray(), - ThrowExceptionOnFindingDuplicates = true - }; - DupFinder(solutionFile, settings); -}); - -Task("InspectCode") -.Description("Inspect the code using Resharper's rule set") -.Does(() =>{ - var settings = new InspectCodeSettings() { - SolutionWideAnalysis = true, - OutputFile = $"{artifactsDir}/inspectcode.xml", - ThrowExceptionOnFindingViolations = false - }; - InspectCode(solutionFile, settings); - - var issues = ReadIssues( - InspectCodeIssuesFromFilePath($"{artifactsDir}/inspectcode.xml"), Context.Environment.WorkingDirectory); - - Information("{0} issues are found.", issues.Count()); - - var errorIssues = issues.Where(issue =>resharperErrorRules.Any(issue.Rule.Contains)).ToList(); - - if (errorIssues.Any()) { - var errorMessage = errorIssues.Aggregate(new StringBuilder(), (stringBuilder, issue) =>stringBuilder.AppendFormat("FileName: {0} Line: {1} Message: {2}{3}", issue.AffectedFileRelativePath, issue.Line, issue.Message, Environment.NewLine)); - throw new CakeException($"{errorIssues.Count} errors detected: {Environment.NewLine}{errorMessage}."); - } -}); - Task("Test") +.IsDependentOn("Build") .Does(() =>{ NUnit3($"./src/**/bin/{configuration}/*.Tests.dll", new NUnit3Settings { // generate the xml file @@ -139,92 +93,167 @@ Task("Test") Results = new NUnit3Result[] { new NUnit3Result() { FileName = $"{artifactsDir}/TestResults.xml", - Transform = Context.Environment.WorkingDirectory + "/nunit3-junit.xslt" + Transform = $"{Context.Environment.WorkingDirectory}/nunit3-junit.xslt" } } }); }); -Task("NugetPush") -.Does(() =>{ - var nupkgs = GetFiles($"{nupkgDir}/*.nupkg"); - - Information("Need to push {0} packages", nupkgs.Count); - foreach(var nupkg in nupkgs) { - Information("Pushing {0}", nupkg); - NuGetPush(nupkg, new NuGetPushSettings { - Source = nugetSource, - ApiKey = nugetApiKey - }); +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("NugetPack") +Task("UpdateAssemblyInfo") .Does(() =>{ + var index = version.IndexOf("-"); + var semanticVersion = index > 0 ? version.Substring(0, index) : version; + foreach(var project in projects) { - var nuspec = $"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec"; - if(!project.ToString().EndsWith(".Tests") - && FileExists(nuspec)) - { - Information("Packing {0}...", nuspec); - - - - if(!DirectoryExists(nupkgDir)) { - CreateDirectory(nupkgDir); - } - - NuGetPack(project.ToString() ,new NuGetPackSettings - { - OutputDirectory = nupkgDir, - Properties = new Dictionary<string, string> { {"Configuration", "Release"}} - }); - } - } + 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."); + } -Task("UpdateAssemblyInfo") -.Does(() =>{ - Information("Running semantic-release in dry run mode to extract next semantic version number"); - - string[] semanticReleaseOutput; - Npx("semantic-release", "--dry-run", requiredSemanticVersionPackages, out semanticReleaseOutput); + 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(); - Information(string.Join(Environment.NewLine, semanticReleaseOutput)); + var url = $"https://git.rwth-aachen.de/{gitlabProjectPath}"; + + if(url.EndsWith(".git")) { + url = url.Substring(0, url.Length - ".git".Length); + } - var nextSemanticVersionNumber = ExtractNextSemanticVersionNumber(semanticReleaseOutput); + if(url.EndsWith("/")) { + url = url.Substring(0, url.Length - 1); + } - if (nextSemanticVersionNumber == null) { - Warning("There are no relevant changes. AssemblyInfo won't be updated!"); + 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 { - Information("Next semantic version number is {0}", nextSemanticVersionNumber); - - var assemblyVersion = $"{nextSemanticVersionNumber}.0"; - - 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 = assemblyVersion, - FileVersion = assemblyVersion, - InformationalVersion = assemblyVersion, - Copyright = $"{DateTime.Now.Year} IT Center, RWTH Aachen University", - Description = $"{project.GetFilenameWithoutExtension().ToString()} is a part of the CoScInE group." - }); + 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(() =>{ - if (IsRunningOnWindows()) { var frameworkSettingsWindows = new MSBuildSettings { - Configuration = configuration, - Restore = true + Configuration = configuration }; frameworkSettingsWindows.ToolPath = msBuildPathX64; @@ -234,74 +263,89 @@ Task("Build") frameworkSettingsWindows.WithProperty("DebugSymbols", "false"); frameworkSettingsWindows.WithProperty("DebugType", "None"); } + // Use MSBuild - Information($"Building {solutionFile}"); + Information("Building {0}", solutionFile); MSBuild(solutionFile, frameworkSettingsWindows); - } - else { - var frameworkSettingsUnix = new XBuildSettings { - Configuration = configuration - }; +}); - if (configuration.Equals("Release")) { - frameworkSettingsUnix.WithProperty("DebugSymbols", "false"); - frameworkSettingsUnix.WithProperty("DebugType", "None"); - } - // Use XBuild - Information($"Building {solutionFile}"); - XBuild(solutionFile, frameworkSettingsUnix); - } - - if (configuration.Equals("Release")) { - if(!DirectoryExists(artifactsDir)) { - CreateDirectory(artifactsDir); - } - - foreach(var project in projects) { - if(!project.GetDirectory().ToString().EndsWith(".Tests") - && !FileExists($"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec")) +Task("NugetPack") +.IsDependentOn("Build") +.Does(() =>{ + foreach(var project in projects) { + var nuspec = $"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec"; + if(!project.ToString().EndsWith(".Tests") && FileExists(nuspec)) { - Information($"Copying {project.GetDirectory()}/bin/{configuration}/* to {artifactsDir}"); - CopyDirectory($"{project.GetDirectory()}/bin/{configuration}/", artifactsDir); + 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("SemanticRelease") +Task("CopyToArtifacts") .Does(() =>{ - Npx("semantic-release", requiredSemanticVersionPackages); + 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("Linter") -.Description("Run DupFinder and InspectCode") -.IsDependentOn("DupFinder") -.IsDependentOn("InspectCode"); +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("LinterAndTest") -.Description("Run Linter and Tests") -.IsDependentOn("Linter") -.IsDependentOn("Test"); +Task("Prerelease") +.IsDependentOn("Build") +.IsDependentOn("CopyToArtifacts") +.IsDependentOn("NugetPushLocal"); + +Task("Release") +.IsDependentOn("NugetPack") +.IsDependentOn("CopyToArtifacts") +.IsDependentOn("NugetPushLocal") +.IsDependentOn("NugetPush"); Task("Default") -.IsDependentOn("Clean") -.IsDependentOn("Restore") -.IsDependentOn("DupFinder") -.IsDependentOn("InspectCode") -.IsDependentOn("Build") .IsDependentOn("Test"); -////////////////////////////////////////////////////////////////////// -// EXECUTION -////////////////////////////////////////////////////////////////////// RunTarget(target); - -/////////////////////////////////////////////////////////////////////////////// -// Helpers -/////////////////////////////////////////////////////////////////////////////// -string ExtractNextSemanticVersionNumber(string[] semanticReleaseOutput) { - var extractRegEx = new System.Text.RegularExpressions.Regex("^.+next release version is (?<SemanticVersionNumber>.*)$"); - - return semanticReleaseOutput.Select(line =>extractRegEx.Match(line).Groups["SemanticVersionNumber"].Value).Where(line =>!string.IsNullOrWhiteSpace(line)).SingleOrDefault(); -} diff --git a/tools/packages.config b/tools/packages.config new file mode 100644 index 0000000000000000000000000000000000000000..14aef3bf00189e621993b61ccea2e4a203e73b9b --- /dev/null +++ b/tools/packages.config @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Cake" version="0.36.0" /> +</packages>