diff --git a/.gitignore b/.gitignore index 5df03641..f26f4578 100644 --- a/.gitignore +++ b/.gitignore @@ -273,5 +273,8 @@ externals/ # Output directory output/ +# Archives directory +archives/ + #google-services google-services.json diff --git a/Apps/Contoso.Forms.Puppet/Contoso.Forms.Puppet.Droid/Contoso.Forms.Puppet.Droid.csproj b/Apps/Contoso.Forms.Puppet/Contoso.Forms.Puppet.Droid/Contoso.Forms.Puppet.Droid.csproj index 5c0438a3..2e0722f2 100644 --- a/Apps/Contoso.Forms.Puppet/Contoso.Forms.Puppet.Droid/Contoso.Forms.Puppet.Droid.csproj +++ b/Apps/Contoso.Forms.Puppet/Contoso.Forms.Puppet.Droid/Contoso.Forms.Puppet.Droid.csproj @@ -31,7 +31,6 @@ 4 None false - true arm64-v8a;armeabi;armeabi-v7a;x86;x86_64 @@ -215,10 +214,10 @@ - + - + diff --git a/build.cake b/build.cake index 95823e89..578a0501 100644 --- a/build.cake +++ b/build.cake @@ -10,33 +10,33 @@ using System.Text.RegularExpressions; // MobileCenter module class definition. class MobileCenterModule { - public string AndroidModule { get; set; } - public string IosModule { get; set; } - public string DotNetModule { get; set; } - public string NuGetVersion { get; set; } - public string PackageId { get; set; } - public string MainNuspecFilename { get; set; } - public string NuGetPackageName - { - get - { - return PackageId + "." + NuGetVersion + ".nupkg"; - } - } - public string MacNuspecFilename - { - get { return "Mac" + MainNuspecFilename; } - } - public string WindowsNuspecFilename - { - get { return "Windows" + MainNuspecFilename; } - } - public MobileCenterModule(string android, string ios, string dotnet, string mainNuspecFilename) { - AndroidModule = android; - IosModule = ios; - DotNetModule = dotnet; - MainNuspecFilename = mainNuspecFilename; - } + public string AndroidModule { get; set; } + public string IosModule { get; set; } + public string DotNetModule { get; set; } + public string NuGetVersion { get; set; } + public string PackageId { get; set; } + public string MainNuspecFilename { get; set; } + public string NuGetPackageName + { + get + { + return PackageId + "." + NuGetVersion + ".nupkg"; + } + } + public string MacNuspecFilename + { + get { return "Mac" + MainNuspecFilename; } + } + public string WindowsNuspecFilename + { + get { return "Windows" + MainNuspecFilename; } + } + public MobileCenterModule(string android, string ios, string dotnet, string mainNuspecFilename) { + AndroidModule = android; + IosModule = ios; + DotNetModule = dotnet; + MainNuspecFilename = mainNuspecFilename; + } } // Prefix for temporary intermediates that are created by this script @@ -75,11 +75,11 @@ var WINDOWS_ASSEMBLIES_URL = SDK_STORAGE_URL + WINDOWS_ASSEMBLIES_ZIP; // Available MobileCenter modules. var MOBILECENTER_MODULES = new [] { - new MobileCenterModule("mobile-center-release.aar", "MobileCenter.framework.zip", "SDK/MobileCenter/Microsoft.Azure.Mobile", "MobileCenter.nuspec"), - new MobileCenterModule("mobile-center-analytics-release.aar", "MobileCenterAnalytics.framework.zip", "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics", "MobileCenterAnalytics.nuspec"), - new MobileCenterModule("mobile-center-crashes-release.aar", "MobileCenterCrashes.framework.zip", "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes", "MobileCenterCrashes.nuspec"), - new MobileCenterModule("mobile-center-distribute-release.aar", "MobileCenterDistribute.framework.zip", "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute", "MobileCenterDistribute.nuspec"), - new MobileCenterModule("mobile-center-push-release.aar", "MobileCenterPush.framework.zip", "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push", "MobileCenterPush.nuspec") + new MobileCenterModule("mobile-center-release.aar", "MobileCenter.framework.zip", "SDK/MobileCenter/Microsoft.Azure.Mobile", "MobileCenter.nuspec"), + new MobileCenterModule("mobile-center-analytics-release.aar", "MobileCenterAnalytics.framework.zip", "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics", "MobileCenterAnalytics.nuspec"), + new MobileCenterModule("mobile-center-crashes-release.aar", "MobileCenterCrashes.framework.zip", "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes", "MobileCenterCrashes.nuspec"), + new MobileCenterModule("mobile-center-distribute-release.aar", "MobileCenterDistribute.framework.zip", "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute", "MobileCenterDistribute.nuspec"), + new MobileCenterModule("mobile-center-push-release.aar", "MobileCenterPush.framework.zip", "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push", "MobileCenterPush.nuspec") }; // Task TARGET for build @@ -90,8 +90,8 @@ var STORAGE_ID = Argument("StorageId", Argument("storage-id", "")); class AssemblyGroup { - public string[] AssemblyPaths {get; set;} - public string AssemblyFolder {get; set;} + public string[] AssemblyPaths {get; set;} + public string AssemblyFolder {get; set;} } // This class contains the assembly folder paths and other platform dependent paths involved in preparing assemblies for VSTS and Azure storage. @@ -99,182 +99,182 @@ class AssemblyGroup // AssemblyFolder must be added to the correct platform's "DownloadAssemblyFolders" array. class PlatformPaths { - public PlatformPaths() - { - UploadAssemblyGroups = new List(); - DownloadAssemblyFolders = new List(); - } + public PlatformPaths() + { + UploadAssemblyGroups = new List(); + DownloadAssemblyFolders = new List(); + } - // Folders for the assemblies that the current platform must create and upload - public List UploadAssemblyGroups {get; set;} + // Folders for the assemblies that the current platform must create and upload + public List UploadAssemblyGroups {get; set;} - // The name of the zip file to upload - public string UploadAssembliesZip {get; set;} + // The name of the zip file to upload + public string UploadAssembliesZip {get; set;} - // The name of the zip file to download - public string DownloadAssembliesZip {get; set;} - // The paths of downloaded assembly folders - public List DownloadAssemblyFolders {get; set;} + // The name of the zip file to download + public string DownloadAssembliesZip {get; set;} + // The paths of downloaded assembly folders + public List DownloadAssemblyFolders {get; set;} - // The URL to download files from - public string DownloadUrl {get; set;} + // The URL to download files from + public string DownloadUrl {get; set;} } // Prepare the platform paths for downloading, uploading, and preparing assemblies Setup(context => { - if (IsRunningOnUnix()) - { - var iosAssemblyGroup = new AssemblyGroup { - AssemblyFolder = IOS_ASSEMBLIES_FOLDER, - AssemblyPaths = new string[] { "SDK/MobileCenter/Microsoft.Azure.Mobile.iOS/bin/Release/Microsoft.Azure.Mobile.dll", - "SDK/MobileCenter/Microsoft.Azure.Mobile.iOS/bin/Release/Microsoft.Azure.Mobile.iOS.Bindings.dll", - "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.iOS/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", - "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.iOS/bin/Release/Microsoft.Azure.Mobile.Analytics.iOS.Bindings.dll", - "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.iOS/bin/Release/Microsoft.Azure.Mobile.Crashes.dll", - "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.iOS/bin/Release/Microsoft.Azure.Mobile.Crashes.iOS.Bindings.dll", - "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.iOS/bin/Release/Microsoft.Azure.Mobile.Distribute.dll", - "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.iOS/bin/Release/Microsoft.Azure.Mobile.Distribute.iOS.Bindings.dll", - "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.iOS/bin/Release/Microsoft.Azure.Mobile.Push.dll", - "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.iOS.Bindings/bin/Release/Microsoft.Azure.Mobile.Push.iOS.Bindings.dll" } - }; - var androidAssemblyGroup = new AssemblyGroup { - AssemblyFolder = ANDROID_ASSEMBLIES_FOLDER, - AssemblyPaths = new string[] { "SDK/MobileCenter/Microsoft.Azure.Mobile.Android/bin/Release/Microsoft.Azure.Mobile.dll", - "SDK/MobileCenter/Microsoft.Azure.Mobile.Android/bin/Release/Microsoft.Azure.Mobile.Android.Bindings.dll", - "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.Android/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", - "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.Android/bin/Release/Microsoft.Azure.Mobile.Analytics.Android.Bindings.dll", - "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.Android/bin/Release/Microsoft.Azure.Mobile.Crashes.dll", - "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.Android/bin/Release/Microsoft.Azure.Mobile.Crashes.Android.Bindings.dll", - "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.Android/bin/Release/Microsoft.Azure.Mobile.Distribute.dll", - "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.Android/bin/Release/Microsoft.Azure.Mobile.Distribute.Android.Bindings.dll", - "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.Android/bin/Release/Microsoft.Azure.Mobile.Push.dll", - "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.Android.Bindings/bin/Release/Microsoft.Azure.Mobile.Push.Android.Bindings.dll" } - }; - var pclAssemblyGroup = new AssemblyGroup { - AssemblyFolder = PCL_ASSEMBLIES_FOLDER, - AssemblyPaths = new string[] { "SDK/MobileCenter/Microsoft.Azure.Mobile/bin/Release/Microsoft.Azure.Mobile.dll", - "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", - "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes/bin/Release/Microsoft.Azure.Mobile.Crashes.dll", - "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute/bin/Release/Microsoft.Azure.Mobile.Distribute.dll", - "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push/bin/Release/Microsoft.Azure.Mobile.Push.dll" } - }; - PLATFORM_PATHS.UploadAssemblyGroups.Add(iosAssemblyGroup); - PLATFORM_PATHS.UploadAssemblyGroups.Add(androidAssemblyGroup); - PLATFORM_PATHS.UploadAssemblyGroups.Add(pclAssemblyGroup); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER + "/x86"); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER + "/x64"); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER + "/ARM"); - PLATFORM_PATHS.UploadAssembliesZip = MAC_ASSEMBLIES_ZIP + STORAGE_ID; - PLATFORM_PATHS.DownloadUrl = WINDOWS_ASSEMBLIES_URL + STORAGE_ID; - PLATFORM_PATHS.DownloadAssembliesZip = WINDOWS_ASSEMBLIES_ZIP + STORAGE_ID; - } - else - { - var uwpAnyCpuAssemblyGroup = new AssemblyGroup { - AssemblyFolder = UWP_ASSEMBLIES_FOLDER, - AssemblyPaths = new string[] { "nuget/Microsoft.Azure.Mobile.Crashes.targets", - "SDK/MobileCenter/Microsoft.Azure.Mobile.UWP/bin/Release/Microsoft.Azure.Mobile.dll", - "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.UWP/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", - "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/Reference/Microsoft.Azure.Mobile.Crashes.dll", - "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.UWP/bin/Release/Microsoft.Azure.Mobile.Push.dll" } - }; - var uwpX86AssemblyGroup = new AssemblyGroup { - AssemblyFolder = UWP_ASSEMBLIES_FOLDER + "/x86", - AssemblyPaths = new string[] { "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/x86/Release/Microsoft.Azure.Mobile.Crashes.dll", - "Release/WatsonRegistrationUtility/WatsonRegistrationUtility.dll", - "Release/WatsonRegistrationUtility/WatsonRegistrationUtility.winmd" } - }; - var uwpX64AssemblyGroup = new AssemblyGroup { - AssemblyFolder = UWP_ASSEMBLIES_FOLDER + "/x64", - AssemblyPaths = new string[] { "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/x64/Release/Microsoft.Azure.Mobile.Crashes.dll", - "x64/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.dll", - "x64/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.winmd" } - }; - var uwpArmAssemblyGroup = new AssemblyGroup { - AssemblyFolder = UWP_ASSEMBLIES_FOLDER + "/ARM", - AssemblyPaths = new string[] { "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/ARM/Release/Microsoft.Azure.Mobile.Crashes.dll", - "ARM/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.dll", - "ARM/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.winmd" } - }; - PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpAnyCpuAssemblyGroup); - PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpX86AssemblyGroup); - PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpX64AssemblyGroup); - PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpArmAssemblyGroup); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(IOS_ASSEMBLIES_FOLDER); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(ANDROID_ASSEMBLIES_FOLDER); - PLATFORM_PATHS.DownloadAssemblyFolders.Add(PCL_ASSEMBLIES_FOLDER); - PLATFORM_PATHS.UploadAssembliesZip = WINDOWS_ASSEMBLIES_ZIP + STORAGE_ID; - PLATFORM_PATHS.DownloadUrl = MAC_ASSEMBLIES_URL + STORAGE_ID; - PLATFORM_PATHS.DownloadAssembliesZip = MAC_ASSEMBLIES_ZIP + STORAGE_ID; - } + if (IsRunningOnUnix()) + { + var iosAssemblyGroup = new AssemblyGroup { + AssemblyFolder = IOS_ASSEMBLIES_FOLDER, + AssemblyPaths = new string[] { "SDK/MobileCenter/Microsoft.Azure.Mobile.iOS/bin/Release/Microsoft.Azure.Mobile.dll", + "SDK/MobileCenter/Microsoft.Azure.Mobile.iOS/bin/Release/Microsoft.Azure.Mobile.iOS.Bindings.dll", + "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.iOS/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", + "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.iOS/bin/Release/Microsoft.Azure.Mobile.Analytics.iOS.Bindings.dll", + "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.iOS/bin/Release/Microsoft.Azure.Mobile.Crashes.dll", + "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.iOS/bin/Release/Microsoft.Azure.Mobile.Crashes.iOS.Bindings.dll", + "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.iOS/bin/Release/Microsoft.Azure.Mobile.Distribute.dll", + "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.iOS/bin/Release/Microsoft.Azure.Mobile.Distribute.iOS.Bindings.dll", + "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.iOS/bin/Release/Microsoft.Azure.Mobile.Push.dll", + "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.iOS.Bindings/bin/Release/Microsoft.Azure.Mobile.Push.iOS.Bindings.dll" } + }; + var androidAssemblyGroup = new AssemblyGroup { + AssemblyFolder = ANDROID_ASSEMBLIES_FOLDER, + AssemblyPaths = new string[] { "SDK/MobileCenter/Microsoft.Azure.Mobile.Android/bin/Release/Microsoft.Azure.Mobile.dll", + "SDK/MobileCenter/Microsoft.Azure.Mobile.Android/bin/Release/Microsoft.Azure.Mobile.Android.Bindings.dll", + "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.Android/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", + "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.Android/bin/Release/Microsoft.Azure.Mobile.Analytics.Android.Bindings.dll", + "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.Android/bin/Release/Microsoft.Azure.Mobile.Crashes.dll", + "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.Android/bin/Release/Microsoft.Azure.Mobile.Crashes.Android.Bindings.dll", + "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.Android/bin/Release/Microsoft.Azure.Mobile.Distribute.dll", + "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute.Android/bin/Release/Microsoft.Azure.Mobile.Distribute.Android.Bindings.dll", + "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.Android/bin/Release/Microsoft.Azure.Mobile.Push.dll", + "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.Android.Bindings/bin/Release/Microsoft.Azure.Mobile.Push.Android.Bindings.dll" } + }; + var pclAssemblyGroup = new AssemblyGroup { + AssemblyFolder = PCL_ASSEMBLIES_FOLDER, + AssemblyPaths = new string[] { "SDK/MobileCenter/Microsoft.Azure.Mobile/bin/Release/Microsoft.Azure.Mobile.dll", + "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", + "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes/bin/Release/Microsoft.Azure.Mobile.Crashes.dll", + "SDK/MobileCenterDistribute/Microsoft.Azure.Mobile.Distribute/bin/Release/Microsoft.Azure.Mobile.Distribute.dll", + "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push/bin/Release/Microsoft.Azure.Mobile.Push.dll" } + }; + PLATFORM_PATHS.UploadAssemblyGroups.Add(iosAssemblyGroup); + PLATFORM_PATHS.UploadAssemblyGroups.Add(androidAssemblyGroup); + PLATFORM_PATHS.UploadAssemblyGroups.Add(pclAssemblyGroup); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER + "/x86"); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER + "/x64"); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(UWP_ASSEMBLIES_FOLDER + "/ARM"); + PLATFORM_PATHS.UploadAssembliesZip = MAC_ASSEMBLIES_ZIP + STORAGE_ID; + PLATFORM_PATHS.DownloadUrl = WINDOWS_ASSEMBLIES_URL + STORAGE_ID; + PLATFORM_PATHS.DownloadAssembliesZip = WINDOWS_ASSEMBLIES_ZIP + STORAGE_ID; + } + else + { + var uwpAnyCpuAssemblyGroup = new AssemblyGroup { + AssemblyFolder = UWP_ASSEMBLIES_FOLDER, + AssemblyPaths = new string[] { "nuget/Microsoft.Azure.Mobile.Crashes.targets", + "SDK/MobileCenter/Microsoft.Azure.Mobile.UWP/bin/Release/Microsoft.Azure.Mobile.dll", + "SDK/MobileCenterAnalytics/Microsoft.Azure.Mobile.Analytics.UWP/bin/Release/Microsoft.Azure.Mobile.Analytics.dll", + "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/Reference/Microsoft.Azure.Mobile.Crashes.dll", + "SDK/MobileCenterPush/Microsoft.Azure.Mobile.Push.UWP/bin/Release/Microsoft.Azure.Mobile.Push.dll" } + }; + var uwpX86AssemblyGroup = new AssemblyGroup { + AssemblyFolder = UWP_ASSEMBLIES_FOLDER + "/x86", + AssemblyPaths = new string[] { "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/x86/Release/Microsoft.Azure.Mobile.Crashes.dll", + "Release/WatsonRegistrationUtility/WatsonRegistrationUtility.dll", + "Release/WatsonRegistrationUtility/WatsonRegistrationUtility.winmd" } + }; + var uwpX64AssemblyGroup = new AssemblyGroup { + AssemblyFolder = UWP_ASSEMBLIES_FOLDER + "/x64", + AssemblyPaths = new string[] { "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/x64/Release/Microsoft.Azure.Mobile.Crashes.dll", + "x64/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.dll", + "x64/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.winmd" } + }; + var uwpArmAssemblyGroup = new AssemblyGroup { + AssemblyFolder = UWP_ASSEMBLIES_FOLDER + "/ARM", + AssemblyPaths = new string[] { "SDK/MobileCenterCrashes/Microsoft.Azure.Mobile.Crashes.UWP/bin/ARM/Release/Microsoft.Azure.Mobile.Crashes.dll", + "ARM/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.dll", + "ARM/Release/WatsonRegistrationUtility/WatsonRegistrationUtility.winmd" } + }; + PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpAnyCpuAssemblyGroup); + PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpX86AssemblyGroup); + PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpX64AssemblyGroup); + PLATFORM_PATHS.UploadAssemblyGroups.Add(uwpArmAssemblyGroup); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(IOS_ASSEMBLIES_FOLDER); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(ANDROID_ASSEMBLIES_FOLDER); + PLATFORM_PATHS.DownloadAssemblyFolders.Add(PCL_ASSEMBLIES_FOLDER); + PLATFORM_PATHS.UploadAssembliesZip = WINDOWS_ASSEMBLIES_ZIP + STORAGE_ID; + PLATFORM_PATHS.DownloadUrl = MAC_ASSEMBLIES_URL + STORAGE_ID; + PLATFORM_PATHS.DownloadAssembliesZip = MAC_ASSEMBLIES_ZIP + STORAGE_ID; + } }); // Versioning task. Task("Version") - .Does(() => + .Does(() => { - var assemblyInfo = ParseAssemblyInfo("./" + "SDK/MobileCenter/Microsoft.Azure.Mobile/Properties/AssemblyInfo.cs"); - var version = assemblyInfo.AssemblyInformationalVersion; - // Read AssemblyInfo.cs and extract versions for modules. - foreach (var module in MOBILECENTER_MODULES) - { - module.NuGetVersion = version; - } + var assemblyInfo = ParseAssemblyInfo("./" + "SDK/MobileCenter/Microsoft.Azure.Mobile/Properties/AssemblyInfo.cs"); + var version = assemblyInfo.AssemblyInformationalVersion; + // Read AssemblyInfo.cs and extract versions for modules. + foreach (var module in MOBILECENTER_MODULES) + { + module.NuGetVersion = version; + } }); // Package id task Task("PackageId") - .Does(() => + .Does(() => { - // Read AssemblyInfo.cs and extract package ids for modules. - foreach (var module in MOBILECENTER_MODULES) - { - var nuspecText = FileReadText("./nuget/" + module.MainNuspecFilename); - var startTag = ""; - var endTag = ""; - int startIndex = nuspecText.IndexOf(startTag) + startTag.Length; - int length = nuspecText.IndexOf(endTag) - startIndex; - var id = nuspecText.Substring(startIndex, length); - Information("id = " + id); - module.PackageId = id; - } + // Read AssemblyInfo.cs and extract package ids for modules. + foreach (var module in MOBILECENTER_MODULES) + { + var nuspecText = FileReadText("./nuget/" + module.MainNuspecFilename); + var startTag = ""; + var endTag = ""; + int startIndex = nuspecText.IndexOf(startTag) + startTag.Length; + int length = nuspecText.IndexOf(endTag) - startIndex; + var id = nuspecText.Substring(startIndex, length); + Information("id = " + id); + module.PackageId = id; + } }); Task("Build").IsDependentOn("MacBuild").IsDependentOn("WindowsBuild"); Task("MacBuild") - .WithCriteria(() => IsRunningOnUnix()) - .Does(() => + .WithCriteria(() => IsRunningOnUnix()) + .Does(() => { - // Run externals here instead of using dependency so that this doesn't get called on windows - RunTarget("Externals"); - // Build solution - NuGetRestore("./MobileCenter-SDK-Build-Mac.sln"); - MSBuild("./MobileCenter-SDK-Build-Mac.sln", c => c.Configuration = "Release"); + // Run externals here instead of using dependency so that this doesn't get called on windows + RunTarget("Externals"); + // Build solution + NuGetRestore("./MobileCenter-SDK-Build-Mac.sln"); + MSBuild("./MobileCenter-SDK-Build-Mac.sln", c => c.Configuration = "Release"); }).OnError(HandleError); // Building Windows code task Task("WindowsBuild") - .WithCriteria(() => !IsRunningOnUnix()) - .Does(() => + .WithCriteria(() => !IsRunningOnUnix()) + .Does(() => { - // Build solution - NuGetRestore("./MobileCenter-SDK-Build-Windows.sln"); - MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release").WithProperty("Platform", "x86")); - MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release").WithProperty("Platform", "x64")); - MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release").WithProperty("Platform", "ARM")); - MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release")); // any cpu - MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Reference")); // any cpu + // Build solution + NuGetRestore("./MobileCenter-SDK-Build-Windows.sln"); + MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release").WithProperty("Platform", "x86")); + MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release").WithProperty("Platform", "x64")); + MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release").WithProperty("Platform", "ARM")); + MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Release")); // any cpu + MSBuild("./MobileCenter-SDK-Build-Windows.sln", settings => settings.SetConfiguration("Reference")); // any cpu }).OnError(HandleError); Task("PrepareAssemblies").IsDependentOn("Build").Does(()=> { - foreach (var assemblyGroup in PLATFORM_PATHS.UploadAssemblyGroups) - { - CopyFiles(assemblyGroup.AssemblyPaths, assemblyGroup.AssemblyFolder); - } + foreach (var assemblyGroup in PLATFORM_PATHS.UploadAssemblyGroups) + { + CopyFiles(assemblyGroup.AssemblyPaths, assemblyGroup.AssemblyFolder); + } }).OnError(HandleError); // Task dependencies for binding each platform. @@ -283,25 +283,25 @@ Task("Bindings-Ios").IsDependentOn("Externals-Ios"); // Downloading Android binaries. Task("Externals-Android") - .Does(() => + .Does(() => { - CleanDirectory("./externals/android"); - - // Download zip file. - DownloadFile(ANDROID_URL, "./externals/android/android.zip"); - Unzip("./externals/android/android.zip", "./externals/android/"); - - // Copy files to {DotNetModule}.Android.Bindings/Jars - foreach (var module in MOBILECENTER_MODULES) - { - var files = GetFiles("./externals/android/*/" + module.AndroidModule); - CopyFiles(files, module.DotNetModule + ".Android.Bindings/Jars/"); - } + CleanDirectory("./externals/android"); + + // Download zip file. + DownloadFile(ANDROID_URL, "./externals/android/android.zip"); + Unzip("./externals/android/android.zip", "./externals/android/"); + + // Copy files to {DotNetModule}.Android.Bindings/Jars + foreach (var module in MOBILECENTER_MODULES) + { + var files = GetFiles("./externals/android/*/" + module.AndroidModule); + CopyFiles(files, module.DotNetModule + ".Android.Bindings/Jars/"); + } }).OnError(HandleError); // Downloading iOS binaries. Task("Externals-Ios") - .Does(() => + .Does(() => { CleanDirectory("./externals/ios"); @@ -332,289 +332,289 @@ Task("Default").IsDependentOn("NuGet").IsDependentOn("RemoveTemporaries"); // Build tests Task("UITest").IsDependentOn("RestoreTestPackages").Does(() => { - MSBuild("./Tests/UITests/Contoso.Forms.Test.UITests.csproj", c => c.Configuration = "Release"); + MSBuild("./Tests/UITests/Contoso.Forms.Test.UITests.csproj", c => c.Configuration = "Release"); }); // Pack NuGets for appropriate platform Task("NuGet") - .IsDependentOn("PrepareAssemblies") - .IsDependentOn("Version") - .Does(()=> + .IsDependentOn("PrepareAssemblies") + .IsDependentOn("Version") + .Does(()=> { - // NuGet on mac trims out the first ./ so adding it twice works around - var basePath = IsRunningOnUnix() ? (System.IO.Directory.GetCurrentDirectory().ToString() + @"/.") : "./"; - CleanDirectory("output"); - - var specCopyName = TEMPORARY_PREFIX + "spec_copy.nuspec"; - - // Packaging NuGets. - foreach (var module in MOBILECENTER_MODULES) - { - var nuspecFilename = IsRunningOnUnix() ? module.MacNuspecFilename : module.WindowsNuspecFilename; - - // Skipping not exists modules. - if (!FileExists("nuget/" + nuspecFilename)) - { - continue; - } - - // Prepare nuspec by making substitutions in a copied nuspec (to avoid altering the original) - CopyFile("nuget/" + nuspecFilename, specCopyName); - ReplaceTextInFiles(specCopyName, "$pcl_dir$", PCL_ASSEMBLIES_FOLDER); - ReplaceTextInFiles(specCopyName, "$ios_dir$", IOS_ASSEMBLIES_FOLDER); - ReplaceTextInFiles(specCopyName, "$windows_dir$", UWP_ASSEMBLIES_FOLDER); - ReplaceTextInFiles(specCopyName, "$android_dir$", ANDROID_ASSEMBLIES_FOLDER); - - var spec = GetFiles(specCopyName); - Information("Building a NuGet package for " + module.DotNetModule + " version " + module.NuGetVersion); - NuGetPack(spec, new NuGetPackSettings { - BasePath = basePath, - Verbosity = NuGetVerbosity.Detailed, - Version = module.NuGetVersion - }); - - // Clean up - DeleteFiles(specCopyName); - } - MoveFiles("Microsoft.Azure.Mobile*.nupkg", "output"); + // NuGet on mac trims out the first ./ so adding it twice works around + var basePath = IsRunningOnUnix() ? (System.IO.Directory.GetCurrentDirectory().ToString() + @"/.") : "./"; + CleanDirectory("output"); + + var specCopyName = TEMPORARY_PREFIX + "spec_copy.nuspec"; + + // Packaging NuGets. + foreach (var module in MOBILECENTER_MODULES) + { + var nuspecFilename = IsRunningOnUnix() ? module.MacNuspecFilename : module.WindowsNuspecFilename; + + // Skipping not exists modules. + if (!FileExists("nuget/" + nuspecFilename)) + { + continue; + } + + // Prepare nuspec by making substitutions in a copied nuspec (to avoid altering the original) + CopyFile("nuget/" + nuspecFilename, specCopyName); + ReplaceTextInFiles(specCopyName, "$pcl_dir$", PCL_ASSEMBLIES_FOLDER); + ReplaceTextInFiles(specCopyName, "$ios_dir$", IOS_ASSEMBLIES_FOLDER); + ReplaceTextInFiles(specCopyName, "$windows_dir$", UWP_ASSEMBLIES_FOLDER); + ReplaceTextInFiles(specCopyName, "$android_dir$", ANDROID_ASSEMBLIES_FOLDER); + + var spec = GetFiles(specCopyName); + Information("Building a NuGet package for " + module.DotNetModule + " version " + module.NuGetVersion); + NuGetPack(spec, new NuGetPackSettings { + BasePath = basePath, + Verbosity = NuGetVerbosity.Detailed, + Version = module.NuGetVersion + }); + + // Clean up + DeleteFiles(specCopyName); + } + MoveFiles("Microsoft.Azure.Mobile*.nupkg", "output"); }).OnError(HandleError); // Add version to nuspecs for vsts (the release definition does not have the solutions and thus cannot extract a version from them) Task("PrepareNuspecsForVSTS").IsDependentOn("Version").Does(()=> { - foreach (var module in MOBILECENTER_MODULES) - { - ReplaceTextInFiles("./nuget/" + module.MainNuspecFilename, "$version$", module.NuGetVersion); - } + foreach (var module in MOBILECENTER_MODULES) + { + ReplaceTextInFiles("./nuget/" + module.MainNuspecFilename, "$version$", module.NuGetVersion); + } }); // Upload assemblies to Azure storage Task("UploadAssemblies") - .IsDependentOn("PrepareAssemblies") - .Does(()=> + .IsDependentOn("PrepareAssemblies") + .Does(()=> { - // The environment variables below must be set for this task to succeed - var apiKey = EnvironmentVariable("AZURE_STORAGE_ACCESS_KEY"); - var accountName = EnvironmentVariable("AZURE_STORAGE_ACCOUNT"); - - foreach (var assemblyGroup in PLATFORM_PATHS.UploadAssemblyGroups) - { - var destinationFolder = DOWNLOADED_ASSEMBLIES_FOLDER + "/" + assemblyGroup.AssemblyFolder; - CleanDirectory(destinationFolder); - CopyFiles(assemblyGroup.AssemblyPaths, destinationFolder); - } - - Information("Uploading to blob " + PLATFORM_PATHS.UploadAssembliesZip); - Zip(DOWNLOADED_ASSEMBLIES_FOLDER, PLATFORM_PATHS.UploadAssembliesZip); - AzureStorage.UploadFileToBlob(new AzureStorageSettings - { - AccountName = accountName, - ContainerName = "sdk", - BlobName = PLATFORM_PATHS.UploadAssembliesZip, - Key = apiKey, - UseHttps = true - }, PLATFORM_PATHS.UploadAssembliesZip); + // The environment variables below must be set for this task to succeed + var apiKey = EnvironmentVariable("AZURE_STORAGE_ACCESS_KEY"); + var accountName = EnvironmentVariable("AZURE_STORAGE_ACCOUNT"); + + foreach (var assemblyGroup in PLATFORM_PATHS.UploadAssemblyGroups) + { + var destinationFolder = DOWNLOADED_ASSEMBLIES_FOLDER + "/" + assemblyGroup.AssemblyFolder; + CleanDirectory(destinationFolder); + CopyFiles(assemblyGroup.AssemblyPaths, destinationFolder); + } + + Information("Uploading to blob " + PLATFORM_PATHS.UploadAssembliesZip); + Zip(DOWNLOADED_ASSEMBLIES_FOLDER, PLATFORM_PATHS.UploadAssembliesZip); + AzureStorage.UploadFileToBlob(new AzureStorageSettings + { + AccountName = accountName, + ContainerName = "sdk", + BlobName = PLATFORM_PATHS.UploadAssembliesZip, + Key = apiKey, + UseHttps = true + }, PLATFORM_PATHS.UploadAssembliesZip); }).OnError(HandleError).Finally(()=>RunTarget("RemoveTemporaries")); // Download assemblies from azure storage Task("DownloadAssemblies").Does(()=> { - Information("Fetching assemblies from url: " + PLATFORM_PATHS.DownloadUrl); - CleanDirectory(DOWNLOADED_ASSEMBLIES_FOLDER); - DownloadFile(PLATFORM_PATHS.DownloadUrl, PLATFORM_PATHS.DownloadAssembliesZip); - Unzip(PLATFORM_PATHS.DownloadAssembliesZip, DOWNLOADED_ASSEMBLIES_FOLDER); - DeleteFiles(PLATFORM_PATHS.DownloadAssembliesZip); - Information("Successfully downloaded assemblies."); + Information("Fetching assemblies from url: " + PLATFORM_PATHS.DownloadUrl); + CleanDirectory(DOWNLOADED_ASSEMBLIES_FOLDER); + DownloadFile(PLATFORM_PATHS.DownloadUrl, PLATFORM_PATHS.DownloadAssembliesZip); + Unzip(PLATFORM_PATHS.DownloadAssembliesZip, DOWNLOADED_ASSEMBLIES_FOLDER); + DeleteFiles(PLATFORM_PATHS.DownloadAssembliesZip); + Information("Successfully downloaded assemblies."); }).OnError(HandleError); Task("MergeAssemblies") - .IsDependentOn("PrepareAssemblies") - .IsDependentOn("DownloadAssemblies") - .IsDependentOn("Version") - .Does(()=> + .IsDependentOn("PrepareAssemblies") + .IsDependentOn("DownloadAssemblies") + .IsDependentOn("Version") + .Does(()=> { - Information("Beginning complete package creation..."); - - // Copy the downloaded files to their proper locations so the structure is as if - // the downloaded assemblies were built locally (for the nuspecs to work) - foreach (var assemblyFolder in PLATFORM_PATHS.DownloadAssemblyFolders) - { - CleanDirectory(assemblyFolder); - var files = GetFiles(DOWNLOADED_ASSEMBLIES_FOLDER + "/" + assemblyFolder + "/*"); - CopyFiles(files, assemblyFolder); - } - - // Create NuGet packages - foreach (var module in MOBILECENTER_MODULES) - { - // Prepare nuspec by making substitutions in a copied nuspec (to avoid altering the original) - var specCopyName = TEMPORARY_PREFIX + "spec_copy.nuspec"; - CopyFile("nuget/" + module.MainNuspecFilename, specCopyName); - ReplaceTextInFiles(specCopyName, "$pcl_dir$", PCL_ASSEMBLIES_FOLDER); - ReplaceTextInFiles(specCopyName, "$ios_dir$", IOS_ASSEMBLIES_FOLDER); - ReplaceTextInFiles(specCopyName, "$windows_dir$", UWP_ASSEMBLIES_FOLDER); - ReplaceTextInFiles(specCopyName, "$android_dir$", ANDROID_ASSEMBLIES_FOLDER); - - var spec = GetFiles(specCopyName); - - // Create the NuGet package - Information("Building a NuGet package for " + module.DotNetModule + " version " + module.NuGetVersion); - NuGetPack(spec, new NuGetPackSettings { - Verbosity = NuGetVerbosity.Detailed, - Version = module.NuGetVersion - }); - - // Clean up - DeleteFiles(specCopyName); - } - CleanDirectory("output"); - MoveFiles("*.nupkg", "output"); + Information("Beginning complete package creation..."); + + // Copy the downloaded files to their proper locations so the structure is as if + // the downloaded assemblies were built locally (for the nuspecs to work) + foreach (var assemblyFolder in PLATFORM_PATHS.DownloadAssemblyFolders) + { + CleanDirectory(assemblyFolder); + var files = GetFiles(DOWNLOADED_ASSEMBLIES_FOLDER + "/" + assemblyFolder + "/*"); + CopyFiles(files, assemblyFolder); + } + + // Create NuGet packages + foreach (var module in MOBILECENTER_MODULES) + { + // Prepare nuspec by making substitutions in a copied nuspec (to avoid altering the original) + var specCopyName = TEMPORARY_PREFIX + "spec_copy.nuspec"; + CopyFile("nuget/" + module.MainNuspecFilename, specCopyName); + ReplaceTextInFiles(specCopyName, "$pcl_dir$", PCL_ASSEMBLIES_FOLDER); + ReplaceTextInFiles(specCopyName, "$ios_dir$", IOS_ASSEMBLIES_FOLDER); + ReplaceTextInFiles(specCopyName, "$windows_dir$", UWP_ASSEMBLIES_FOLDER); + ReplaceTextInFiles(specCopyName, "$android_dir$", ANDROID_ASSEMBLIES_FOLDER); + + var spec = GetFiles(specCopyName); + + // Create the NuGet package + Information("Building a NuGet package for " + module.DotNetModule + " version " + module.NuGetVersion); + NuGetPack(spec, new NuGetPackSettings { + Verbosity = NuGetVerbosity.Detailed, + Version = module.NuGetVersion + }); + + // Clean up + DeleteFiles(specCopyName); + } + CleanDirectory("output"); + MoveFiles("*.nupkg", "output"); }).OnError(HandleError).Finally(()=>RunTarget("RemoveTemporaries")); Task("TestApps").IsDependentOn("UITest").Does(() => { - // Build tests and package the applications - // It is important that the entire solution is built before rebuilding the iOS and Android versions - // due to an apparent bug that causes improper linking of the forms application to iOS - MSBuild("./MobileCenter-SDK-Test.sln", c => c.Configuration = "Release"); - MDToolBuild("./Tests/iOS/Contoso.Forms.Test.iOS.csproj", c => c.Configuration = "Release|iPhone"); - AndroidPackage("./Tests/Droid/Contoso.Forms.Test.Droid.csproj", false, c => c.Configuration = "Release"); - MSBuild("./Tests/UITests/Contoso.Forms.Test.UITests.csproj", c => c.Configuration = "Release"); + // Build tests and package the applications + // It is important that the entire solution is built before rebuilding the iOS and Android versions + // due to an apparent bug that causes improper linking of the forms application to iOS + MSBuild("./MobileCenter-SDK-Test.sln", c => c.Configuration = "Release"); + MDToolBuild("./Tests/iOS/Contoso.Forms.Test.iOS.csproj", c => c.Configuration = "Release|iPhone"); + AndroidPackage("./Tests/Droid/Contoso.Forms.Test.Droid.csproj", false, c => c.Configuration = "Release"); + MSBuild("./Tests/UITests/Contoso.Forms.Test.UITests.csproj", c => c.Configuration = "Release"); }).OnError(HandleError); Task("RestoreTestPackages").Does(() => { - NuGetRestore("./MobileCenter-SDK-Test.sln"); - NuGetUpdate("./Tests/Contoso.Forms.Test/packages.config"); - NuGetUpdate("./Tests/iOS/packages.config"); - NuGetUpdate("./Tests/Droid/packages.config", new NuGetUpdateSettings { - - // workaround for https://stackoverflow.com/questions/44861995/xamarin-build-error-building-target - Source = new string[] { EnvironmentVariable("NUGET_URL") } - }); + NuGetRestore("./MobileCenter-SDK-Test.sln"); + NuGetUpdate("./Tests/Contoso.Forms.Test/packages.config"); + NuGetUpdate("./Tests/iOS/packages.config"); + NuGetUpdate("./Tests/Droid/packages.config", new NuGetUpdateSettings { + + // workaround for https://stackoverflow.com/questions/44861995/xamarin-build-error-building-target + Source = new string[] { EnvironmentVariable("NUGET_URL") } + }); }).OnError(HandleError); // Remove any uploaded nugets from azure storage Task("CleanAzureStorage").Does(()=> { - var apiKey = EnvironmentVariable("AZURE_STORAGE_ACCESS_KEY"); - var accountName = EnvironmentVariable("AZURE_STORAGE_ACCOUNT"); - - try - { - AzureStorage.DeleteBlob(new AzureStorageSettings - { - AccountName = accountName, - ContainerName = "sdk", - BlobName = MAC_ASSEMBLIES_ZIP + STORAGE_ID, - Key = apiKey, - UseHttps = true - }); - - AzureStorage.DeleteBlob(new AzureStorageSettings - { - AccountName = accountName, - ContainerName = "sdk", - BlobName = WINDOWS_ASSEMBLIES_ZIP + STORAGE_ID, - Key = apiKey, - UseHttps = true - }); - } - catch - { - // not an error if the blob is not found - } + var apiKey = EnvironmentVariable("AZURE_STORAGE_ACCESS_KEY"); + var accountName = EnvironmentVariable("AZURE_STORAGE_ACCOUNT"); + + try + { + AzureStorage.DeleteBlob(new AzureStorageSettings + { + AccountName = accountName, + ContainerName = "sdk", + BlobName = MAC_ASSEMBLIES_ZIP + STORAGE_ID, + Key = apiKey, + UseHttps = true + }); + + AzureStorage.DeleteBlob(new AzureStorageSettings + { + AccountName = accountName, + ContainerName = "sdk", + BlobName = WINDOWS_ASSEMBLIES_ZIP + STORAGE_ID, + Key = apiKey, + UseHttps = true + }); + } + catch + { + // not an error if the blob is not found + } }).OnError(HandleError); // Remove all temporary files and folders Task("RemoveTemporaries").Does(()=> { - DeleteFiles(TEMPORARY_PREFIX + "*"); - var dirs = GetDirectories(TEMPORARY_PREFIX + "*"); - foreach (var directory in dirs) - { - DeleteDirectory(directory, true); - } - DeleteFiles("./nuget/*.temp.nuspec"); + DeleteFiles(TEMPORARY_PREFIX + "*"); + var dirs = GetDirectories(TEMPORARY_PREFIX + "*"); + foreach (var directory in dirs) + { + DeleteDirectory(directory, true); + } + DeleteFiles("./nuget/*.temp.nuspec"); }); // Clean up files/directories. Task("clean") - .IsDependentOn("RemoveTemporaries") - .Does(() => + .IsDependentOn("RemoveTemporaries") + .Does(() => { - DeleteDirectoryIfExists("externals"); - DeleteDirectoryIfExists("output"); - DeleteFiles("./*.nupkg"); - CleanDirectories("./**/bin"); - CleanDirectories("./**/obj"); + DeleteDirectoryIfExists("externals"); + DeleteDirectoryIfExists("output"); + DeleteFiles("./*.nupkg"); + CleanDirectories("./**/bin"); + CleanDirectories("./**/obj"); }); Task("PrepareAssemblyPathsVSTS").Does(()=> { - var iosAssemblies = EnvironmentVariable("IOS_ASSEMBLY_PATH_NUSPEC"); - var androidAssemblies = EnvironmentVariable("ANDROID_ASSEMBLY_PATH_NUSPEC"); - var pclAssemblies = EnvironmentVariable("PCL_ASSEMBLY_PATH_NUSPEC"); - var uwpAssemblies = EnvironmentVariable("UWP_ASSEMBLY_PATH_NUSPEC"); - var nuspecPathPrefix = EnvironmentVariable("NUSPEC_PATH"); - - foreach (var module in MOBILECENTER_MODULES) - { - ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$pcl_dir$", pclAssemblies); - ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$ios_dir$", iosAssemblies); - ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$windows_dir$", uwpAssemblies); - ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$android_dir$", androidAssemblies); - } + var iosAssemblies = EnvironmentVariable("IOS_ASSEMBLY_PATH_NUSPEC"); + var androidAssemblies = EnvironmentVariable("ANDROID_ASSEMBLY_PATH_NUSPEC"); + var pclAssemblies = EnvironmentVariable("PCL_ASSEMBLY_PATH_NUSPEC"); + var uwpAssemblies = EnvironmentVariable("UWP_ASSEMBLY_PATH_NUSPEC"); + var nuspecPathPrefix = EnvironmentVariable("NUSPEC_PATH"); + + foreach (var module in MOBILECENTER_MODULES) + { + ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$pcl_dir$", pclAssemblies); + ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$ios_dir$", iosAssemblies); + ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$windows_dir$", uwpAssemblies); + ReplaceTextInFiles(nuspecPathPrefix + module.MainNuspecFilename, "$android_dir$", androidAssemblies); + } }).OnError(HandleError); Task("NugetPackVSTS").Does(()=> { - var nuspecPathPrefix = EnvironmentVariable("NUSPEC_PATH"); - foreach (var module in MOBILECENTER_MODULES) - { - var spec = GetFiles(nuspecPathPrefix + module.MainNuspecFilename); - // Create the NuGet packages - Information("Building a NuGet package for " + module.MainNuspecFilename); - NuGetPack(spec, new NuGetPackSettings { - Verbosity = NuGetVerbosity.Detailed, - }); - } + var nuspecPathPrefix = EnvironmentVariable("NUSPEC_PATH"); + foreach (var module in MOBILECENTER_MODULES) + { + var spec = GetFiles(nuspecPathPrefix + module.MainNuspecFilename); + // Create the NuGet packages + Information("Building a NuGet package for " + module.MainNuspecFilename); + NuGetPack(spec, new NuGetPackSettings { + Verbosity = NuGetVerbosity.Detailed, + }); + } }).OnError(HandleError); // Copy files to a clean directory using string names instead of FilePath[] and DirectoryPath void CopyFiles(IEnumerable files, string targetDirectory, bool clean = true) { - if (clean) - { - CleanDirectory(targetDirectory); - } - foreach (var file in files) - { - CopyFile(file, targetDirectory + "/" + System.IO.Path.GetFileName(file)); - } + if (clean) + { + CleanDirectory(targetDirectory); + } + foreach (var file in files) + { + CopyFile(file, targetDirectory + "/" + System.IO.Path.GetFileName(file)); + } } void DeleteDirectoryIfExists(string directoryName) { - if (DirectoryExists(directoryName)) - { - DeleteDirectory(directoryName, true); - } + if (DirectoryExists(directoryName)) + { + DeleteDirectory(directoryName, true); + } } void CleanDirectory(string directoryName) { - DeleteDirectoryIfExists(directoryName); - CreateDirectory(directoryName); + DeleteDirectoryIfExists(directoryName); + CreateDirectory(directoryName); } void HandleError(Exception exception) { - RunTarget("clean"); - throw exception; + RunTarget("clean"); + throw exception; } RunTarget(TARGET); diff --git a/scripts/distribute-release.sh b/scripts/distribute-release.sh new file mode 100755 index 00000000..3b3861cb --- /dev/null +++ b/scripts/distribute-release.sh @@ -0,0 +1,19 @@ +# Define default arguments. +MANDATORY="" +GROUP="" +ENVIRONMENT="" +PLATFORM="" + +# NOTE: For "--group", use '_' instead of spaces. +for i in "$@"; do + case $1 in + -m|--mandatory) MANDATORY="-Mandatory true" ;; + -e|--environment) ENVIRONMENT="-Environment $2"; shift ;; + -p|--platform) PLATFORM="-Platform $2"; shift ;; + -g|--group) GROUP="-Group $2"; shift ;; + *) shift ;; + esac + shift +done + +./build.sh -s test-tools.cake -t "ReleaseApplication" $GROUP $MANDATORY $PLATFORM $ENVIRONMENT diff --git a/scripts/send-push.sh b/scripts/send-push.sh new file mode 100755 index 00000000..f2327297 --- /dev/null +++ b/scripts/send-push.sh @@ -0,0 +1,15 @@ +# Define default arguments. +ENVIRONMENT="" +PLATFORM="" + +# NOTE: For "--group", use '_' instead of spaces. +for i in "$@"; do + case $1 in + -e|--environment) ENVIRONMENT="-Environment $2"; shift ;; + -p|--platform) PLATFORM="-Platform $2"; shift ;; + *) shift ;; + esac + shift +done + +./build.sh -s test-tools.cake -t "SendPushNotification" $PLATFORM $ENVIRONMENT \ No newline at end of file diff --git a/test-tools.cake b/test-tools.cake new file mode 100644 index 00000000..d823ac7f --- /dev/null +++ b/test-tools.cake @@ -0,0 +1,382 @@ +#tool nuget:?package=XamarinComponent +#addin nuget:?package=Cake.Xamarin +#addin nuget:?package=Cake.FileHelpers +#addin nuget:?package=Cake.SemVer +#addin nuget:?package=Newtonsoft.Json + +using System; +using System.Collections.Generic; +using System.Net; +using Newtonsoft.Json.Linq; + +// Task Target for build +var Target = Argument("target", Argument("t", "Default")); + +string ArchiveDirectory = "archives"; +bool IsMandatory = false; +string DistributionGroup = "Private Release Script Group"; +string Token = EnvironmentVariable("MOBILE_CENTER_API_TOKEN"); +string BaseUrl = "https://api.mobile.azure.com"; +ApplicationInfo CurrentApp = null; + +public enum Environment +{ + Int, + Prod +} + +public enum Platform +{ + iOS, + Android, + UWP +} + +public class ApplicationInfo +{ + public static ICakeContext Context; + public static string OutputDirectory; + public Environment AppEnvironment { get; } + public Platform AppPlatform { get; } + public string AppOwner { get; } + public string AppId { get; } + public string AppPath + { + get + { + return OutputDirectory + "/" + AppId + "." + _appExtension; + } + } + public string ProjectPath + { + get + { + if (_projectPath == null) + { + _projectPath = Context.GetFiles("**/" + _projectFile).Single().ToString(); + } + return _projectPath; + } + } + + public string ProjectDirectory + { + get + { + return System.IO.Path.GetDirectoryName(ProjectPath); + } + } + + private string _appExtension = null; + private string _projectPath = null; + private string _projectFile = null; + public ApplicationInfo(Environment environment, Platform platform, string appOwner, string appId, string projectFile, string appExtension) + { + AppOwner = appOwner; + AppId = appId; + AppEnvironment = environment; + AppPlatform = platform; + _projectFile = projectFile; + _appExtension = appExtension; + } +} + +ApplicationInfo.Context = Context; +ApplicationInfo.OutputDirectory = ArchiveDirectory; +IList Applications = new List +{ + new ApplicationInfo(Environment.Prod, Platform.iOS, "mobile-center", "xamarin-demo-ios", "Contoso.Forms.Demo.iOS.csproj", "ipa"), + new ApplicationInfo(Environment.Prod, Platform.Android, "mobile-center", "xamarin-demo-android", "Contoso.Forms.Demo.Droid.csproj", "apk"), + new ApplicationInfo(Environment.Prod, Platform.UWP, "mobile-center", "UWP-Forms-Puppet", "Contoso.Forms.Demo.UWP.csproj", ""), + new ApplicationInfo(Environment.Int, Platform.iOS, "mobile-center-sdk", "xamarin-puppet-ios", "Contoso.Forms.Puppet.iOS.csproj", "ipa"), + new ApplicationInfo(Environment.Int, Platform.Android, "mobile-center-sdk", "xamarin-puppet-android-03", "Contoso.Forms.Puppet.Droid.csproj", "apk"), + new ApplicationInfo(Environment.Int, Platform.UWP, "mobile-center-sdk", "xamarin-forms-puppet-uwp-2", "Contoso.Forms.Puppet.UWP.csproj", "") +}; + +Setup(context => +{ + // Arguments: + // -environment (-e): App "environment" ("prod" or "int") -- Default is "prod" + // -group (-g): Distribution group name -- Default is "Private Release Script Group" + // -mandatory (-m): Should the release be mandatory ("true" or "false") -- Default is "false" + // -platform (-p): ios, android, or uwp -- Default is ios + + // Read arguments + var environment = Environment.Prod; + if (Argument("Environment", "int") == "int") + { + environment = Environment.Int; + Token = EnvironmentVariable("MOBILE_CENTER_INT_API_TOKEN"); + BaseUrl = "https://asgard-int.trafficmanager.net/api"; + } + var platformString = Argument("Platform", "ios"); + var platform = Platform.iOS; + if (platformString == "android") + { + platform = Platform.Android; + } + else if (platformString == "uwp") + { + platform = Platform.UWP; + } + + CurrentApp = ( from app in Applications + where app.AppPlatform == platform && + app.AppEnvironment == environment + select app + ).Single(); + + DistributionGroup = Argument("Group", DistributionGroup); + DistributionGroup = DistributionGroup.Replace('_', ' '); + IsMandatory = Argument("Mandatory", false); +}); + +// Distribution Tasks + +Task("CreateIosArchive").IsDependentOn("IncreaseIosVersion").Does(()=> +{ + MSBuild(CurrentApp.ProjectPath, settings => settings.SetConfiguration("Release") + .WithTarget("Build") + .WithProperty("Platform", "iPhone") + .WithProperty("BuildIpa", "true") + .WithProperty("OutputPath", "bin/Release/") + .WithProperty("AllowUnsafeBlocks", "true")); + var projectLocation = CurrentApp.ProjectDirectory; + var ipaLocation = projectLocation + + "/bin/Release/" + + System.IO.Path.GetFileNameWithoutExtension(CurrentApp.ProjectPath) + + ".ipa"; + EnsureDirectoryExists(ArchiveDirectory); + if (System.IO.File.Exists(CurrentApp.AppPath)) + { + System.IO.File.Delete(CurrentApp.AppPath); + } + CopyFile(ipaLocation, CurrentApp.AppPath); +}); + +Task("CreateAndroidArchive").IsDependentOn("IncreaseAndroidVersion").Does(()=> +{ + AndroidPackage(CurrentApp.ProjectPath, true, c => c.Configuration = "Release"); + var projectLocation = CurrentApp.ProjectDirectory; + var apks = GetFiles(projectLocation + "/bin/Release/*.apk"); + var unsignedApk = ""; + foreach (var path in apks) + { + if (!path.ToString().EndsWith("-Signed.apk")) + { + unsignedApk = path.ToString(); + break; + } + } + EnsureDirectoryExists(ArchiveDirectory); + if (System.IO.File.Exists(CurrentApp.AppPath)) + { + System.IO.File.Delete(CurrentApp.AppPath); + } + CopyFile(unsignedApk, CurrentApp.AppPath); +}); + +Task("IncreaseIosVersion").Does(()=> +{ + var infoPlistLocation = CurrentApp.ProjectDirectory + "/Info.plist"; + var plist = File(infoPlistLocation); + var bundleVersionPattern = @"CFBundleVersion<\/key>\s*[^<]*<\/string>"; + var match = FindRegexMatchInFile(File(infoPlistLocation), bundleVersionPattern, System.Text.RegularExpressions.RegexOptions.None); + var openTag = ""; + var closeTag = ""; + var currentVersion = match.Substring(match.IndexOf(openTag) + openTag.Length, match.IndexOf(closeTag) - match.IndexOf(openTag) - openTag.Length); + var newVersion = IncrementSemVer(currentVersion); + var newBundleVersionString = "CFBundleVersion\n\t" + newVersion + ""; + ReplaceRegexInFiles(infoPlistLocation, bundleVersionPattern, newBundleVersionString); + Information("iOS Version increased to " + newVersion); +}); + +Task("IncreaseAndroidVersion").Does(()=> +{ + // Setup + var manifestLocation = CurrentApp.ProjectDirectory + "/Properties/AndroidManifest.xml"; + var xmlNamespaces = new Dictionary {{"android", "http://schemas.android.com/apk/res/android"}}; + var peekSettings = new XmlPeekSettings(); + peekSettings.Namespaces = xmlNamespaces; + var pokeSettings = new XmlPokeSettings(); + pokeSettings.Namespaces = xmlNamespaces; + + // Manifest version code + var versionCode = int.Parse(XmlPeek(manifestLocation, "manifest/@android:versionCode", peekSettings)); + var newVersionCode = versionCode + 1; + XmlPoke(manifestLocation, "manifest/@android:versionCode", newVersionCode.ToString(), pokeSettings); + + // Manifest version name + var versionName = XmlPeek(manifestLocation, "manifest/@android:versionName", peekSettings); + var suffix = "-SNAPSHOT"; + if (versionName.Contains(suffix)) + { + versionName = versionName.Substring(0, versionName.IndexOf(suffix)); + } + var newVersionName = IncrementSemVer(versionName); + XmlPoke(manifestLocation, "manifest/@android:versionName", newVersionName, pokeSettings); + Information("Android version name changed to " + newVersionName + ", version code increased to " + newVersionCode); +}); + +Task("ReleaseApplication") +.Does(()=> +{ + if (CurrentApp.AppPlatform == Platform.iOS) + { + RunTarget("CreateIosArchive"); + } + else if (CurrentApp.AppPlatform == Platform.Android) + { + RunTarget("CreateAndroidArchive"); + } + else + { + Error("Cannot distribute for this platform."); + return; + } + + // Start the upload. + Information("Initiating distribution process..."); + var startUploadUrl = GetApiUrl(BaseUrl, CurrentApp.AppOwner, CurrentApp.AppId, "release_uploads"); + var startUploadRequest = GetWebRequest(startUploadUrl, Token); + var startUploadResponse = GetResponseJson(startUploadRequest); + + // Upload the file to the given endpoint. The label "ipa" is correct for all platforms. + var uploadUrl = startUploadResponse["upload_url"].ToString(); + HttpUploadFile(uploadUrl, CurrentApp.AppPath, "ipa"); + + // Commit the upload + Information("Committing distribution..."); + var uploadId = startUploadResponse["upload_id"].ToString(); + var commitRequestUrl = startUploadUrl + "/" + uploadId; + var commitRequest = GetWebRequest(commitRequestUrl, Token, "PATCH"); + AttachJsonPayload(commitRequest, + new JObject( + new JProperty("status", "committed"))); + var commitResponse = GetResponseJson(commitRequest); + var releaseUrl = BaseUrl + "/" + commitResponse["release_url"].ToString(); + + // Release the upload + Information("Finalizing release..."); + var releaseRequest = GetWebRequest(releaseUrl, Token, "PATCH"); + var releaseNotes = "This release has been created by the script test-tools.cake."; + AttachJsonPayload(releaseRequest, + new JObject( + new JProperty("destination_name", DistributionGroup), + new JProperty("release_notes", releaseNotes), + new JProperty("mandatory", IsMandatory.ToString().ToLower()))); + releaseRequest.GetResponse().Dispose(); + var mandatorySuffix = IsMandatory ? " as a mandatory update" : ""; + Information("Successfully released " + CurrentApp.AppOwner + + "/" + CurrentApp.AppId + " to group " + + DistributionGroup + mandatorySuffix + "."); +}); + +// Push tasks +Task("SendPushNotification") +.Does(()=> +{ + var name = "Test Notification"; + var title = "Test Notification"; + var timeSent = DateTime.Now.ToString(); + var body = "Notification sent from test script at " + timeSent + "."; + var properties = new Dictionary {{"time_sent", timeSent}}; + var notificationJson = new JObject( + new JProperty("notification_content", + new JObject( + new JProperty("name", name), + new JProperty("title", title), + new JProperty("body", body), + new JProperty("custom_data", + new JObject( + from key in properties.Keys + select new JProperty(key, properties[key])))))); + Information("Sending notification:\n" + notificationJson.ToString()); + var url = GetApiUrl(BaseUrl, CurrentApp.AppOwner, CurrentApp.AppId, "push/notifications"); + var request = GetWebRequest(url, Token); + AttachJsonPayload(request, notificationJson); + var responseJson = GetResponseJson(request); + Information("Successfully sent push notification and received result:\n" + responseJson.ToString()); +}); + +// Helper methods + +string GetApiUrl(string baseUrl, string appOwner, string appId, string apiName) +{ + return string.Format("{0}/v0.1/apps/{1}/{2}/{3}", baseUrl, appOwner, appId, apiName); +} + +JObject GetResponseJson(HttpWebRequest request) +{ + using (var response = request.GetResponse()) + using (var reader = new StreamReader(response.GetResponseStream())) + { + return JObject.Parse(reader.ReadToEnd()); + } +} + +HttpWebRequest GetWebRequest(string url, string token, string method = "POST") +{ + Information(string.Format("About to call url '{0}'", url)); + var request = (HttpWebRequest)WebRequest.Create(url); + request.Headers["X-API-Token"] = token; + request.ContentType = "application/json"; + request.Accept = "application/json"; + request.Method = method; + return request; +} + +void AttachJsonPayload(HttpWebRequest request, JObject json) +{ + using (var stream = request.GetRequestStream()) + using (var sr = new StreamWriter(stream)) + { + sr.Write(json.ToString()); + } +} + +string IncrementSemVer(string semVer) +{ + var parsedVersion = ParseSemVer(semVer); + return CreateSemVer(parsedVersion.Major, parsedVersion.Minor, parsedVersion.Patch + 1).ToString(); +} + +// Adapted from https://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data/2996904#2996904 +void HttpUploadFile(string url, string file, string paramName) +{ + Information(string.Format("Uploading {0} to {1}", file, url)); + var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); + byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); + var request = (HttpWebRequest)WebRequest.Create(url); + request.ContentType = "multipart/form-data; boundary=" + boundary; + request.Method = "POST"; + request.KeepAlive = true; + using (var requestStream = request.GetRequestStream()) + { + requestStream.Write(boundaryBytes, 0, boundaryBytes.Length); + var headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n\r\n"; + var header = string.Format(headerTemplate, paramName, file); + byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header); + requestStream.Write(headerBytes, 0, headerBytes.Length); + using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) + { + byte[] buffer = new byte[4096]; + var bytesRead = 0; + while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) + { + requestStream.Write(buffer, 0, bytesRead); + } + } + byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); + requestStream.Write(trailer, 0, trailer.Length); + } + request.GetResponse().Dispose(); + Information("File uploaded."); +} + +Task("Default").Does(()=> +{ + Error("Please run a specific target."); +}); + +RunTarget(Target);