#I @"tools/FAKE/tools" #r "FakeLib.dll" open System open System.IO open System.Text open Fake open Fake.DotNetCli open Fake.DocFxHelper open Fake.FileHelper // Information about the project for Nuget and Assembly info files let configuration = "Release" // Read release notes and version let solutionFile = FindFirstMatchingFile "*.sln" __SOURCE_DIRECTORY__ // dynamically look up the solution let buildNumber = environVarOrDefault "BUILD_NUMBER" "0" let preReleaseVersionSuffix = "beta" + (if (not (buildNumber = "0")) then (buildNumber) else DateTime.UtcNow.Ticks.ToString()) let versionSuffix = match (getBuildParam "nugetprerelease") with | "dev" -> preReleaseVersionSuffix | _ -> "" let releaseNotes = File.ReadLines "./RELEASE_NOTES.md" |> ReleaseNotesHelper.parseReleaseNotes // Directories let toolsDir = __SOURCE_DIRECTORY__ @@ "tools" let output = __SOURCE_DIRECTORY__ @@ "bin" let outputTests = __SOURCE_DIRECTORY__ @@ "TestResults" let outputPerfTests = __SOURCE_DIRECTORY__ @@ "PerfResults" let outputNuGet = output @@ "nuget" // Copied from original NugetCreate target let nugetDir = output @@ "nuget" let workingDir = output @@ "build" let nugetExe = FullName @"./tools/nuget.exe" Target "Clean" (fun _ -> CleanDir output CleanDir outputTests CleanDir outputPerfTests CleanDir outputNuGet CleanDir "docs/_site" CleanDirs !! "./**/bin" CleanDirs !! "./**/obj" ) Target "AssemblyInfo" (fun _ -> XmlPokeInnerText "./src/common.props" "//Project/PropertyGroup/VersionPrefix" releaseNotes.AssemblyVersion XmlPokeInnerText "./src/common.props" "//Project/PropertyGroup/PackageReleaseNotes" (releaseNotes.Notes |> String.concat "\n") ) Target "RestorePackages" (fun _ -> DotNetCli.Restore (fun p -> { p with Project = solutionFile NoCache = false}) ) Target "Build" (fun _ -> let additionalArgs = if versionSuffix.Length > 0 then [sprintf "/p:VersionSuffix=%s" versionSuffix;"--no-incremental"] else ["--no-incremental"] let runSingleProject project = DotNetCli.Build (fun p -> { p with Project = project Configuration = configuration AdditionalArgs = additionalArgs}) // "Rebuild" let assemblies = !! "./src/**/*.*sproj" assemblies |> Seq.iter (runSingleProject) ) //-------------------------------------------------------------------------------- // Tests targets //-------------------------------------------------------------------------------- module internal ResultHandling = let (|OK|Failure|) = function | 0 -> OK | x -> Failure x let buildErrorMessage = function | OK -> None | Failure errorCode -> Some (sprintf "xUnit2 reported an error (Error Code %d)" errorCode) let failBuildWithMessage = function | DontFailBuild -> traceError | _ -> (fun m -> raise(FailedTestsException m)) let failBuildIfXUnitReportedError errorLevel = buildErrorMessage >> Option.iter (failBuildWithMessage errorLevel) Target "RunTests" (fun _ -> let projects = match (isWindows) with | true -> !! "./src/**/*.Tests.csproj" | _ -> !! "./src/**/*.Tests.csproj" // if you need to filter specs for Linux vs. Windows, do it here let runSingleProject project = let result = ExecProcess(fun info -> info.FileName <- "dotnet" info.WorkingDirectory <- (Directory.GetParent project).FullName info.Arguments <- (sprintf "xunit -c Release -nobuild -parallel none -teamcity -xml %s_xunit.xml" (outputTests @@ fileNameWithoutExt project))) (TimeSpan.FromMinutes 30.) ResultHandling.failBuildIfXUnitReportedError TestRunnerErrorLevel.DontFailBuild result projects |> Seq.iter (log) projects |> Seq.iter (runSingleProject) ) Target "NBench" <| fun _ -> let nbenchTestPath = findToolInSubPath "NBench.Runner.exe" (toolsDir @@ "NBench.Runner*") printfn "Using NBench.Runner: %s" nbenchTestPath let nbenchTestAssemblies = !! "./src/**/*Tests.Performance.csproj" let runNBench assembly = let includes = getBuildParam "include" let excludes = getBuildParam "exclude" let teamcityStr = (getBuildParam "teamcity") let enableTeamCity = match teamcityStr with | null -> false | "" -> false | _ -> bool.Parse teamcityStr let args = StringBuilder() |> append assembly |> append (sprintf "output-directory=\"%s\"" outputPerfTests) |> append (sprintf "concurrent=\"%b\"" true) |> append (sprintf "trace=\"%b\"" true) |> append (sprintf "teamcity=\"%b\"" enableTeamCity) |> appendIfNotNullOrEmpty includes "include=" |> appendIfNotNullOrEmpty excludes "include=" |> toText let result = ExecProcess(fun info -> info.FileName <- nbenchTestPath info.WorkingDirectory <- (Path.GetDirectoryName (FullName nbenchTestPath)) info.Arguments <- args) (System.TimeSpan.FromMinutes 45.0) (* Reasonably long-running task. *) if result <> 0 then failwithf "NBench.Runner failed. %s %s" nbenchTestPath args nbenchTestAssemblies |> Seq.iter runNBench //-------------------------------------------------------------------------------- // Nuget targets //-------------------------------------------------------------------------------- let overrideVersionSuffix (project:string) = match project with | _ -> versionSuffix // add additional matches to publish different versions for different projects in solution Target "CreateNuget" (fun _ -> let projects = !! "src/**/*.csproj" -- "src/**/*Tests.csproj" // Don't publish unit tests -- "src/**/*Tests*.csproj" -- "src/**/*.Demo.csproj" // Don't publish demo apps let runSingleProject project = DotNetCli.Pack (fun p -> { p with Project = project Configuration = configuration AdditionalArgs = ["--include-symbols"] VersionSuffix = overrideVersionSuffix project OutputPath = outputNuGet }) projects |> Seq.iter (runSingleProject) ) Target "PublishNuget" (fun _ -> let projects = !! "./bin/nuget/*.nupkg" -- "./bin/nuget/*.symbols.nupkg" let apiKey = getBuildParamOrDefault "nugetkey" "" let source = getBuildParamOrDefault "nugetpublishurl" "" let symbolSource = getBuildParamOrDefault "symbolspublishurl" "" let shouldPublishSymbolsPackages = not (symbolSource = "") if (not (source = "") && not (apiKey = "") && shouldPublishSymbolsPackages) then let runSingleProject project = DotNetCli.RunCommand (fun p -> { p with TimeOut = TimeSpan.FromMinutes 10. }) (sprintf "nuget push %s --api-key %s --source %s --symbol-source %s" project apiKey source symbolSource) projects |> Seq.iter (runSingleProject) else if (not (source = "") && not (apiKey = "") && not shouldPublishSymbolsPackages) then let runSingleProject project = DotNetCli.RunCommand (fun p -> { p with TimeOut = TimeSpan.FromMinutes 10. }) (sprintf "nuget push %s --api-key %s --source %s" project apiKey source) projects |> Seq.iter (runSingleProject) ) //-------------------------------------------------------------------------------- // Documentation //-------------------------------------------------------------------------------- Target "DocFx" (fun _ -> DotNetCli.Restore (fun p -> { p with Project = solutionFile }) DotNetCli.Build (fun p -> { p with Project = solutionFile; Configuration = configuration }) let docsPath = "./docs" DocFx (fun p -> { p with Timeout = TimeSpan.FromMinutes 30.0; WorkingDirectory = docsPath; DocFxJson = docsPath @@ "docfx.json" }) ) //-------------------------------------------------------------------------------- // Help //-------------------------------------------------------------------------------- Target "Help" <| fun _ -> List.iter printfn [ "usage:" "./build.ps1 [target]" "" " Targets for building:" " * Build Builds" " * Nuget Create and optionally publish nugets packages" " * RunTests Runs tests" " * All Builds, run tests, creates and optionally publish nuget packages" " * DocFx Creates a DocFx-based website for this solution" "" " Other Targets" " * Help Display this help" ""] //-------------------------------------------------------------------------------- // Target dependencies //-------------------------------------------------------------------------------- Target "BuildRelease" DoNothing Target "All" DoNothing Target "Nuget" DoNothing // build dependencies "Clean" ==> "RestorePackages" ==> "AssemblyInfo" ==> "Build" ==> "BuildRelease" // tests dependencies // nuget dependencies "Clean" ==> "RestorePackages" ==> "Build" ==> "CreateNuget" "CreateNuget" ==> "PublishNuget" ==> "Nuget" // docs "BuildRelease" ==> "Docfx" // all "BuildRelease" ==> "All" "RunTests" ==> "All" //"NBench" ==> "All" "Nuget" ==> "All" RunTargetOrDefault "Help"