diff --git a/.gitattributes b/.gitattributes index d23fda4b9d..5891e81525 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,9 @@ # Auto detect text files and perform LF normalization * text=auto eol=crlf +# Declare files that will always have LF line endings on checkout. +*.sh text eol=lf + # Don't check these into the repo as LF to work around TeamCity bug *.xml -text *.targets -text diff --git a/.gitignore b/.gitignore index fa9646b36e..a615c13e66 100644 --- a/.gitignore +++ b/.gitignore @@ -101,4 +101,10 @@ site/ # Visual Studio Code #################### -.vscode \ No newline at end of file +.vscode + +#################### +# Cake +#################### +/tools +/*.zip \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 7601be96ac..2f95b12cf3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,29 +1,15 @@ language: csharp -solution: src/GitVersion.sln sudo: false mono: - latest os: - linux - osx -before_install: # We need to download nuget.exe due to: https://github.com/travis-ci/travis-ci/issues/5932 +before_install: - git fetch --unshallow # Travis always does a shallow clone, but GitVersion needs the full history including branches and tags - - mkdir -p .nuget - - wget -O .nuget/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe - - mono .nuget/nuget.exe -install: - - mono .nuget/nuget.exe restore src/GitVersion.sln -Verbosity detailed - - mono .nuget/nuget.exe install NUnit.Runners -Version 3.2.1 -OutputDirectory ./src/packages script: - - xbuild ./src/GitVersion.sln /property:Configuration="Debug" /verbosity:detailed - - mono ./build/NuGetCommandLineBuild/tools/GitVersion.exe -l console -output buildserver -updateAssemblyInfo - - xbuild ./src/GitVersion.sln /property:Configuration="Debug" /verbosity:detailed - - mono ./src/packages/NUnit.ConsoleRunner.3.2.1/tools/nunit3-console.exe ./src/GitVersionTask.Tests/bin/Debug/GitVersionTask.Tests.dll ./src/GitVersionCore.Tests/bin/Debug/GitVersionCore.Tests.dll ./src/GitVersionTask.Tests/bin/Debug/GitVersionTask.Tests.dll ./src/GitVersionExe.Tests/bin/Debug/GitVersionExe.Tests.dll --where "cat != NoMono" --noresult - -# -# To run a clean build with Mono, executing just one test, do: -# xbuild ./src/GitVersion.sln /t:Clean /verbosity:quiet && xbuild ./src/GitVersion.sln /property:Configuration="Debug" /verbosity:quiet && mono ./src/packages/NUnit.ConsoleRunner.3.2.1/tools/nunit3-console.exe ./src/GitVersionTask.Tests/bin/Debug/GitVersionTask.Tests.dll ./src/GitVersionCore.Tests/bin/Debug/GitVersionCore.Tests.dll ./src/GitVersionTask.Tests/bin/Debug/GitVersionTask.Tests.dll ./src/GitVersionExe.Tests/bin/Debug/GitVersionExe.Tests.dll --noresult --where "test =~ /TheNameOfTheTest/" -# -# To run a clean build with Mono, executing all tests, do: -# xbuild ./src/GitVersion.sln /t:Clean /verbosity:quiet && xbuild ./src/GitVersion.sln /property:Configuration="Debug" /verbosity:quiet && mono ./src/packages/NUnit.ConsoleRunner.3.2.1/tools/nunit3-console.exe ./src/GitVersionTask.Tests/bin/Debug/GitVersionTask.Tests.dll ./src/GitVersionCore.Tests/bin/Debug/GitVersionCore.Tests.dll ./src/GitVersionTask.Tests/bin/Debug/GitVersionTask.Tests.dll ./src/GitVersionExe.Tests/bin/Debug/GitVersionExe.Tests.dll --noresult --where "cat != NoMono" --noresult -# + - ./build.sh +cache: + directories: + - src/packages + - tools diff --git a/Build.cmd b/Build.cmd deleted file mode 100644 index 364d1ab554..0000000000 --- a/Build.cmd +++ /dev/null @@ -1,17 +0,0 @@ -@echo on - -set framework=v4.0.30319 -set src=%~dp0src\ - -"%src%.nuget\nuget.exe" restore %src% - -"%SystemDrive%\Windows\Microsoft.NET\Framework\%framework%\MSBuild.exe" "%src%GitVersion.sln" - -rmdir /s /q "%tmp%GitVersion" -md "%tmp%GitVersion" - -xcopy /E "%~dp0build\NuGetCommandLineBuild\tools" "%tmp%GitVersion" - -"%tmp%GitVersion\GitVersion.exe" /l console /output buildserver /updateAssemblyInfo /proj "%src%GitVersion.sln" - -rmdir /s /q "%tmp%GitVersion" diff --git a/appveyor.deploy.yml b/appveyor.deploy.yml new file mode 100644 index 0000000000..56e8d38394 --- /dev/null +++ b/appveyor.deploy.yml @@ -0,0 +1,11 @@ +install: + npm i -g tfx-cli + +assembly_info: + patch: false + +build_script: + - ps: .\deploy.ps1 + +test: off +skip_non_tags: true diff --git a/appveyor.yml b/appveyor.yml index 46018c2de1..d25bd9bb1f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,36 +1,17 @@ +install: + npm i -g tfx-cli + assembly_info: patch: false -platform: - - Any CPU - configuration: - Debug build_script: - - cmd: nuget restore src/GitVersion.sln - - cmd: npm i -g tfx-cli - - - cmd: msbuild src/GitVersion.sln "/p:Configuration=%CONFIGURATION%;Platform=%PLATFORM%" - - ps: .\build\NuGetCommandLineBuild\tools\GitVersion.exe /l console /output buildserver /updateAssemblyInfo - - cmd: msbuild src/GitVersion.sln "/p:Configuration=%CONFIGURATION%;Platform=%PLATFORM%" - - - cmd: appveyor PushArtifact "build\NuGetExeBuild\GitVersion.Portable.%GitVersion_NuGetVersion%.nupkg" - - - cmd: appveyor PushArtifact "build\NuGetCommandLineBuild\GitVersion.CommandLine.%GitVersion_NuGetVersion%.nupkg" - - cmd: appveyor PushArtifact "build\NuGetRefBuild\GitVersion.%GitVersion_NuGetVersion%.nupkg" - - cmd: appveyor PushArtifact "build\NuGetTaskBuild\GitVersionTask.%GitVersion_NuGetVersion%.nupkg" - - ps: appveyor PushArtifact ("build\GemBuild\gitversion-$env:GitVersion_MajorMinorPatch" + (&{If($env:GitVersion_PreReleaseTag -eq '' -or $env:GitVersion_PreReleaseTag -eq $null) {""} Else {"."+$env:GitVersion_PreReleaseTag}}) + ".gem") - - - cmd: 7z a "GitVersion_%GitVersion_NuGetVersion%.zip" -r .\build\NuGetCommandLineBuild\Tools\*.* - - cmd: appveyor PushArtifact "GitVersion_%GitVersion_NuGetVersion%.zip" - - - cmd: 7z a "GitVersionTfsBuildTask_%GitVersion_NuGetVersion%.zip" -r .\build\GitVersionTfsTaskBuild\GitVersionTask\*.* - - cmd: appveyor PushArtifact "GitVersionTfsBuildTask_%GitVersion_NuGetVersion%.zip" - - cmd: appveyor PushArtifact "build\GitVersionTfsTaskBuild\gittools.gitversion-%GitVersion_SemVer%.vsix" + - ps: .\build.ps1 -test_script: - - nunit3-console "src\GitVersionTask.Tests\bin\%CONFIGURATION%\GitVersionTask.Tests.dll" "src\GitVersionExe.Tests\bin\%CONFIGURATION%\GitVersionExe.Tests.dll" "src\GitVersionCore.Tests\bin\%CONFIGURATION%\GitVersionCore.Tests.dll" +test: off +skip_tags: true cache: - - src\packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified + - src\packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified \ No newline at end of file diff --git a/build.cake b/build.cake new file mode 100644 index 0000000000..d5005309b4 --- /dev/null +++ b/build.cake @@ -0,0 +1,174 @@ +#tool "nuget:?package=NUnit.ConsoleRunner" +#tool "nuget:?package=GitReleaseNotes" + +var target = Argument("target", "Default"); +var configuration = Argument("configuration", "Release"); + +string version = null; +string nugetVersion = null; +string preReleaseTag = null; +string semVersion = null; +string milestone = null; +bool publishingError = false; +bool IsTagged = (BuildSystem.AppVeyor.Environment.Repository.Tag.IsTag && + !string.IsNullOrWhiteSpace(BuildSystem.AppVeyor.Environment.Repository.Tag.Name)); +bool IsMainGitVersionRepo = StringComparer.OrdinalIgnoreCase.Equals("gittools/gitversion", BuildSystem.AppVeyor.Environment.Repository.Name); +bool IsPullRequest = BuildSystem.AppVeyor.Environment.PullRequest.IsPullRequest; + +void Build(string configuration, string nugetVersion, string semVersion, string version, string preReleaseTag) +{ + if(IsRunningOnUnix()) + { + XBuild("./src/GitVersion.sln", new XBuildSettings() + .SetConfiguration(configuration) + .WithProperty("POSIX", "True") + .SetVerbosity(Verbosity.Verbose)); + } + else + { + var msBuildSettings = new MSBuildSettings() + .SetConfiguration(configuration) + .SetPlatformTarget(PlatformTarget.MSIL) + .WithProperty("Windows", "True") + .UseToolVersion(MSBuildToolVersion.VS2015) + .SetVerbosity(Verbosity.Minimal) + .SetNodeReuse(false); + + if (BuildSystem.AppVeyor.IsRunningOnAppVeyor) + { + msBuildSettings = msBuildSettings + .WithProperty("GitVersion_NuGetVersion", nugetVersion) + .WithProperty("GitVersion_SemVer", semVersion) + .WithProperty("GitVersion_MajorMinorPatch", version) + .WithProperty("GitVersion_PreReleaseTag", preReleaseTag); + } + MSBuild("./src/GitVersion.sln", msBuildSettings); + } +} + +Task("DogfoodBuild") + .IsDependentOn("NuGet-Package-Restore") + .Does(() => +{ + Build(configuration, nugetVersion, semVersion, version, preReleaseTag); +}); + +Task("Version") + .IsDependentOn("DogfoodBuild") + .Does(() => +{ + GitVersion(new GitVersionSettings + { + UpdateAssemblyInfo = true, + LogFilePath = "console", + OutputType = GitVersionOutput.BuildServer, + ToolPath = @"src\GitVersionExe\bin\Release\GitVersion.exe" + }); + GitVersion assertedVersions = GitVersion(new GitVersionSettings + { + OutputType = GitVersionOutput.Json, + ToolPath = @"src\GitVersionExe\bin\Release\GitVersion.exe" + }); + + version = assertedVersions.MajorMinorPatch; + nugetVersion = assertedVersions.NuGetVersion; + preReleaseTag = assertedVersions.PreReleaseTag; + semVersion = assertedVersions.LegacySemVerPadded; +}); + +Task("NuGet-Package-Restore") + .Does(() => +{ + NuGetRestore("./src/GitVersion.sln"); +}); + +Task("Build") + .IsDependentOn("Version") + .IsDependentOn("NuGet-Package-Restore") + .Does(() => +{ + Build(configuration, nugetVersion, semVersion, version, preReleaseTag); +}); + +Task("Run-NUnit-Tests") + .IsDependentOn("Build") + .Does(() => +{ + var settings = new NUnit3Settings(); + if(IsRunningOnUnix()) + { + settings.Where = "cat != NoMono"; + } + NUnit3(new [] { + "src/GitVersionCore.Tests/bin/" + configuration + "/GitVersionCore.Tests.dll", + "src/GitVersionExe.Tests/bin/" + configuration + "/GitVersionExe.Tests.dll", + "src/GitVersionTask.Tests/bin/" + configuration + "/GitVersionTask.Tests.dll" }, + settings); + if (AppVeyor.IsRunningOnAppVeyor) + { + Information("Uploading test results"); + AppVeyor.UploadTestResults("TestResult.xml", AppVeyorTestResultsType.NUnit3); + } +}); + +Task("Zip-Files") + .IsDependentOn("Run-NUnit-Tests") + .Does(() => +{ + Zip("./build/NuGetCommandLineBuild/Tools/", "build/GitVersion_" + nugetVersion + ".zip"); +}); + +Task("Create-Release-Notes") + .IsDependentOn("Build") + .Does(() => +{ + var releaseNotesExitCode = StartProcess( + @"tools\GitReleaseNotes\tools\gitreleasenotes.exe", + new ProcessSettings { Arguments = ". /o build/releasenotes.md" }); + if (string.IsNullOrEmpty(System.IO.File.ReadAllText("./build/releasenotes.md"))) + System.IO.File.WriteAllText("./build/releasenotes.md", "No issues closed since last release"); + + if (releaseNotesExitCode != 0) throw new Exception("Failed to generate release notes"); +}); + +Task("Package") + .IsDependentOn("Create-Release-Notes") + .IsDependentOn("Zip-Files"); + +Task("Upload-AppVeyor-Artifacts") + .IsDependentOn("Package") + .WithCriteria(() => AppVeyor.IsRunningOnAppVeyor) + .Does(() => +{ + var gem = string.IsNullOrEmpty(preReleaseTag) ? + "gitversion-" + version + ".gem" : + "gitversion-" + version + "." + preReleaseTag + ".gem"; + + System.IO.File.WriteAllLines("build/artifacts", new[]{ + "NuGetExeBuild:GitVersion.Portable." + nugetVersion +".nupkg", + "NuGetCommandLineBuild:GitVersion.CommandLine." + nugetVersion +".nupkg", + "NuGetRefBuild:GitVersion." + nugetVersion +".nupkg", + "NuGetTaskBuild:GitVersionTask." + nugetVersion +".nupkg", + "GitVersionTfsTaskBuild:gittools.gitversion." + semVersion +".vsix", + "GemBuild:" + gem, + "zip:GitVersion_" + nugetVersion + ".zip", + "releaseNotes:releasenotes.md" + }); + + AppVeyor.UploadArtifact("build/NuGetExeBuild/GitVersion.Portable." + nugetVersion +".nupkg"); + AppVeyor.UploadArtifact("build/NuGetCommandLineBuild/GitVersion.CommandLine." + nugetVersion +".nupkg"); + AppVeyor.UploadArtifact("build/NuGetRefBuild/GitVersion." + nugetVersion +".nupkg"); + AppVeyor.UploadArtifact("build/NuGetTaskBuild/GitVersionTask." + nugetVersion +".nupkg"); + AppVeyor.UploadArtifact("build/GitVersionTfsTaskBuild/gittools.gitversion-" + semVersion + ".vsix"); + AppVeyor.UploadArtifact("build/GitVersion_" + nugetVersion + ".zip"); + AppVeyor.UploadArtifact("build/GemBuild/" + gem); +}); + + +Task("Travis") + .IsDependentOn("Run-NUnit-Tests"); + +Task("Default") + .IsDependentOn("Upload-AppVeyor-Artifacts"); + +RunTarget(target); \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000000..18b8560520 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,145 @@ +########################################################################## +# This is the Cake bootstrapper script for PowerShell. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +<# + +.SYNOPSIS +This is a Powershell script to bootstrap a Cake build. + +.DESCRIPTION +This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) +and execute your Cake build script with the parameters you provide. + +.PARAMETER Script +The build script to execute. +.PARAMETER Target +The build script target to run. +.PARAMETER Configuration +The build configuration to use. +.PARAMETER Verbosity +Specifies the amount of information to be displayed. +.PARAMETER Experimental +Tells Cake to use the latest Roslyn release. +.PARAMETER WhatIf +Performs a dry run of the build script. +No tasks will be executed. +.PARAMETER Mono +Tells Cake to use the Mono scripting engine. +.PARAMETER SkipToolPackageRestore +Skips restoring of packages. +.PARAMETER ScriptArgs +Remaining arguments are added here. + +.LINK +http://cakebuild.net + +#> + +[CmdletBinding()] +Param( + [string]$Script = "build.cake", + [string]$Target = "Default", + [string]$Configuration = "Release", + [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] + [string]$Verbosity = "Verbose", + [switch]$Experimental, + [Alias("DryRun","Noop")] + [switch]$WhatIf, + [switch]$Mono, + [switch]$SkipToolPackageRestore, + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$ScriptArgs +) + +Write-Host "Preparing to run build script..." + +$PSScriptRoot = split-path -parent $MyInvocation.MyCommand.Definition; +$TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" +$NUGET_URL = "http://dist.nuget.org/win-x86-commandline/latest/nuget.exe" +$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" +$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" + +# Should we use mono? +$UseMono = ""; +if($Mono.IsPresent) { + Write-Verbose -Message "Using the Mono based scripting engine." + $UseMono = "-mono" +} + +# Should we use the new Roslyn? +$UseExperimental = ""; +if($Experimental.IsPresent -and !($Mono.IsPresent)) { + Write-Verbose -Message "Using experimental version of Roslyn." + $UseExperimental = "-experimental" +} + +# Is this a dry run? +$UseDryRun = ""; +if($WhatIf.IsPresent) { + $UseDryRun = "-dryrun" +} + +# Make sure tools folder exists +if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { + Write-Verbose -Message "Creating tools directory..." + New-Item -Path $TOOLS_DIR -Type directory | out-null +} + +# Make sure that packages.config exist. +if (!(Test-Path $PACKAGES_CONFIG)) { + Write-Verbose -Message "Downloading packages.config..." + try { Invoke-WebRequest -Uri http://cakebuild.net/download/bootstrapper/packages -OutFile $PACKAGES_CONFIG } catch { + Throw "Could not download packages.config." + } +} + +# Try find NuGet.exe in path if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Trying to find nuget.exe in PATH..." + $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) } + $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 + if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { + Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." + $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName + } +} + +# Try download NuGet.exe if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Downloading NuGet.exe..." + try { + (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) + } catch { + Throw "Could not download NuGet.exe." + } +} + +# Save nuget.exe path to environment to be available to child processed +$ENV:NUGET_EXE = $NUGET_EXE + +# Restore tools from NuGet? +if(-Not $SkipToolPackageRestore.IsPresent) { + Push-Location + Set-Location $TOOLS_DIR + Write-Verbose -Message "Restoring tools from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" + if ($LASTEXITCODE -ne 0) { + Throw "An error occured while restoring NuGet tools." + } + Write-Verbose -Message ($NuGetOutput | out-string) + Pop-Location +} + +# Make sure that Cake has been installed. +if (!(Test-Path $CAKE_EXE)) { + Throw "Could not find Cake.exe at $CAKE_EXE" +} + +# Start Cake +Write-Host "Running build script..." +Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" +exit $LASTEXITCODE diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000..3d74a70fb5 --- /dev/null +++ b/build.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +############################################################### +# This is the Cake bootstrapper script that is responsible for +# downloading Cake and all specified tools from NuGet. +############################################################### + +# Define directories. +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +TOOLS_DIR=$SCRIPT_DIR/tools +NUGET_EXE=$TOOLS_DIR/nuget.exe +CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe + +# Define default arguments. +SCRIPT="build.cake" +TARGET="Travis" +CONFIGURATION="Release" +VERBOSITY="verbose" +DRYRUN= +SHOW_VERSION=false +SCRIPT_ARGUMENTS=() + +# Parse arguments. +for i in "$@"; do + case $1 in + -s|--script) SCRIPT="$2"; shift ;; + -t|--target) TARGET="$2"; shift ;; + -c|--configuration) CONFIGURATION="$2"; shift ;; + -v|--verbosity) VERBOSITY="$2"; shift ;; + -d|--dryrun) DRYRUN="-dryrun" ;; + --version) SHOW_VERSION=true ;; + --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; + *) SCRIPT_ARGUMENTS+=("$1") ;; + esac + shift +done + +# Make sure the tools folder exist. +if [ ! -d $TOOLS_DIR ]; then + mkdir $TOOLS_DIR +fi + +# Make sure that packages.config exist. +if [ ! -f $TOOLS_DIR/packages.config ]; then + echo "Downloading packages.config..." + curl -Lsfo $TOOLS_DIR/packages.config http://cakebuild.net/download/bootstrapper/packages + if [ $? -ne 0 ]; then + echo "An error occured while downloading packages.config." + exit 1 + fi +fi + +# Download NuGet if it does not exist. +if [ ! -f $NUGET_EXE ]; then + echo "Downloading NuGet..." + curl -Lsfo $NUGET_EXE https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + if [ $? -ne 0 ]; then + echo "An error occured while downloading nuget.exe." + exit 1 + fi +fi + +# Restore tools from NuGet. +pushd $TOOLS_DIR >/dev/null +mono $NUGET_EXE install -ExcludeVersion +if [ $? -ne 0 ]; then + echo "Could not restore NuGet packages." + exit 1 +fi +popd >/dev/null + +# Make sure that Cake has been installed. +if [ ! -f $CAKE_EXE ]; then + echo "Could not find Cake.exe at '$CAKE_EXE'." + exit 1 +fi + +# Start Cake +if $SHOW_VERSION; then + exec mono $CAKE_EXE -version +else + exec mono $CAKE_EXE $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" +fi diff --git a/deploy.cake b/deploy.cake new file mode 100644 index 0000000000..29517c37c2 --- /dev/null +++ b/deploy.cake @@ -0,0 +1,178 @@ +#addin "Cake.Json" + +using System.Net; +using System.Linq; +using System.Collections.Generic; + +string Get(string url) +{ + var assetsRequest = WebRequest.CreateHttp(url); + assetsRequest.Method = "GET"; + assetsRequest.Accept = "application/vnd.github.v3+json"; + assetsRequest.UserAgent = "BuildScript"; + + using (var assetsResponse = assetsRequest.GetResponse()) + { + var assetsStream = assetsResponse.GetResponseStream(); + var assetsReader = new StreamReader(assetsStream); + var assetsBody = assetsReader.ReadToEnd(); + return assetsBody; + } +} + +Task("EnsureRequirements") + .Does(() => + { + if (!AppVeyor.IsRunningOnAppVeyor) + throw new Exception("Deployment should happen via appveyor"); + + var isTag = + AppVeyor.Environment.Repository.Tag.IsTag && + !string.IsNullOrWhiteSpace(AppVeyor.Environment.Repository.Tag.Name); + if (!isTag) + throw new Exception("Deployment should happen from a published GitHub release"); + }); + +var tag = ""; +Dictionary artifactLookup = null; +Task("UpdateVersionInfo") + .IsDependentOn("EnsureRequirements") + .Does(() => + { + tag = AppVeyor.Environment.Repository.Tag.Name; + AppVeyor.UpdateBuildVersion(tag); + }); + +Task("DownloadGitHubReleaseArtifacts") + .IsDependentOn("UpdateVersionInfo") + .Does(() => + { + var assets_url = ParseJson(Get("https://api.github.com/repos/shouldly/shouldly/releases/tags/" + tag)) + .GetValue("assets_url").Value(); + EnsureDirectoryExists("./releaseArtifacts"); + foreach(var asset in DeserializeJson(Get(assets_url))) + { + DownloadFile(asset.Value("browser_download_url"), "./releaseArtifacts/" + asset.Value("name")); + } + + // Turns .artifacts file into a lookup + artifactLookup = System.IO.File + .ReadAllLines("./releaseArtifacts/artifacts") + .Select(l => l.Split(':')) + .ToDictionary(v => v[0], v => v[1]); + }); + +Task("Publish-NuGetPackage") + .IsDependentOn("DownloadGitHubReleaseArtifacts") + .Does(() => +{ + NuGetPush( + "./releaseArtifacts/" + artifactLookup["NuGetExeBuild"], + new NuGetPushSettings { + ApiKey = EnvironmentVariable("NuGetApiKey"), + Source = "https://www.nuget.org/api/v2/package" + }); +}) +.OnError(exception => +{ + Information("Publish-NuGet Task failed, but continuing with next Task..."); + publishingError = true; +}); + +Task("Publish-NuGetCommandLine") + .IsDependentOn("DownloadGitHubReleaseArtifacts") + .Does(() => +{ + NuGetPush( + "./releaseArtifacts/" + artifactLookup["NuGetCommandLineBuild"], + new NuGetPushSettings { + ApiKey = EnvironmentVariable("NuGetApiKey"), + Source = "https://www.nuget.org/api/v2/package" + }); +}) +.OnError(exception => +{ + Information("Publish-NuGet Task failed, but continuing with next Task..."); + publishingError = true; +}); + + +Task("Publish-MsBuildTask") + .IsDependentOn("DownloadGitHubReleaseArtifacts") + .Does(() => +{ + NuGetPush( + "./releaseArtifacts/" + artifactLookup["NuGetTaskBuild"], + new NuGetPushSettings { + ApiKey = EnvironmentVariable("NuGetApiKey"), + Source = "https://www.nuget.org/api/v2/package" + }); +}) +.OnError(exception => +{ + Information("Publish-NuGet Task failed, but continuing with next Task..."); + publishingError = true; +}); + +Task("Publish-Chocolatey") + .IsDependentOn("DownloadGitHubReleaseArtifacts") + .Does(() => +{ + NuGetPush( + "./releaseArtifacts/" + artifactLookup["NuGetExeBuild"], + new NuGetPushSettings { + ApiKey = EnvironmentVariable("ChocolateyApiKey"), + Source = "https://chocolatey.org/api/v2/package" + }); +}) +.OnError(exception => +{ + Information("Publish-Chocolatey Task failed, but continuing with next Task..."); + publishingError = true; +}); + +Task("Publish-Gem") + .IsDependentOn("DownloadGitHubReleaseArtifacts") + .Does(() => +{ + var returnCode = StartProcess("gem", new ProcessSettings + { + Arguments = "push ./releaseArtifacts/" + artifactLookup["NuGetExeBuild"] + " --key " + EnvironmentVariable("GemApiKey") + }); + + if (returnCode != 0) { + Information("Publish-Gem Task failed, but continuing with next Task..."); + publishingError = true; + } +}); + + +Task("Publish-VstsTask") + .IsDependentOn("DownloadGitHubReleaseArtifacts") + .Does(() => +{ + var returnCode = StartProcess("tfx", new ProcessSettings + { + Arguments = "extension publish --vsix ./releaseArtifacts/" + artifactLookup["GitVersionTfsTaskBuild"] + " --no-prompt --auth-type pat --token " + EnvironmentVariable("GemApiKey") + }); + + if (returnCode != 0) { + Information("Publish-VstsTask Task failed, but continuing with next Task..."); + publishingError = true; + } +}); + +Task("Deploy") + .IsDependentOn("Publish-NuGetPackage") + .IsDependentOn("Publish-NuGetCommandLine") + .IsDependentOn("Publish-MsBuildTask") + .IsDependentOn("Publish-Chocolatey") + .IsDependentOn("Publish-Gem") + .IsDependentOn("Publish-VstsTask") + .Finally(() => +{ + if(publishingError) + { + throw new Exception("An error occurred during the publishing of Cake. All publishing tasks have been attempted."); + } +}); \ No newline at end of file diff --git a/deploy.ps1 b/deploy.ps1 new file mode 100644 index 0000000000..eaf1d62d9a --- /dev/null +++ b/deploy.ps1 @@ -0,0 +1,145 @@ +########################################################################## +# This is the Cake bootstrapper script for PowerShell. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +<# + +.SYNOPSIS +This is a Powershell script to bootstrap a Cake build. + +.DESCRIPTION +This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) +and execute your Cake build script with the parameters you provide. + +.PARAMETER Script +The build script to execute. +.PARAMETER Target +The build script target to run. +.PARAMETER Configuration +The build configuration to use. +.PARAMETER Verbosity +Specifies the amount of information to be displayed. +.PARAMETER Experimental +Tells Cake to use the latest Roslyn release. +.PARAMETER WhatIf +Performs a dry run of the build script. +No tasks will be executed. +.PARAMETER Mono +Tells Cake to use the Mono scripting engine. +.PARAMETER SkipToolPackageRestore +Skips restoring of packages. +.PARAMETER ScriptArgs +Remaining arguments are added here. + +.LINK +http://cakebuild.net + +#> + +[CmdletBinding()] +Param( + [string]$Script = "deploy.cake", + [string]$Target = "Default", + [string]$Configuration = "Release", + [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] + [string]$Verbosity = "Verbose", + [switch]$Experimental, + [Alias("DryRun","Noop")] + [switch]$WhatIf, + [switch]$Mono, + [switch]$SkipToolPackageRestore, + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$ScriptArgs +) + +Write-Host "Preparing to run build script..." + +$PSScriptRoot = split-path -parent $MyInvocation.MyCommand.Definition; +$TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" +$NUGET_URL = "http://dist.nuget.org/win-x86-commandline/latest/nuget.exe" +$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" +$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" + +# Should we use mono? +$UseMono = ""; +if($Mono.IsPresent) { + Write-Verbose -Message "Using the Mono based scripting engine." + $UseMono = "-mono" +} + +# Should we use the new Roslyn? +$UseExperimental = ""; +if($Experimental.IsPresent -and !($Mono.IsPresent)) { + Write-Verbose -Message "Using experimental version of Roslyn." + $UseExperimental = "-experimental" +} + +# Is this a dry run? +$UseDryRun = ""; +if($WhatIf.IsPresent) { + $UseDryRun = "-dryrun" +} + +# Make sure tools folder exists +if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { + Write-Verbose -Message "Creating tools directory..." + New-Item -Path $TOOLS_DIR -Type directory | out-null +} + +# Make sure that packages.config exist. +if (!(Test-Path $PACKAGES_CONFIG)) { + Write-Verbose -Message "Downloading packages.config..." + try { Invoke-WebRequest -Uri http://cakebuild.net/download/bootstrapper/packages -OutFile $PACKAGES_CONFIG } catch { + Throw "Could not download packages.config." + } +} + +# Try find NuGet.exe in path if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Trying to find nuget.exe in PATH..." + $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) } + $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 + if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { + Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." + $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName + } +} + +# Try download NuGet.exe if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Downloading NuGet.exe..." + try { + (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) + } catch { + Throw "Could not download NuGet.exe." + } +} + +# Save nuget.exe path to environment to be available to child processed +$ENV:NUGET_EXE = $NUGET_EXE + +# Restore tools from NuGet? +if(-Not $SkipToolPackageRestore.IsPresent) { + Push-Location + Set-Location $TOOLS_DIR + Write-Verbose -Message "Restoring tools from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" + if ($LASTEXITCODE -ne 0) { + Throw "An error occured while restoring NuGet tools." + } + Write-Verbose -Message ($NuGetOutput | out-string) + Pop-Location +} + +# Make sure that Cake has been installed. +if (!(Test-Path $CAKE_EXE)) { + Throw "Could not find Cake.exe at $CAKE_EXE" +} + +# Start Cake +Write-Host "Running build script..." +Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" +exit $LASTEXITCODE diff --git a/src/GitVersion.sln b/src/GitVersion.sln index d9c3232212..5df3d460f1 100644 --- a/src/GitVersion.sln +++ b/src/GitVersion.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitVersionExe", "GitVersionExe\GitVersionExe.csproj", "{C3578A7B-09A6-4444-9383-0DEAFA4958BD}" EndProject @@ -18,8 +18,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\.travis.yml = ..\.travis.yml ..\appveyor.yml = ..\appveyor.yml ..\BREAKING CHANGES.md = ..\BREAKING CHANGES.md - ..\Build.cmd = ..\Build.cmd + ..\build.cake = ..\build.cake + ..\build.ps1 = ..\build.ps1 + ..\build.sh = ..\build.sh ..\CONTRIBUTING.md = ..\CONTRIBUTING.md + ..\deploy.cake = ..\deploy.cake ..\GitVersion.yml = ..\GitVersion.yml ..\LICENSE = ..\LICENSE ..\mkdocs.yml = ..\mkdocs.yml @@ -33,9 +36,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TfsTask", "TfsTask", "{A0ED1410-E970-45E8-A357-05605E2B7BFF}" ProjectSection(SolutionItems) = preProject GitVersionTfsTask\Create-Vsix.ps1 = GitVersionTfsTask\Create-Vsix.ps1 + GitVersionTfsTask\extension-icon.png = GitVersionTfsTask\extension-icon.png GitVersionTfsTask\GitVersion.ps1 = GitVersionTfsTask\GitVersion.ps1 GitVersionTfsTask\icon.png = GitVersionTfsTask\icon.png - GitVersionTfsTask\extension-icon.png = GitVersionTfsTask\extension-icon.png GitVersionTfsTask\manifest.json = GitVersionTfsTask\manifest.json GitVersionTfsTask\overview.md = GitVersionTfsTask\overview.md GitVersionTfsTask\task.json = GitVersionTfsTask\task.json diff --git a/src/GitVersion.sln.DotSettings b/src/GitVersion.sln.DotSettings index 1640e95699..9b2f0d5ba1 100644 --- a/src/GitVersion.sln.DotSettings +++ b/src/GitVersion.sln.DotSettings @@ -549,6 +549,7 @@ II.2.12 <HandlesEvent /> True True True + True True True False diff --git a/src/GitVersionCore/GitVersionCore.csproj b/src/GitVersionCore/GitVersionCore.csproj index b6e9fc9b07..e43cb37b2f 100644 --- a/src/GitVersionCore/GitVersionCore.csproj +++ b/src/GitVersionCore/GitVersionCore.csproj @@ -36,6 +36,7 @@ prompt 4 bin\Release\GitVersionCore.xml + 1591 diff --git a/src/GitVersionExe/GitVersionExe.csproj b/src/GitVersionExe/GitVersionExe.csproj index d013548403..2c71c9a75e 100644 --- a/src/GitVersionExe/GitVersionExe.csproj +++ b/src/GitVersionExe/GitVersionExe.csproj @@ -38,6 +38,7 @@ 4 false bin\Release\GitVersion.xml + 1591 @@ -176,7 +177,6 @@ - diff --git a/src/GitVersionTask/GitVersionTask.csproj b/src/GitVersionTask/GitVersionTask.csproj index f73562bfb9..07a3bc47cf 100644 --- a/src/GitVersionTask/GitVersionTask.csproj +++ b/src/GitVersionTask/GitVersionTask.csproj @@ -36,6 +36,7 @@ prompt 4 false + 1591