CP-45071: Convert XenCenter build scripts to PowerShell. (#3219)

* CP-45071: Convert XenCenter build scripts to PowerShell.
* Removed obsolete variable.
* Pass the timestamp server and the certificate thumbprint as parameters to the build and sign scripts.
* Added further logging and made the verbose output of cmdlets optional.
* Updated README.
* Improved script readability.

Signed-off-by: Konstantina Chremmou <Konstantina.Chremmou@cloud.com>
This commit is contained in:
Konstantina Chremmou 2023-09-06 15:48:12 +01:00 committed by GitHub
parent 53dd3d97ca
commit dd98fe6732
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 520 additions and 441 deletions

8
Jenkinsfile vendored
View File

@ -1,6 +1,6 @@
#!groovy #!groovy
/* Copyright (c) Cloud Software Group, Inc. /* Copyright (c) Cloud Software Group, Inc.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
* with or without modification, are permitted provided * with or without modification, are permitted provided
@ -30,10 +30,10 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
def XENADMIN_BRANDING_TAG = 'v5.1' def XENADMIN_BRANDING_TAG = 'v5.2'
@Library(['PacmanSharedLibrary', "xencenter-pipeline@v4.9"]) @Library(['PacmanSharedLibrary', "xencenter-pipeline@v4.10"])
import com.citrix.pipeline.xencenter.* import com.xenserver.pipeline.xencenter.*
properties([ properties([
[ [

View File

@ -54,3 +54,7 @@ To run the [NUnit](http://www.nunit.org/) tests you will need the following libr
* Moq.dll * Moq.dll
which can be obtained from <http://www.nuget.org/>. which can be obtained from <http://www.nuget.org/>.
Note that the build script assumes that you have added MSBuild's location (usually
`C:\Program Files\Microsoft Visual Studio\2022\<edition>\MSBuild\Current\Bin`)
to your `PATH` environment variable.

View File

@ -40,7 +40,7 @@
<Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder"> <Directory Id="ProgramFilesFolder">
<Directory Id="XenServer" Name="$(var.BrandProduct)"> <Directory Id="XenServer" Name="$(var.BrandProduct)">
<Directory Id="INSTALLDIR" ShortName="$(var.BrandConsoleShort)" Name="$(var.BrandConsoleNoSpace)"> <Directory Id="INSTALLDIR" ShortName="$(var.BrandConsoleShort)" Name="$(var.BrandConsole)">
<Component Id="ReportViewer" Guid="$(var.ReportViewerGuid)"> <Component Id="ReportViewer" Guid="$(var.ReportViewerGuid)">
<File Id="MicRepVwrCmnDLL" Source="$(env.RepoRoot)\XenAdmin\ReportViewer\Microsoft.ReportViewer.Common.dll" /> <File Id="MicRepVwrCmnDLL" Source="$(env.RepoRoot)\XenAdmin\ReportViewer\Microsoft.ReportViewer.Common.dll" />
<File Id="MicRepVwrPrcObjDLL" Source="$(env.RepoRoot)\XenAdmin\ReportViewer\Microsoft.ReportViewer.ProcessingObjectModel.dll" /> <File Id="MicRepVwrPrcObjDLL" Source="$(env.RepoRoot)\XenAdmin\ReportViewer\Microsoft.ReportViewer.ProcessingObjectModel.dll" />
@ -56,11 +56,11 @@
</Component> </Component>
<Component Id="MainExecutable" Guid="$(var.MainExeGuid)"> <Component Id="MainExecutable" Guid="$(var.MainExeGuid)">
<!-- XenCenter EXE --> <!-- XenCenter EXE -->
<File Id="XenCenterEXE" Source="$(env.RepoRoot)\XenAdmin\bin\Release\$(var.BrandConsoleNoSpace).exe" KeyPath="yes" /> <File Id="XenCenterEXE" Source="$(env.RepoRoot)\XenAdmin\bin\Release\$(var.BrandConsole).exe" KeyPath="yes" />
<!-- other EXEs --> <!-- other EXEs -->
<File Id="XeEXE" Source="$(env.RepoRoot)\xe\bin\Release\xe.exe" /> <File Id="XeEXE" Source="$(env.RepoRoot)\xe\bin\Release\xe.exe" />
<!-- config --> <!-- config -->
<File Id="XenCenterCONFIG" Source="$(env.RepoRoot)\XenAdmin\bin\Release\$(var.BrandConsoleNoSpace).exe.config" /> <File Id="XenCenterCONFIG" Source="$(env.RepoRoot)\XenAdmin\bin\Release\$(var.BrandConsole).exe.config" />
<!-- DLLs --> <!-- DLLs -->
<File Id="CommandLibDLL" Source="$(env.RepoRoot)\XenAdmin\bin\Release\CommandLib.dll" /> <File Id="CommandLibDLL" Source="$(env.RepoRoot)\XenAdmin\bin\Release\CommandLib.dll" />
<File Id="CookComputingDLL" Source="$(env.RepoRoot)\XenAdmin\bin\Release\CookComputing.XmlRpcV2.dll" /> <File Id="CookComputingDLL" Source="$(env.RepoRoot)\XenAdmin\bin\Release\CookComputing.XmlRpcV2.dll" />
@ -149,16 +149,16 @@
<Condition>INSTALLSHORTCUT</Condition> <Condition>INSTALLSHORTCUT</Condition>
<Shortcut Id="DesktopXenCenter" <Shortcut Id="DesktopXenCenter"
Name="$(var.BrandConsole)" Name="$(var.BrandConsole)"
Target="[INSTALLDIR]$(var.BrandConsoleNoSpace).exe" Target="[INSTALLDIR]$(var.BrandConsole).exe"
WorkingDirectory="INSTALLDIR" WorkingDirectory="INSTALLDIR"
/> />
<RegistryValue Root="HKCU" Key="Software\$(var.BrandProduct)\$(var.BrandConsoleNoSpace)" Name="installed" Type="integer" Value="1" KeyPath="yes" /> <RegistryValue Root="HKCU" Key="Software\$(var.BrandProduct)\$(var.BrandConsole)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component> </Component>
</Directory> </Directory>
</Directory> </Directory>
<DirectoryRef Id="TARGETDIR"> <DirectoryRef Id="TARGETDIR">
<Component Id="RegistryEntries" Guid="$(var.RegEntriesGuid)"> <Component Id="RegistryEntries" Guid="$(var.RegEntriesGuid)">
<RegistryKey Root="HKMU" Key="Software\$(var.BrandProduct)\$(var.BrandConsoleNoSpace)"> <RegistryKey Root="HKMU" Key="Software\$(var.BrandProduct)\$(var.BrandConsole)">
<RegistryValue Type="string" Name="InstallDir" Value="[INSTALLDIR]" /> <RegistryValue Type="string" Name="InstallDir" Value="[INSTALLDIR]" />
<?if "$(var.HiddenFeatures)" != ""?> <?if "$(var.HiddenFeatures)" != ""?>
<RegistryValue Type="string" Name="HiddenFeatures" Value="$(var.HiddenFeatures)" /> <RegistryValue Type="string" Name="HiddenFeatures" Value="$(var.HiddenFeatures)" />
@ -172,9 +172,9 @@
<DirectoryRef Id="ApplicationProgramsFolder"> <DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="$(var.AppShortcutGuid)"> <Component Id="ApplicationShortcut" Guid="$(var.AppShortcutGuid)">
<Shortcut Id="StartmenuXenCenter" ShortName="$(var.BrandConsoleShort)" Name="$(var.BrandConsole)" Target="[INSTALLDIR]$(var.BrandConsoleNoSpace).exe" WorkingDirectory="INSTALLDIR" Icon="XenCenterICO" /> <Shortcut Id="StartmenuXenCenter" ShortName="$(var.BrandConsoleShort)" Name="$(var.BrandConsole)" Target="[INSTALLDIR]$(var.BrandConsole).exe" WorkingDirectory="INSTALLDIR" Icon="XenCenterICO" />
<RemoveFolder Id="ApplicationProgramsFolder" On="both" /> <RemoveFolder Id="ApplicationProgramsFolder" On="both" />
<RegistryValue Root="HKCU" Key="Software\$(var.BrandProduct)\$(var.BrandConsoleNoSpace)" Name="installed" Type="integer" Value="1" KeyPath="yes" /> <RegistryValue Root="HKCU" Key="Software\$(var.BrandProduct)\$(var.BrandConsole)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component> </Component>
</DirectoryRef> </DirectoryRef>
@ -200,7 +200,7 @@
<![CDATA[Installed OR (WIXNETFX4RELEASEINSTALLED >= "#528040")]]> <![CDATA[Installed OR (WIXNETFX4RELEASEINSTALLED >= "#528040")]]>
</Condition> </Condition>
<Property Id="PERMACHINEINSTALL"> <Property Id="PERMACHINEINSTALL">
<RegistrySearch Id="InstallRegistry" Type="raw" Root="HKLM" Key="Software\$(var.BrandProduct)\$(var.BrandConsoleNoSpace)" Name="InstallDir" /> <RegistrySearch Id="InstallRegistry" Type="raw" Root="HKLM" Key="Software\$(var.BrandProduct)\$(var.BrandConsole)" Name="InstallDir" />
</Property> </Property>
<Property Id="REINSTALLMODE" Value="amus" /> <Property Id="REINSTALLMODE" Value="amus" />
<Property Id="INSTALLSHORTCUT" Value="0"/> <Property Id="INSTALLSHORTCUT" Value="0"/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright (c) Cloud Software Group, Inc. Copyright (c) Cloud Software Group, Inc.
Redistribution and use in source and binary forms, Redistribution and use in source and binary forms,
with or without modification, are permitted provided with or without modification, are permitted provided
@ -49,7 +49,6 @@
<?define CompanyNameLegal="@COMPANY_NAME_LEGAL@"?> <?define CompanyNameLegal="@COMPANY_NAME_LEGAL@"?>
<?define CompanyNameShort="@COMPANY_NAME_SHORT@"?> <?define CompanyNameShort="@COMPANY_NAME_SHORT@"?>
<?define BrandConsole="@BRAND_CONSOLE@"?> <?define BrandConsole="@BRAND_CONSOLE@"?>
<?define BrandConsoleNoSpace="@BRAND_CONSOLE_NO_SPACE@"?>
<?define BrandConsoleShort="@BRAND_CONSOLE_SHORT@"?> <?define BrandConsoleShort="@BRAND_CONSOLE_SHORT@"?>
<?define BrandProduct="@PRODUCT_BRAND@"?> <?define BrandProduct="@PRODUCT_BRAND@"?>
<?define FileExtBackup="xbk"?> <?define FileExtBackup="xbk"?>

View File

@ -1,29 +0,0 @@
wixlib/WixUI_InstallDir.wxs
wixlib/WixUI_FeatureTree.wxs
wixlib/BrowseDlg.wxs
wixlib/CancelDlg.wxs
wixlib/Common.wxs
wixlib/CustomizeDlg.wxs
wixlib/CustomizeStdDlg.wxs
wixlib/DiskCostDlg.wxs
wixlib/ErrorDlg.wxs
wixlib/ErrorProgressText.wxs
wixlib/ExitDialog.wxs
wixlib/FatalError.wxs
wixlib/FilesInUse.wxs
wixlib/InstallDirDlg.wxs
wixlib/InvalidDirDlg.wxs
wixlib/LicenseAgreementDlg.wxs
wixlib/MaintenanceTypeDlg.wxs
wixlib/MaintenanceWelcomeDlg.wxs
wixlib/MsiRMFilesInUse.wxs
wixlib/OutOfDiskDlg.wxs
wixlib/OutOfRbDiskDlg.wxs
wixlib/PrepareDlg.wxs
wixlib/ProgressDlg.wxs
wixlib/ResumeDlg.wxs
wixlib/SetupTypeDlg.wxs
wixlib/UserExit.wxs
wixlib/VerifyReadyDlg.wxs
wixlib/WaitForCostingDlg.wxs
wixlib/WelcomeDlg.wxs

View File

@ -1,29 +0,0 @@
obj/WixUI_InstallDir.wixobj
obj/WixUI_FeatureTree.wixobj
obj/BrowseDlg.wixobj
obj/CancelDlg.wixobj
obj/Common.wixobj
obj/CustomizeDlg.wixobj
obj/CustomizeStdDlg.wixobj
obj/DiskCostDlg.wixobj
obj/ErrorDlg.wixobj
obj/ErrorProgressText.wixobj
obj/ExitDialog.wixobj
obj/FatalError.wixobj
obj/FilesInUse.wixobj
obj/InstallDirDlg.wixobj
obj/InvalidDirDlg.wixobj
obj/LicenseAgreementDlg.wixobj
obj/MaintenanceTypeDlg.wixobj
obj/MaintenanceWelcomeDlg.wixobj
obj/MsiRMFilesInUse.wixobj
obj/OutOfDiskDlg.wixobj
obj/OutOfRbDiskDlg.wixobj
obj/PrepareDlg.wixobj
obj/ProgressDlg.wixobj
obj/ResumeDlg.wixobj
obj/SetupTypeDlg.wixobj
obj/UserExit.wixobj
obj/VerifyReadyDlg.wixobj
obj/WaitForCostingDlg.wixobj
obj/WelcomeDlg.wixobj

View File

@ -95,7 +95,7 @@ diff -ru wixlib/Common.wxs wixlib/Common.wxs
+<Fragment> +<Fragment>
+ <Binary Id="WixUIWixca" SourceFile="PrintEula.dll" /> + <Binary Id="WixUIWixca" SourceFile="PrintEula.dll" />
+</Fragment> +</Fragment>
+ +
</Wix> </Wix>
diff -ru wixlib/CustomizeDlg.wxs wixlib/CustomizeDlg.wxs diff -ru wixlib/CustomizeDlg.wxs wixlib/CustomizeDlg.wxs
--- wixlib/CustomizeDlg.wxs 2019-09-15 07:13:54.000000000 +0100 --- wixlib/CustomizeDlg.wxs 2019-09-15 07:13:54.000000000 +0100
@ -158,7 +158,7 @@ diff -ru wixlib/CustomizeDlg.wxs wixlib/CustomizeDlg.wxs
diff -ru wixlib/CustomizeStdDlg.wxs wixlib/CustomizeStdDlg.wxs diff -ru wixlib/CustomizeStdDlg.wxs wixlib/CustomizeStdDlg.wxs
--- wixlib/CustomizeStdDlg.wxs Tue Feb 21 12:03:46 2012 --- wixlib/CustomizeStdDlg.wxs Tue Feb 21 12:03:46 2012
+++ wixlib/CustomizeStdDlg.wxs Tue Jul 20 20:54:33 2015 +++ wixlib/CustomizeStdDlg.wxs Tue Jul 20 20:54:33 2015
@@ -13,7 +13,7 @@ @@ -5,7 +5,7 @@
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment> <Fragment>
<UI> <UI>
@ -554,7 +554,7 @@ diff -ru wixlib/WixUI_en-us.wxl wixlib/WixUI_en-us.wxl
<String Id="UITextVolumeCostRequired" Overridable="yes"><!-- _locID_text="UITextVolumeCostRequired" _locComment="UITextVolumeCostRequired" -->Required</String> <String Id="UITextVolumeCostRequired" Overridable="yes"><!-- _locID_text="UITextVolumeCostRequired" _locComment="UITextVolumeCostRequired" -->Required</String>
<String Id="UITextVolumeCostSize" Overridable="yes"><!-- _locID_text="UITextVolumeCostSize" _locComment="UITextVolumeCostSize" -->Disk Size</String> <String Id="UITextVolumeCostSize" Overridable="yes"><!-- _locID_text="UITextVolumeCostSize" _locComment="UITextVolumeCostSize" -->Disk Size</String>
<String Id="UITextVolumeCostVolume" Overridable="yes"><!-- _locID_text="UITextVolumeCostVolume" _locComment="UITextVolumeCostVolume" -->Volume</String> <String Id="UITextVolumeCostVolume" Overridable="yes"><!-- _locID_text="UITextVolumeCostVolume" _locComment="UITextVolumeCostVolume" -->Volume</String>
+ +
+ <String Id="ErrorNewerProduct">A newer version of this product is already installed.</String> + <String Id="ErrorNewerProduct">A newer version of this product is already installed.</String>
+ <String Id="InstallDirDlgUsersLabel">Install for:</String> + <String Id="InstallDirDlgUsersLabel">Install for:</String>
+ <String Id="InstallDirDlgUsersAllRadioButton">&amp;All Users</String> + <String Id="InstallDirDlgUsersAllRadioButton">&amp;All Users</String>
@ -600,10 +600,10 @@ diff -ru wixlib/WixUI_FeatureTree.wxs wixlib/WixUI_FeatureTree.wxs
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish> <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish> <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish> <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
+ +
+ <Publish Dialog="CustomizeStdDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish> + <Publish Dialog="CustomizeStdDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
+ <Publish Dialog="CustomizeStdDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish> + <Publish Dialog="CustomizeStdDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ +
</UI> </UI>
<UIRef Id="WixUI_Common" /> <UIRef Id="WixUI_Common" />
@ -1023,4 +1023,5 @@ diff --git wixlib/MsiRMFilesInUse.wxs wixlib/MsiRMFilesInUse.wxs
+ <Publish Property="XS_WixUIRMPressedOk" Value="1">1</Publish> + <Publish Property="XS_WixUIRMPressedOk" Value="1">1</Publish>
</Control> </Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)"> <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
<Publish Event="EndDialog" Value="Exit">1</Publish> <Publish Event="EndDialog" Value="Exit">1</Publish>

View File

@ -98,7 +98,7 @@ namespace XenAdmin.Alerts
public static void DownloadAndInstallNewClient(ClientUpdateAlert updateAlert, IWin32Window parent) public static void DownloadAndInstallNewClient(ClientUpdateAlert updateAlert, IWin32Window parent)
{ {
var outputPathAndFileName = Path.Combine(Path.GetTempPath(), $"{BrandManager.BrandConsoleNoSpace}.msi"); var outputPathAndFileName = Path.Combine(Path.GetTempPath(), $"{BrandManager.BrandConsole}.msi");
var downloadAndInstallClientAction = new DownloadAndUpdateClientAction(updateAlert.Name, new Uri(updateAlert.NewVersion.Url), outputPathAndFileName, updateAlert.Checksum); var downloadAndInstallClientAction = new DownloadAndUpdateClientAction(updateAlert.Name, new Uri(updateAlert.NewVersion.Url), outputPathAndFileName, updateAlert.Checksum);

View File

@ -266,7 +266,7 @@ namespace XenAdmin.Core
private const string FORCE_SYSTEM_FONTS = "ForceSystemFonts"; private const string FORCE_SYSTEM_FONTS = "ForceSystemFonts";
private const string DISABLE_PLUGINS = "DisablePlugins"; private const string DISABLE_PLUGINS = "DisablePlugins";
private const string DONT_SUDO = "DontSudo"; private const string DONT_SUDO = "DontSudo";
private static readonly string XENCENTER_LOCAL_KEYS = $"SOFTWARE\\{BrandManager.ProductBrand}\\{BrandManager.BrandConsoleNoSpace}"; private static readonly string XENCENTER_LOCAL_KEYS = $"SOFTWARE\\{BrandManager.ProductBrand}\\{BrandManager.BrandConsole}";
private const string PSExecutionPolicyKey = @"Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"; private const string PSExecutionPolicyKey = @"Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell";
private const string PSExecutionPolicyName = "ExecutionPolicy"; private const string PSExecutionPolicyName = "ExecutionPolicy";
private const string PowerShellKey = @"Software\Microsoft\PowerShell\1"; private const string PowerShellKey = @"Software\Microsoft\PowerShell\1";

View File

@ -125,12 +125,12 @@ namespace XenAdmin
var logFolder = Path.Combine( var logFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
BrandManager.ProductBrand, BrandManager.ProductBrand,
BrandManager.BrandConsoleNoSpace, BrandManager.BrandConsole,
"logs"); "logs");
log4net.GlobalContext.Properties["LOG_FILE"] = Path.Combine(logFolder, $"{BrandManager.BrandConsoleNoSpace}.log"); log4net.GlobalContext.Properties["LOG_FILE"] = Path.Combine(logFolder, $"{BrandManager.BrandConsole}.log");
log4net.GlobalContext.Properties["AUDIT_TRAIL"] = Path.Combine(logFolder, $"{BrandManager.BrandConsoleNoSpace}-AuditTrail.log"); log4net.GlobalContext.Properties["AUDIT_TRAIL"] = Path.Combine(logFolder, $"{BrandManager.BrandConsole}-AuditTrail.log");
log4net.GlobalContext.Properties["NETWORK_TRACE"] = Path.Combine(logFolder, $"{BrandManager.BrandConsoleNoSpace}-NetworkTrace.log"); log4net.GlobalContext.Properties["NETWORK_TRACE"] = Path.Combine(logFolder, $"{BrandManager.BrandConsole}-NetworkTrace.log");
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Assembly.GetCallingAssembly().Location + ".config")); log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(Assembly.GetCallingAssembly().Location + ".config"));
log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -145,7 +145,7 @@ namespace XenAdmin
public static void Main(string[] args) public static void Main(string[] args)
{ {
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value; string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value;
_pipePath = string.Format(PIPE_PATH_PATTERN, BrandManager.BrandConsoleNoSpace, Process.GetCurrentProcess().SessionId, Environment.UserName, appGuid); _pipePath = string.Format(PIPE_PATH_PATTERN, BrandManager.BrandConsole, Process.GetCurrentProcess().SessionId, Environment.UserName, appGuid);
if (NamedPipes.Pipe.ExistsPipe(_pipePath)) if (NamedPipes.Pipe.ExistsPipe(_pipePath))
{ {

View File

@ -781,7 +781,7 @@ namespace XenAdmin
Version previousVersion = null; Version previousVersion = null;
Version currentVersion = Program.Version; Version currentVersion = Program.Version;
var directories = companyFolder.GetDirectories($"{BrandManager.BrandConsoleNoSpace}*"); var directories = companyFolder.GetDirectories($"{BrandManager.BrandConsole}*");
foreach (var dir in directories) foreach (var dir in directories)
{ {

View File

@ -9,7 +9,7 @@
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>XenAdmin</RootNamespace> <RootNamespace>XenAdmin</RootNamespace>
<AssemblyName>[XenCenter_No_Space]</AssemblyName> <AssemblyName>[XenCenter]</AssemblyName>
<ApplicationIcon>..\Branding\Images\AppIcon.ico</ApplicationIcon> <ApplicationIcon>..\Branding\Images\AppIcon.ico</ApplicationIcon>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl> <PublishUrl>publish\</PublishUrl>

View File

@ -44,7 +44,7 @@ namespace XenAdminTests.CodeTests
[TestFixture, Category(TestCategories.Unit)] [TestFixture, Category(TestCategories.Unit)]
public class AssemblyTests public class AssemblyTests
{ {
private static readonly string MainAssemblyName = BrandManager.BrandConsoleNoSpace; private static readonly string MainAssemblyName = BrandManager.BrandConsole;
public class TestDataClass public class TestDataClass
{ {

View File

@ -82,7 +82,7 @@ namespace XenAdmin.Actions
private void CopyClientLogs() private void CopyClientLogs()
{ {
string logDestination = string.Format("{0}\\{1}-{2}.log", filePath, timeString, BrandManager.BrandConsoleNoSpace); string logDestination = string.Format("{0}\\{1}-{2}.log", filePath, timeString, BrandManager.BrandConsole);
if (includeClientLogs) if (includeClientLogs)
{ {
string logPath = XenAdminConfigManager.Provider.GetLogFile(); string logPath = XenAdminConfigManager.Provider.GetLogFile();

View File

@ -47,7 +47,6 @@ namespace XenAdmin.Core
var customBranding = (CustomBrandingAttribute)assembly.GetCustomAttribute(typeof(CustomBrandingAttribute)); var customBranding = (CustomBrandingAttribute)assembly.GetCustomAttribute(typeof(CustomBrandingAttribute));
BrandConsole = customBranding.BrandConsole; BrandConsole = customBranding.BrandConsole;
BrandConsoleNoSpace = customBranding.BrandConsoleNoSpace;
CompanyNameShort = customBranding.CompanyNameShort; CompanyNameShort = customBranding.CompanyNameShort;
ProductBrand = customBranding.ProductBrand; ProductBrand = customBranding.ProductBrand;
ProductVersionPost82 = customBranding.ProductVersionText; ProductVersionPost82 = customBranding.ProductVersionText;
@ -66,8 +65,6 @@ namespace XenAdmin.Core
public static readonly string BrandConsole; public static readonly string BrandConsole;
public static readonly string BrandConsoleNoSpace;
public static readonly string Cis = Get("CIS"); public static readonly string Cis = Get("CIS");
public static readonly string CompanyNameLegacy = Get("COMPANY_NAME_LEGACY"); public static readonly string CompanyNameLegacy = Get("COMPANY_NAME_LEGACY");

View File

@ -34,7 +34,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using XenAdmin.Properties; using XenAdmin.Properties;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
@ -43,8 +43,8 @@ using XenAdmin.Properties;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyProduct("[XenCenter]")] [assembly: AssemblyProduct("[XenCenter]")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type. // COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
@ -55,7 +55,6 @@ using XenAdmin.Properties;
[assembly: CustomBranding( [assembly: CustomBranding(
"[XenCenter]", "[XenCenter]",
"[XenCenter_No_Space]",
"[Vendor]", "[Vendor]",
"[XenServerProduct]", "[XenServerProduct]",
"[XenServer version]", "[XenServer version]",
@ -77,7 +76,6 @@ namespace XenAdmin.Properties
{ {
public CustomBrandingAttribute( public CustomBrandingAttribute(
string brandConsole, string brandConsole,
string brandConsoleNoSpace,
string companyNameShort, string companyNameShort,
string productBrand, string productBrand,
string productVersionText, string productVersionText,
@ -94,7 +92,6 @@ namespace XenAdmin.Properties
) )
{ {
BrandConsole = brandConsole; BrandConsole = brandConsole;
BrandConsoleNoSpace = brandConsoleNoSpace;
CompanyNameShort = companyNameShort; CompanyNameShort = companyNameShort;
ProductBrand = productBrand; ProductBrand = productBrand;
ProductVersionText = productVersionText; ProductVersionText = productVersionText;
@ -111,7 +108,6 @@ namespace XenAdmin.Properties
} }
public string BrandConsole { get; } public string BrandConsole { get; }
public string BrandConsoleNoSpace { get; }
public string CompanyNameShort { get; } public string CompanyNameShort { get; }
public string ProductBrand { get; } public string ProductBrand { get; }
public string ProductVersionText { get; } public string ProductVersionText { get; }

View File

@ -1,6 +1,4 @@
#!/bin/sh # Copyright (c) Cloud Software Group, Inc.
# Copyright (c) Cloud Software Group, Inc.
# #
# Redistribution and use in source and binary forms, # Redistribution and use in source and binary forms,
# with or without modification, are permitted provided # with or without modification, are permitted provided
@ -29,23 +27,22 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. # SUCH DAMAGE.
BRANDING_COMPANY_NAME_LEGAL="[Vendor Legal]" $BRANDING_COMPANY_NAME_LEGAL="[Vendor Legal]"
BRANDING_COMPANY_NAME_SHORT="[Vendor]" $BRANDING_COMPANY_NAME_SHORT="[Vendor]"
BRANDING_PRODUCT_BRAND="[XenServerProduct]" $BRANDING_PRODUCT_BRAND="[XenServerProduct]"
BRANDING_SERVER="[XenServer host]" $BRANDING_SERVER="[XenServer host]"
BRANDING_BRAND_CONSOLE="[XenCenter]" $BRANDING_BRAND_CONSOLE="[XenCenter]"
BRANDING_BRAND_CONSOLE_NO_SPACE="[XenCenter]" $BRANDING_BRAND_CONSOLE_SHORT="XenCente"
BRANDING_BRAND_CONSOLE_SHORT=XenCente $BRANDING_HELP_PATH="xencenter/current-release/"
BRANDING_HELP_PATH=xencenter/current-release/ $BRANDING_PV_TOOLS="[Guest Tools]"
BRANDING_PV_TOOLS="[Guest Tools]" $BRANDING_PRODUCT_VERSION_TEXT="0.0.0"
BRANDING_PRODUCT_VERSION_TEXT=0.0.0 $BRANDING_XC_PRODUCT_VERSION="0.0.0"
BRANDING_XC_PRODUCT_VERSION=0.0.0 $BRANDING_XC_PRODUCT_VERSION_INSTALLER="0.0.0"
BRANDING_XC_PRODUCT_VERSION_INSTALLER=0.0.0 $XC_UPDATES_URL="[Xc updates url]"
XC_UPDATES_URL="[Xc updates url]" $CFU_URL="[Cfu url]"
CFU_URL="[Cfu url]" $YUM_REPO_BASE_BIN="[YumRepoBaseBin]"
YUM_REPO_BASE_BIN="[YumRepoBaseBin]" $YUM_REPO_BASE_SRC="[YumRepoBaseSource]"
YUM_REPO_BASE_SRC="[YumRepoBaseSource]" $YUM_REPO_EARLY_ACCESS_BIN="[YumRepoEarlyAccessBin]"
YUM_REPO_EARLY_ACCESS_BIN="[YumRepoEarlyAccessBin]" $YUM_REPO_EARLY_ACCESS_SRC="[YumRepoEarlyAccessSource]"
YUM_REPO_EARLY_ACCESS_SRC="[YumRepoEarlyAccessSource]" $YUM_REPO_NORMAL_BIN="[YumRepoNormalBin]"
YUM_REPO_NORMAL_BIN="[YumRepoNormalBin]" $YUM_REPO_NORMAL_SRC="[YumRepoNormalSource]"
YUM_REPO_NORMAL_SRC="[YumRepoNormalSource]"

View File

@ -1,91 +0,0 @@
#!/bin/bash
# Copyright (c) Cloud Software Group, Inc.
#
#Redistribution and use in source and binary forms, with or without modification,
#are permitted provided that the following conditions are met:
#
#1. Redistributions of source code must retain the above copyright notice, this
#list of conditions and the following disclaimer.
#
#2. Redistributions in binary form must reproduce the above copyright notice,
#this list of conditions and the following disclaimer in the documentation and/or
#other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
#INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
#NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#POSSIBILITY OF SUCH DAMAGE.
echo Entered re-branding.sh
set -u
GLOBAL_BUILD_NUMBER=$1
REPO="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
version_csharp()
{
sed -b -i -e "s/0\.0\.0\.0/${BRANDING_XC_PRODUCT_VERSION}.${GLOBAL_BUILD_NUMBER}/g" \
-e "s/0000/${BRANDING_XC_PRODUCT_VERSION}.${GLOBAL_BUILD_NUMBER}/g" \
$1
}
rebranding_global()
{
sed -b -i -e "s#\[Vendor Legal\]#${BRANDING_COMPANY_NAME_LEGAL}#g" \
-e "s#\[Vendor\]#${BRANDING_COMPANY_NAME_SHORT}#g" \
-e "s#\[Guest Tools\]#${BRANDING_PV_TOOLS}#g" \
-e "s#\[XenServerProduct\]#${BRANDING_PRODUCT_BRAND}#g" \
-e "s#\[XenServer version\]#${BRANDING_PRODUCT_VERSION_TEXT}#g" \
-e "s#\[XenServer host\]#${BRANDING_SERVER}#g" \
-e "s#\[XenCenter\]#${BRANDING_BRAND_CONSOLE}#g" \
-e "s#\[XenCenter_No_Space\]#${BRANDING_BRAND_CONSOLE_NO_SPACE}#g" \
-e "s#xencenter\/current-release\/#${BRANDING_HELP_PATH}#g" \
-e "s#\[Xc updates url\]#${XC_UPDATES_URL}#g" \
-e "s#\[Cfu url\]#${CFU_URL}#g" \
-e "s#\[YumRepoBaseBin\]#${YUM_REPO_BASE_BIN}#g" \
-e "s#\[YumRepoBaseSource\]#${YUM_REPO_BASE_SRC}#g" \
-e "s#\[YumRepoEarlyAccessBin\]#${YUM_REPO_EARLY_ACCESS_BIN}#g" \
-e "s#\[YumRepoEarlyAccessSource\]#${YUM_REPO_EARLY_ACCESS_SRC}#g" \
-e "s#\[YumRepoNormalBin\]#${YUM_REPO_NORMAL_BIN}#g" \
-e "s#\[YumRepoNormalSource\]#${YUM_REPO_NORMAL_SRC}#g" \
$1
}
version_csharp "${REPO}/CommonAssemblyInfo.cs"
rebranding_global "${REPO}/CommonAssemblyInfo.cs"
#AssemblyInfo rebranding
for projectDir in CFUValidator CommandLib xe XenAdmin XenAdminTests XenCenterLib XenModel XenOvfApi
do
assemblyInfo="${REPO}/${projectDir}/Properties/AssemblyInfo.cs"
version_csharp ${assemblyInfo}
rebranding_global ${assemblyInfo}
done
rebranding_global ${REPO}/XenAdmin/XenAdmin.csproj
PRODUCT_GUID=$(uuidgen | tr [a-z] [A-Z] | tr -d [:space:])
sed -b -i -e "s/@AUTOGEN_PRODUCT_GUID@/${PRODUCT_GUID}/g" \
-e "s/@PRODUCT_VERSION@/${BRANDING_XC_PRODUCT_VERSION_INSTALLER}/g" \
-e "s/@COMPANY_NAME_LEGAL@/${BRANDING_COMPANY_NAME_LEGAL}/g" \
-e "s/@COMPANY_NAME_SHORT@/${BRANDING_COMPANY_NAME_SHORT}/g" \
-e "s/@BRAND_CONSOLE@/${BRANDING_BRAND_CONSOLE}/g" \
-e "s/@BRAND_CONSOLE_NO_SPACE@/${BRANDING_BRAND_CONSOLE_NO_SPACE}/g" \
-e "s/@BRAND_CONSOLE_SHORT@/${BRANDING_BRAND_CONSOLE_SHORT}/g" \
-e "s/@PRODUCT_BRAND@/${BRANDING_PRODUCT_BRAND}/g" \
${REPO}/WixInstaller/branding.wxi
#XenAdminTests
rebranding_global ${REPO}/XenAdminTests/TestResources/ContextMenuBuilderTestResults.xml
rebranding_global ${REPO}/XenAdminTests/XenAdminTests.csproj
set +u

122
scripts/rebranding.ps1 Normal file
View File

@ -0,0 +1,122 @@
# Copyright (c) Cloud Software Group, Inc.
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
# * Redistributions of source code must retain the above
# copyright notice, this list of conditions and the
# following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the
# following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
Param(
[Parameter(HelpMessage = "Global build number", Mandatory = $true)]
[int]$buildNumber
)
$verbose = $false
if ($PSBoundParameters.ContainsKey('Verbose')) {
$verbose = $PsBoundParameters['Verbose']
}
####################
# Helper functions #
####################
function version_csharp([string]$file) {
Write-Verbose "Versioning file $file" -Verbose:$verbose
(Get-Content -Path $file -Encoding "utf8") `
-replace "0.0.0.0", "$BRANDING_XC_PRODUCT_VERSION.$buildNumber" `
-replace "0000", "$BRANDING_XC_PRODUCT_VERSION.$buildNumber" |`
Set-Content -Path $file -Encoding "utf8"
}
function rebranding_global([string]$file) {
Write-Verbose "Rebranding file $file" -Verbose:$verbose
(Get-Content -Path $file -Encoding "utf8") `
-replace "\[Vendor Legal\]", $BRANDING_COMPANY_NAME_LEGAL `
-replace "\[Vendor\]", $BRANDING_COMPANY_NAME_SHORT `
-replace "\[Guest Tools\]", $BRANDING_PV_TOOLS `
-replace "\[XenServerProduct\]", $BRANDING_PRODUCT_BRAND `
-replace "\[XenServer version\]", $BRANDING_PRODUCT_VERSION_TEXT `
-replace "\[XenServer host\]", $BRANDING_SERVER `
-replace "\[XenCenter\]", $BRANDING_BRAND_CONSOLE `
-replace "xencenter/current-release/", $BRANDING_HELP_PATH `
-replace "\[Xc updates url\]", $XC_UPDATES_URL `
-replace "\[Cfu url\]", $CFU_URL `
-replace "\[YumRepoBaseBin\]", $YUM_REPO_BASE_BIN `
-replace "\[YumRepoBaseSource\]", $YUM_REPO_BASE_SRC `
-replace "\[YumRepoEarlyAccessBin\]", $YUM_REPO_EARLY_ACCESS_BIN `
-replace "\[YumRepoEarlyAccessSource\]", $YUM_REPO_EARLY_ACCESS_SRC `
-replace "\[YumRepoNormalBin\]", $YUM_REPO_NORMAL_BIN `
-replace "\[YumRepoNormalSource\]", $YUM_REPO_NORMAL_SRC |`
Set-Content -Path $file -Encoding "utf8"
}
##########################
# Rebrand solution files #
##########################
Write-Host "Started product rebranding"
$REPO = Get-Item "$PSScriptRoot\.." | Select-Object -ExpandProperty FullName
. $REPO\scripts\branding.ps1
version_csharp $REPO\CommonAssemblyInfo.cs
rebranding_global $REPO\CommonAssemblyInfo.cs
$projects = @("CFUValidator", "CommandLib", "xe", "XenAdmin", "XenAdminTests", "XenCenterLib", "XenModel", "XenOvfApi")
foreach ($project in $projects) {
$assemblyInfo = "$REPO\$project\Properties\AssemblyInfo.cs"
version_csharp $assemblyInfo
rebranding_global $assemblyInfo
}
rebranding_global $REPO\XenAdmin\XenAdmin.csproj
rebranding_global $REPO\XenAdminTests\TestResources\ContextMenuBuilderTestResults.xml
rebranding_global $REPO\XenAdminTests\XenAdminTests.csproj
#####################
# Rebrand installer #
#####################
$PRODUCT_GUID = [guid]::NewGuid().ToString()
$wxiFile="$REPO\WixInstaller\branding.wxi"
Write-Verbose "Rebranding file $wxiFile" -Verbose:$verbose
(Get-Content -Path $wxiFile -Encoding "utf8") `
-replace "@AUTOGEN_PRODUCT_GUID@", $PRODUCT_GUID `
-replace "@PRODUCT_VERSION@", $BRANDING_XC_PRODUCT_VERSION_INSTALLER `
-replace "@COMPANY_NAME_LEGAL@", $BRANDING_COMPANY_NAME_LEGAL `
-replace "@COMPANY_NAME_SHORT@", $BRANDING_COMPANY_NAME_SHORT `
-replace "@BRAND_CONSOLE@", $BRANDING_BRAND_CONSOLE `
-replace "@BRAND_CONSOLE_SHORT@", $BRANDING_BRAND_CONSOLE_SHORT `
-replace "@PRODUCT_BRAND@", $BRANDING_PRODUCT_BRAND |`
Set-Content -Path $wxiFile -Encoding "utf8"
Write-Host "Completed product rebranding"

339
scripts/xenadmin-build.ps1 Normal file
View File

@ -0,0 +1,339 @@
# Copyright (c) Cloud Software Group, Inc.
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
# * Redistributions of source code must retain the above
# copyright notice, this list of conditions and the
# following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the
# following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
Param(
[Parameter(HelpMessage = "Global build number", Mandatory = $true)]
[int]$buildNumber,
[Parameter(HelpMessage = "Thumbprint of the certificate to use for signing")]
[string]$thumbPrint,
[Parameter(HelpMessage = "Timestamp server to use for signing")]
[string]$timestampServer
)
$verbose = $false
if ($PSBoundParameters.ContainsKey('Verbose')) {
$verbose = $PsBoundParameters['Verbose']
}
$ErrorActionPreference = "Stop"
####################
# Helper functions #
####################
function mkdir_clean([string]$path) {
if ([System.IO.Directory]::Exists($path)) {
Remove-Item -Path $path -Force -Recurse -Verbose:$verbose
}
New-Item -ItemType Directory -Path $path -Verbose:$verbose
}
function build([string]$solution) {
msbuild /m /verbosity:minimal /p:Configuration=Release /p:TargetFrameworkVersion=v4.8 /p:VisualStudioVersion=17.0 $solution
}
function get_locale_id([string]$locale) {
switch ($locale) {
"ja-jp" { 1041 }
"zh-cn" { 2052 }
"zh-tw" { 1028 }
default { 1033 } #en-us
}
}
######################
# clean working area #
######################
$REPO = Get-Item "$PSScriptRoot\.." | Select-Object -ExpandProperty FullName
$SCRATCH_DIR="$REPO\_scratch"
$OUTPUT_DIR="$REPO\_output"
Write-Host "INFO: Cleaning scratch and output directories"
mkdir_clean $SCRATCH_DIR
mkdir_clean $OUTPUT_DIR
. $REPO\scripts\branding.ps1
$appName = $BRANDING_BRAND_CONSOLE
############################################
# package sources BEFORE applying branding #
############################################
Write-Host "INFO: Packaging source files"
$gitCommit = git rev-parse HEAD
git archive --format=zip -o "$SCRATCH_DIR\xenadmin-sources.zip" $gitCommit
Compress-Archive -Path "$SCRATCH_DIR\xenadmin-sources.zip","$REPO\packages\dotnet-packages-sources.zip" `
-DestinationPath "$OUTPUT_DIR\$appName-source.zip" -Verbose:$verbose
##################
# apply branding #
##################
.$REPO\scripts\rebranding.ps1 $buildNumber -Verbose:$verbose
Write-Host "INFO: Expanding External Tools"
Expand-Archive -Path $REPO\packages\XenCenterOVF.zip -DestinationPath $SCRATCH_DIR -Verbose:$verbose
Write-Host "INFO: Building solution"
build $REPO\XenAdmin.sln
##############
# sign files #
##############
if ([System.IO.File]::Exists("$REPO\scripts\sign.ps1")) {
. $REPO\scripts\sign.ps1
$filesToSign = @(
"$REPO\XenAdmin\bin\Release\CommandLib.dll",
"$REPO\XenAdmin\bin\Release\MSTSCLib.dll",
"$REPO\XenAdmin\bin\Release\CoreUtilsLib.dll",
"$REPO\XenAdmin\bin\Release\XenModel.dll",
"$REPO\XenAdmin\bin\Release\XenOvf.dll",
"$REPO\XenAdmin\bin\Release\$appName.exe",
"$REPO\xe\bin\Release\xe.exe",
"$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.Common.dll",
"$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.ProcessingObjectModel.dll",
"$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.WinForms.dll",
"$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.Common.resources.dll",
"$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.WinForms.resources.dll"
)
foreach ($file in $filesToSign) {
sign_artifact $file $appName $thumbPrint $timestampServer
}
sign_artifact $REPO\XenAdmin\bin\Release\CookComputing.XmlRpcV2.dll "XML-RPC.NET" $thumbPrint $timestampServer
sign_artifact $REPO\XenAdmin\bin\Release\Newtonsoft.Json.CH.dll "JSON.NET" $thumbPrint $timestampServer
sign_artifact $REPO\XenAdmin\bin\Release\log4net.dll "Log4Net" $thumbPrint $timestampServer
sign_artifact $REPO\XenAdmin\bin\Release\ICSharpCode.SharpZipLib.dll "SharpZipLib" $thumbPrint $timestampServer
sign_artifact $REPO\XenAdmin\bin\Release\DiscUtils.dll "DiscUtils" $thumbPrint $timestampServer
}
else {
Write-Host "INFO: Sign script does not exist; skip signing binaries"
}
###############
# prepare Wix #
###############
Write-Host "INFO: Preparing Wix binaries and UI sources"
mkdir_clean $SCRATCH_DIR\wixbin
Expand-Archive -Path $REPO\packages\wix311-binaries.zip -DestinationPath $SCRATCH_DIR\wixbin
mkdir_clean $SCRATCH_DIR\wixsrc
Expand-Archive -Path $REPO\packages\wix311-debug.zip -DestinationPath $SCRATCH_DIR\wixsrc
Copy-Item -Recurse $REPO\WixInstaller $SCRATCH_DIR -Verbose:$verbose
Copy-Item -Recurse $SCRATCH_DIR\wixsrc\src\ext\UIExtension\wixlib $SCRATCH_DIR\WixInstaller -Verbose:$verbose
Copy-Item $SCRATCH_DIR\WixInstaller\wixlib\CustomizeDlg.wxs $SCRATCH_DIR\WixInstaller\wixlib\CustomizeStdDlg.wxs -Verbose:$verbose
if ("XenCenter" -ne $appName) {
Rename-Item -Path $SCRATCH_DIR\WixInstaller\XenCenter.wxs -NewName "$appName.wxs" -Verbose:$verbose
}
$origLocation = Get-Location
Set-Location $SCRATCH_DIR\WixInstaller\wixlib -Verbose:$verbose
try {
Write-Host "INFO: Patching Wix UI library"
git apply --verbose $SCRATCH_DIR\WixInstaller\wix_src.patch
Write-Host "INFO: Patching Wix UI library completed"
}
finally {
Set-Location $origLocation -Verbose:$verbose
}
New-Item -ItemType File -Path $SCRATCH_DIR\WixInstaller\PrintEula.dll -Verbose:$verbose
###############
# compile Wix #
###############
$CANDLE="$SCRATCH_DIR\wixbin\candle.exe"
$LIT="$SCRATCH_DIR\wixbin\lit.exe"
$LIGHT="$SCRATCH_DIR\wixbin\light.exe"
$installerUiFiles = @(
"BrowseDlg",
"CancelDlg",
"Common",
"CustomizeDlg",
"CustomizeStdDlg",
"DiskCostDlg",
"ErrorDlg",
"ErrorProgressText",
"ExitDialog",
"FatalError",
"FilesInUse",
"InstallDirDlg",
"InvalidDirDlg",
"LicenseAgreementDlg",
"MaintenanceTypeDlg",
"MaintenanceWelcomeDlg",
"MsiRMFilesInUse",
"OutOfDiskDlg",
"OutOfRbDiskDlg",
"PrepareDlg",
"ProgressDlg",
"ResumeDlg",
"SetupTypeDlg",
"UserExit",
"VerifyReadyDlg",
"WaitForCostingDlg",
"WelcomeDlg",
"WixUI_InstallDir",
"WixUI_FeatureTree"
)
$candleList = $installerUiFiles | ForEach-Object { "$SCRATCH_DIR\WixInstaller\wixlib\$_.wxs" }
$candleListString = $candleList -join " "
$litList = $installerUiFiles | ForEach-Object { "$SCRATCH_DIR\WixInstaller\wixlib\$_.wixobj" }
$litListString = $litList -join " "
$env:RepoRoot=$REPO
$env:WixLangId=get_locale_id $locale
Write-Host "INFO: Compiling Wix UI"
Invoke-Expression "$CANDLE -v -out $SCRATCH_DIR\WixInstaller\wixlib\ $candleListString"
Invoke-Expression "$LIT -v -out $SCRATCH_DIR\WixInstaller\wixlib\WixUiLibrary.wixlib $litListString"
##########################################################
# for each locale create an msi containing all resources #
##########################################################
$locales = @("en-us")
foreach ($locale in $locales) {
if ($locale -eq "en-us") {
$name=$appName
}
else {
$name=$appName.$locale
}
Write-Host "INFO: Building msi installer"
Invoke-Expression "$CANDLE -v -ext WiXNetFxExtension -ext WixUtilExtension -out $SCRATCH_DIR\WixInstaller\ $SCRATCH_DIR\WixInstaller\$appName.wxs"
Invoke-Expression "$LIGHT -v -sval -ext WiXNetFxExtension -ext WixUtilExtension -out $SCRATCH_DIR\WixInstaller\$name.msi -loc $SCRATCH_DIR\WixInstaller\wixlib\wixui_$locale.wxl -loc $SCRATCH_DIR\WixInstaller\$locale.wxl $SCRATCH_DIR\WixInstaller\$appName.wixobj $SCRATCH_DIR\WixInstaller\wixlib\WixUiLibrary.wixlib"
}
########################################
# copy and sign the combined installer #
########################################
if ([System.IO.File]::Exists("$REPO\scripts\sign.ps1")) {
sign_artifact "$SCRATCH_DIR\WixInstaller\$appName.msi" $appName $thumbPrint $timestampServer
}
else {
Write-Host "INFO: Sign script does not exist; skip signing installer"
}
Copy-Item "$SCRATCH_DIR\WixInstaller\$appName.msi" $OUTPUT_DIR
###################
# build the tests #
###################
Write-Host "INFO: Building the tests"
build $REPO\XenAdminTests\XenAdminTests.csproj
Copy-Item $REPO\XenAdmin\ReportViewer\* $REPO\XenAdminTests\bin\Release\ -Verbose:$verbose
Compress-Archive -Path $REPO\XenAdminTests\bin\Release -DestinationPath $OUTPUT_DIR\XenAdminTests.zip -Verbose:$verbose
Compress-Archive -Path $REPO\XenAdmin\TestResources\* -DestinationPath "$OUTPUT_DIR\$($appName)TestResources.zip" -Verbose:$verbose
####################################################
# include cfu validator binary in output directory #
####################################################
Compress-Archive -Path $REPO\CFUValidator\bin\Release\*.dll -DestinationPath $OUTPUT_DIR\CFUValidator.zip -Verbose:$verbose
Compress-Archive -Path $REPO\CFUValidator\bin\Release\CFUValidator.exe -Update -DestinationPath $OUTPUT_DIR\CFUValidator.zip -Verbose:$verbose
Compress-Archive -Path $REPO\CFUValidator\bin\Release\$appName.exe -Update -DestinationPath $OUTPUT_DIR\CFUValidator.zip -Verbose:$verbose
####################
# package the pdbs #
####################
Compress-Archive -Path $REPO\packages\*.pdb,$REPO\XenAdmin\bin\Release\*.pdb,$REPO\xe\bin\Release\xe.pdb `
-DestinationPath "$OUTPUT_DIR\$appName.Symbols.zip" -Verbose:$verbose
################################################
# calculate installer and source zip checksums #
################################################
$msi_checksum = (Get-FileHash -Path "$OUTPUT_DIR\$appName.msi" -Algorithm SHA256 |`
Select-Object -ExpandProperty Hash).ToLower()
$msi_checksum | Out-File -FilePath "$OUTPUT_DIR\$appName.msi.checksum" -Encoding utf8
Write-Host "INFO: Calculated checksum installer checksum: $msi_checksum"
$source_checksum = (Get-FileHash -Path "$OUTPUT_DIR\$appName-source.zip" -Algorithm SHA256 |`
Select-Object -ExpandProperty Hash).ToLower()
$source_checksum | Out-File -FilePath "$OUTPUT_DIR\$appName-source.zip.checksum" -Encoding utf8
Write-Host "INFO: Calculated checksum source checksum: $source_checksum"
$xmlFormat=@"
<?xml version=\"1.0\" ?>
<patchdata>
<versions>
<version
latest="true"
latestcr="true"
name="{0}"
timestamp="{1}"
url="{2}"
checksum="{3}"
value="{4}"
/>
</versions>
</patchdata>
"@
$msi_url = $XC_UPDATES_URL -replace "XCUpdates.xml","$appName.msi"
$date=(Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
$productFullName = "$appName $productVersion"
$productVersion = "$BRANDING_XC_PRODUCT_VERSION.$buildNumber"
Write-Host "INFO: Generating XCUpdates.xml"
[string]::Format($xmlFormat, $productFullName, $date, $msi_url, $msi_checksum, $productVersion) |`
Out-File -FilePath $OUTPUT_DIR\XCUpdates.xml -Encoding utf8
Write-Host "INFO: Generating stage-test-XCUpdates.xml. URL is a placeholder value"
[string]::Format($xmlFormat, $productFullName, $date, "@DEV_MSI_URL_PLACEHOLDER@", $msi_checksum, $productVersion) |`
Out-File -FilePath $OUTPUT_DIR\stage-test-XCUpdates.xml -Encoding utf8

View File

@ -1,227 +0,0 @@
#!/bin/bash
# Copyright (c) Cloud Software Group, Inc.
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
# * Redistributions of source code must retain the above
# copyright notice, this list of conditions and the
# following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the
# following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# Script parameters:
# 1 Global build number
set -exu
UNZIP="unzip -q -o"
mkdir_clean()
{
rm -rf $1 && mkdir -p $1
}
REPO="$(cd -P "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRATCH_DIR=${REPO}/_scratch
OUTPUT_DIR=${REPO}/_output
#build
MSBUILD="/cygdrive/c/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/MSBuild.exe"
SWITCHES="/m /verbosity:minimal /p:Configuration=Release /p:TargetFrameworkVersion=v4.8 /p:VisualStudioVersion=17.0"
if [ ! -f "${MSBUILD}" ] ; then
echo "DEBUG: Did not find VS Community edition. Trying Professional"
MSBUILD="/cygdrive/c/Program Files/Microsoft Visual Studio/2022/Professional/MSBuild/Current/Bin/MSBuild.exe"
fi
if [ ! -f "${MSBUILD}" ] ; then
echo "DEBUG: Did not find VS Professional edition. Trying Enterprise"
MSBUILD="/cygdrive/c/Program Files/Microsoft Visual Studio/2022/Enterprise/MSBuild/Current/Bin/MSBuild.exe"
fi
mkdir_clean ${SCRATCH_DIR}
mkdir_clean ${OUTPUT_DIR}
source ${REPO}/Branding/branding.sh
source ${REPO}/scripts/re-branding.sh $1
#packages sources
mkdir_clean ${SCRATCH_DIR}/SOURCES
cd ${REPO}
gitCommit=`git rev-parse HEAD`
git archive --format=zip -o "_scratch/SOURCES/xenadmin-sources.zip" ${gitCommit}
cp ${REPO}/packages/dotnet-packages-sources.zip ${SCRATCH_DIR}/SOURCES
cd ${SCRATCH_DIR}/SOURCES && zip ${OUTPUT_DIR}/${BRANDING_BRAND_CONSOLE_NO_SPACE}-source.zip dotnet-packages-sources.zip xenadmin-sources.zip
${UNZIP} -d ${SCRATCH_DIR} ${REPO}/packages/XenCenterOVF.zip
cd ${REPO} && "${MSBUILD}" ${SWITCHES} XenAdmin.sln
#sign files only if all parameters are set and non-empty
SIGN_BAT="${REPO}/scripts/sign.bat"
if [ -f "${SIGN_BAT}" ] ; then
for file in ${BRANDING_BRAND_CONSOLE_NO_SPACE}.exe CommandLib.dll MSTSCLib.dll CoreUtilsLib.dll XenModel.dll XenOvf.dll
do
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} ${file} "${BRANDING_BRAND_CONSOLE}"
done
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} ${BRANDING_BRAND_CONSOLE_NO_SPACE}.exe "${BRANDING_BRAND_CONSOLE}"
cd ${REPO}/xe/bin/Release && ${SIGN_BAT} xe.exe "${BRANDING_BRAND_CONSOLE}"
for file in Microsoft.ReportViewer.Common.dll Microsoft.ReportViewer.ProcessingObjectModel.dll Microsoft.ReportViewer.WinForms.dll Microsoft.ReportViewer.Common.resources.dll Microsoft.ReportViewer.WinForms.resources.dll
do
cd ${REPO}/XenAdmin/ReportViewer && ${SIGN_BAT} ${file} "${BRANDING_BRAND_CONSOLE}"
done
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} CookComputing.XmlRpcV2.dll "XML-RPC.NET"
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} Newtonsoft.Json.CH.dll "JSON.NET"
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} log4net.dll "Log4Net"
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} ICSharpCode.SharpZipLib.dll "SharpZipLib"
cd ${REPO}/XenAdmin/bin/Release && ${SIGN_BAT} DiscUtils.dll "DiscUtils"
else
echo "Sign script does not exist; skip signing binaries"
fi
#prepare wix
WIX_BIN=${SCRATCH_DIR}/wixbin
WIX_SRC=${SCRATCH_DIR}/wixsrc
WIX=${SCRATCH_DIR}/WixInstaller
CANDLE=${WIX_BIN}/candle.exe
LIT=${WIX_BIN}/lit.exe
LIGHT=${WIX_BIN}/light.exe
mkdir_clean ${WIX_BIN} && ${UNZIP} ${REPO}/packages/wix311-binaries.zip -d ${WIX_BIN}
mkdir_clean ${WIX_SRC} && ${UNZIP} ${REPO}/packages/wix311-debug.zip -d ${WIX_SRC}
cp -r ${REPO}/WixInstaller ${SCRATCH_DIR}/
cp -r ${WIX_SRC}/src/ext/UIExtension/wixlib ${WIX}/
cd ${WIX}/wixlib && cp CustomizeDlg.wxs CustomizeStdDlg.wxs
cd ${WIX}/wixlib && patch -p1 --binary < ${WIX}/wix_src.patch
touch ${WIX}/PrintEula.dll
#compile_wix
chmod -R u+rx ${WIX_BIN}
cd ${WIX} && mkdir -p obj lib
RepoRoot=$(cygpath -w ${REPO}) ${CANDLE} -out obj/ @candleList.txt
${LIT} -out lib/WixUI_InstallDir.wixlib @litList.txt
locale_id() {
case "$1" in
"ja-jp") echo 1041 ;;
"zh-cn") echo 2052 ;;
"zh-tw") echo 1028 ;;
*) echo 1033 ;; #en-us
esac
}
if [ "XenCenter" != "${BRANDING_BRAND_CONSOLE}" ] ; then
cd ${WIX} && mv XenCenter.wxs ${BRANDING_BRAND_CONSOLE_NO_SPACE}.wxs
fi
#for each locale create an msi containing all resources
for locale in en-us
do
if [ "${locale}" = "en-us" ] ; then
name=${BRANDING_BRAND_CONSOLE_NO_SPACE}
else
name=${BRANDING_BRAND_CONSOLE_NO_SPACE}.${locale}
fi
cd ${WIX}
mkdir -p obj${name} out${name}
WixLangId=$(locale_id ${locale} | tr -d [:space:]) RepoRoot=$(cygpath -w ${REPO}) \
${CANDLE} -ext WiXNetFxExtension -ext WixUtilExtension -out obj${name}/ ${BRANDING_BRAND_CONSOLE_NO_SPACE}.wxs
${LIGHT} -sval -ext WiXNetFxExtension -ext WixUtilExtension -out out${name}/${name}.msi \
-loc wixlib/wixui_${locale}.wxl -loc ${locale}.wxl \
obj${name}/${BRANDING_BRAND_CONSOLE_NO_SPACE}.wixobj lib/WixUI_InstallDir.wixlib
cp ${WIX}/out${name}/${name}.msi ${WIX}
done
#copy and sign the combined installer
if [ -f "${SIGN_BAT}" ] ; then
cd ${WIX} && chmod a+rw ${BRANDING_BRAND_CONSOLE_NO_SPACE}.msi && ${SIGN_BAT} ${BRANDING_BRAND_CONSOLE_NO_SPACE}.msi "${BRANDING_BRAND_CONSOLE}"
else
echo "Sign script does not exist; skip signing installer"
fi
cp ${WIX}/${BRANDING_BRAND_CONSOLE_NO_SPACE}.msi ${OUTPUT_DIR}
#build the tests
echo "INFO: Build the tests..."
cd ${REPO}/XenAdminTests && "${MSBUILD}" ${SWITCHES}
cp ${REPO}/XenAdmin/ReportViewer/* ${REPO}/XenAdminTests/bin/Release/
cd ${REPO}/XenAdminTests/bin/ && zip -r ${OUTPUT_DIR}/XenAdminTests.zip Release
cd ${REPO}/XenAdmin/TestResources && zip -r ${OUTPUT_DIR}/${BRANDING_BRAND_CONSOLE_NO_SPACE}TestResources.zip *
#include cfu validator binary in output directory
cd ${REPO}/CFUValidator/bin/Release && zip ${OUTPUT_DIR}/CFUValidator.zip ./{*.dll,CFUValidator.exe,${BRANDING_BRAND_CONSOLE_NO_SPACE}.exe}
#now package the pdbs
cp ${REPO}/packages/*.pdb ${OUTPUT_DIR}
cp ${REPO}/XenAdmin/bin/Release/{CommandLib.pdb,${BRANDING_BRAND_CONSOLE_NO_SPACE}.pdb,CoreUtilsLib.pdb,${BRANDING_BRAND_CONSOLE_NO_SPACE}.pdb,XenModel.pdb,XenOvf.pdb} \
${REPO}/xe/bin/Release/xe.pdb \
${OUTPUT_DIR}
cd ${OUTPUT_DIR} && zip -r -m ${BRANDING_BRAND_CONSOLE_NO_SPACE}.Symbols.zip *.pdb
msi_checksum_with_file_name=`sha256sum ./${BRANDING_BRAND_CONSOLE_NO_SPACE}.msi`
echo $msi_checksum_with_file_name > ${OUTPUT_DIR}/${BRANDING_BRAND_CONSOLE_NO_SPACE}.msi.checksum
msi_checksum=($msi_checksum_with_file_name)
sha256sum ${OUTPUT_DIR}/${BRANDING_BRAND_CONSOLE_NO_SPACE}-source.zip > ${OUTPUT_DIR}/${BRANDING_BRAND_CONSOLE_NO_SPACE}-source.zip.checksum
echo "INFO: Generating XCUpdates.xml"
# UPDATE_URL points at the updates XML, we need to point to the MSI
msi_url="${XC_UPDATES_URL/XCUpdates.xml/$BRANDING_BRAND_CONSOLE_NO_SPACE.msi}"
output_xml="<?xml version=\"1.0\" ?>
<patchdata>
<versions>
<version
latest=\"true\"
latestcr=\"true\"
name=\"${BRANDING_BRAND_CONSOLE} ${BRANDING_XC_PRODUCT_VERSION}.${1}\"
timestamp=\"`date -u +"%Y-%m-%dT%H:%M:%SZ"`\"
url=\"${msi_url}\"
checksum=\"${msi_checksum}\"
value=\"${BRANDING_XC_PRODUCT_VERSION}.${1}\"
/>
</versions>
</patchdata>"
echo $output_xml > ${OUTPUT_DIR}/XCUpdates.xml
echo "INFO: Generating stage-test-XCUpdates.xml. URL is a placeholder value"
echo "${output_xml/"url=\"${msi_url}\""/"url=\"@DEV_MSI_URL_PLACEHOLDER@\""}" > ${OUTPUT_DIR}/stage-test-XCUpdates.xml
set +u