Browse Source

Merge pull request #878 from wieslawsoltes/SplitCakeBuildScript

Split cake build script
Nikita Tsukanov 8 years ago
parent
commit
4a3902202f
3 changed files with 701 additions and 634 deletions
  1. 89 634
      build.cake
  2. 469 0
      packages.cake
  3. 143 0
      parameters.cake

+ 89 - 634
build.cake

@@ -24,611 +24,62 @@ using Polly;
 using NuGet;
 
 ///////////////////////////////////////////////////////////////////////////////
-// ARGUMENTS
+// SCRIPTS
 ///////////////////////////////////////////////////////////////////////////////
 
-var target = Argument("target", "Default");
-var platform = Argument("platform", "Any CPU");
-var configuration = Argument("configuration", "Release");
-var skipTests = HasArgument("skip-tests");
+#load "./parameters.cake"
+#load "./packages.cake"
 
-///////////////////////////////////////////////////////////////////////////////
-// CONFIGURATION
-///////////////////////////////////////////////////////////////////////////////
-
-var MainRepo = "AvaloniaUI/Avalonia";
-var MasterBranch = "master";
-var AssemblyInfoPath = File("./src/Shared/SharedAssemblyInfo.cs");
-var ReleasePlatform = "Any CPU";
-var ReleaseConfiguration = "Release";
-var MSBuildSolution = "./Avalonia.sln";
-var XBuildSolution = "./Avalonia.XBuild.sln";
-
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
 // PARAMETERS
-///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
 
-var isPlatformAnyCPU = StringComparer.OrdinalIgnoreCase.Equals(platform, "Any CPU");
-var isPlatformX86 = StringComparer.OrdinalIgnoreCase.Equals(platform, "x86");
-var isPlatformX64 = StringComparer.OrdinalIgnoreCase.Equals(platform, "x64");
-var isLocalBuild = BuildSystem.IsLocalBuild;
-var isRunningOnUnix = IsRunningOnUnix();
-var isRunningOnWindows = IsRunningOnWindows();
-var isRunningOnAppVeyor = BuildSystem.AppVeyor.IsRunningOnAppVeyor;
-var isPullRequest = BuildSystem.AppVeyor.Environment.PullRequest.IsPullRequest;
-var isMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, BuildSystem.AppVeyor.Environment.Repository.Name);
-var isMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, BuildSystem.AppVeyor.Environment.Repository.Branch);
-var isTagged = BuildSystem.AppVeyor.Environment.Repository.Tag.IsTag 
-               && !string.IsNullOrWhiteSpace(BuildSystem.AppVeyor.Environment.Repository.Tag.Name);
-var isReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleasePlatform, platform) 
-                   && StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, configuration);
-var isMyGetRelease = !isTagged && isReleasable;
-var isNuGetRelease = isTagged && isReleasable;
+Parameters parameters = new Parameters(Context);
+Packages packages = new Packages(Context, parameters);
 
 ///////////////////////////////////////////////////////////////////////////////
-// VERSION
+// SETUP
 ///////////////////////////////////////////////////////////////////////////////
 
-var version = Argument("force-nuget-version", ParseAssemblyInfo(AssemblyInfoPath).AssemblyVersion);
-
-if (isRunningOnAppVeyor)
+Setup(context =>
 {
-    if (isTagged)
-    {
-        // Use Tag Name as version
-        version = BuildSystem.AppVeyor.Environment.Repository.Tag.Name;
-    }
-    else
-    {
-        // Use AssemblyVersion with Build as version
-        version += "-build" + EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-alpha";
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DIRECTORIES
-///////////////////////////////////////////////////////////////////////////////
+    Information("Building version {0} of Avalonia ({1}, {2}, {3}) using version {4} of Cake.", 
+        parameters.Version,
+        parameters.Platform,
+        parameters.Configuration,
+        parameters.Target,
+        typeof(ICakeContext).Assembly.GetName().Version.ToString());
 
-var artifactsDir = (DirectoryPath)Directory("./artifacts");
-var nugetRoot = artifactsDir.Combine("nuget");
-var zipRoot = artifactsDir.Combine("zip");
-var binRoot = artifactsDir.Combine("bin");
-var testsRoot = artifactsDir.Combine("tests");
-
-var dirSuffix = configuration;
-var dirSuffixSkia = (isPlatformAnyCPU ? "x86" : platform) + "/" + configuration;
-var dirSuffixIOS = "iPhone" + "/" + configuration;
-
-var buildDirs = 
-    GetDirectories("./src/**/bin/" + dirSuffix) + 
-    GetDirectories("./src/**/obj/" + dirSuffix) + 
-    GetDirectories("./src/Markup/**/bin/" + dirSuffix) + 
-    GetDirectories("./src/Markup/**/obj/" + dirSuffix) + 
-    GetDirectories("./src/Android/**/bin/" + dirSuffix) + 
-    GetDirectories("./src/Android/**/obj/" + dirSuffix) + 
-    GetDirectories("./src/Gtk/**/bin/" + dirSuffix) + 
-    GetDirectories("./src/Gtk/**/obj/" + dirSuffix) + 
-    GetDirectories("./src/iOS/**/bin/" + dirSuffixIOS) + 
-    GetDirectories("./src/iOS/**/obj/" + dirSuffixIOS) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android/bin/" + dirSuffix) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android/obj/" + dirSuffix) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android.TestApp/bin/" + dirSuffix) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android.TestApp/obj/" + dirSuffix) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + dirSuffixSkia) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop/obj/" + dirSuffixSkia) +
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop.NetStandard/bin/" + dirSuffix) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop.NetStandard/obj/" + dirSuffix) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + dirSuffixIOS) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS/obj/" + dirSuffixIOS) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/bin/" + dirSuffixIOS) + 
-    (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/obj/" + dirSuffixIOS) + 
-    GetDirectories("./src/Windows/**/bin/" + dirSuffix) + 
-    GetDirectories("./src/Windows/**/obj/" + dirSuffix) + 
-    GetDirectories("./tests/**/bin/" + dirSuffix) + 
-    GetDirectories("./tests/**/obj/" + dirSuffix) + 
-    GetDirectories("./Samples/**/bin/" + dirSuffix) + 
-    GetDirectories("./Samples/**/obj/" + dirSuffix);
-
-var fileZipSuffix = version + ".zip";
-var zipCoreArtifacts = zipRoot.CombineWithFilePath("Avalonia-" + fileZipSuffix);
-var zipSourceControlCatalogDesktopDirs = (DirectoryPath)Directory("./samples/ControlCatalog.Desktop/bin/" + dirSuffix);
-var zipTargetControlCatalogDesktopDirs = zipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + fileZipSuffix);
-
-///////////////////////////////////////////////////////////////////////////////
-// NUGET NUSPECS
-///////////////////////////////////////////////////////////////////////////////
-
-Information("Getting git modules:");
-
-var ignoredSubModulesPaths = System.IO.File.ReadAllLines(".git/config").Where(m=>m.StartsWith("[submodule ")).Select(m => 
-{
-    var path = m.Split(' ')[1].Trim("\"[] \t".ToArray());
-    Information(path);
-    return ((DirectoryPath)Directory(path)).FullPath;
-}).ToList();
-
-var normalizePath = new Func<string, string>(
-    path => path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).ToUpperInvariant());
-
-// Key: Package Id
-// Value is Tuple where Item1: Package Version, Item2: The packages.config file path.
-var packageVersions = new Dictionary<string, IList<Tuple<string,string>>>();
-
-System.IO.Directory.EnumerateFiles(((DirectoryPath)Directory("./src")).FullPath, "packages.config", SearchOption.AllDirectories).ToList().ForEach(fileName =>
-{
-    if (!ignoredSubModulesPaths.Any(i => normalizePath(fileName).Contains(normalizePath(i))))
+    if (parameters.IsRunningOnAppVeyor)
     {
-        var file = new PackageReferenceFile(fileName);
-        foreach (PackageReference packageReference in file.GetPackageReferences())
-        {
-            IList<Tuple<string, string>> versions;
-            packageVersions.TryGetValue(packageReference.Id, out versions);
-            if (versions == null)
-            {
-                versions = new List<Tuple<string, string>>();
-                packageVersions[packageReference.Id] = versions;
-            }
-            versions.Add(Tuple.Create(packageReference.Version.ToString(), fileName));
-        }
+        Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name);
+        Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch);
     }
-});
 
-Information("Checking installed NuGet package dependencies versions:");
-
-packageVersions.ToList().ForEach(package =>
-{
-    var packageVersion = package.Value.First().Item1;
-    bool isValidVersion = package.Value.All(x => x.Item1 == packageVersion);
-    if (!isValidVersion)
-    {
-        Information("Error: package {0} has multiple versions installed:", package.Key);
-        foreach (var v in package.Value)
-        {
-            Information("{0}, file: {1}", v.Item1, v.Item2);
-        }
-        throw new Exception("Detected multiple NuGet package version installed for different projects.");
-    }
-});
-
-Information("Setting NuGet package dependencies versions:");
-
-var SerilogVersion = packageVersions["Serilog"].FirstOrDefault().Item1;
-var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1;
-var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1;
-var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1;
-var SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1;
-var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1;
-var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1;
-var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1;
-var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1;
-
-Information("Package: Serilog, version: {0}", SerilogVersion);
-Information("Package: Splat, version: {0}", SplatVersion);
-Information("Package: Sprache, version: {0}", SpracheVersion);
-Information("Package: System.Reactive, version: {0}", SystemReactiveVersion);
-Information("Package: SkiaSharp, version: {0}", SkiaSharpVersion);
-Information("Package: SharpDX, version: {0}", SharpDXVersion);
-Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version);
-Information("Package: SharpDX.Direct3D11, version: {0}", SharpDXDirect3D11Version);
-Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion);
-
-var SetNuGetNuspecCommonProperties = new Action<NuGetPackSettings> ((nuspec) => {
-    nuspec.Version = version;
-    nuspec.Authors = new [] { "Avalonia Team" };
-    nuspec.Owners = new [] { "stevenk" };
-    nuspec.LicenseUrl = new Uri("http://opensource.org/licenses/MIT");
-    nuspec.ProjectUrl = new Uri("https://github.com/AvaloniaUI/Avalonia/");
-    nuspec.RequireLicenseAcceptance = false;
-    nuspec.Symbols = false;
-    nuspec.NoPackageAnalysis = true;
-    nuspec.Description = "The Avalonia UI framework";
-    nuspec.Copyright = "Copyright 2015";
-    nuspec.Tags = new [] { "Avalonia" };
-});
-
-var coreLibraries = new string[][]
-{
-    new [] { "./src/", "Avalonia.Animation", ".dll" },
-    new [] { "./src/", "Avalonia.Animation", ".xml" },
-    new [] { "./src/", "Avalonia.Base", ".dll" },
-    new [] { "./src/", "Avalonia.Base", ".xml" },
-    new [] { "./src/", "Avalonia.Controls", ".dll" },
-    new [] { "./src/", "Avalonia.Controls", ".xml" },
-    new [] { "./src/", "Avalonia.DesignerSupport", ".dll" },
-    new [] { "./src/", "Avalonia.DesignerSupport", ".xml" },
-    new [] { "./src/", "Avalonia.Diagnostics", ".dll" },
-    new [] { "./src/", "Avalonia.Diagnostics", ".xml" },
-    new [] { "./src/", "Avalonia.Input", ".dll" },
-    new [] { "./src/", "Avalonia.Input", ".xml" },
-    new [] { "./src/", "Avalonia.Interactivity", ".dll" },
-    new [] { "./src/", "Avalonia.Interactivity", ".xml" },
-    new [] { "./src/", "Avalonia.Layout", ".dll" },
-    new [] { "./src/", "Avalonia.Layout", ".xml" },
-    new [] { "./src/", "Avalonia.Logging.Serilog", ".dll" },
-    new [] { "./src/", "Avalonia.Logging.Serilog", ".xml" },
-    new [] { "./src/", "Avalonia.Visuals", ".dll" },
-    new [] { "./src/", "Avalonia.Visuals", ".xml" },
-    new [] { "./src/", "Avalonia.Styling", ".dll" },
-    new [] { "./src/", "Avalonia.Styling", ".xml" },
-    new [] { "./src/", "Avalonia.ReactiveUI", ".dll" },
-    new [] { "./src/", "Avalonia.Themes.Default", ".dll" },
-    new [] { "./src/", "Avalonia.Themes.Default", ".xml" },
-    new [] { "./src/Markup/", "Avalonia.Markup", ".dll" },
-    new [] { "./src/Markup/", "Avalonia.Markup", ".xml" },
-    new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".dll" },
-    new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".xml" }
-};
-
-var coreLibrariesFiles = coreLibraries.Select((lib) => {
-    return (FilePath)File(lib[0] + lib[1] + "/bin/" + dirSuffix + "/" + lib[1] + lib[2]);
-}).ToList();
-
-var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
-    return new NuSpecContent { 
-        Source = file.FullPath, Target = "lib/portable-windows8+net45" 
-    };
-});
-
-var win32CoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
-    return new NuSpecContent { 
-        Source = file.FullPath, Target = "lib/net45" 
-    };
+    Information("Target: " + parameters.Target);
+    Information("Platform: " + parameters.Platform);
+    Information("Configuration: " + parameters.Configuration);
+    Information("IsLocalBuild: " + parameters.IsLocalBuild);
+    Information("IsRunningOnUnix: " + parameters.IsRunningOnUnix);
+    Information("IsRunningOnWindows: " + parameters.IsRunningOnWindows);
+    Information("IsRunningOnAppVeyor: " + parameters.IsRunningOnAppVeyor);
+    Information("IsPullRequest: " + parameters.IsPullRequest);
+    Information("IsMainRepo: " + parameters.IsMainRepo);
+    Information("IsMasterBranch: " + parameters.IsMasterBranch);
+    Information("IsTagged: " + parameters.IsTagged);
+    Information("IsReleasable: " + parameters.IsReleasable);
+    Information("IsMyGetRelease: " + parameters.IsMyGetRelease);
+    Information("IsNuGetRelease: " + parameters.IsNuGetRelease);
 });
 
-var netcoreappCoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
-    return new NuSpecContent { 
-        Source = file.FullPath, Target = "lib/netcoreapp1.0" 
-    };
-});
-
-var net45RuntimePlatformExtensions = new [] {".xml", ".dll"};
-var net45RuntimePlatform = net45RuntimePlatformExtensions.Select(libSuffix => {
-    return new NuSpecContent {
-        Source = ((FilePath)File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + dirSuffix + "/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, 
-        Target = "lib/net45" 
-    };
-});
-
-var netCoreRuntimePlatformExtensions = new [] {".xml", ".dll"};
-var netCoreRuntimePlatform = netCoreRuntimePlatformExtensions.Select(libSuffix => {
-    return new NuSpecContent {
-        Source = ((FilePath)File("./src/Avalonia.DotNetCoreRuntime/bin/" + dirSuffix + "/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, 
-        Target = "lib/netcoreapp1.0" 
-    };
-});
-
-
-var nuspecNuGetSettingsCore = new []
-{
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion },
-            new NuSpecDependency() { Id = "Splat", Version = SplatVersion },
-            new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
-            new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
-            new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" },
-            //.NET Core
-            new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp1.0", Version = "1.6.0" },
-            new NuSpecDependency() { Id = "Microsoft.NETCore.Portable.Compatibility", TargetFramework = "netcoreapp1.0", Version = "1.0.1" },
-            new NuSpecDependency() { Id = "Splat", TargetFramework = "netcoreapp1.0", Version = "2.0.0" },
-            new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp1.0", Version = "2.3.0" },
-            new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp1.0", Version = SpracheVersion },
-            new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp1.0", Version = SystemReactiveVersion }
-        },
-        Files = coreLibrariesNuSpecContent
-            .Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform)
-            .Concat(netcoreappCoreLibrariesNuSpecContent).Concat(netCoreRuntimePlatform)
-            .ToList(),
-        BasePath = Directory("./"),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.HtmlRenderer
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.HtmlRenderer",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/portable-windows8+net45" }
-        },
-        BasePath = Directory("./src/Avalonia.HtmlRenderer/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    }
-};
-
-var nuspecNuGetSettingsMobile = new []
-{
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Android
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Android",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.Skia.Android", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" }
-        },
-        BasePath = Directory("./src/Android/Avalonia.Android/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Skia.Android
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Skia.Android",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version },
-            new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Skia.Android.dll", Target = "lib/MonoAndroid10" }
-        },
-        BasePath = Directory("./src/Skia/Avalonia.Skia.Android/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.iOS
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.iOS",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.Skia.iOS", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.iOS.dll", Target = "lib/Xamarin.iOS10" }
-        },
-        BasePath = Directory("./src/iOS/Avalonia.iOS/bin/" + dirSuffixIOS),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Skia.iOS
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Skia.iOS",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version },
-            new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Skia.iOS.dll", Target = "lib/Xamarin.iOS10" }
-        },
-        BasePath = Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + dirSuffixIOS),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Mobile
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Mobile",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia.Android", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.iOS", Version = version }
-        },
-        Files = new NuSpecContent[]
-        {
-            new NuSpecContent { Source = "licence.md", Target = "" }
-        },
-        BasePath = Directory("./"),
-        OutputDirectory = nugetRoot
-    }
-};
-
-var nuspecNuGetSettingsDesktop = new []
-{
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Win32
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Win32",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Win32/bin/" + dirSuffix + "/Avalonia.Win32.dll", Target = "lib/net45" },
-            new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + dirSuffix + "/Avalonia.Win32.dll", Target = "lib/netstandard1.1" }
-        },
-        BasePath = Directory("./src/Windows"),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Direct2D1
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Direct2D1",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version },
-            new NuSpecDependency() { Id = "SharpDX", Version = SharpDXVersion },
-            new NuSpecDependency() { Id = "SharpDX.Direct2D1", Version = SharpDXDirect2D1Version },
-            new NuSpecDependency() { Id = "SharpDX.Direct3D11", Version = SharpDXDirect3D11Version },
-            new NuSpecDependency() { Id = "SharpDX.DXGI", Version = SharpDXDXGIVersion }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/net45" }
-        },
-        BasePath = Directory("./src/Windows/Avalonia.Direct2D1/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Gtk
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Gtk",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Gtk.dll", Target = "lib/net45" }
-        },
-        BasePath = Directory("./src/Gtk/Avalonia.Gtk/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Gtk3
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Gtk3",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.1" }
-        },
-        BasePath = Directory("./src/Gtk/Avalonia.Gtk3/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Cairo
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Cairo",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Cairo.dll", Target = "lib/net45" }
-        },
-        BasePath = Directory("./src/Gtk/Avalonia.Cairo/bin/" + dirSuffix),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Skia.Desktop
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Skia.Desktop",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia", Version = version },
-            new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion },
-            //.NET Core
-            new NuSpecDependency() { Id = "Avalonia", TargetFramework = "netcoreapp1.0", Version = version },
-            new NuSpecDependency() { Id = "SkiaSharp", TargetFramework = "netcoreapp1.0", Version = SkiaSharpVersion },
-            new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp1.0", Version = "1.6.0" },
-            new NuSpecDependency() { Id = "Microsoft.NETCore.Portable.Compatibility", TargetFramework = "netcoreapp1.0", Version = "1.0.1" }
-        },
-        Files = new []
-        {
-            new NuSpecContent { Source = "Avalonia.Skia.Desktop/bin/" + dirSuffixSkia + "/Avalonia.Skia.Desktop.dll", Target = "lib/net45" },
-            new NuSpecContent { Source = "Avalonia.Skia.Desktop.NetStandard/bin/" + dirSuffix + "/Avalonia.Skia.Desktop.dll", Target = "lib/netcoreapp1.0" }
-        },
-        BasePath = Directory("./src/Skia/"),
-        OutputDirectory = nugetRoot
-    },
-    ///////////////////////////////////////////////////////////////////////////////
-    // Avalonia.Desktop
-    ///////////////////////////////////////////////////////////////////////////////
-    new NuGetPackSettings()
-    {
-        Id = "Avalonia.Desktop",
-        Dependencies = new []
-        {
-            new NuSpecDependency() { Id = "Avalonia.Win32", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.Gtk", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.Cairo", Version = version },
-            new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", Version = version }
-        },
-        Files = new NuSpecContent[]
-        {
-            new NuSpecContent { Source = "licence.md", Target = "" }
-        },
-        BasePath = Directory("./"),
-        OutputDirectory = nugetRoot
-    }
-};
-
-var nuspecNuGetSettings = new List<NuGetPackSettings>();
-
-nuspecNuGetSettings.AddRange(nuspecNuGetSettingsCore);
-nuspecNuGetSettings.AddRange(nuspecNuGetSettingsDesktop);
-nuspecNuGetSettings.AddRange(nuspecNuGetSettingsMobile);
-
-nuspecNuGetSettings.ForEach((nuspec) => SetNuGetNuspecCommonProperties(nuspec));
-
-var nugetPackages = nuspecNuGetSettings.Select(nuspec => {
-    return nuspec.OutputDirectory.CombineWithFilePath(string.Concat(nuspec.Id, ".", nuspec.Version, ".nupkg"));
-}).ToArray();
-
-var binFiles = nuspecNuGetSettings.SelectMany(nuspec => {
-    return nuspec.Files.Select(file => {
-        return ((DirectoryPath)nuspec.BasePath).CombineWithFilePath(file.Source);
-    });
-}).GroupBy(f => f.FullPath).Select(g => g.First());
-
 ///////////////////////////////////////////////////////////////////////////////
-// INFORMATION
+// TEARDOWN
 ///////////////////////////////////////////////////////////////////////////////
 
-Information("Building version {0} of Avalonia ({1}, {2}, {3}) using version {4} of Cake.", 
-    version,
-    platform,
-    configuration,
-    target,
-    typeof(ICakeContext).Assembly.GetName().Version.ToString());
-
-if (isRunningOnAppVeyor)
+Teardown(context =>
 {
-    Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name);
-    Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch);
-}
-
-Information("Target: " + target);
-Information("Platform: " + platform);
-Information("Configuration: " + configuration);
-Information("IsLocalBuild: " + isLocalBuild);
-Information("IsRunningOnUnix: " + isRunningOnUnix);
-Information("IsRunningOnWindows: " + isRunningOnWindows);
-Information("IsRunningOnAppVeyor: " + isRunningOnAppVeyor);
-Information("IsPullRequest: " + isPullRequest);
-Information("IsMainRepo: " + isMainRepo);
-Information("IsMasterBranch: " + isMasterBranch);
-Information("IsTagged: " + isTagged);
-Information("IsReleasable: " + isReleasable);
-Information("IsMyGetRelease: " + isMyGetRelease);
-Information("IsNuGetRelease: " + isNuGetRelease);
+    Information("Finished running tasks.");
+});
 
 ///////////////////////////////////////////////////////////////////////////////
 // TASKS
@@ -637,13 +88,14 @@ Information("IsNuGetRelease: " + isNuGetRelease);
 Task("Clean")
     .Does(() =>
 {
-    CleanDirectories(buildDirs);
-    CleanDirectory(artifactsDir);
-    CleanDirectory(nugetRoot);
-    CleanDirectory(zipRoot);
-    CleanDirectory(binRoot);
-    CleanDirectory(testsRoot);
+    CleanDirectories(parameters.BuildDirs);
+    CleanDirectory(parameters.ArtifactsDir);
+    CleanDirectory(parameters.NugetRoot);
+    CleanDirectory(parameters.ZipRoot);
+    CleanDirectory(parameters.BinRoot);
+    CleanDirectory(parameters.TestsRoot);
 });
+
 Task("Prepare-XBuild-Solution")
     .Does(() =>
 {
@@ -654,7 +106,7 @@ Task("Prepare-XBuild-Solution")
         "Avalonia.Skia.Desktop.NetStandard",
         "Avalonia.Gtk3"
     };
-    var blacklistedGuids = System.IO.File.ReadAllLines(MSBuildSolution)
+    var blacklistedGuids = System.IO.File.ReadAllLines(parameters.MSBuildSolution)
         .Where(l=>l.StartsWith("Project") && blacklistedProjects.Any(p=>l.Contains(p)))
         .Select(l => l.Split(',').Select(part => part.Trim()).FirstOrDefault(part => part.StartsWith("\"{")))
         .Where(g=>g!=null)
@@ -663,7 +115,7 @@ Task("Prepare-XBuild-Solution")
     Console.WriteLine("Blacklisted guids are: " + string.Join(",", blacklistedGuids));
     var removeUntilEndProject = false;
 
-    System.IO.File.WriteAllLines(XBuildSolution, System.IO.File.ReadAllLines(MSBuildSolution)
+    System.IO.File.WriteAllLines(parameters.XBuildSolution, System.IO.File.ReadAllLines(parameters.MSBuildSolution)
         .Where(l => 
         {
             if(removeUntilEndProject)
@@ -701,15 +153,15 @@ Task("Restore-NuGet-Packages")
                 toolTimeout+=0.5;
             }})
         .Execute(()=> {
-            if(isRunningOnWindows)
+            if(parameters.IsRunningOnWindows)
             {
-                NuGetRestore(MSBuildSolution, new NuGetRestoreSettings {
+                NuGetRestore(parameters.MSBuildSolution, new NuGetRestoreSettings {
                     ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
                 });
             }
             else
             {
-                NuGetRestore(XBuildSolution, new NuGetRestoreSettings {
+                NuGetRestore(parameters.XBuildSolution, new NuGetRestoreSettings {
                     ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
                 });
             }
@@ -720,11 +172,11 @@ Task("Build")
     .IsDependentOn("Restore-NuGet-Packages")
     .Does(() =>
 {
-    if(isRunningOnWindows)
+    if(parameters.IsRunningOnWindows)
     {
-        MSBuild(MSBuildSolution, settings => {
-            settings.SetConfiguration(configuration);
-            settings.WithProperty("Platform", "\"" + platform + "\"");
+        MSBuild(parameters.MSBuildSolution, settings => {
+            settings.SetConfiguration(parameters.Configuration);
+            settings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
             settings.SetVerbosity(Verbosity.Minimal);
             settings.WithProperty("Windows", "True");
             settings.UseToolVersion(MSBuildToolVersion.VS2015);
@@ -733,9 +185,9 @@ Task("Build")
     }
     else
     {
-        XBuild(XBuildSolution, settings => {
-            settings.SetConfiguration(configuration);
-            settings.WithProperty("Platform", "\"" + platform + "\"");
+        XBuild(parameters.XBuildSolution, settings => {
+            settings.SetConfiguration(parameters.Configuration);
+            settings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
             settings.SetVerbosity(Verbosity.Minimal);
         });
     }
@@ -743,23 +195,23 @@ Task("Build")
 
 Task("Run-Unit-Tests")
     .IsDependentOn("Build")
-    .WithCriteria(() => !skipTests)
+    .WithCriteria(() => !parameters.SkipTests)
     .Does(() =>
 {
     var unitTests = GetDirectories("./tests/Avalonia.*.UnitTests")
         .Select(dir => System.IO.Path.GetFileName(dir.FullPath))
-        .Where(name => isRunningOnWindows ? true : !(name.IndexOf("Direct2D", StringComparison.OrdinalIgnoreCase) >= 0))
-        .Select(name => MakeAbsolute(File("./tests/" + name + "/bin/" + dirSuffix + "/" + name + ".dll")))
+        .Where(name => parameters.IsRunningOnWindows ? true : !(name.IndexOf("Direct2D", StringComparison.OrdinalIgnoreCase) >= 0))
+        .Select(name => MakeAbsolute(File("./tests/" + name + "/bin/" + parameters.DirSuffix + "/" + name + ".dll")))
         .ToList();
 
-    if (isRunningOnWindows)
+    if (parameters.IsRunningOnWindows)
     {
-        var leakTests = GetFiles("./tests/Avalonia.LeakTests/bin/" + dirSuffix + "/*.LeakTests.dll");
+        var leakTests = GetFiles("./tests/Avalonia.LeakTests/bin/" + parameters.DirSuffix + "/*.LeakTests.dll");
 
         unitTests.AddRange(leakTests);
     }
 
-    var toolPath = (isPlatformAnyCPU || isPlatformX86) ? 
+    var toolPath = (parameters.IsPlatformAnyCPU || parameters.IsPlatformX86) ? 
         "./tools/xunit.runner.console/tools/xunit.console.x86.exe" :
         "./tools/xunit.runner.console/tools/xunit.console.exe";
 
@@ -770,9 +222,9 @@ Task("Run-Unit-Tests")
         ShadowCopy = false
     };
 
-    xUnitSettings.NoAppDomain = !isRunningOnWindows;
+    xUnitSettings.NoAppDomain = !parameters.IsRunningOnWindows;
 
-    var openCoverOutput = artifactsDir.GetFilePath(new FilePath("./coverage.xml"));
+    var openCoverOutput = parameters.ArtifactsDir.GetFilePath(new FilePath("./coverage.xml"));
     var openCoverSettings = new OpenCoverSettings()
         .WithFilter("+[Avalonia.*]* -[*Test*]* -[ControlCatalog*]*")
         .WithFilter("-[Avalonia.*]OmniXaml.* -[Avalonia.*]Glass.*")
@@ -782,11 +234,11 @@ Task("Run-Unit-Tests")
 
     foreach(var test in unitTests.Where(testFile => FileExists(testFile)))
     {
-        CopyDirectory(test.GetDirectory(), testsRoot);
+        CopyDirectory(test.GetDirectory(), parameters.TestsRoot);
     }
 
     var testsInDirectoryToRun = new List<FilePath>();
-    if(isRunningOnWindows)
+    if(parameters.IsRunningOnWindows)
     {
         testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*Tests.dll"));
     }
@@ -795,7 +247,7 @@ Task("Run-Unit-Tests")
         testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*.UnitTests.dll"));
     }
 
-    if(isRunningOnWindows)
+    if(parameters.IsRunningOnWindows)
     {
         OpenCover(context => {
             context.XUnit2(testsInDirectoryToRun, xUnitSettings);
@@ -811,26 +263,26 @@ Task("Copy-Files")
     .IsDependentOn("Run-Unit-Tests")
     .Does(() =>
 {
-    CopyFiles(binFiles, binRoot);
+    CopyFiles(packages.BinFiles, parameters.BinRoot);
 });
 
 Task("Zip-Files")
     .IsDependentOn("Copy-Files")
     .Does(() =>
 {
-    Zip(binRoot, zipCoreArtifacts);
+    Zip(parameters.BinRoot, parameters.ZipCoreArtifacts);
 
-    Zip(zipSourceControlCatalogDesktopDirs, 
-        zipTargetControlCatalogDesktopDirs, 
-        GetFiles(zipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") + 
-        GetFiles(zipSourceControlCatalogDesktopDirs.FullPath + "/*.exe"));
+    Zip(parameters.ZipSourceControlCatalogDesktopDirs, 
+        parameters.ZipTargetControlCatalogDesktopDirs, 
+        GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") + 
+        GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe"));
 });
 
 Task("Create-NuGet-Packages")
     .IsDependentOn("Run-Unit-Tests")
     .Does(() =>
 {
-    foreach(var nuspec in nuspecNuGetSettings)
+    foreach(var nuspec in packages.NuspecNuGetSettings)
     {
         NuGetPack(nuspec);
     }
@@ -838,11 +290,11 @@ Task("Create-NuGet-Packages")
 
 Task("Publish-MyGet")
     .IsDependentOn("Create-NuGet-Packages")
-    .WithCriteria(() => !isLocalBuild)
-    .WithCriteria(() => !isPullRequest)
-    .WithCriteria(() => isMainRepo)
-    .WithCriteria(() => isMasterBranch)
-    .WithCriteria(() => isMyGetRelease)
+    .WithCriteria(() => !parameters.IsLocalBuild)
+    .WithCriteria(() => !parameters.IsPullRequest)
+    .WithCriteria(() => parameters.IsMainRepo)
+    .WithCriteria(() => parameters.IsMasterBranch)
+    .WithCriteria(() => parameters.IsMyGetRelease)
     .Does(() =>
 {
     var apiKey = EnvironmentVariable("MYGET_API_KEY");
@@ -857,7 +309,7 @@ Task("Publish-MyGet")
         throw new InvalidOperationException("Could not resolve MyGet API url.");
     }
 
-    foreach(var nupkg in nugetPackages)
+    foreach(var nupkg in packages.NugetPackages)
     {
         NuGetPush(nupkg, new NuGetPushSettings {
             Source = apiUrl,
@@ -872,11 +324,11 @@ Task("Publish-MyGet")
 
 Task("Publish-NuGet")
     .IsDependentOn("Create-NuGet-Packages")
-    .WithCriteria(() => !isLocalBuild)
-    .WithCriteria(() => !isPullRequest)
-    .WithCriteria(() => isMainRepo)
-    .WithCriteria(() => isMasterBranch)
-    .WithCriteria(() => isNuGetRelease)
+    .WithCriteria(() => !parameters.IsLocalBuild)
+    .WithCriteria(() => !parameters.IsPullRequest)
+    .WithCriteria(() => parameters.IsMainRepo)
+    .WithCriteria(() => parameters.IsMasterBranch)
+    .WithCriteria(() => parameters.IsNuGetRelease)
     .Does(() =>
 {
     var apiKey = EnvironmentVariable("NUGET_API_KEY");
@@ -891,7 +343,7 @@ Task("Publish-NuGet")
         throw new InvalidOperationException("Could not resolve NuGet API url.");
     }
 
-    foreach(var nupkg in nugetPackages)
+    foreach(var nupkg in packages.NugetPackages)
     {
         NuGetPush(nupkg, new NuGetPushSettings {
             ApiKey = apiKey,
@@ -926,4 +378,7 @@ Task("Travis")
 // EXECUTE
 ///////////////////////////////////////////////////////////////////////////////
 
-RunTarget(target);
+Information("[Setup]");
+
+
+RunTarget(parameters.Target);

+ 469 - 0
packages.cake

@@ -0,0 +1,469 @@
+public class Packages
+{
+    public List<NuGetPackSettings> NuspecNuGetSettings { get; private set; }
+    public FilePath[] NugetPackages { get; private set; }
+    public FilePath[] BinFiles { get; private set; }
+
+    public Packages(ICakeContext context, Parameters parameters)
+    {
+        // NUGET NUSPECS
+        context.Information("Getting git modules:");
+
+        var ignoredSubModulesPaths = System.IO.File.ReadAllLines(".git/config").Where(m=>m.StartsWith("[submodule ")).Select(m => 
+        {
+            var path = m.Split(' ')[1].Trim("\"[] \t".ToArray());
+            context.Information(path);
+            return ((DirectoryPath)context.Directory(path)).FullPath;
+        }).ToList();
+
+        var normalizePath = new Func<string, string>(
+            path => path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).ToUpperInvariant());
+
+        // Key: Package Id
+        // Value is Tuple where Item1: Package Version, Item2: The packages.config file path.
+        var packageVersions = new Dictionary<string, IList<Tuple<string,string>>>();
+
+        System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./src")).FullPath, "packages.config", SearchOption.AllDirectories).ToList().ForEach(fileName =>
+        {
+            if (!ignoredSubModulesPaths.Any(i => normalizePath(fileName).Contains(normalizePath(i))))
+            {
+                var file = new PackageReferenceFile(fileName);
+                foreach (PackageReference packageReference in file.GetPackageReferences())
+                {
+                    IList<Tuple<string, string>> versions;
+                    packageVersions.TryGetValue(packageReference.Id, out versions);
+                    if (versions == null)
+                    {
+                        versions = new List<Tuple<string, string>>();
+                        packageVersions[packageReference.Id] = versions;
+                    }
+                    versions.Add(Tuple.Create(packageReference.Version.ToString(), fileName));
+                }
+            }
+        });
+
+        context.Information("Checking installed NuGet package dependencies versions:");
+
+        packageVersions.ToList().ForEach(package =>
+        {
+            var packageVersion = package.Value.First().Item1;
+            bool isValidVersion = package.Value.All(x => x.Item1 == packageVersion);
+            if (!isValidVersion)
+            {
+                context.Information("Error: package {0} has multiple versions installed:", package.Key);
+                foreach (var v in package.Value)
+                {
+                    context.Information("{0}, file: {1}", v.Item1, v.Item2);
+                }
+                throw new Exception("Detected multiple NuGet package version installed for different projects.");
+            }
+        });
+
+        context.Information("Setting NuGet package dependencies versions:");
+
+        var SerilogVersion = packageVersions["Serilog"].FirstOrDefault().Item1;
+        var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1;
+        var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1;
+        var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1;
+        var SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1;
+        var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1;
+        var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1;
+        var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1;
+        var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1;
+
+        context.Information("Package: Serilog, version: {0}", SerilogVersion);
+        context.Information("Package: Splat, version: {0}", SplatVersion);
+        context.Information("Package: Sprache, version: {0}", SpracheVersion);
+        context.Information("Package: System.Reactive, version: {0}", SystemReactiveVersion);
+        context.Information("Package: SkiaSharp, version: {0}", SkiaSharpVersion);
+        context.Information("Package: SharpDX, version: {0}", SharpDXVersion);
+        context.Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version);
+        context.Information("Package: SharpDX.Direct3D11, version: {0}", SharpDXDirect3D11Version);
+        context.Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion);
+
+        var SetNuGetNuspecCommonProperties = new Action<NuGetPackSettings> ((nuspec) => {
+            nuspec.Version = parameters.Version;
+            nuspec.Authors = new [] { "Avalonia Team" };
+            nuspec.Owners = new [] { "stevenk" };
+            nuspec.LicenseUrl = new Uri("http://opensource.org/licenses/MIT");
+            nuspec.ProjectUrl = new Uri("https://github.com/AvaloniaUI/Avalonia/");
+            nuspec.RequireLicenseAcceptance = false;
+            nuspec.Symbols = false;
+            nuspec.NoPackageAnalysis = true;
+            nuspec.Description = "The Avalonia UI framework";
+            nuspec.Copyright = "Copyright 2015";
+            nuspec.Tags = new [] { "Avalonia" };
+        });
+
+        var coreLibraries = new string[][]
+        {
+            new [] { "./src/", "Avalonia.Animation", ".dll" },
+            new [] { "./src/", "Avalonia.Animation", ".xml" },
+            new [] { "./src/", "Avalonia.Base", ".dll" },
+            new [] { "./src/", "Avalonia.Base", ".xml" },
+            new [] { "./src/", "Avalonia.Controls", ".dll" },
+            new [] { "./src/", "Avalonia.Controls", ".xml" },
+            new [] { "./src/", "Avalonia.DesignerSupport", ".dll" },
+            new [] { "./src/", "Avalonia.DesignerSupport", ".xml" },
+            new [] { "./src/", "Avalonia.Diagnostics", ".dll" },
+            new [] { "./src/", "Avalonia.Diagnostics", ".xml" },
+            new [] { "./src/", "Avalonia.Input", ".dll" },
+            new [] { "./src/", "Avalonia.Input", ".xml" },
+            new [] { "./src/", "Avalonia.Interactivity", ".dll" },
+            new [] { "./src/", "Avalonia.Interactivity", ".xml" },
+            new [] { "./src/", "Avalonia.Layout", ".dll" },
+            new [] { "./src/", "Avalonia.Layout", ".xml" },
+            new [] { "./src/", "Avalonia.Logging.Serilog", ".dll" },
+            new [] { "./src/", "Avalonia.Logging.Serilog", ".xml" },
+            new [] { "./src/", "Avalonia.Visuals", ".dll" },
+            new [] { "./src/", "Avalonia.Visuals", ".xml" },
+            new [] { "./src/", "Avalonia.Styling", ".dll" },
+            new [] { "./src/", "Avalonia.Styling", ".xml" },
+            new [] { "./src/", "Avalonia.ReactiveUI", ".dll" },
+            new [] { "./src/", "Avalonia.Themes.Default", ".dll" },
+            new [] { "./src/", "Avalonia.Themes.Default", ".xml" },
+            new [] { "./src/Markup/", "Avalonia.Markup", ".dll" },
+            new [] { "./src/Markup/", "Avalonia.Markup", ".xml" },
+            new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".dll" },
+            new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".xml" }
+        };
+
+        var coreLibrariesFiles = coreLibraries.Select((lib) => {
+            return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/" + lib[1] + lib[2]);
+        }).ToList();
+
+        var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
+            return new NuSpecContent { 
+                Source = file.FullPath, Target = "lib/portable-windows8+net45" 
+            };
+        });
+
+        var win32CoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
+            return new NuSpecContent { 
+                Source = file.FullPath, Target = "lib/net45" 
+            };
+        });
+
+        var netcoreappCoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
+            return new NuSpecContent { 
+                Source = file.FullPath, Target = "lib/netcoreapp1.0" 
+            };
+        });
+
+        var net45RuntimePlatformExtensions = new [] {".xml", ".dll"};
+        var net45RuntimePlatform = net45RuntimePlatformExtensions.Select(libSuffix => {
+            return new NuSpecContent {
+                Source = ((FilePath)context.File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + parameters.DirSuffix + "/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, 
+                Target = "lib/net45" 
+            };
+        });
+
+        var netCoreRuntimePlatformExtensions = new [] {".xml", ".dll"};
+        var netCoreRuntimePlatform = netCoreRuntimePlatformExtensions.Select(libSuffix => {
+            return new NuSpecContent {
+                Source = ((FilePath)context.File("./src/Avalonia.DotNetCoreRuntime/bin/" + parameters.DirSuffix + "/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, 
+                Target = "lib/netcoreapp1.0" 
+            };
+        });
+
+        var nuspecNuGetSettingsCore = new []
+        {
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion },
+                    new NuSpecDependency() { Id = "Splat", Version = SplatVersion },
+                    new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
+                    new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
+                    new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" },
+                    //.NET Core
+                    new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp1.0", Version = "1.6.0" },
+                    new NuSpecDependency() { Id = "Microsoft.NETCore.Portable.Compatibility", TargetFramework = "netcoreapp1.0", Version = "1.0.1" },
+                    new NuSpecDependency() { Id = "Splat", TargetFramework = "netcoreapp1.0", Version = "2.0.0" },
+                    new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp1.0", Version = "2.3.0" },
+                    new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp1.0", Version = SpracheVersion },
+                    new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp1.0", Version = SystemReactiveVersion }
+                },
+                Files = coreLibrariesNuSpecContent
+                    .Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform)
+                    .Concat(netcoreappCoreLibrariesNuSpecContent).Concat(netCoreRuntimePlatform)
+                    .ToList(),
+                BasePath = context.Directory("./"),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.HtmlRenderer
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.HtmlRenderer",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/portable-windows8+net45" }
+                },
+                BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            }
+        };
+
+        var nuspecNuGetSettingsMobile = new []
+        {
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Android
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Android",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Skia.Android", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" }
+                },
+                BasePath = context.Directory("./src/Android/Avalonia.Android/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Skia.Android
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Skia.Android",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Skia.Android.dll", Target = "lib/MonoAndroid10" }
+                },
+                BasePath = context.Directory("./src/Skia/Avalonia.Skia.Android/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.iOS
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.iOS",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Skia.iOS", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.iOS.dll", Target = "lib/Xamarin.iOS10" }
+                },
+                BasePath = context.Directory("./src/iOS/Avalonia.iOS/bin/" + parameters.DirSuffixIOS),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Skia.iOS
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Skia.iOS",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Skia.iOS.dll", Target = "lib/Xamarin.iOS10" }
+                },
+                BasePath = context.Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + parameters.DirSuffixIOS),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Mobile
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Mobile",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia.Android", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.iOS", Version = parameters.Version }
+                },
+                Files = new NuSpecContent[]
+                {
+                    new NuSpecContent { Source = "licence.md", Target = "" }
+                },
+                BasePath = context.Directory("./"),
+                OutputDirectory = parameters.NugetRoot
+            }
+        };
+
+        var nuspecNuGetSettingsDesktop = new []
+        {
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Win32
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Win32",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Win32/bin/" + parameters.DirSuffix + "/Avalonia.Win32.dll", Target = "lib/net45" },
+                    new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/Avalonia.Win32.dll", Target = "lib/netstandard1.1" }
+                },
+                BasePath = context.Directory("./src/Windows"),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Direct2D1
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Direct2D1",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SharpDX", Version = SharpDXVersion },
+                    new NuSpecDependency() { Id = "SharpDX.Direct2D1", Version = SharpDXDirect2D1Version },
+                    new NuSpecDependency() { Id = "SharpDX.Direct3D11", Version = SharpDXDirect3D11Version },
+                    new NuSpecDependency() { Id = "SharpDX.DXGI", Version = SharpDXDXGIVersion }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/net45" }
+                },
+                BasePath = context.Directory("./src/Windows/Avalonia.Direct2D1/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Gtk
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Gtk",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Gtk.dll", Target = "lib/net45" }
+                },
+                BasePath = context.Directory("./src/Gtk/Avalonia.Gtk/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Gtk3
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Gtk3",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.1" }
+                },
+                BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Cairo
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Cairo",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Cairo.dll", Target = "lib/net45" }
+                },
+                BasePath = context.Directory("./src/Gtk/Avalonia.Cairo/bin/" + parameters.DirSuffix),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Skia.Desktop
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Skia.Desktop",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion },
+                    //.NET Core
+                    new NuSpecDependency() { Id = "Avalonia", TargetFramework = "netcoreapp1.0", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SkiaSharp", TargetFramework = "netcoreapp1.0", Version = SkiaSharpVersion },
+                    new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp1.0", Version = "1.6.0" },
+                    new NuSpecDependency() { Id = "Microsoft.NETCore.Portable.Compatibility", TargetFramework = "netcoreapp1.0", Version = "1.0.1" }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Skia.Desktop/bin/" + parameters.DirSuffixSkia + "/Avalonia.Skia.Desktop.dll", Target = "lib/net45" },
+                    new NuSpecContent { Source = "Avalonia.Skia.Desktop.NetStandard/bin/" + parameters.DirSuffix + "/Avalonia.Skia.Desktop.dll", Target = "lib/netcoreapp1.0" }
+                },
+                BasePath = context.Directory("./src/Skia/"),
+                OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.Desktop
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Desktop",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia.Win32", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Gtk", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Cairo", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", Version = parameters.Version }
+                },
+                Files = new NuSpecContent[]
+                {
+                    new NuSpecContent { Source = "licence.md", Target = "" }
+                },
+                BasePath = context.Directory("./"),
+                OutputDirectory = parameters.NugetRoot
+            }
+        };
+
+        NuspecNuGetSettings = new List<NuGetPackSettings>();
+
+        NuspecNuGetSettings.AddRange(nuspecNuGetSettingsCore);
+        NuspecNuGetSettings.AddRange(nuspecNuGetSettingsDesktop);
+        NuspecNuGetSettings.AddRange(nuspecNuGetSettingsMobile);
+
+        NuspecNuGetSettings.ForEach((nuspec) => SetNuGetNuspecCommonProperties(nuspec));
+
+        NugetPackages = NuspecNuGetSettings.Select(nuspec => {
+            return nuspec.OutputDirectory.CombineWithFilePath(string.Concat(nuspec.Id, ".", nuspec.Version, ".nupkg"));
+        }).ToArray();
+
+        BinFiles = NuspecNuGetSettings.SelectMany(nuspec => {
+            return nuspec.Files.Select(file => {
+                return ((DirectoryPath)nuspec.BasePath).CombineWithFilePath(file.Source);
+            });
+        }).GroupBy(f => f.FullPath).Select(g => g.First()).ToArray();
+    }
+}

+ 143 - 0
parameters.cake

@@ -0,0 +1,143 @@
+public class Parameters
+{
+    public string Target { get; private set; }
+    public string Platform { get; private set; }
+    public string Configuration { get; private set; }
+    public bool SkipTests { get; private set; }
+    public string MainRepo { get; private set; }
+    public string MasterBranch { get; private set; }
+    public string AssemblyInfoPath { get; private set; }
+    public string ReleasePlatform { get; private set; }
+    public string ReleaseConfiguration { get; private set; }
+    public string MSBuildSolution { get; private set; } 
+    public string XBuildSolution { get; private set; } 
+    public bool IsPlatformAnyCPU { get; private set; }
+    public bool IsPlatformX86 { get; private set; }
+    public bool IsPlatformX64 { get; private set; }
+    public bool IsLocalBuild { get; private set; }
+    public bool IsRunningOnUnix { get; private set; }
+    public bool IsRunningOnWindows { get; private set; }
+    public bool IsRunningOnAppVeyor { get; private set; }
+    public bool IsPullRequest { get; private set; }
+    public bool IsMainRepo { get; private set; }
+    public bool IsMasterBranch { get; private set; }
+    public bool IsTagged { get; private set; }
+    public bool IsReleasable { get; private set; }
+    public bool IsMyGetRelease { get; private set; }
+    public bool IsNuGetRelease { get; private set; }
+    public string Version { get; private set; } 
+    public DirectoryPath ArtifactsDir { get; private set; }
+    public DirectoryPath NugetRoot { get; private set; }
+    public DirectoryPath ZipRoot { get; private set; }
+    public DirectoryPath BinRoot { get; private set; }
+    public DirectoryPath TestsRoot { get; private set; }
+    public string DirSuffix { get; private set; }
+    public string DirSuffixSkia { get; private set; }
+    public string DirSuffixIOS { get; private set; }
+    public DirectoryPathCollection BuildDirs { get; private set; }
+    public string FileZipSuffix { get; private set; }
+    public FilePath ZipCoreArtifacts { get; private set; }
+    public DirectoryPath ZipSourceControlCatalogDesktopDirs { get; private set; }
+    public FilePath ZipTargetControlCatalogDesktopDirs { get; private set; }
+
+    public Parameters(ICakeContext context)
+    {
+        var buildSystem = context.BuildSystem();
+
+        // ARGUMENTS
+        Target = context.Argument("target", "Default");
+        Platform = context.Argument("platform", "Any CPU");
+        Configuration = context.Argument("configuration", "Release");
+        SkipTests = context.HasArgument("skip-tests");
+
+        // CONFIGURATION
+        MainRepo = "AvaloniaUI/Avalonia";
+        MasterBranch = "master";
+        AssemblyInfoPath = context.File("./src/Shared/SharedAssemblyInfo.cs");
+        ReleasePlatform = "Any CPU";
+        ReleaseConfiguration = "Release";
+        MSBuildSolution = "./Avalonia.sln";
+        XBuildSolution = "./Avalonia.XBuild.sln";
+
+        // PARAMETERS
+        IsPlatformAnyCPU = StringComparer.OrdinalIgnoreCase.Equals(Platform, "Any CPU");
+        IsPlatformX86 = StringComparer.OrdinalIgnoreCase.Equals(Platform, "x86");
+        IsPlatformX64 = StringComparer.OrdinalIgnoreCase.Equals(Platform, "x64");
+        IsLocalBuild = buildSystem.IsLocalBuild;
+        IsRunningOnUnix = context.IsRunningOnUnix();
+        IsRunningOnWindows = context.IsRunningOnWindows();
+        IsRunningOnAppVeyor = buildSystem.AppVeyor.IsRunningOnAppVeyor;
+        IsPullRequest = buildSystem.AppVeyor.Environment.PullRequest.IsPullRequest;
+        IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, buildSystem.AppVeyor.Environment.Repository.Name);
+        IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, buildSystem.AppVeyor.Environment.Repository.Branch);
+        IsTagged = buildSystem.AppVeyor.Environment.Repository.Tag.IsTag 
+                && !string.IsNullOrWhiteSpace(buildSystem.AppVeyor.Environment.Repository.Tag.Name);
+        IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleasePlatform, Platform) 
+                    && StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration);
+        IsMyGetRelease = !IsTagged && IsReleasable;
+        IsNuGetRelease = IsTagged && IsReleasable;
+
+        // VERSION
+        Version = context.Argument("force-nuget-version", context.ParseAssemblyInfo(AssemblyInfoPath).AssemblyVersion);
+
+        if (IsRunningOnAppVeyor)
+        {
+            if (IsTagged)
+            {
+                // Use Tag Name as version
+                Version = buildSystem.AppVeyor.Environment.Repository.Tag.Name;
+            }
+            else
+            {
+                // Use AssemblyVersion with Build as version
+                Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-alpha";
+            }
+        }
+
+        // DIRECTORIES
+        ArtifactsDir = (DirectoryPath)context.Directory("./artifacts");
+        NugetRoot = ArtifactsDir.Combine("nuget");
+        ZipRoot = ArtifactsDir.Combine("zip");
+        BinRoot = ArtifactsDir.Combine("bin");
+        TestsRoot = ArtifactsDir.Combine("tests");
+
+        DirSuffix = Configuration;
+        DirSuffixSkia = (IsPlatformAnyCPU ? "x86" : Platform) + "/" + Configuration;
+        DirSuffixIOS = "iPhone" + "/" + Configuration;
+
+        BuildDirs = 
+            context.GetDirectories("./src/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./src/**/obj/" + DirSuffix) + 
+            context.GetDirectories("./src/Markup/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./src/Markup/**/obj/" + DirSuffix) + 
+            context.GetDirectories("./src/Android/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./src/Android/**/obj/" + DirSuffix) + 
+            context.GetDirectories("./src/Gtk/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./src/Gtk/**/obj/" + DirSuffix) + 
+            context.GetDirectories("./src/iOS/**/bin/" + DirSuffixIOS) + 
+            context.GetDirectories("./src/iOS/**/obj/" + DirSuffixIOS) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android/bin/" + DirSuffix) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android/obj/" + DirSuffix) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android.TestApp/bin/" + DirSuffix) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android.TestApp/obj/" + DirSuffix) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + DirSuffixSkia) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop/obj/" + DirSuffixSkia) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop.NetStandard/bin/" + DirSuffix) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop.NetStandard/obj/" + DirSuffix) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + DirSuffixIOS) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS/obj/" + DirSuffixIOS) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/bin/" + DirSuffixIOS) + 
+            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/obj/" + DirSuffixIOS) + 
+            context.GetDirectories("./src/Windows/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./src/Windows/**/obj/" + DirSuffix) + 
+            context.GetDirectories("./tests/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./tests/**/obj/" + DirSuffix) + 
+            context.GetDirectories("./Samples/**/bin/" + DirSuffix) + 
+            context.GetDirectories("./Samples/**/obj/" + DirSuffix);
+
+        FileZipSuffix = Version + ".zip";
+        ZipCoreArtifacts = ZipRoot.CombineWithFilePath("Avalonia-" + FileZipSuffix);
+        ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix);
+        ZipTargetControlCatalogDesktopDirs = ZipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + FileZipSuffix);
+    }
+}