Skip to content
Snippets Groups Projects
Commit 25c7f9c2 authored by Marcel Nellesen's avatar Marcel Nellesen
Browse files

Merge branch 'Sprint/2020-05' into 'master'

Sprint/2020-05

See merge request coscine/cs/configuration!15
parents 62524027 5db21610
Branches
Tags v1.5.0
1 merge request!15Sprint/2020-05
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs
# Database connection for t4 class generation from database
**/*.generated.cs
# Build results # Build results
[Dd]ebug/ [Dd]ebug/
[Dd]ebugPublic/ [Dd]ebugPublic/
......
stages: stages:
- build
- test - test
- docs
- update-assembly-info
- build-release
- semantic-release
- release - release
- releasetrigger
build: cake:Test:
stage: build
script:
- PowerShell .\build.ps1 -Target Build -Configuration Debug
variables:
GIT_STRATEGY: clone
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
test:
stage: test stage: test
script: script:
- PowerShell .\build.ps1 -Target LinterAndTest -Configuration Debug - PowerShell .\build.ps1 -Target Test -Configuration Debug
variables: variables:
GIT_STRATEGY: none GIT_STRATEGY: clone
dependencies:
- build
artifacts: artifacts:
reports: reports:
junit: "./Artifacts/TestResults.xml" junit: "./Artifacts/TestResults.xml"
paths: paths:
- "./Artifacts/*" - "./Artifacts/*"
except: 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 - master
except: - tags
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
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: cake:Release:
stage: semantic-release stage: release
script: script:
- PowerShell .\build.ps1 -Target SemanticRelease - PowerShell .\build.ps1 -Target Release -Configuration Release --nugetApiKey="${NUGET_API_KEY}"
variables: variables:
GIT_STRATEGY: none GIT_STRATEGY: clone
dependencies: dependencies:
- test - cake:Test
artifacts:
paths:
- "./Artifacts/*"
only: only:
- master - tags
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
release: cake:Prerelease:
before_script:
stage: release stage: release
script: script:
- PowerShell .\build.ps1 -Target Build -Configuration Release - PowerShell .\build.ps1 -Target Prerelease -Configuration Release
- PowerShell .\build.ps1 -Configuration Release -Target NugetPack
- PowerShell .\build.ps1 -Configuration Release -Target NugetPush --nugetApiKey="$NUGET_API_KEY"
variables: variables:
GIT_STRATEGY: clone GIT_STRATEGY: clone
dependencies:
- cake:Test
artifacts: artifacts:
paths: paths:
- "./Artifacts/*" - "./Artifacts/*"
only: except:
- tags - tags
- master
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
{
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "eslint"
}],
["@semantic-release/release-notes-generator", {
"preset": "eslint",
}],
["@semantic-release/gitlab", {
"preset": "eslint",
"gitlabUrl": "https://git.rwth-aachen.de"
}],
["@semantic-release/exec", {
"prepareCmd" : "echo ${nextRelease.version}",
"publishCmd" : "echo test"
}],
["@semantic-release/git", {
"preset": "eslint",
"assets": "src/**/Properties/AssemblyInfo.cs",
"message": "Chore: ${nextRelease.version}\n\n${nextRelease.notes}"
}]
]
}
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
MIT License MIT License
Copyright (c) 2019 RWTH Aachen University Copyright (c) 2020 RWTH Aachen University
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
#tool nuget:?package=NUnit.ConsoleRunner&version=3.9.0 #tool nuget:?package=NUnit.ConsoleRunner&version=3.10.0
#tool nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.3.4 #tool nuget:?package=vswhere&version=2.8.4
#tool nuget:?package=vswhere&version=2.6.7 #tool nuget:?package=GitVersion.CommandLine&version=5.1.3
#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.Npx&version=1.3.0 #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=Cake.Issues&version=0.6.2 #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.Issues.InspectCode&version=0.6.1 #addin nuget:https://api.nuget.org/v3/index.json?package=Cake.FileHelpers&version=3.2.1
#addin nuget:https://api.nuget.org/v3/index.json?package=Cake.FileHelpers&version=3.1.0
////////////////////////////////////////////////////////////////////// using System.Net;
// ARGUMENTS using System.Net.Http;
//////////////////////////////////////////////////////////////////////
// Commandline arguments
var target = Argument("target", "Default"); var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release"); var configuration = Argument("configuration", "Release");
var nugetApiKey = Argument<string>("nugetApiKey", null); var nugetApiKey = Argument<string>("nugetApiKey", null);
var version = Argument("nugetVersion", "");
var gitlabProjectPath = Argument("gitlabProjectPath", "");
var gitlabProjectId = Argument("gitlabProjectId", "");
var gitlabToken = Argument("gitlabToken", "");
////////////////////////////////////////////////////////////////////// // Define directories
// PREPARATION
//////////////////////////////////////////////////////////////////////
// Define directories.
var projects = GetFiles("./**/*.csproj"); var projects = GetFiles("./**/*.csproj");
var artifactsDir = Directory("./Artifacts"); var artifactsDir = Directory("./Artifacts");
string nupkgDir; string nupkgDir;
var solutionFile = GetFiles("./**/*.sln").First(); var solutionFile = GetFiles("./**/*.sln").First();
var projectName = solutionFile.GetFilenameWithoutExtension().ToString(); var projectName = solutionFile.GetFilenameWithoutExtension().ToString();
var assemblyInfoSubPath = "Properties/AssemblyInfo.cs";
var nugetSource = "https://api.nuget.org/v3/index.json"; var nugetSource = "https://api.nuget.org/v3/index.json";
var assemblyInfoSubPath = "Properties/AssemblyInfo.cs";
var semanticVersion = "";
string localNugetFeed;
// get latest MSBuild version // get latest MSBuild version
var vsLatest = VSWhereLatest(); var vsLatest = VSWhereLatest();
var msBuildPathX64 = (vsLatest == null) ? null : vsLatest.CombineWithFilePath("./MSBuild/Current/Bin/MSBuild.exe"); 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 =>{ Setup(context =>{
nupkgDir = $"{artifactsDir.ToString()}/nupkg"; 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 =>{ Teardown(context =>{
Information("Finished running tasks."); Information("Finished at {0}", DateTime.Now);
}); });
//////////////////////////////////////////////////////////////////////
// TASKS
//////////////////////////////////////////////////////////////////////
Task("Clean") Task("Clean")
.Description("Cleans all build and artifacts directories") .Description("Cleans all build and artifacts directories")
.Does(() =>{ .Does(() =>{
...@@ -68,70 +56,36 @@ Task("Clean") ...@@ -68,70 +56,36 @@ Task("Clean")
Force = true Force = true
}; };
var directoriesToDelete = new List<DirectoryPath>(); var directoriesToClean = new List<DirectoryPath>();
foreach(var project in projects) { foreach(var project in projects) {
directoriesToDelete.Add(Directory($"{project.GetDirectory()}/obj")); directoriesToClean.Add(Directory($"{project.GetDirectory()}/obj"));
directoriesToDelete.Add(Directory($"{project.GetDirectory()}/bin")); 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)) { if (DirectoryExists(dir)) {
Information($"Cleaning path {dir} ...");
DeleteDirectory(dir, settings); DeleteDirectory(dir, settings);
CreateDirectory(dir);
} else {
CreateDirectory(dir);
} }
} }
}); });
Task("Restore") Task("Restore")
.Does(() =>{ .Does(() =>{
// Restore all NuGet packages.
Information($"Restoring {solutionFile}...");
NuGetRestore(solutionFile, new NuGetRestoreSettings { 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") Task("Test")
.IsDependentOn("Build")
.Does(() =>{ .Does(() =>{
NUnit3($"./src/**/bin/{configuration}/*.Tests.dll", new NUnit3Settings { NUnit3($"./src/**/bin/{configuration}/*.Tests.dll", new NUnit3Settings {
// generate the xml file // generate the xml file
...@@ -139,92 +93,167 @@ Task("Test") ...@@ -139,92 +93,167 @@ Task("Test")
Results = new NUnit3Result[] { Results = new NUnit3Result[] {
new NUnit3Result() { new NUnit3Result() {
FileName = $"{artifactsDir}/TestResults.xml", FileName = $"{artifactsDir}/TestResults.xml",
Transform = Context.Environment.WorkingDirectory + "/nunit3-junit.xslt" Transform = $"{Context.Environment.WorkingDirectory}/nunit3-junit.xslt"
} }
} }
}); });
}); });
Task("NugetPush") Task("GitVersion")
.Does(() => { .Does(() => {
var nupkgs = GetFiles($"{nupkgDir}/*.nupkg"); 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);
});
Information("Need to push {0} packages", nupkgs.Count); Task("UpdateAssemblyInfo")
foreach(var nupkg in nupkgs) { .Does(() =>{
Information("Pushing {0}", nupkg); var index = version.IndexOf("-");
NuGetPush(nupkg, new NuGetPushSettings { var semanticVersion = index > 0 ? version.Substring(0, index) : version;
Source = nugetSource,
ApiKey = nugetApiKey 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("NugetPack") Task("GitlabRelease")
.IsDependentOn("GitVersion")
.Does(() => { .Does(() => {
foreach(var project in projects) { var client = new HttpClient();
var nuspec = $"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec"; client.DefaultRequestHeaders.Add("PRIVATE-TOKEN", gitlabToken);
if(!project.ToString().EndsWith(".Tests")
&& FileExists(nuspec)) // get the latest tag
{ var result = client.GetAsync($"https://git.rwth-aachen.de/api/v4/projects/{gitlabProjectId}/repository/tags").Result;
Information("Packing {0}...", nuspec); 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(!DirectoryExists(nupkgDir)) { if(url.EndsWith(".git")) {
CreateDirectory(nupkgDir); url = url.Substring(0, url.Length - ".git".Length);
} }
NuGetPack(project.ToString() ,new NuGetPackSettings if(url.EndsWith("/")) {
{ url = url.Substring(0, url.Length - 1);
OutputDirectory = nupkgDir,
Properties = new Dictionary<string, string> { {"Configuration", "Release"}}
});
} }
}
});
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";
}
Task("UpdateAssemblyInfo") // From when will messages be parsed, null results in all messages
.Does(() =>{ var logParam = "";
Information("Running semantic-release in dry run mode to extract next semantic version number"); if(lastTag != null) {
logParam = $"{lastTag}..Head";
string[] semanticReleaseOutput; }
Npx("semantic-release", "--dry-run", requiredSemanticVersionPackages, out semanticReleaseOutput);
Information(string.Join(Environment.NewLine, semanticReleaseOutput));
var nextSemanticVersionNumber = ExtractNextSemanticVersionNumber(semanticReleaseOutput); 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>()},
};
if (nextSemanticVersionNumber == null) { var currentHash = "";
Warning("There are no relevant changes. AssemblyInfo won't be updated!"); // 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 { } else {
Information("Next semantic version number is {0}", nextSemanticVersionNumber); commitMessage = line;
}
var assemblyVersion = $"{nextSemanticVersionNumber}.0"; foreach(var kv in prefixList) {
if(commitMessage.StartsWith($"{kv.Key}:")) {
kv.Value.Add($"* {commitMessage.Substring(kv.Key.Length + 1).Trim()} {currentHash}");
break;
}
};
}
foreach(var project in projects) { foreach(var kv in prefixList) {
CreateAssemblyInfo($"{project.GetDirectory()}/{assemblyInfoSubPath}", new AssemblyInfoSettings { if(kv.Value.Any()) {
Product = project.GetFilenameWithoutExtension().ToString(), description += $" ### {kv.Key}\n\n";
Title = project.GetFilenameWithoutExtension().ToString(), foreach(var line in kv.Value) {
Company = "IT Center, RWTH Aachen University", description += $"{line}\n";
Version = assemblyVersion, }
FileVersion = assemblyVersion, description += "\n";
InformationalVersion = assemblyVersion,
Copyright = $"{DateTime.Now.Year} IT Center, RWTH Aachen University",
Description = $"{project.GetFilenameWithoutExtension().ToString()} is a part of the CoScInE group."
});
} }
} }
// 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") Task("Build")
.IsDependentOn("Clean") .IsDependentOn("Clean")
.IsDependentOn("GitVersion")
.IsDependentOn("UpdateAssemblyInfo")
.IsDependentOn("Restore") .IsDependentOn("Restore")
.Does(() =>{ .Does(() =>{
if (IsRunningOnWindows()) {
var frameworkSettingsWindows = new MSBuildSettings { var frameworkSettingsWindows = new MSBuildSettings {
Configuration = configuration, Configuration = configuration
Restore = true
}; };
frameworkSettingsWindows.ToolPath = msBuildPathX64; frameworkSettingsWindows.ToolPath = msBuildPathX64;
...@@ -234,74 +263,89 @@ Task("Build") ...@@ -234,74 +263,89 @@ Task("Build")
frameworkSettingsWindows.WithProperty("DebugSymbols", "false"); frameworkSettingsWindows.WithProperty("DebugSymbols", "false");
frameworkSettingsWindows.WithProperty("DebugType", "None"); frameworkSettingsWindows.WithProperty("DebugType", "None");
} }
// Use MSBuild // Use MSBuild
Information($"Building {solutionFile}"); Information("Building {0}", solutionFile);
MSBuild(solutionFile, frameworkSettingsWindows); 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}
} }
else {
var frameworkSettingsUnix = new XBuildSettings {
Configuration = configuration
}; };
NuGetPack(project.ToString(), settings);
if (configuration.Equals("Release")) {
frameworkSettingsUnix.WithProperty("DebugSymbols", "false");
frameworkSettingsUnix.WithProperty("DebugType", "None");
} }
// Use XBuild
Information($"Building {solutionFile}");
XBuild(solutionFile, frameworkSettingsUnix);
} }
});
if (configuration.Equals("Release")) { Task("NugetPush")
if(!DirectoryExists(artifactsDir)) { .IsDependentOn("NugetPack")
CreateDirectory(artifactsDir); .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) { foreach(var project in projects) {
if(!project.GetDirectory().ToString().EndsWith(".Tests") if(!project.GetDirectory().ToString().EndsWith(".Tests")
&& !FileExists($"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec")) && !FileExists($"{project.GetDirectory()}/{project.GetFilenameWithoutExtension()}.nuspec")
&& DirectoryExists(project.GetDirectory()))
{ {
Information($"Copying {project.GetDirectory()}/bin/{configuration}/* to {artifactsDir}"); Information("Copying {0}/* to {1}", $"{project.GetDirectory()}/bin/{configuration}", artifactsDir);
CopyDirectory($"{project.GetDirectory()}/bin/{configuration}/", artifactsDir); CopyDirectory($"{project.GetDirectory()}/bin/{configuration}/", artifactsDir);
} }
} }
}
}); });
Task("SemanticRelease") Task("NugetPushLocal")
.IsDependentOn("NugetPack")
.Does(() =>{ .Does(() =>{
Npx("semantic-release", requiredSemanticVersionPackages); var nupkgs = GetFiles($"{nupkgDir}/*.nupkg");
foreach(var nupkg in nupkgs) {
if(!DirectoryExists(localNugetFeed)) {
CreateDirectory(localNugetFeed);
}
CopyFile(nupkg.ToString(), $"{localNugetFeed}\\{nupkg.GetFilename()}");
}
}); });
Task("Linter") Task("Prerelease")
.Description("Run DupFinder and InspectCode") .IsDependentOn("Build")
.IsDependentOn("DupFinder") .IsDependentOn("CopyToArtifacts")
.IsDependentOn("InspectCode"); .IsDependentOn("NugetPushLocal");
Task("LinterAndTest") Task("Release")
.Description("Run Linter and Tests") .IsDependentOn("NugetPack")
.IsDependentOn("Linter") .IsDependentOn("CopyToArtifacts")
.IsDependentOn("Test"); .IsDependentOn("NugetPushLocal")
.IsDependentOn("NugetPush");
Task("Default") Task("Default")
.IsDependentOn("Clean")
.IsDependentOn("Restore")
.IsDependentOn("DupFinder")
.IsDependentOn("InspectCode")
.IsDependentOn("Build")
.IsDependentOn("Test"); .IsDependentOn("Test");
//////////////////////////////////////////////////////////////////////
// EXECUTION
//////////////////////////////////////////////////////////////////////
RunTarget(target); 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();
}
## Configuration
This project represents a class library for communicating with different key-value stores.
\ No newline at end of file
param(
$token
)
$remoteUrl = git config --get remote.origin.url
$remoteUrl = $remoteUrl.replace("git@", "")
$remoteUrl = $remoteUrl -replace "https(.*?)@",""
$remoteUrl = $remoteUrl.replace(":", "/")
$remoteUrl = $remoteUrl.replace(".git", ".wiki.git")
$temporaryFolderName = "publishDocsTempFolder"
git clone "https://gitlab-ci-token:$($token)@$($remoteUrl)" $temporaryFolderName
cd $temporaryFolderName
Remove-Item *
cp -r ../docs/* ./
git add .
git commit -m "Docs: Documentation Update"
git push
\ No newline at end of file
...@@ -20,6 +20,12 @@ namespace Coscine.Configuration.Tests ...@@ -20,6 +20,12 @@ namespace Coscine.Configuration.Tests
DefaultTester.ConfigurationAsyncTest(_configuration); DefaultTester.ConfigurationAsyncTest(_configuration);
} }
[Test]
public void ConsulConfigurationAndWaitTest()
{
DefaultTester.ConfigurationAndWaitTest(_configuration);
}
[Test] [Test]
public void ConsulConfigurationTest() public void ConsulConfigurationTest()
{ {
......
...@@ -24,12 +24,36 @@ namespace Coscine.Configuration.Tests ...@@ -24,12 +24,36 @@ namespace Coscine.Configuration.Tests
Assert.IsTrue(_configuration.GetStringAsync("TestingKeyNotExisting").GetAwaiter().GetResult() == null); Assert.IsTrue(_configuration.GetStringAsync("TestingKeyNotExisting").GetAwaiter().GetResult() == null);
Assert.IsTrue(_configuration.GetStringAsync("TestingKeyNotExisting", "default").GetAwaiter().GetResult() == "default");
Assert.IsTrue(_configuration.DeleteAsync(key).GetAwaiter().GetResult()); Assert.IsTrue(_configuration.DeleteAsync(key).GetAwaiter().GetResult());
keys = _configuration.KeysAsync("").GetAwaiter().GetResult(); keys = _configuration.KeysAsync("").GetAwaiter().GetResult();
Assert.IsFalse(keys.Contains(key)); Assert.IsFalse(keys.Contains(key));
} }
public static void ConfigurationAndWaitTest(IConfiguration _configuration)
{
string key = "TestKey";
string value = "TheTestValue";
Assert.IsTrue(_configuration.PutAndWait(key, value));
var keys = _configuration.KeysAndWait("");
Assert.IsTrue(keys.Contains(key));
Assert.IsTrue(_configuration.GetStringAndWait(key).Equals(value));
Assert.IsTrue(_configuration.GetStringAndWait("TestingKeyNotExisting") == null);
Assert.IsTrue(_configuration.GetStringAndWait("TestingKeyNotExisting", "default") == "default");
Assert.IsTrue(_configuration.DeleteAndWait(key));
keys = _configuration.KeysAndWait("");
Assert.IsFalse(keys.Contains(key));
}
public static void ConfigurationTest(IConfiguration _configuration) public static void ConfigurationTest(IConfiguration _configuration)
{ {
string key = "TestKey"; string key = "TestKey";
...@@ -44,6 +68,8 @@ namespace Coscine.Configuration.Tests ...@@ -44,6 +68,8 @@ namespace Coscine.Configuration.Tests
Assert.IsTrue(_configuration.GetString("TestingKeyNotExisting") == null); Assert.IsTrue(_configuration.GetString("TestingKeyNotExisting") == null);
Assert.IsTrue(_configuration.GetString("TestingKeyNotExisting", "default") == "default");
Assert.IsTrue(_configuration.Delete(key)); Assert.IsTrue(_configuration.Delete(key));
keys = _configuration.Keys(""); keys = _configuration.Keys("");
......
...@@ -23,6 +23,12 @@ namespace Coscine.Configuration.Tests ...@@ -23,6 +23,12 @@ namespace Coscine.Configuration.Tests
DefaultTester.ConfigurationAsyncTest(_configuration); DefaultTester.ConfigurationAsyncTest(_configuration);
} }
[Test]
public void EnvironmentConfigurationAndWaitTest()
{
DefaultTester.ConfigurationAndWaitTest(_configuration);
}
[Test] [Test]
public void EnvironmentConfigurationTest() public void EnvironmentConfigurationTest()
{ {
......
...@@ -57,6 +57,11 @@ namespace Coscine.Configuration ...@@ -57,6 +57,11 @@ namespace Coscine.Configuration
} }
} }
public bool PutAndWait(string key, string value)
{
return PutAndWait(key, Encoding.UTF8.GetBytes(value));
}
public async Task<byte[]> GetAsync(string key) public async Task<byte[]> GetAsync(string key)
{ {
using (var client = new ConsulClient(Configuration)) using (var client = new ConsulClient(Configuration))
...@@ -69,9 +74,9 @@ namespace Coscine.Configuration ...@@ -69,9 +74,9 @@ namespace Coscine.Configuration
} }
else else
{ {
// TODO: Add logging that key has not been found
return null; return null;
} }
} }
} }
...@@ -89,9 +94,9 @@ namespace Coscine.Configuration ...@@ -89,9 +94,9 @@ namespace Coscine.Configuration
} }
else else
{ {
// TODO: Add logging that key has not been found
return null; return null;
} }
} }
} }
...@@ -108,6 +113,17 @@ namespace Coscine.Configuration ...@@ -108,6 +113,17 @@ namespace Coscine.Configuration
} }
} }
public async Task<string> GetStringAsync(string key, string defaultValue)
{
var value = await GetStringAsync(key);
if (value == null)
{
// TODO: Log use of default value
return defaultValue;
}
return value;
}
public string GetStringAndWait(string key) public string GetStringAndWait(string key)
{ {
var value = GetAndWait(key); var value = GetAndWait(key);
...@@ -121,6 +137,17 @@ namespace Coscine.Configuration ...@@ -121,6 +137,17 @@ namespace Coscine.Configuration
} }
} }
public string GetStringAndWait(string key, string defaultValue)
{
var value = GetStringAndWait(key);
if (value == null)
{
// TODO: Log use of default value
return defaultValue;
}
return value;
}
public async Task<string[]> KeysAsync(string prefix) public async Task<string[]> KeysAsync(string prefix)
{ {
using (var client = new ConsulClient(Configuration)) using (var client = new ConsulClient(Configuration))
...@@ -179,6 +206,11 @@ namespace Coscine.Configuration ...@@ -179,6 +206,11 @@ namespace Coscine.Configuration
return GetStringAsync(key).GetAwaiter().GetResult(); return GetStringAsync(key).GetAwaiter().GetResult();
} }
public string GetString(string key, string defaultValue)
{
return GetStringAsync(key, defaultValue).GetAwaiter().GetResult();
}
public string[] Keys(string prefix) public string[] Keys(string prefix)
{ {
return KeysAsync(prefix).GetAwaiter().GetResult(); return KeysAsync(prefix).GetAwaiter().GetResult();
......
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Coscine.Configuration namespace Coscine.Configuration
...@@ -81,23 +79,48 @@ namespace Coscine.Configuration ...@@ -81,23 +79,48 @@ namespace Coscine.Configuration
} }
catch (Exception) catch (Exception)
{ {
// TODO: Add logging that key has not been found
return null; return null;
} }
} }
public string GetString(string key, string defaultValue)
{
var value = GetString(key);
if(value == null)
{
// TODO: Log Default value usage
return defaultValue;
}
return value;
}
public string GetStringAndWait(string key) public string GetStringAndWait(string key)
{ {
return GetString(key); return GetString(key);
} }
public Task<string> GetStringAsync(string key) public string GetStringAndWait(string key, string defaultValue)
{ {
return Task.Factory.StartNew(() => return GetString(key, defaultValue);
}
public async Task<string> GetStringAsync(string key)
{
return await Task.Factory.StartNew(() =>
{ {
return GetString(key); return GetString(key);
}); });
} }
public async Task<string> GetStringAsync(string key, string defaultValue)
{
return await Task.Factory.StartNew(() =>
{
return GetString(key, defaultValue);
});
}
public string[] Keys(string prefix) public string[] Keys(string prefix)
{ {
IDictionary envVars = Environment.GetEnvironmentVariables(); IDictionary envVars = Environment.GetEnvironmentVariables();
...@@ -148,6 +171,11 @@ namespace Coscine.Configuration ...@@ -148,6 +171,11 @@ namespace Coscine.Configuration
return Put(key, value); return Put(key, value);
} }
public bool PutAndWait(string key, string value)
{
return Put(key, value);
}
public Task<bool> PutAsync(string key, string value) public Task<bool> PutAsync(string key, string value)
{ {
return Task.Factory.StartNew(() => return Task.Factory.StartNew(() =>
......
...@@ -8,6 +8,8 @@ namespace Coscine.Configuration ...@@ -8,6 +8,8 @@ namespace Coscine.Configuration
Task<bool> PutAsync(string key, byte[] value); Task<bool> PutAsync(string key, byte[] value);
bool PutAndWait(string key, string value);
bool PutAndWait(string key, byte[] value); bool PutAndWait(string key, byte[] value);
Task<byte[]> GetAsync(string key); Task<byte[]> GetAsync(string key);
...@@ -16,8 +18,12 @@ namespace Coscine.Configuration ...@@ -16,8 +18,12 @@ namespace Coscine.Configuration
Task<string> GetStringAsync(string key); Task<string> GetStringAsync(string key);
Task<string> GetStringAsync(string key, string defaultValue);
string GetStringAndWait(string key); string GetStringAndWait(string key);
string GetStringAndWait(string key, string defaultValue);
Task<string[]> KeysAsync(string prefix); Task<string[]> KeysAsync(string prefix);
string[] KeysAndWait(string prefix); string[] KeysAndWait(string prefix);
...@@ -34,6 +40,8 @@ namespace Coscine.Configuration ...@@ -34,6 +40,8 @@ namespace Coscine.Configuration
string GetString(string key); string GetString(string key);
string GetString(string key, string defaultValue);
string[] Keys(string prefix); string[] Keys(string prefix);
bool Delete(string key); bool Delete(string key);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment