diff --git a/.circleci/config.yml b/.circleci/config.yml index bb5b181c..536914b2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,4 @@ -version: 2 +version: 2.1 jobs: build: docker: @@ -16,7 +16,7 @@ workflows: version: 2 master: jobs: - - build: + - release: filters: branches: only: master @@ -25,4 +25,6 @@ workflows: - build: filters: branches: - ignore: master + ignore: + - master + - develop diff --git a/Makefile b/Makefile index 5b2f1c5f..a24d2a92 100644 --- a/Makefile +++ b/Makefile @@ -4,16 +4,17 @@ build: ./build.sh build_and_run_tests: - ./build.ps1 -target RunTests && exit $LASTEXITCODE + ./build.sh --target=RunTests release: - ./build.ps1 -target Release && exit $LASTEXITCODE + ./build.sh --target=Release run_acceptance_tests: - ./build -target RunAcceptanceTests && exit $LASTEXITCODE + ./build.sh --target=RunAcceptanceTests run_benchmarks: - ./build.ps1 -target RunBenchmarkTests && exit $LASTEXITCODE + ./build.sh --target=RunBenchmarkTests run_unit_tests: - ./build.ps1 -target RunUnitTests && exit $LASTEXITCODE + ./build.sh --target=RunUnitTests + \ No newline at end of file diff --git a/build.cake b/build.cake index 078e1074..c6b1e79e 100644 --- a/build.cake +++ b/build.cake @@ -2,6 +2,7 @@ #tool "nuget:?package=GitReleaseNotes" #addin nuget:?package=Cake.Json #addin nuget:?package=Newtonsoft.Json +#addin nuget:?package=System.Net.Http #tool "nuget:?package=ReportGenerator" #tool "nuget:?package=coveralls.net&version=0.7.0" #addin Cake.Coveralls&version=0.10.1 @@ -40,15 +41,16 @@ var artifactsFile = packagesDir + File("artifacts.txt"); // stable releases var tagsUrl = "https://api.github.com/repos/tompallister/ocelot/releases/tags/"; -var nugetFeedStableKey = EnvironmentVariable("nuget-apikey-stable"); +var nugetFeedStableKey = EnvironmentVariable("OCELOT_NUTGET_API_KEY"); var nugetFeedStableUploadUrl = "https://www.nuget.org/api/v2/package"; var nugetFeedStableSymbolsUploadUrl = "https://www.nuget.org/api/v2/package"; // internal build variables - don't change these. -var releaseTag = ""; string committedVersion = "0.0.0-dev"; -var buildVersion = committedVersion; GitVersion versioning = null; +int releaseId = 0; +string gitHubUsername = "TomPallister"; +string gitHubPassword = Environment.GetEnvironmentVariable("OCELOT_GITHUB_API_KEY"); var target = Argument("target", "Default"); @@ -59,9 +61,32 @@ Task("Default") .IsDependentOn("Build"); Task("Build") - .IsDependentOn("RunTests") - .IsDependentOn("CreatePackages"); - + .IsDependentOn("RunTests"); + +Task("RunTests") + .IsDependentOn("RunUnitTests") + .IsDependentOn("RunAcceptanceTests") + .IsDependentOn("RunIntegrationTests"); + +Task("Release") + .IsDependentOn("Build") + .IsDependentOn("CreateArtifacts") + .IsDependentOn("PublishGitHubRelease") + .IsDependentOn("PublishToNuget"); + +Task("Compile") + .IsDependentOn("Clean") + .IsDependentOn("Version") + .Does(() => + { + var settings = new DotNetCoreBuildSettings + { + Configuration = compileConfig, + }; + + DotNetCoreBuild(slnFile, settings); + }); + Task("Clean") .Does(() => { @@ -83,7 +108,6 @@ Task("Version") { Information("Persisting version number..."); PersistVersion(committedVersion, nugetVersion); - buildVersion = nugetVersion; } else { @@ -91,19 +115,6 @@ Task("Version") } }); -Task("Compile") - .IsDependentOn("Clean") - .IsDependentOn("Version") - .Does(() => - { - var settings = new DotNetCoreBuildSettings - { - Configuration = compileConfig, - }; - - DotNetCoreBuild(slnFile, settings); - }); - Task("RunUnitTests") .IsDependentOn("Compile") .Does(() => @@ -188,12 +199,7 @@ Task("RunIntegrationTests") DotNetCoreTest(integrationTestAssemblies, settings); }); -Task("RunTests") - .IsDependentOn("RunUnitTests") - .IsDependentOn("RunAcceptanceTests") - .IsDependentOn("RunIntegrationTests"); - -Task("CreatePackages") +Task("CreateArtifacts") .IsDependentOn("Compile") .Does(() => { @@ -225,16 +231,24 @@ Task("CreatePackages") Information("Created package " + codePackage); } + }); +Task("PublishGitHubRelease") + .IsDependentOn("CreateArtifacts") + .Does(() => + { if (IsRunningOnCircleCI()) { var path = packagesDir.ToString() + @"/**/*"; + CreateGitHubRelease(); + foreach (var file in GetFiles(path)) { - // todo - upload to github releases? - // AppVeyor.UploadArtifact(file.FullPath); + UploadFileToGitHubRelease(file); } + + CompleteGitHubRelease(); } }); @@ -248,64 +262,29 @@ Task("EnsureStableReleaseRequirements") throw new Exception("Stable release should happen via circleci"); } - // todo how this on circle? - // var isTag = - // AppVeyor.Environment.Repository.Tag.IsTag && - // !string.IsNullOrWhiteSpace(AppVeyor.Environment.Repository.Tag.Name); - - // if (!isTag) - // { - // throw new Exception("Stable release should happen from a published GitHub release"); - // } - Information("Release is stable..."); }); -Task("UpdateVersionInfo") - .IsDependentOn("EnsureStableReleaseRequirements") - .Does(() => - { - // todo need a way to get the tag - releaseTag = AppVeyor.Environment.Repository.Tag.Name; - }); - Task("DownloadGitHubReleaseArtifacts") - .IsDependentOn("UpdateVersionInfo") .Does(() => { + try { - Information("DownloadGitHubReleaseArtifacts"); - EnsureDirectoryExists(packagesDir); - Information("Directory exists..."); - - var releaseUrl = tagsUrl + releaseTag; - - Information("Release url " + releaseUrl); + var releaseUrl = tagsUrl + versioning.NuGetVersion; var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl)) .Value("assets_url"); - Information("Assets url " + assets_url); - var assets = GetResource(assets_url); - Information("Assets " + assets_url); - foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject(assets)) { - Information("In the loop.."); - var file = packagesDir + File(asset.Value("name")); - - Information("Downloading " + file); - DownloadFile(asset.Value("browser_download_url"), file); } - - Information("Out of the loop..."); } catch(Exception exception) { @@ -314,16 +293,16 @@ Task("DownloadGitHubReleaseArtifacts") } }); -Task("ReleasePackagesToStableFeed") +Task("PublishToNuget") .IsDependentOn("DownloadGitHubReleaseArtifacts") .Does(() => { - PublishPackages(packagesDir, artifactsFile, nugetFeedStableKey, nugetFeedStableUploadUrl, nugetFeedStableSymbolsUploadUrl); + if (IsRunningOnCircleCI()) + { + PublishPackages(packagesDir, artifactsFile, nugetFeedStableKey, nugetFeedStableUploadUrl, nugetFeedStableSymbolsUploadUrl); + } }); -Task("Release") - .IsDependentOn("ReleasePackagesToStableFeed"); - RunTarget(target); /// Gets nuique nuget version for this commit @@ -386,6 +365,7 @@ private void GenerateReleaseNotes(ConvertableFilePath file) /// Publishes code and symbols packages to nuget feed, based on contents of artifacts file private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFilePath artifactsFile, string feedApiKey, string codeFeedUrl, string symbolFeedUrl) { + Information("PublishPackages"); var artifacts = System.IO.File .ReadAllLines(artifactsFile) .Distinct(); @@ -407,6 +387,80 @@ private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFi } } +private void CreateGitHubRelease() +{ + var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"master\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"todo: notes coming\", \"draft\": true, \"prerelease\": true }}"; + var content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json"); + + using(var client = new System.Net.Http.HttpClient()) + { + client.DefaultRequestHeaders.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue( + "Basic", Convert.ToBase64String( + System.Text.ASCIIEncoding.ASCII.GetBytes( + $"{gitHubUsername}:{gitHubPassword}"))); + + client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release"); + + var result = client.PostAsync("https://api.github.com/repos/ThreeMammals/Ocelot/releases", content).Result; + if(result.StatusCode != System.Net.HttpStatusCode.Created) + { + throw new Exception("CreateGitHubRelease result.StatusCode = " + result.StatusCode); + } + var returnValue = result.Content.ReadAsStringAsync().Result; + dynamic test = Newtonsoft.Json.JsonConvert.DeserializeObject(returnValue); + releaseId = test.id; + } +} + +private void UploadFileToGitHubRelease(FilePath file) +{ + var data = System.IO.File.ReadAllBytes(file.FullPath); + var content = new System.Net.Http.ByteArrayContent(data); + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); + + using(var client = new System.Net.Http.HttpClient()) + { + client.DefaultRequestHeaders.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue( + "Basic", Convert.ToBase64String( + System.Text.ASCIIEncoding.ASCII.GetBytes( + $"{gitHubUsername}:{gitHubPassword}"))); + + client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release"); + + var result = client.PostAsync($"https://uploads.github.com/repos/ThreeMammals/Ocelot/releases/{releaseId}/assets?name={file.GetFilename()}", content).Result; + if(result.StatusCode != System.Net.HttpStatusCode.Created) + { + throw new Exception("UploadFileToGitHubRelease result.StatusCode = " + result.StatusCode); + } + } +} + +private void CompleteGitHubRelease() +{ + var json = $"{{ \"tag_name\": \"{versioning.NuGetVersion}\", \"target_commitish\": \"master\", \"name\": \"{versioning.NuGetVersion}\", \"body\": \"todo: notes coming\", \"draft\": false, \"prerelease\": false }}"; + var content = new System.Net.Http.StringContent(json, System.Text.Encoding.UTF8, "application/json"); + + using(var client = new System.Net.Http.HttpClient()) + { + client.DefaultRequestHeaders.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue( + "Basic", Convert.ToBase64String( + System.Text.ASCIIEncoding.ASCII.GetBytes( + $"{gitHubUsername}:{gitHubPassword}"))); + + client.DefaultRequestHeaders.Add("User-Agent", "Ocelot Release"); + + var result = client.PatchAsync($"https://api.github.com/repos/ThreeMammals/Ocelot/releases/{releaseId}", content).Result; + if(result.StatusCode != System.Net.HttpStatusCode.OK) + { + throw new Exception("CompleteGitHubRelease result.StatusCode = " + result.StatusCode); + } + } +} + + /// gets the resource from the specified url private string GetResource(string url) { diff --git a/docker/Dockerfile b/docker/Dockerfile index 0e9137b3..684c5423 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,3 +1,4 @@ +# this is the dockerfile that create the ocelot build container FROM mcr.microsoft.com/dotnet/core/sdk:3.1-bionic AS build RUN apt install gnupg ca-certificates diff --git a/Dockerfile b/docker/Dockerfile.build similarity index 100% rename from Dockerfile rename to docker/Dockerfile.build diff --git a/docker/Dockerfile.release b/docker/Dockerfile.release new file mode 100644 index 00000000..a6e88888 --- /dev/null +++ b/docker/Dockerfile.release @@ -0,0 +1,18 @@ +# call from root with +# docker build --build-arg OCELOT_NUTGET_API_KEY=$OCELOT_NUTGET_API_KEY --build-arg OCELOT_GITHUB_API_KEY=$OCELOT_GITHUB_API_KEY -f ./docker/Dockerfile.release . + +FROM mijitt0m/ocelot-build:0.0.1 + +ARG OCELOT_GITHUB_API_KEY +ARG OCELOT_NUTGET_API_KEY + +ENV OCELOT_NUTGET_API_KEY=$OCELOT_NUTGET_API_KEY +ENV OCELOT_GITHUB_API_KEY=$OCELOT_GITHUB_API_KEY + +WORKDIR /src + +COPY ./. . + +RUN chmod u+x build.sh + +RUN make release \ No newline at end of file diff --git a/docker/docker-build.sh b/docker/docker-build.sh index 221868cf..d9aa0448 100755 --- a/docker/docker-build.sh +++ b/docker/docker-build.sh @@ -1,3 +1,4 @@ +# this script build the ocelot docker file docker build -t mijitt0m/ocelot-build . echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin docker tag mijitt0m/ocelot-build mijitt0m/ocelot-build:0.0.1