diff --git a/Fake.sln b/Fake.sln
index d817991c01a..be03269ca1d 100644
--- a/Fake.sln
+++ b/Fake.sln
@@ -170,6 +170,8 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fake.Tools.Octo", "src\app\
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fake.Core.Vault", "src\app\Fake.Core.Vault\Fake.Core.Vault.fsproj", "{AAAF92C5-C40D-40B8-84BA-137DF0E98B56}"
EndProject
+Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Fake.Installer.Squirrel", "src\app\Fake.Installer.Squirrel\Fake.Installer.Squirrel.fsproj", "{3DEF2E95-4BF8-413F-930E-32103A39364A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1056,6 +1058,18 @@ Global
{AAAF92C5-C40D-40B8-84BA-137DF0E98B56}.Release|x64.Build.0 = Release|Any CPU
{AAAF92C5-C40D-40B8-84BA-137DF0E98B56}.Release|x86.ActiveCfg = Release|Any CPU
{AAAF92C5-C40D-40B8-84BA-137DF0E98B56}.Release|x86.Build.0 = Release|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Debug|x64.Build.0 = Debug|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Debug|x86.Build.0 = Debug|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Release|x64.ActiveCfg = Release|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Release|x64.Build.0 = Release|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Release|x86.ActiveCfg = Release|Any CPU
+ {3DEF2E95-4BF8-413F-930E-32103A39364A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1136,6 +1150,7 @@ Global
{E656E3E2-18D2-4D8E-935C-200DB00E1F19} = {7BFFAE76-DEE9-417A-A79B-6A6644C4553A}
{F1641150-B89D-40B7-A3BE-9DC357410FDA} = {7BFFAE76-DEE9-417A-A79B-6A6644C4553A}
{AAAF92C5-C40D-40B8-84BA-137DF0E98B56} = {901F162F-8925-4390-89C5-9EE2C343F744}
+ {3DEF2E95-4BF8-413F-930E-32103A39364A} = {901F162F-8925-4390-89C5-9EE2C343F744}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {058A0C5E-2216-4306-8AFB-0AE28320C26A}
diff --git a/build.fsx b/build.fsx
index 8017b5dbba1..fc774d63960 100644
--- a/build.fsx
+++ b/build.fsx
@@ -302,6 +302,7 @@ let dotnetAssemblyInfos =
"Fake.DotNet.Testing.XUnit2", "Running xunit test runner"
"Fake.DotNet.Xamarin", "Running Xamarin builds"
"Fake.Installer.InnoSetup", "Creating installers with InnoSetup"
+ "Fake.Installer.Squirrel", "Squirrel for windows Squirrel.exe tool helper"
"Fake.Installer.Wix", "WiX helper to create msi installers"
"Fake.IO.FileSystem", "Core Filesystem utilities and globbing support"
"Fake.IO.Zip", "Core Zip functionality"
@@ -522,7 +523,7 @@ Target.create "GenerateDocs" (fun _ ->
ProjectParameters = ("api-docs-prefix", "/apidocs/v5/legacy/") :: ("CurrentPage", "APIReference") :: projInfo
SourceRepository = githubLink + "/blob/master" })
else
- buildLegacyFromDocsDir legacyLayoutRoots (apidocsDir @@ "v5/legacy") "/apidocs/v5/legacy/" "/blob/master" ("packages/docslegacyv5/FAKE/tools")
+ buildLegacyFromDocsDir legacyLayoutRoots (apidocsDir @@ "v5/legacy") "/apidocs/v5/legacy/" "/blob/master" ("packages/docslegacyv5/FAKE/tools")
// FAKE 4 legacy documentation
buildLegacyFromDocsDir fake4LayoutRoots (apidocsDir @@ "v4") "/apidocs/v4/" "/blob/hotfix_fake4" ("packages/docslegacyv4/FAKE/tools")
@@ -844,14 +845,14 @@ Target.create "CheckReleaseSecrets" (fun _ ->
Target.create "DotNetCoreCreateDebianPackage" (fun _ ->
let runtime = "linux-x64"
- let targetFramework = "netcoreapp2.1"
- let args =
+ let targetFramework = "netcoreapp2.1"
+ let args =
[
- sprintf "/t:%s" "Restore;CreateDeb"
+ sprintf "/t:%s" "Restore;CreateDeb"
sprintf "/p:TargetFramework=%s" targetFramework
sprintf "/p:CustomTarget=%s" "CreateDeb"
sprintf "/p:RuntimeIdentifier=%s" runtime
- sprintf "/p:Configuration=%s" "Release"
+ sprintf "/p:Configuration=%s" "Release"
sprintf "/p:PackageVersion=%s" simpleVersion
] |> String.concat " "
let result =
@@ -862,7 +863,7 @@ Target.create "DotNetCoreCreateDebianPackage" (fun _ ->
if result.OK |> not then
failwith "Debian package creation failed"
-
+
let fileName = sprintf "fake-cli.%s.%s.deb" simpleVersion runtime
let sourceFile = sprintf "src/app/fake-cli/bin/Release/%s/%s/%s" targetFramework runtime fileName
Directory.ensure nugetDncDir
diff --git a/help/markdown/fake-installer-squirrel.md b/help/markdown/fake-installer-squirrel.md
new file mode 100644
index 00000000000..ef950eac639
--- /dev/null
+++ b/help/markdown/fake-installer-squirrel.md
@@ -0,0 +1,25 @@
+# Releasifying NuGet packages with Squirrel
+
+
+
INFO
+
This documentation is for FAKE version 5.0 or later.
+
+
+[Squirrel.Windows](https://github.com/Squirrel/Squirrel.Windows) is an installation an auto-update system for Windows desktop apps.
+
+[API-Reference](apidocs/v5/fake-installer-squirrel.html)
+
+## Squirrel.exe CLI tool
+
+This module is a wrapper around the [Squirrel.exe](https://github.com/Squirrel/Squirrel.Windows/blob/master/docs/using/squirrel-command-line.md) CLI tool that is available in the [squirrel.windows](https://www.nuget.org/packages/squirrel.windows/) NuGet package.
+
+## Releasify
+
+[Releasifying](https://github.com/Squirrel/Squirrel.Windows/blob/master/docs/getting-started/2-packaging.md#releasifying) create all files necessary for release from a NuGet package
+
+```fsharp
+open Fake.Installer
+
+Squirrel.releasify "./my.nupkg" (fun p -> { p with ReleaseDir = "./squirrel_release")
+```
+
diff --git a/help/templates/template.cshtml b/help/templates/template.cshtml
index 190d2423a35..8b98ce302ae 100644
--- a/help/templates/template.cshtml
+++ b/help/templates/template.cshtml
@@ -156,6 +156,7 @@
Installer
diff --git a/src/app/Fake.Installer.Squirrel/AssemblyInfo.fs b/src/app/Fake.Installer.Squirrel/AssemblyInfo.fs
new file mode 100644
index 00000000000..56d4a8197db
--- /dev/null
+++ b/src/app/Fake.Installer.Squirrel/AssemblyInfo.fs
@@ -0,0 +1,17 @@
+// Auto-Generated by FAKE; do not edit
+namespace System
+open System.Reflection
+
+[]
+[]
+[]
+[]
+[]
+do ()
+
+module internal AssemblyVersionInformation =
+ let [] AssemblyTitle = "FAKE - F# Make Squirrel for windows Squirrel.exe tool helper"
+ let [] AssemblyProduct = "FAKE - F# Make"
+ let [] AssemblyVersion = "5.3.1"
+ let [] AssemblyInformationalVersion = "5.3.1-alpha"
+ let [] AssemblyFileVersion = "5.3.1"
diff --git a/src/app/Fake.Installer.Squirrel/Fake.Installer.Squirrel.fsproj b/src/app/Fake.Installer.Squirrel/Fake.Installer.Squirrel.fsproj
new file mode 100644
index 00000000000..3b420946c0c
--- /dev/null
+++ b/src/app/Fake.Installer.Squirrel/Fake.Installer.Squirrel.fsproj
@@ -0,0 +1,24 @@
+
+
+ net46;netstandard1.6;netstandard2.0
+ $(DefineConstants);NO_DOTNETCORE_BOOTSTRAP
+ Fake.Installer.Squirrel
+ Library
+
+
+ $(DefineConstants);NETSTANDARD
+
+
+ $(DefineConstants);RELEASE
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/Fake.Installer.Squirrel/Squirrel.fs b/src/app/Fake.Installer.Squirrel/Squirrel.fs
new file mode 100644
index 00000000000..fbe3e28f366
--- /dev/null
+++ b/src/app/Fake.Installer.Squirrel/Squirrel.fs
@@ -0,0 +1,142 @@
+/// Contains types and utility functions related to creating [Squirrel](https://github.com/Squirrel/Squirrel.Windows) installer.
+[]
+module Fake.Installer.Squirrel
+
+open Fake.Core
+open Fake.IO
+open Fake.IO.FileSystemOperators
+open Fake.IO.Globbing
+open System
+open System.IO
+open System.Text
+
+/// The [Squirrel](https://github.com/Squirrel/Squirrel.Windows) Console Parameters type.
+///
+/// For reference, see: [Squirrel Command Line Options](https://github.com/Squirrel/Squirrel.Windows/blob/master/docs/advanced-releasify.md)
+type ReleasifyParams = {
+ /// The output directory for the generated installer
+ ReleaseDir : string
+
+ /// The working directory.
+ WorkingDir : string option
+
+ /// The full path to an optional setup.exe template
+ BootstrapperExe : string option
+
+ /// The full path to an optional animated gif to be displayed during installation
+ LoadingGif : string option
+
+ /// The full path to an optional icon, which will be used for the generated installer.
+ SetupIcon : string option
+
+ /// Do not create an MSI file
+ NoMsi : bool
+
+ /// The path to Squirrel: `squirrel.exe`
+ ToolPath : string
+
+ /// Maximum time to allow Squirrel to run before being killed.
+ TimeOut : TimeSpan
+
+ /// Sign the installer with signtool.exe
+ SignExecutable : bool option
+
+ /// The code signing certificate to be used for signing
+ SigningKeyFile : string option
+
+ /// The secret key for the code signing certificate
+ SigningSecret : string option
+}
+
+let internal defaultParams = lazy(
+ let toolname = "Squirrel.exe"
+ { ReleaseDir = ""
+ WorkingDir = None
+ BootstrapperExe = None
+ LoadingGif = None
+ SetupIcon = None
+ NoMsi = false
+ ToolPath = Tools.findToolInSubPath toolname ( Directory.GetCurrentDirectory() > "tools" > "Squirrel")
+ TimeOut = TimeSpan.FromMinutes 10.
+ SignExecutable = None
+ SigningKeyFile = None
+ SigningSecret = None })
+
+let private createSigningArgs (parameters : ReleasifyParams) =
+ new StringBuilder()
+ |> StringBuilder.appendWithoutQuotes "--signWithParams=\""
+ |> StringBuilder.appendWithoutQuotes "/a"
+ |> StringBuilder.appendIfSome parameters.SigningKeyFile (sprintf "/f %s")
+ |> StringBuilder.appendIfSome parameters.SigningSecret (sprintf "/p %s")
+ |> StringBuilder.appendWithoutQuotes "\""
+ |> StringBuilder.toText
+
+let internal buildSquirrelArgs parameters nugetPackage =
+ new StringBuilder()
+ |> StringBuilder.appendIfNotNullOrEmpty nugetPackage "--releasify="
+ |> StringBuilder.appendIfNotNullOrEmpty parameters.ReleaseDir "--releaseDir="
+ |> StringBuilder.appendIfSome parameters.LoadingGif (sprintf "\"--loadingGif=%s\"")
+ |> StringBuilder.appendIfSome parameters.SetupIcon (sprintf "\"--setupIcon=%s\"")
+ |> StringBuilder.appendIfTrue parameters.NoMsi "--no-msi"
+ |> StringBuilder.appendIfSome parameters.BootstrapperExe (sprintf "\"--bootstrapperExe=%s\"")
+ |> StringBuilder.appendIfSome parameters.SignExecutable (fun _ -> createSigningArgs parameters)
+ |> StringBuilder.toText
+
+module internal ResultHandling =
+ let (|OK|Failure|) = function
+ | 0 -> OK
+ | x -> Failure x
+
+ let buildErrorMessage = function
+ | OK -> None
+ | Failure errorCode ->
+ Some (sprintf "Squirrel reported an error (Error Code %d)" errorCode)
+
+ let failBuildIfSquirrelReportedError =
+ buildErrorMessage
+ >> Option.iter failwith
+
+/// Creates a Squirrel installer for given NuGet package
+/// Will fail if Squirrel terminates with non-zero exit code.
+///
+/// ## Parameters
+///
+/// - `setParams` - Function used to manipulate the default `SquirrelParams` value.
+/// - `nugetPackage` - The package to create an installer for
+///
+/// ## Sample usage
+///
+/// Target.create "CreatePackage" (fun _ ->
+/// Squirrel.releasify "./my.nupkg" (fun p -> { p with ReleaseDir = "./squirrel_release")
+/// )
+///
+/// ## Defaults for setParams
+///
+/// - `ReleaseDir` - `""`
+/// - `WorkingDir` - `None`
+/// - `BootstrapperExe` - `None`
+/// - `LoadingGif` - `None`
+/// - `SetupIcon` - `None`
+/// - `NoMsi` - `false`
+/// - `ToolPath` - The `squirrel.exe` path if it exists in a subdirectory of the current directory.
+/// - `TimeOut` - 10 minutes
+/// - `SignExecutable` - `None`
+/// - `SigningKeyFile` - `None`
+/// - `SigningSecret` - `None`
+let releasify (nugetPackage: string) (setParams: ReleasifyParams -> ReleasifyParams): unit =
+ use __ = Trace.traceTask "Squirrel" nugetPackage
+ let parameters = defaultParams.Value |> setParams
+ let args = buildSquirrelArgs parameters nugetPackage
+ Trace.tracefn "%s" args
+
+ let result =
+ Process.execSimple
+ (fun info -> { info with
+ FileName = parameters.ToolPath
+ WorkingDirectory = defaultArg parameters.WorkingDir "."
+ Arguments = args})
+ parameters.TimeOut
+
+ ResultHandling.failBuildIfSquirrelReportedError result
+
+ __.MarkSuccess()
diff --git a/src/app/Fake.Installer.Squirrel/paket.references b/src/app/Fake.Installer.Squirrel/paket.references
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/legacy/FakeLib/SquirrelHelper.fs b/src/legacy/FakeLib/SquirrelHelper.fs
index 04c463c9461..bc3b16ed027 100644
--- a/src/legacy/FakeLib/SquirrelHelper.fs
+++ b/src/legacy/FakeLib/SquirrelHelper.fs
@@ -1,5 +1,5 @@
/// Contains types and utility functions related to creating [Squirrel](https://github.com/Squirrel/Squirrel.Windows) installer.
-[]
+[]
module Fake.Squirrel
open Fake
@@ -11,7 +11,7 @@ open System.Text
///
/// For reference, see: [Squirrel Command Line Options](https://github.com/Squirrel/Squirrel.Windows/blob/master/docs/advanced-releasify.md)
[]
-[]
+[]
type SquirrelParams =
{
/// The output directory for the generated installer
@@ -62,7 +62,7 @@ type SquirrelParams =
/// - `SignExecutable` - `None`
/// - `SigningKeyFile` - `None`
/// - `SigningSecret` - `None`
-[]
+[]
let SquirrelDefaults =
let toolname = "Squirrel.exe"
{
@@ -125,7 +125,7 @@ module internal ResultHandling =
/// Target "CreatePackage" (fun _ ->
/// SquirrelPack (fun p -> { p with WorkingDir = Some "./tmp" }) "./my.nupkg"
/// )
-[]
+[]
let SquirrelPack setParams nugetPackage =
use __ = traceStartTaskUsing "Squirrel" ""
let parameters = SquirrelDefaults |> setParams