M(EG!Ry7mykNx^
zio=e`lqRT-%b%83fMb_ns327&5~J?S{&(NhdQ)?LRZwgU&-VcBL0KB#_n5FB#_*j)
zflpFTK48sA=`RyiOgzeJ)kvYgaZ!lKsY3VhNkS8sVn
z+sYU0lXi3|j|IFry046$Flhpd2SQ@8VmElt^z@l4+%INXK4Lk1O^$ufeQxpPQ&UHi
zH?vYEts>FivU@T{b(+F_P;J1bzf@7dV49cM)>^zAf4Ky$ha5%zRbRidw)FJdnldJFC(lZ6X#=IRP_3lg3ws1iKb1I
zV-TPYF(|ZRDJ-4dib#g)bVq423Jg)oRcIOE;cq_d!i?1{+X!Q`!v$gFEb_b{MvA*S
zodpRY%Gh6RM%-UBvkw26ZUARY*BAx!nYyq)hQnzCE80hh8_!JY+$fF^h`X_xi^Loa
zvjPp0qa)34&l+X{6y3Mn2{8V@8gfy7IY_KDY9d5qD9?F
zODcpE7~aTv5N2uRp$R(*uK*Hk5o)5ps3PF68`auU8IWNr(q7ut)CGHApRUPn}@g9qmrPd4ib
zhaEsWhM?Fwxokk2nvcjuz&Jz(%YEl{F3e3hOv3F2YG6{db9e4zShuwEJ#06sVNlma
zIbpL2AG)s>+gkwD8Mh4aQZ%$X1%NBQj$-3OCU{Yqh6*Z(z=k`g?!{^``$0_x
znu}wAxa6K&48yDmE!sXcCPVe|adVseJ5$U1TJFAx|D7*CGdjmhOcgrx{&
zu+Yh{yS4gs_9U^@x4WOMn+f`=b0Y+|yU};im_7oNi%?B{>cn9U$u{`_(KK9Tz3eyT^D;@@E!a$fpN>3z=H;fbal;;!i-jTIz3+IX-LKq@`S_sS
zCPW7K6e&1$2s$CQG#`6#+#6Me5mb5|!sqSHoR3_xsMYNANu-xO{|J0Xc{b!6C6o5a
zWZ^?SrT2IvVea1zv?9fUVuJMW1%uwbvgSbM-+AN1!(qk`77}Af`a#RWjUcDD&v9~t
zNIjD%z-?fXhfuafh4w?gF7;IEksgiUR6};jCRk0)LZ^9}yj;NJi)#BlvBGT~loWI<
zO-6X$FSwY;5wBT(2v2Sw%y9lTzQaOwn
z{)JbsHmd{fLkKQswv*-Z&=RHt-u2J&<5`*CLhyKVEUeNqr7mpGe_9Rsr3fASZ_RR!
z-X($Ci}#kvjcWR#5!Zp_Hn~l%#S}Rwg|*v$QW-llhXZN_vVNe8U3U
zz@H=9J*)M7SH}DEqdIRaUnOcg-6}Q?mpD9KDHnck=m+8k7T3ZKvZjpD4Ufqy%y==({BVcCvh+_hfI
z>GfK5-tU*~KOeYPb6?fXr{4i?r|-XZuBU6Z@;5efJ35?8zuMe4aymL5%CG))vT3tC
z>^E|L*L1aY@N(Ktf2rv>ySoQ=wITkQ`K&{G0ckC1$_>CV>|hNy5h#zZfr%ybV0vom
zAbpql(*D;rNcok2l-F$K=scyhC%vz4wFP}Ew^aT!beu7|cDyGh(RasxlWZue7@oJR
z7$7?K_SWzj>=wjgdXz1I6P!8(Kyv8_eg8(n#~^SLwYps2
zGrxLKve0qAd~qK+k6QgEsjvyf(RXBQ9oR1C;gzU4g|-Ayaagr&&BpU7PO=%J
zq;PO!l-iX!yv^8Em<6MzmGG79+tyT~mvWL73bCiO(1*>C^}ST0lHZ(=`}A%`*<%V1VZdjX{vj
zr=NrkBq4yq=S>XEPh&20TH6=15?|AtB)A=;ZsT5KZ&Cn1Nq}}RH02T64M=gIJcB%Q
zP3&`XXR>x!Co#&YI^7H_MyA2j%=Q;en6N
z?I;rdi|u6xv-gOl1A_D@y2grfLTM)UlbDOGgv@(lDbWPlodJo6%}09({f!ls=mo
zH7&B1T%E4VAkyoy7r0{t4rsRkUn5U&YcRS(s^xq7o5rJ!f2%i0$5KA%vV~ZmQ>4O)
zu6soA-7RwmK`8MB8u2A@+&fOSg@$8p@h?DzV_2NKR-Og&OuA&jow-~yR12A1^-q8os4wf&|&Z&9Q&Lb-{;_(ULl|iUzbW7Oipe)^~Md_op(%B4(mXR=Uzi#RaUI
zxDBvRNmseLqF_cLLJO2a^~@kCja8ATUl@8k0A-#UOYx?uE$5*{U-*dBt{+?6F^EV;
z;*y`frO*ZT*RqFf#{!s-nEKmOM*xyb?qqIG_KY7Vz;Jb)8t|T(G2>t3IhJmv8GzOP
zNwd779~IzyBw3AVm}p~bYp0LH{Snzd4?-Us46fRYg~o#;e-&Xyh
zy;y8@m2~32m|*E!)Wo|(0^XaT$t{5$fo(1Bg-9e37JWAsOR~4_-pZ%Ut%m<#$X(YL
zAEKH5ItrS0e6h8-T}h4m^Ok@M;GP0I-MZjx8tCCeKZS4n?GD-0V8}s;-r!3YjeYn4
zBSPgK0=-1k0_67ZVnY+}-6n_e7Oe{(uJ5nZUPIH<;J<6ZS|YZ*DDfryO|^OIM;w
zgvV;<9xEsEW?B%Ff7C+D9`?ZRwf~g^^<#uSy2i|y@YhTAj;#Y@uao&1y&sQEyXjzF
zpWj5$a@@a^#JaMexRqG$-9xEDPxo8(?!A9FWML3w-YTt5?kcG2-bHJdKE<}Vz%J`J
zgkCGj2xcb@y)R66)FqV3$!IR6ca;TH-4%yi)Ix5?TJGH+%=Jxp(l7xh^YIR;Uyca9
zwmVcBoAh+@0!#8cg?fxwYW=YVWd1NuaG-};>^-VG9T315U)4q8Yq1b^0+Ew{6P|XX
zOm??Z!xdIH2Y+^v>GS1k9IC7bNG{BAv=<#_orCA~Lc2pDomK_xq7GZFqoAI+6*1#`
zk!Lb`4sIjFPijeI4n3G3VD&0l#pQ!QFuZA|8?uwkg)=B^6@`g85!XV~=$IGk$J4^4
z^Gi4x$4;r_t*LRu=&_JsuW2ZBx3$qPfdH4%c
zjF#Hp%8pWE1b#zBn;;l_$FGDB*74xB+Kp1{cPE+7nYNRcewQ8g?IcPv6e4;nd$po(
zR5#Yp&3Z1Q9XN1C{~G_xgoIZ(S78zV6|nIbJQ%4tpv6~npKnX~>nA$N?BY}fY&g$I
zuOfIT#C?E1J~vv{cRrlXQWdO)^XMMBLS1~HBseG$Vnnq1oopbfDX2|3G3KUvoGgvf
zIVB3P?3G|G4Zq+z@_Ru}eZD3ZPis&tdVO=JK(fAss?}ReGl~i?wN2CPP~1xA?QrMwJ6N%uj?LYamr=x&h3OB$
zX2#V8pyzLS&N~atMzu{+uyFT8YEUZ;Wn)5e6sl&-B2oj~T&P7LRIsv;%LXJWBDb75
z*7yki>QG!kj#K+_BwTn>5RTc(ED6k+4aVQ@j`8pd7F_jiY9!&ET*CQ;xmiIzN^Bdp0kj?Q#A=DU!qL&
zayDYix(%W|J9&ZVfSEf^o~B=w@GN$jV^oqeXPnSgo7R<<;XW#tYfOtGO;)dgf8w!8
z_lV1qhC^gP`RN3T{{xi-uHyDN4GP6P0GkPV6nT$Plo0-2o0a;kET$$%!@(A~jyg-cexXAcJ3>Sua3^qt2>Xjv@D)_<7
zkk3Z3p^yANYQ;WJATgpXlv3VbGug=!&EX`PN*Du%X6?vqs*@~7rFdJAqtH5K*{v8l
zsdYe&0=1SOIJViJ7Y=Bb0aACBmi&87i_Om;U7uwKVS^a4gvCV)HMA&Vc}s2)g({
z2+{zo-2ymOOlP|b&d}jLGm4rc@fIyb_gaB;oMl)a+@gHNQxUVN;u?SHCK9UO2o7Xt
z^(Z-v?0Q0HTyyOEqY3W={1rni0zEODz-JK&i2%C5=nvR3x31
zesQBq9Jq+L474YjUS1lPLARC+7wgxh&PJ$)HyQb(E#WY>a<5$#O-61yD@+^W^Ro`K
zb9Q3!hU0BTul9y1&SUSJ=lPEvnK_kNG3XUNt^cGA7&
z*fU8NUKB>kWZD+C=?vmC%AZ0Ch>EIhmpra&LY;?1EP)F3%}LPmvUbp*LDdDI`c+RS
zPFL3#R3&8QFI%X%8Y5JnkgEqBrYz6i!CBgG@}TYFWAdP6O$?UwRZBcAOlO+0
z9)}uNG`TOTF4Auk)xf=_VO49}bpJ$k7Hem3&}|_an{U+~7;27zdah*cGhRpS;wi~r2FHU&
z2wKC&Uu1~FN#1cIQ08wE53w=(*iQ9P_U$?e39NJ%n`|5ba}@$9Php3ebT9+9gy#tv
zmK)4k@h|gKerWjU^cRs}K+GxqpTDh~!B%m^0qxD#M-kdhLRei^!w5{W@w(uKUd4wb
zUGJvL)t*T%3!wAnv6!-}l9kgHrtBybrOm8Hz&H0LUd)sQeKbVeZt{9m5>1aw1rMYuH=qGKKg#cEZa-PBI_E$U@UN<{;@cTwb24GJR_V#y&pwWfYHyB1SIX
zn7y3G0k0qt_-L&P(pJ9PbhL#k0JjhnKD(pD^e~PHaQ%JD0NKxXb?$|n-48SmRF(La
zfroeok3QvkB2EdGVO20T#p?YMHUg&7U@rCSk=}~mI`U>0=J}Ik)!EC$V#DgQbXNH`
z0MD>59oPp9#!OET6x2u0RN|lXMV7?T^5iwA2n(wOOc|bKP&p+>WhHyCCJ3?ynkNJ#
z+)=qMYE>H|0R$@&(F+i`UvN?gKCCSk0jrOt;l+-aG0!
z(AcmfAxk4{9wWH-LPFbmi8Tgk+f5`#)#L&fwek$CFbL&^3fpE~hcj=w>oFBt143WS
zvB-x~6#ck{1=R5UlL1}G;4>lfGm-hqRhk
za7=7zJN7aRoND7~rRTGL_r@h1{K`yy1FOv^^jC{k9E&$2`~1
zS^q)&A2KfW9|L=NgXlN#kAby=`NzTjd)}a7?*y>1H!_tova>Qbb9P~{cDA>hN>%y~
z4I8rakA^*K=&CY7xT{7WY>7bdMk1W&Ft*G}CR>+V^W(Hisy;u*sAj^l+1zrzUi(U{
ze_24Cc`#tc3|9J?hn+bW8S+SFO@>kPT0vK%mF&+jRA9;1gdmv;{C~@wFd3I^a5^SR80gK
zNLDJ5rKqBkishz@A8i)TsaJ<+mElF#q=+^NA9pH>P7jWF*B6@9B4v7r)h&{1^3a(uVpP@Y2}Sxi9*1K3)EW1eA^a*c$}W?e4HLZ
zlcm$xv~rj^%voN*5~Q5%GOo1k@=)FPgrirXKH>j({XdUdxOn>e$^Lmg2owki>;LC<
z7b7PNGZ*Kfq&{m9W~9)YkZw^;7#+l^?q2a#ZEAkY;wF#Sjv~3Oso=5j)zX`?sHGqn
zF-!Te!K0p`Cg~ABM4nm^Bo^?r=Q-t(*5DA1kWQk
zOZ#=rJCdmB7|bH9)hjuR>B&~mKXPq5gNeF^w_c6M3Xdyh2z7xMC~@zZ7LY}hbyva7Ki81|tt=4Gf0X?v=Kn4T
z|9Uo7#*B7mE*uO@j0Ow_|2_AA@#ogJbgpOr=FI+MrT>A{KsuuKb}nXiE(WTe4rb1J
z3?8;Ne-ee|2bhq=UL-gB?lH&_=#WIDI)LnEeayH~N8+O;a-~wXyX_`mBG3|wpT2+W
z_sUxyxXM7u5Rh@dG}X0%+gBkTV{-q{>OZk+Twas-wb>R&B4V!bqhGt4)
zD4CP?rLZ4uXT0d+Q(J0qL1B<7;c
z$O3H^lpSg*o}7{i{Sf+$2i49nU>`KOIQ1jJL`6$xkwe*ShWQGlOs!cQeQrw-X1^C^XyiwgNh%g
zo?P|l{l6cqM<*8th+plr`FrEy#k()^$^-ghtdwNSmt=%KjlFh-h2LRL=30hF^O-o@
zi0pQeZ&Z!wXB{AP
zMF3MaX(t~bn~iPPI>PK%KySeIup{fjwqOyVOH~Tz@iW)cQ
internal static readonly Guid ProductCodeNamespaceUuid = Guid.Parse("3B04DD8B-41C4-4DA3-9E49-4B69F11533A7");
+ ///
+ /// Static RTF text for inserting a EULA into the MSI. The license URL of the NuGet package will be embedded
+ /// as plain text since the text control used to render the MSI UI does not render hyperlinks even though RTF supports it.
+ ///
+ internal static readonly string Eula = @"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
+{\colortbl ;\red0\green0\blue255;}
+{\*\generator Riched20 10.0.19041}\viewkind4\uc1
+\pard\sa200\sl276\slmult1\f0\fs22\lang9 This software is licensed separately as set out in its accompanying license. By continuing, you also agree to that license (__LICENSE_URL__).\par
+\par
+}";
+
+ ///
+ /// An item group containing information to shorten the names of packages.
+ ///
+ public ITaskItem[] ShortNames
+ {
+ get;
+ set;
+ }
+
///
/// The set of supported target platforms for MSIs.
///
@@ -124,6 +143,9 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
sourceFiles.Add(EmbeddedTemplates.Extract("Directories.wxs", msiSourcePath));
sourceFiles.Add(EmbeddedTemplates.Extract("Product.wxs", msiSourcePath));
sourceFiles.Add(EmbeddedTemplates.Extract("Registry.wxs", msiSourcePath));
+
+ string EulaRtfPath = Path.Combine(msiSourcePath, "eula.rtf");
+ File.WriteAllText(EulaRtfPath, Eula.Replace("__LICENSE_URL__", nupkg.LicenseUrl));
EmbeddedTemplates.Extract("Variables.wxi", msiSourcePath);
// Harvest the package contents and add it to the source files we need to compile.
@@ -171,6 +193,7 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
candle.PreprocessorDefinitions.Add($@"Platform={platform}");
candle.PreprocessorDefinitions.Add($@"SourceDir={packageContentsDirectory}");
candle.PreprocessorDefinitions.Add($@"Manufacturer={manufacturer}");
+ candle.PreprocessorDefinitions.Add($@"EulaRtf={EulaRtfPath}");
// Compiler extension to process dependency provider authoring for package reference counting.
candle.Extensions.Add("WixDependencyExtension");
@@ -183,9 +206,12 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
// Link the MSI. The generated filename contains a the semantic version (excluding build metadata) and platform.
// If the source package already contains a platform, e.g. an aliased package that has a RID, then we don't add
// the platform again.
+
+ string shortPackageName = Path.GetFileNameWithoutExtension(sourcePackage).Replace(ShortNames);
+
string outputFile = sourcePackage.Contains(platform) ?
- Path.Combine(OutputPath, Path.GetFileNameWithoutExtension(sourcePackage) + ".msi") :
- Path.Combine(OutputPath, Path.GetFileNameWithoutExtension(sourcePackage) + $"-{platform}.msi");
+ Path.Combine(OutputPath, shortPackageName + ".msi") :
+ Path.Combine(OutputPath, shortPackageName + $"-{platform}.msi");
LinkToolTask light = new(BuildEngine, WixToolsetPath)
{
@@ -204,17 +230,18 @@ protected IEnumerable Generate(string sourcePackage, string swixPacka
}
TaskItem msi = new(light.OutputFile);
- msi.SetMetadata("Platform", platform);
- msi.SetMetadata("Version", nupkg.ProductVersion);
+ msi.SetMetadata(Metadata.Platform, platform);
+ msi.SetMetadata(Metadata.Version, nupkg.ProductVersion);
if (GenerateSwixAuthoring)
{
- string swixProject = GenerateSwixPackageAuthoring(light.OutputFile,
- !string.IsNullOrWhiteSpace(swixPackageId) ? swixPackageId : $"{nupkg.Id}", platform);
+ string swixProject = GenerateSwixPackageAuthoring(light.OutputFile,
+ !string.IsNullOrWhiteSpace(swixPackageId) ? swixPackageId :
+ $"{nupkg.Id.Replace(ShortNames)}.{nupkg.Version}", platform);
if (!string.IsNullOrWhiteSpace(swixProject))
{
- msi.SetMetadata("SwixProject", swixProject);
+ msi.SetMetadata(Metadata.SwixProject, swixProject);
}
}
@@ -232,10 +259,9 @@ private string GenerateSwixPackageAuthoring(string msiPath, string packageId, st
IntermediateBaseOutputPath = this.IntermediateBaseOutputPath,
PackageName = packageId,
MsiPath = msiPath,
+ BuildEngine = this.BuildEngine,
};
- swixTask.BuildEngine = BuildEngine;
-
if (!swixTask.Execute())
{
Log.LogError($"Failed to generate SWIX authoring for '{msiPath}'");
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs
index 75d0c576eb2..e1583969a02 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioMsiPackageProject.cs
@@ -4,9 +4,8 @@
using System;
using System.Collections.Generic;
using System.IO;
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
using System.Text;
+using Microsoft.Build.Framework;
namespace Microsoft.DotNet.Build.Tasks.Workloads
{
@@ -82,6 +81,15 @@ internal long InstallSize
set;
}
+ ///
+ /// The product architecture to which the package applies, the default is neutral.
+ ///
+ internal string ProductArch
+ {
+ get;
+ set;
+ } = "neutral";
+
public override bool Execute()
{
try
@@ -98,9 +106,10 @@ public override bool Execute()
string swixSourceDirectory = Path.Combine(SwixDirectory, PackageName, Chip);
string msiSwr = EmbeddedTemplates.Extract("msi.swr", swixSourceDirectory);
- string msiSwixProj = EmbeddedTemplates.Extract("msi.swixproj", swixSourceDirectory, $"{PackageName}.{Version.ToString(3)}.{Chip}.swixproj");
+ string fullProjectName = $"{PackageName}.{Version.ToString(3)}.{Chip}";
+ string msiSwixProj = EmbeddedTemplates.Extract("msi.swixproj", swixSourceDirectory, $"{Utils.GetHash(fullProjectName, "MD5")}.swixproj");
- FileInfo msiInfo = new (MsiPath);
+ FileInfo msiInfo = new(MsiPath);
PayloadSize = msiInfo.Length;
InstallSize = MsiUtils.GetInstallSize(MsiPath);
Log.LogMessage($"MSI payload size: {PayloadSize}, install size (estimated): {InstallSize} ");
@@ -127,6 +136,7 @@ private Dictionary GetReplacementTokens()
{"__VS_PACKAGE_VERSION__", Version.ToString() },
{"__VS_PACKAGE_CHIP__", Chip },
{"__VS_PACKAGE_INSTALL_SIZE_SYSTEM_DRIVE__", $"{InstallSize}"},
+ {"__VS_PACKAGE_PRODUCT_ARCH__", $"{ProductArch}" },
{"__VS_PAYLOAD_SOURCE__", MsiPath },
{"__VS_PAYLOAD_SIZE__", $"{PayloadSize}" },
};
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs
index ead8941848f..e590fdfe609 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateVisualStudioWorkload.cs
@@ -5,12 +5,11 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.NET.Sdk.WorkloadManifestReader;
-namespace Microsoft.DotNet.Build.Tasks.Workloads.src
+namespace Microsoft.DotNet.Build.Tasks.Workloads
{
///
/// MSBuild task for generating Visual Studio component projects representing
@@ -18,6 +17,70 @@ namespace Microsoft.DotNet.Build.Tasks.Workloads.src
///
public class GenerateVisualStudioWorkload : GenerateTaskBase
{
+ ///
+ /// An item group used to provide a customized title, description, and category for a specific workload ID in Visual Studio.
+ /// Workloads only define a description. Visual Studio defines a separate title (checkbox text) and description (checkbox tooltip).
+ ///
+ public ITaskItem[] ComponentResources
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The version of the component in the Visual Studio manifest. If no version is specified,
+ /// the manifest version is used.
+ ///
+ public string ComponentVersion
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Gets or sets whether MSIs for workload packs will be generated. When set to , only
+ /// Visual Studio component authoring files are generated.
+ ///
+ public bool GenerateMsis
+ {
+ get;
+ set;
+ } = true;
+
+ ///
+ /// Set of missing workload pack packages.
+ ///
+ [Output]
+ public ITaskItem[] MissingPacks
+ {
+ get;
+ set;
+ } = Array.Empty();
+
+ public string OutputPath
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// The path where the workload-pack packages referenced by the workload manifests are located.
+ ///
+ public string PackagesPath
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// An item group containing information to shorten the names of packages.
+ ///
+ public ITaskItem[] ShortNames
+ {
+ get;
+ set;
+ }
+
///
/// The workload manifest files to use for generating the Visual Studio components.
///
@@ -37,7 +100,7 @@ public ITaskItem[] WorkloadPackages
}
///
- ///
+ /// The paths of the generated .swixproj files.
///
[Output]
public ITaskItem[] SwixProjects
@@ -50,14 +113,19 @@ public override bool Execute()
{
try
{
- List swixProjects = new();
-
- foreach (ITaskItem workloadPackage in WorkloadPackages)
+ if (WorkloadManifests != null)
{
- swixProjects.AddRange(ProcessWorkloadManifest(workloadPackage.GetMetadata("FullPath")));
+ SwixProjects = GenerateSwixProjects(WorkloadManifests);
+ }
+ else if (WorkloadPackages != null)
+ {
+ SwixProjects = GenerateSwixProjects(GetManifestsFromManifestPackages(WorkloadPackages));
+ }
+ else
+ {
+ Log.LogError($"Either {nameof(WorkloadPackages)} or {nameof(WorkloadManifests)} item must be non-empty");
+ return false;
}
-
- SwixProjects = swixProjects.ToArray();
}
catch (Exception e)
{
@@ -68,13 +136,94 @@ public override bool Execute()
return !Log.HasLoggedErrors;
}
+ ITaskItem[] GenerateSwixProjects(ITaskItem[] workloadManifests)
+ {
+ List swixProjects = new();
+
+ // Generate the MSIs first to see if we have missing packs so we can remove
+ // those dependencies from the components.
+ if (GenerateMsis)
+ {
+ Log?.LogMessage(MessageImportance.Low, "Generating MSIs...");
+ // Generate MSIs for workload packs and add their .swixproj files
+ swixProjects.AddRange(GenerateMsisFromManifests(workloadManifests));
+ }
+
+ foreach (ITaskItem workloadManifest in workloadManifests)
+ {
+ swixProjects.AddRange(ProcessWorkloadManifestFile(workloadManifest.GetMetadata("FullPath")));
+ }
+
+ return swixProjects.ToArray();
+ }
+
+ internal IEnumerable GenerateMsisFromManifests(ITaskItem[] workloadManifests)
+ {
+ GenerateWorkloadMsis msiTask = new()
+ {
+ BuildEngine = this.BuildEngine,
+ GenerateSwixAuthoring = true,
+ IntermediateBaseOutputPath = this.IntermediateBaseOutputPath,
+ OutputPath = this.OutputPath,
+ PackagesPath = this.PackagesPath,
+ ShortNames = this.ShortNames,
+ WixToolsetPath = this.WixToolsetPath,
+ WorkloadManifests = workloadManifests
+ };
+
+ if (!msiTask.Execute())
+ {
+ Log?.LogError($"Failed to generate MSIs for workload packs.");
+ return Enumerable.Empty();
+ }
+ else
+ {
+ if (msiTask.MissingPacks != null)
+ {
+ MissingPacks = msiTask.MissingPacks;
+
+ foreach (ITaskItem item in MissingPacks)
+ {
+ Log?.LogWarning($"Unable to locate '{item.GetMetadata(Metadata.SourcePackage)}'. Short name: {item.GetMetadata(Metadata.ShortName)}, Platform: {item.GetMetadata(Metadata.Platform)}, Workload Pack: ({item.ItemSpec}).");
+ }
+ }
+
+ return msiTask.Msis.Select(m => new TaskItem(m.GetMetadata(Metadata.SwixProject)));
+ }
+ }
+
+ internal IEnumerable ProcessWorkloadManifestFile(string workloadManifestJsonPath)
+ {
+ WorkloadManifest manifest = WorkloadManifestReader.ReadWorkloadManifest(Path.GetFileNameWithoutExtension(workloadManifestJsonPath), File.OpenRead(workloadManifestJsonPath));
+
+ List swixProjects = new();
+
+ foreach (WorkloadDefinition workloadDefinition in manifest.Workloads.Values)
+ {
+ // Each workload maps to a Visual Studio component.
+ VisualStudioComponent component = VisualStudioComponent.Create(Log, manifest, workloadDefinition,
+ ComponentVersion, ShortNames, ComponentResources, MissingPacks);
+
+ // If there are no dependencies, regardless of whether we are generating MSIs, we'll report an
+ // error as we'd produce invalid SWIX.
+ if (!component.HasDependencies)
+ {
+ Log?.LogError($"Visual Studio components '{component.Name}' must have at least one dependency.");
+ }
+
+ swixProjects.Add(component.Generate(Path.Combine(SourceDirectory, $"{workloadDefinition.Id}.{manifest.Version}.0")));
+ }
+
+ return swixProjects;
+ }
+
///
/// Extracts the workload manifest from the manifest package and generate a SWIX project for a Visual Studio component
/// matching the manifests dependencies.
///
/// The path of the workload package containing the manifest.
/// A set of items containing the generated SWIX projects.
- internal IEnumerable ProcessWorkloadManifest(string workloadManifestPackage)
+ internal IEnumerable ProcessWorkloadManifestPackage(string workloadManifestPackage)
{
NugetPackage workloadPackage = new(workloadManifestPackage, Log);
@@ -87,17 +236,31 @@ internal IEnumerable ProcessWorkloadManifest(string workloadManifestP
throw new FileNotFoundException($"Unable to locate WorkloadManifest.json under '{packageContentPath}'.");
}
- WorkloadManifest manifest = WorkloadManifestReader.ReadWorkloadManifest(File.OpenRead(workloadManifestJsonPath));
+ return ProcessWorkloadManifestFile(workloadManifestJsonPath);
+ }
- List swixProjects = new();
-
- foreach (WorkloadDefinition workloadDefinition in manifest.Workloads.Values)
+ internal ITaskItem[] GetManifestsFromManifestPackages(ITaskItem[] workloadPackages)
+ {
+ List manifests = new();
+
+ foreach (ITaskItem item in workloadPackages)
{
- VisualStudioComponent component = VisualStudioComponent.Create(manifest, workloadDefinition);
- swixProjects.Add(component.Generate(Path.Combine(SourceDirectory, $"{workloadDefinition.Id}.{manifest.Version}.0")));
+ NugetPackage workloadPackage = new(item.GetMetadata("FullPath"), Log);
+ string packageContentPath = Path.Combine(PackageDirectory, $"{workloadPackage.Identity}");
+ workloadPackage.Extract(packageContentPath, Enumerable.Empty());
+ string workloadManifestJsonPath = Directory.GetFiles(packageContentPath, "WorkloadManifest.json").FirstOrDefault();
+
+ if (string.IsNullOrWhiteSpace(workloadManifestJsonPath))
+ {
+ throw new FileNotFoundException($"Unable to locate WorkloadManifest.json under '{packageContentPath}'.");
+ }
+
+ Log?.LogMessage(MessageImportance.Low, $"Adding manifest: {workloadManifestJsonPath}");
+
+ manifests.Add(new TaskItem(workloadManifestJsonPath));
}
- return swixProjects;
+ return manifests.ToArray();
}
}
}
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateWorkloadMsis.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateWorkloadMsis.cs
index 563a8bb9be3..375071c27fc 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateWorkloadMsis.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/GenerateWorkloadMsis.cs
@@ -28,7 +28,7 @@ public ITaskItem[] WorkloadManifests
}
///
- /// The path where the packages referenced by the manifest files are located.
+ /// The path where the workload-pack packages referenced by the manifest files are located.
///
public string PackagesPath
{
@@ -36,11 +36,22 @@ public string PackagesPath
set;
}
+ ///
+ /// Gets the set of missing workload packs.
+ ///
+ [Output]
+ public ITaskItem[] MissingPacks
+ {
+ get;
+ set;
+ }
+
public override bool Execute()
{
try
{
List msis = new();
+ List missingPacks = new();
if (string.IsNullOrWhiteSpace(PackagesPath))
{
@@ -48,18 +59,37 @@ public override bool Execute()
return false;
}
- foreach (WorkloadPack pack in GetWorkloadPacks())
+ // Each pack maps to multiple packs and different MSI packages. We considering a pack
+ // to be missing when none of its dependent MSIs were found/generated.
+ IEnumerable workloadPacks = GetWorkloadPacks();
+ List missingPackIds = new(workloadPacks.Select(p => $"{p.Id}"));
+
+ foreach (WorkloadPack pack in workloadPacks)
{
Log.LogMessage($"Processing workload pack: {pack.Id}, Version: {pack.Version}");
foreach ((string sourcePackage, string[] platforms) in GetSourcePackages(pack))
{
- // Always select the pack ID for the VS MSI package.
- msis.AddRange(Generate(sourcePackage, $"{pack.Id}", OutputPath, GetInstallDir(pack.Kind), platforms));
+ if (!File.Exists(sourcePackage))
+ {
+ Log?.LogWarning($"Workload pack package does not exist: {sourcePackage}");
+ continue;
+ }
+
+ missingPackIds.Remove(pack.Id.ToString());
+
+ // Swix package is always versioned to support upgrading SxS installs. The pack alias will be
+ // used for individual MSIs
+ string swixPackageId = $"{pack.Id.ToString().Replace(ShortNames)}.{pack.Version}";
+
+ // Always select the pack ID for the VS MSI package, even when aliased.
+ msis.AddRange(Generate(sourcePackage, swixPackageId,
+ OutputPath, GetInstallDir(pack.Kind), platforms));
}
}
Msis = msis.ToArray();
+ MissingPacks = missingPackIds.Select(p => new TaskItem(p)).ToArray();
}
catch (Exception e)
{
@@ -74,13 +104,18 @@ private IEnumerable GetWorkloadPacks()
{
// We need to track duplicate packs so we only generate MSIs once. We'll key off the pack ID and version.
IEnumerable manifests = WorkloadManifests.Select(
- w => WorkloadManifestReader.ReadWorkloadManifest(File.OpenRead(w.ItemSpec)));
+ w => WorkloadManifestReader.ReadWorkloadManifest(Path.GetFileNameWithoutExtension(w.ItemSpec), File.OpenRead(w.ItemSpec)));
return manifests.SelectMany(m => m.Packs.Values).GroupBy(x => new { x.Id, x.Version }).
Select(g => g.First());
}
- private IEnumerable<(string, string[])> GetSourcePackages(WorkloadPack pack)
+ ///
+ /// Gets the packages associated with a specific workload pack.
+ ///
+ ///
+ /// An enumerable of tuples. Each tuple contains the full path of the NuGet package and the target platforms.
+ internal IEnumerable<(string, string[])> GetSourcePackages(WorkloadPack pack)
{
if (pack.IsAlias)
{
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Metadata.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Metadata.cs
new file mode 100644
index 00000000000..ae45d44be14
--- /dev/null
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Metadata.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.DotNet.Build.Tasks.Workloads
+{
+ internal class Metadata
+ {
+ public const string AliasTo = "AliasTo";
+ public const string Category = "Category";
+ public const string Description = "Description";
+ public const string Platform = "Platform";
+ public const string Replacement = "Replacement";
+ public const string ShortName = "ShortName";
+ public const string SourcePackage = "SourcePackage";
+ public const string SwixProject = "SwixProject";
+ public const string Title = "Title";
+ public const string Version = "Version";
+ }
+}
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj
index 367c432da07..824ba35510e 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Microsoft.DotNet.Build.Tasks.Workloads.csproj
@@ -1,7 +1,7 @@
- net472
+ net472;netcoreapp3.1
true
Latest
true
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs
index 3ee2a5a7762..98d2a78515c 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiTemplate/Product.wxs
@@ -20,7 +20,7 @@
-
+
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs
index 3b017d199c6..caa99c8170c 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/MsiUtils.cs
@@ -4,10 +4,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.Deployment.WindowsInstaller.Package;
using Microsoft.Deployment.WindowsInstaller;
+using Microsoft.Deployment.WindowsInstaller.Package;
namespace Microsoft.DotNet.Build.Tasks.Workloads
{
@@ -17,10 +15,10 @@ public class MsiUtils
public static IEnumerable GetAllFiles(string packagePath)
{
- using InstallPackage ip = new InstallPackage(packagePath, DatabaseOpenMode.ReadOnly);
- using Database db = new Database(packagePath, DatabaseOpenMode.ReadOnly);
+ using InstallPackage ip = new(packagePath, DatabaseOpenMode.ReadOnly);
+ using Database db = new(packagePath, DatabaseOpenMode.ReadOnly);
using View fileView = db.OpenView(_getFilesQuery);
- List files = new List();
+ List files = new();
fileView.Execute();
foreach (Record file in fileView)
@@ -33,7 +31,7 @@ public static IEnumerable GetAllFiles(string packagePath)
public static string GetProperty(string packagePath, string property)
{
- using InstallPackage ip = new InstallPackage(packagePath, DatabaseOpenMode.ReadOnly);
+ using InstallPackage ip = new(packagePath, DatabaseOpenMode.ReadOnly);
return ip.Property[property];
}
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/NuGetPackage.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/NuGetPackage.cs
index 9a31a2afd26..a9b9c299425 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/NuGetPackage.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/NuGetPackage.cs
@@ -1,17 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System;
using System.Collections.Generic;
-using System.Linq;
using System.IO;
-using System.Text.RegularExpressions;
using System.IO.Compression;
+using System.Linq;
+using System.Text.RegularExpressions;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.Versioning;
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
namespace Microsoft.DotNet.Build.Tasks.Workloads
{
@@ -41,6 +40,11 @@ public PackageIdentity Identity
get;
}
+ public string LicenseUrl
+ {
+ get;
+ }
+
public string PackagePath
{
get;
@@ -73,6 +77,7 @@ public NugetPackage(string packagePath, TaskLoggingHelper log)
Identity = nuspecReader.GetIdentity();
Title = nuspecReader.GetTitle();
Authors = nuspecReader.GetAuthors();
+ LicenseUrl = nuspecReader.GetLicenseUrl();
}
///
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/StringExtensions.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/StringExtensions.cs
new file mode 100644
index 00000000000..a48d04655bb
--- /dev/null
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/StringExtensions.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Tasks;
+
+namespace Microsoft.DotNet.Build.Tasks.Workloads
+{
+ public static class StringExtensions
+ {
+ public static string TrimStart(this string str, string trimString)
+ {
+ return str.StartsWith(trimString) ? str.Remove(0, trimString.Length) : str;
+ }
+
+ public static string TrimStart(this string str, string trimString, StringComparison comparisonType)
+ {
+ return str.StartsWith(trimString, comparisonType) ? str.Remove(0, trimString.Length) : str;
+ }
+
+ ///
+ /// Replace multiple substrings using task items.
+ ///
+ ///
+ /// An array of task items containing substrings and replacement strings.
+ ///
+ public static string Replace(this string str, ITaskItem[] replacementStrings)
+ {
+ if ((replacementStrings is not null) && (replacementStrings.Length > 0))
+ {
+ foreach (ITaskItem item in replacementStrings)
+ {
+ str = str.Replace(item.ItemSpec, item.GetMetadata(Metadata.Replacement));
+ }
+ }
+
+ return str;
+ }
+ }
+}
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/SwixTemplate/msi.swr b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/SwixTemplate/msi.swr
index f24c2f61e52..5108da84125 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/SwixTemplate/msi.swr
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/SwixTemplate/msi.swr
@@ -3,7 +3,8 @@ use vs
package name=__VS_PACKAGE_NAME__
version=__VS_PACKAGE_VERSION__
vs.package.chip=__VS_PACKAGE_CHIP__
- vs.package.type=msi
+ vs.package.productArch=__VS_PACKAGE_PRODUCT_ARCH__
+ vs.package.type=msi
vs.installSize
SystemDrive=__VS_PACKAGE_INSTALL_SIZE_SYSTEM_DRIVE__
diff --git a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs
index 2098a162816..da7a91bf17f 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Workloads/src/VisualStudioComponent.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
@@ -33,6 +34,11 @@ public string Description
get;
}
+ ///
+ /// Gets whether this component has any dependencies.
+ ///
+ public bool HasDependencies => Dependencies.Count > 0;
+
///
/// The component name (ID).
///
@@ -41,6 +47,15 @@ public string Name
get;
}
+ ///
+ /// An item group containing information to shorten the names of packages.
+ ///
+ public ITaskItem[] ShortNames
+ {
+ get;
+ set;
+ }
+
///
/// The title of the component to display in the installer UI, e.g. the individual component tab.
///
@@ -59,12 +74,15 @@ public Version Version
private ICollection Dependencies = new List();
- public VisualStudioComponent(string name, string description, string title, Version version)
+ public VisualStudioComponent(string name, string description, string title, Version version, ITaskItem[] shortNames,
+ string category)
{
Name = name;
Description = description;
Title = title;
Version = version;
+ ShortNames = shortNames;
+ Category = category;
}
///
@@ -92,16 +110,32 @@ public void AddDependency(VisualStudioDependency dependency)
/// The dependency to add to this component.
public void AddDependency(ITaskItem dependency)
{
- AddDependency(new VisualStudioDependency(dependency.ItemSpec, new Version(dependency.GetMetadata("Version"))));
+ AddDependency(new VisualStudioDependency(dependency.ItemSpec.Replace(ShortNames), new Version(dependency.GetMetadata(Metadata.Version))));
}
///
/// Add a dependency using the specified workload pack.
///
- /// The dependency to add to this component.
- public void AddDependency(WorkloadPack dependency)
+ /// The dependency to add to this component.
+ public void AddDependency(WorkloadPack pack)
{
- AddDependency($"{dependency.Id}", new NuGetVersion(dependency.Version).Version);
+ AddDependency($"{pack.Id.ToString().Replace(ShortNames)}.{pack.Version}", new NuGetVersion(pack.Version).Version);
+ }
+
+ public IEnumerable GetAliasedDependencies(WorkloadPack pack)
+ {
+ foreach (var rid in pack.AliasTo.Keys)
+ {
+ switch (rid)
+ {
+ case "win-x86":
+ case "win-x64":
+ yield return new VisualStudioDependency($"{pack.AliasTo[rid].ToString().Replace(ShortNames)}.{pack.Version}", new NuGetVersion(pack.Version).Version);
+ break;
+ default:
+ break;
+ }
+ }
}
///
@@ -145,27 +179,53 @@ private Dictionary GetReplacementTokens()
{"__VS_PACKAGE_VERSION__", Version.ToString() },
{"__VS_COMPONENT_TITLE__", Title },
{"__VS_COMPONENT_DESCRIPTION__", Description },
- {"__VS_COMPONENT_CATEGORY__", Category }
+ {"__VS_COMPONENT_CATEGORY__", Category ?? ".NET" }
};
}
///
/// Creates a using a workload definition.
///
- ///
- ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public static VisualStudioComponent Create(WorkloadManifest manifest, WorkloadDefinition definition)
+ public static VisualStudioComponent Create(TaskLoggingHelper log, WorkloadManifest manifest, WorkloadDefinition workload, string componentVersion,
+ ITaskItem[] shortNames, ITaskItem[] componentResources, ITaskItem[] missingPacks)
{
- VisualStudioComponent package = new(Utils.ToSafeId(definition.Id.ToString()), definition.Description,
- definition.Description, new Version($"{manifest.Version}.0"));
+ log?.LogMessage("Creating Visual Studio component");
+ Version version = string.IsNullOrWhiteSpace(componentVersion) ? new Version($"{manifest.Version}.0") :
+ new Version(componentVersion);
+
+ ITaskItem resourceItem = componentResources?.Where(
+ r => string.Equals(r.ItemSpec, workload.Id.ToString(), StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
+
+ // Workload definitions do not have separate title/description fields so the only option
+ // is to default to the workload description for both.
+ string title = resourceItem?.GetMetadata(Metadata.Title) ?? workload.Description;
+ string description = resourceItem?.GetMetadata(Metadata.Description) ?? workload.Description;
+ string category = resourceItem?.GetMetadata(Metadata.Category) ?? ".NET";
+
+ VisualStudioComponent component = new(Utils.ToSafeId(workload.Id.ToString()), description,
+ title, version, shortNames, category);
+
+ IEnumerable missingPackIds = missingPacks.Select(p => p.ItemSpec);
+ log?.LogMessage(MessageImportance.Low, $"Missing packs: {string.Join(", ", missingPackIds)}");
+
+ // Visual Studio is case-insensitive.
+ IEnumerable packIds = workload.Packs.Where(p => !missingPackIds.Contains($"{p}", StringComparer.OrdinalIgnoreCase));
+ log?.LogMessage(MessageImportance.Low, $"Packs: {string.Join(", ", packIds.Select(p=>$"{p}"))}");
- foreach (WorkloadPackId packId in definition.Packs)
+ foreach (WorkloadPackId packId in packIds)
{
- package.AddDependency(manifest.Packs[packId]);
+ log?.LogMessage(MessageImportance.Low, $"Adding component dependency for {packId} ");
+ component.AddDependency(manifest.Packs[packId]);
}
- return package;
+ return component;
}
}
}
From 08e48f6beab7b5286b281b7924fcc891b7450500 Mon Sep 17 00:00:00 2001
From: Matt Mitchell
Date: Thu, 6 May 2021 12:44:34 -0700
Subject: [PATCH 063/699] Fix positional parameter issue in symbols-validation
(#7354)
I added a parameter for WindowsPdbVerification to the code block, but then called the code block with the parameter in the wrong place.
I am very sorry and won't do it again.
Verified that the script works as expected now.
---
eng/common/post-build/symbols-validation.ps1 | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1
index 788321d773d..f26f6de81f0 100644
--- a/eng/common/post-build/symbols-validation.ps1
+++ b/eng/common/post-build/symbols-validation.ps1
@@ -114,6 +114,7 @@ $CountMissingSymbols = {
$totalRetries = 0
while ($totalRetries -lt $using:MaxRetry) {
+
# Save the output and get diagnostic output
$output = & $dotnetSymbolExe --symbols --modules $WindowsPdbVerificationParam $TargetServerParam $FullPath -o $SymbolsPath --diagnostics | Out-String
@@ -144,8 +145,16 @@ $CountMissingSymbols = {
return $null
}
- $SymbolsOnMSDL = & $FirstMatchingSymbolDescriptionOrDefault $FileName '--microsoft-symbol-server' $SymbolsPath $WindowsPdbVerificationParam
- $SymbolsOnSymWeb = & $FirstMatchingSymbolDescriptionOrDefault $FileName '--internal-server' $SymbolsPath $WindowsPdbVerificationParam
+ $SymbolsOnMSDL = & $FirstMatchingSymbolDescriptionOrDefault `
+ -FullPath $FileName `
+ -TargetServerParam '--microsoft-symbol-server' `
+ -SymbolsPath $SymbolsPath `
+ -WindowsPdbVerificationParam $WindowsPdbVerificationParam
+ $SymbolsOnSymWeb = & $FirstMatchingSymbolDescriptionOrDefault `
+ -FullPath $FileName `
+ -TargetServerParam '--internal-server' `
+ -SymbolsPath $SymbolsPath `
+ -WindowsPdbVerificationParam $WindowsPdbVerificationParam
Write-Host -NoNewLine "`t Checking file " $FileName "... "
From 3094203c203fdbd77c2ba43578a1a8f92e1b467d Mon Sep 17 00:00:00 2001
From: Jeremy Koritzinsky
Date: Thu, 6 May 2021 14:14:22 -0700
Subject: [PATCH 064/699] Limit the version range for the VS generator to
versions that CMake currently understands. (#7342)
---
.../build/Microsoft.DotNet.CMake.Sdk.targets | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/Microsoft.DotNet.CMake.Sdk/build/Microsoft.DotNet.CMake.Sdk.targets b/src/Microsoft.DotNet.CMake.Sdk/build/Microsoft.DotNet.CMake.Sdk.targets
index f8b6cc87f79..89299a0672d 100644
--- a/src/Microsoft.DotNet.CMake.Sdk/build/Microsoft.DotNet.CMake.Sdk.targets
+++ b/src/Microsoft.DotNet.CMake.Sdk/build/Microsoft.DotNet.CMake.Sdk.targets
@@ -30,6 +30,8 @@
<_CMakeMultiConfigurationGenerator>true
<_CMakePassArchitectureToGenerator>true
+
+ [,17.0)
Win32
@@ -37,7 +39,7 @@
From f1e67a4d97c955a1f6ff2e5e609e49faa953f516 Mon Sep 17 00:00:00 2001
From: Epsitha Ananth <47157394+epananth@users.noreply.github.com>
Date: Thu, 6 May 2021 14:30:09 -0700
Subject: [PATCH 065/699] Upped timeout and added logs for downloading and
publishing operation (#7351)
* increased http timeout and added more logging around download and publishing operations
---
.../src/PublishArtifactsInManifestBase.cs | 37 +++++++++++++++++--
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs b/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs
index fed9ab0bdee..7fbd6aebb18 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
@@ -191,7 +192,7 @@ private enum ArtifactName
BlobArtifacts
}
- private int TimeoutInSeconds = 180;
+ private int TimeoutInSeconds = 300;
public override bool Execute()
{
@@ -418,6 +419,7 @@ public async Task PublishSymbolsUsingStreamingAsync(
{
using (HttpClient client = CreateAzdoClient(AzureDevOpsOrg, true))
{
+ client.Timeout = TimeSpan.FromSeconds(TimeoutInSeconds);
await Task.WhenAll(symbolsToPublish.Select(async symbol =>
{
try
@@ -427,13 +429,18 @@ await Task.WhenAll(symbolsToPublish.Select(async symbol =>
string localSymbolPath = Path.Combine(temporarySymbolsDirectory, symbol);
symbolLog.AppendLine($"Downloading symbol : {symbol} to {localSymbolPath}");
+ Stopwatch gatherDownloadTime = Stopwatch.StartNew();
await DownloadFileAsync(
client,
ArtifactName.BlobArtifacts,
containerId,
symbol,
localSymbolPath);
+
+ gatherDownloadTime.Stop();
+ symbolLog.AppendLine($"Time taken to download file to '{localSymbolPath}' is {gatherDownloadTime.ElapsedMilliseconds / 1000.0} (seconds)");
symbolLog.AppendLine($"Successfully downloaded symbol : {symbol} to {localSymbolPath}");
+
List symbolFiles = new List();
symbolFiles.Add(localSymbolPath);
symbolLog.AppendLine($"Uploading symbol file '{string.Join(",", symbolFiles)}'");
@@ -443,6 +450,7 @@ await DownloadFileAsync(
var serverPath = server.Key;
var token = server.Value;
symbolLog.AppendLine($"Publishing symbol file {symbol} to {serverPath}:");
+ Stopwatch gatherSymbolPublishingTime = Stopwatch.StartNew();
try
{
@@ -465,6 +473,10 @@ await PublishSymbolsHelper.PublishAsync(
{
Log.LogError(ex.Message);
}
+
+ gatherSymbolPublishingTime.Stop();
+ symbolLog.AppendLine(
+ $"Symbol publishing for {symbol} took {gatherSymbolPublishingTime.ElapsedMilliseconds / 1000.0} (seconds)");
}
DeleteTemporaryDirectory(temporarySymbolsDirectory);
@@ -1148,6 +1160,7 @@ await Task.WhenAll(packagesToPublish.Select(async package =>
Log.LogMessage(MessageImportance.Low,
$"Downloading package : {packageFilename} to {localPackagePath}");
+ Stopwatch gatherPackageDownloadTime = Stopwatch.StartNew();
await DownloadFileAsync(
client,
ArtifactName.PackageArtifacts,
@@ -1162,6 +1175,8 @@ await DownloadFileAsync(
return;
}
+ gatherPackageDownloadTime.Stop();
+ Log.LogMessage(MessageImportance.Low, $"Time taken to download file to '{localPackagePath}' is {gatherPackageDownloadTime.ElapsedMilliseconds / 1000.0} (seconds)");
Log.LogMessage(MessageImportance.Low,
$"Successfully downloaded package : {packageFilename} to {localPackagePath}");
@@ -1183,7 +1198,10 @@ await DownloadFileAsync(
Convert.ToBase64String(
Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "", feedConfig.Token))));
+ Stopwatch gatherPackagePublishingTime = Stopwatch.StartNew();
await PushPackageToNugetFeed(httpClient, feedConfig, localPackagePath, package.Id, package.Version);
+ gatherPackagePublishingTime.Stop();
+ Log.LogMessage(MessageImportance.Low,$"Publishing package {localPackagePath} took {gatherPackagePublishingTime.ElapsedMilliseconds / 1000.0} (seconds)");
DeleteTemporaryDirectory(localPackagePath);
}
@@ -1243,7 +1261,7 @@ public async Task PushNugetPackagesAsync(
using (HttpClient httpClient = new HttpClient(new HttpClientHandler
{CheckCertificateRevocationList = true}))
{
- httpClient.Timeout = TimeSpan.FromSeconds(180);
+ httpClient.Timeout = TimeSpan.FromSeconds(TimeoutInSeconds);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "", feedConfig.Token))));
@@ -1500,6 +1518,7 @@ await Task.WhenAll(blobsToPublish.Select(async blob =>
string localBlobPath = Path.Combine(temporaryBlobDirectory, fileName);
Log.LogMessage(MessageImportance.Low, $"Downloading blob : {fileName} to {localBlobPath}");
+ Stopwatch gatherBlobDownloadTime = Stopwatch.StartNew();
await DownloadFileAsync(
client,
ArtifactName.BlobArtifacts,
@@ -1511,6 +1530,8 @@ await DownloadFileAsync(
{
Log.LogError($"Could not locate '{blob.Id} at '{localBlobPath}'");
}
+ gatherBlobDownloadTime.Stop();
+ Log.LogMessage(MessageImportance.Low, $"Time taken to download file to '{localBlobPath}' is {gatherBlobDownloadTime.ElapsedMilliseconds / 1000.0} (seconds)");
Log.LogMessage(MessageImportance.Low,
$"Successfully downloaded blob : {fileName} to {localBlobPath}");
@@ -1524,11 +1545,14 @@ await DownloadFileAsync(
version = packageIdentity.Version.ToString();
}
+ Stopwatch gatherBlobPublishingTime = Stopwatch.StartNew();
await PushBlobToNugetFeed(
feedConfig,
localBlobPath,
id,
version);
+ gatherBlobPublishingTime.Stop();
+ Log.LogMessage(MessageImportance.Low, $"Time taken to publish blob {localBlobPath} is {gatherBlobPublishingTime.ElapsedMilliseconds / 1000.0} (seconds)");
DeleteTemporaryDirectory(temporaryBlobDirectory);
}
@@ -1556,7 +1580,7 @@ private async Task PushBlobToNugetFeed(TargetFeedConfig feedConfig, string local
using HttpClient httpClient = new HttpClient(new HttpClientHandler
{CheckCertificateRevocationList = true});
- httpClient.Timeout = TimeSpan.FromSeconds(180);
+ httpClient.Timeout = TimeSpan.FromSeconds(TimeoutInSeconds);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(
@@ -1656,6 +1680,7 @@ await Task.WhenAll(blobsToPublish.Select(async blob =>
var localBlobPath = Path.Combine(temporaryBlobDirectory, fileName);
Log.LogMessage(MessageImportance.Low, $"Downloading blob : {fileName} to {localBlobPath}");
+ Stopwatch gatherBlobDownloadTime = Stopwatch.StartNew();
await DownloadFileAsync(
client,
ArtifactName.BlobArtifacts,
@@ -1667,6 +1692,8 @@ await DownloadFileAsync(
{
Log.LogError($"Could not locate '{blob.Id} at '{localBlobPath}'");
}
+ gatherBlobDownloadTime.Stop();
+ Log.LogMessage(MessageImportance.Low, $"Time taken to download file to '{localBlobPath}' is {gatherBlobDownloadTime.ElapsedMilliseconds / 1000.0} (seconds)");
Log.LogMessage(MessageImportance.Low,
$"Successfully downloaded blob : {fileName} to {localBlobPath}");
@@ -1684,7 +1711,11 @@ await DownloadFileAsync(
feedConfig,
AddAssetLocationToAssetAssetLocationType.Container);
+ Stopwatch gatherBlobPublishingTime = Stopwatch.StartNew();
await blobFeedAction.UploadAssetAsync(item, pushOptions, null);
+ gatherBlobPublishingTime.Stop();
+ Log.LogMessage(MessageImportance.Low,$"Publishing {item.ItemSpec} completed in {gatherBlobPublishingTime.ElapsedMilliseconds / 1000.0} (seconds)");
+
DeleteTemporaryDirectory(temporaryBlobDirectory);
}
finally
From 54518f24e4ea05ab97d259d5af9d57467879579d Mon Sep 17 00:00:00 2001
From: Michelle McDaniel
Date: Thu, 6 May 2021 15:23:40 -0700
Subject: [PATCH 066/699] Add public symbols feed override option (#7355)
* Allow for the override of the public feed for symbols
Symbols nupkg feeds were either the static symbols feed provided if a build was internal, or the legacy feed otherwise. We need to be able to also override the public feed in post-signing publishing. This adds the ability to override in the public case.
---
.../tools/SdkTasks/PublishArtifactsInManifest.proj | 1 +
.../src/PublishArtifactsInManifest.cs | 3 +++
.../src/PublishArtifactsInManifestV3.cs | 3 +++
.../src/model/SetupTargetFeedConfigV3.cs | 10 ++++++++++
4 files changed, 17 insertions(+)
diff --git a/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj b/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj
index 28d23ef95c2..fa4778f6aea 100644
--- a/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj
+++ b/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj
@@ -154,6 +154,7 @@
TransportFeedOverride="$(TransportFeedOverride)"
ShippingFeedOverride="$(ShippingFeedOverride)"
SymbolsFeedOverride="$(SymbolsFeedOverride)"
+ PublicSymbolsFeedOverride="$(PublicSymbolsFeedOverride)"
AzdoApiToken="$(AzdoApiToken)"
ArtifactsBasePath="$(ArtifactsBasePath)"
BuildId="$(BuildId)"
diff --git a/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs b/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs
index ee706c1efc0..0cdbd667c59 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs
@@ -129,6 +129,8 @@ public class PublishArtifactsInManifest : MSBuildTaskBase
public string SymbolsFeedOverride { get; set; }
+ public string PublicSymbolsFeedOverride { get; set; }
+
///
/// Path to dll and pdb files
///
@@ -381,6 +383,7 @@ internal PublishArtifactsInManifestBase ConstructPublishingV3Task(BuildModel bui
ShippingFeedOverride = this.ShippingFeedOverride,
TransportFeedOverride = this.TransportFeedOverride,
SymbolsFeedOverride = this.SymbolsFeedOverride,
+ PublicSymbolsFeedOverride = this.PublicSymbolsFeedOverride,
ArtifactsBasePath = this.ArtifactsBasePath,
AzdoApiToken = this.AzdoApiToken,
BuildId = this.BuildId,
diff --git a/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs b/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs
index c9f2e7a0610..1f8f61d3f2c 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs
@@ -64,6 +64,8 @@ public class PublishArtifactsInManifestV3 : PublishArtifactsInManifestBase
public string SymbolsFeedOverride { get; set; }
+ public string PublicSymbolsFeedOverride { get; set; }
+
public override bool Execute()
{
ExecuteAsync().GetAwaiter().GetResult();
@@ -160,6 +162,7 @@ public override async Task ExecuteAsync()
AzureDevOpsFeedsKey,
BuildEngine = this.BuildEngine,
targetChannelConfig.SymbolTargetType,
+ azureDevOpsPublicStaticSymbolsFeed: GetFeed(null, PublicSymbolsFeedOverride),
filesToExclude: targetChannelConfig.FilenamesToExclude,
flatten: targetChannelConfig.Flatten);
diff --git a/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/SetupTargetFeedConfigV3.cs b/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/SetupTargetFeedConfigV3.cs
index 58eb22fb996..b98e91740c4 100644
--- a/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/SetupTargetFeedConfigV3.cs
+++ b/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/SetupTargetFeedConfigV3.cs
@@ -29,6 +29,8 @@ public class SetupTargetFeedConfigV3 : SetupTargetFeedConfigBase
private string StableSymbolsFeed { get; set; }
+ private string AzureDevOpsPublicStaticSymbolsFeed { get; set; }
+
private SymbolTargetType SymbolTargetType { get; set; }
private List FilesToExclude { get; }
@@ -54,6 +56,7 @@ public SetupTargetFeedConfigV3(bool isInternalBuild,
SymbolTargetType symbolTargetType,
string stablePackagesFeed = null,
string stableSymbolsFeed = null,
+ string azureDevOpsPublicStaticSymbolsFeed = null,
List filesToExclude = null,
bool flatten = true)
: base(isInternalBuild, isStableBuild, repositoryName, commitSha, azureStorageTargetFeedPAT, publishInstallersAndChecksums, installersTargetStaticFeed, installersAzureAccountKey, checksumsTargetStaticFeed, checksumsAzureAccountKey, azureDevOpsStaticShippingFeed, azureDevOpsStaticTransportFeed, azureDevOpsStaticSymbolsFeed, latestLinkShortUrlPrefix, azureDevOpsFeedsKey)
@@ -62,6 +65,7 @@ public SetupTargetFeedConfigV3(bool isInternalBuild,
StableSymbolsFeed = stableSymbolsFeed;
StablePackagesFeed = stablePackagesFeed;
SymbolTargetType = symbolTargetType;
+ AzureDevOpsPublicStaticSymbolsFeed = azureDevOpsPublicStaticSymbolsFeed;
FilesToExclude = filesToExclude ?? new List();
Flatten = flatten;
}
@@ -159,6 +163,12 @@ private List NonStableFeeds()
symbolsFeedType = FeedType.AzDoNugetFeed;
symbolsFeedSecret = AzureDevOpsFeedsKey;
}
+ else if (!string.IsNullOrEmpty(AzureDevOpsPublicStaticSymbolsFeed))
+ {
+ symbolsFeed = AzureDevOpsPublicStaticSymbolsFeed;
+ symbolsFeedType = FeedType.AzDoNugetFeed;
+ symbolsFeedSecret = AzureDevOpsFeedsKey;
+ }
else
{
symbolsFeed = PublishingConstants.LegacyDotNetBlobFeedURL;
From f9ce6058792211e652243db3b07fa511cf83486b Mon Sep 17 00:00:00 2001
From: Matt Mitchell
Date: Thu, 6 May 2021 16:15:47 -0700
Subject: [PATCH 067/699] Add the ability to use the .NET certificate with a
switch (#7347)
* Add the ability to use the .NET certificate with a switch
A subset of arcade repositories will ship .NET 6 using a different certificate for most executable files. This leads to a question: How to specify that this cert should be used rather than Microsoft400? There are a number of options:
1. Use certificate replacement in post-build signing to switch all uses of Microsoft400 to MicrosoftDotNet500 - This has the disadvantage that if there are any binaries that still need to ship to end-customers with Microsoft400, they would get the new cert. It's also a little hacky, and certificate replacement was only intended for limited use by internal customers in specific scenarios.
2. Update default metadata in each repo that needs to switch to specify MicrosoftDotNet500 instead of Microsoft400 - This is easy to do for explicit specifications in a repo's eng/Signing.props file, but the arcade defaults are still present. They can be replaced with something like:
```
```
However, this bit of code isn't entirely easy to understand, would have to be inserted into every repo.
3. Change the arcade default to MicrosoftDotNet500 - This has wide-ranging implications for repos that we don't want to change, at least not now. I think this will eventually be an option, but is too risky with too many unknowns right now.
4. Introduce a new property `UseDotNetCertificate` which can be set in eng/Signing.props. This causes all existing use of Microsoft400 in the repo to switch to MicrosoftDotNet500. This is the preferable for repos repos that use arcade defaults for most things (use Sign.proj and Publish.proj). The certificate metadata update happens prior to signing or encoding of the signing metadata in the manifests.
Repos should use a combination of 4 and 2 for now to update to the .NET cert
---
Documentation/CorePackages/Signing.md | 24 +++++++++++++++++++
.../tools/Publish.proj | 10 ++++++++
.../tools/Sign.proj | 10 ++++++++
.../tools/Sign.props | 8 +++++++
4 files changed, 52 insertions(+)
diff --git a/Documentation/CorePackages/Signing.md b/Documentation/CorePackages/Signing.md
index d65de76c097..f2e8f96cdb5 100644
--- a/Documentation/CorePackages/Signing.md
+++ b/Documentation/CorePackages/Signing.md
@@ -223,6 +223,30 @@ Click [here](../../src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj) to see how t
...
```
+#### 8. How can I use the .NET specific certificate for executable files?
+
+By default, `Microsoft400` is the cert used by default for most executable files (e.g .dll, .js, .exe). To use the .NET specific cert (`MicrosoftDotNet500`),
+use one of the following approaches:
+
+1. Update the existing `FileExtensionSignInfo` and `StrongNameSignInfo` metadata in [Sign.props](../../src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props)
+to use `MicrosoftDotNet500`. This approach must be used if some files still need to be signed with `Microsoft400`.
+ ```
+
+
+
+
+
+
+
+
+ ```
+2. Specify the property `UseDotNetCertificate` with value `true` in your `eng/Signing.props` file. This **replaces** all existing use of `Microsoft400` with `MicrosoftDotNet500`.
+ ```
+
+ f
+
+ ```
+
## Logs & MicroBuild configuration files
The log messages from the SignToolTask itself will be included in the log (+.binlog) of the original build process. The binary log of executing the MicroBuild signing plugin will be stored in files named `SigningX.binlog` in the `LogDir` folder. The project files used to call the MicroBuild plugin will be stored in files named `RoundX.proj` in the `TempDir` folder. In both cases the `X` in the name refers to a signing round.
diff --git a/src/Microsoft.DotNet.Arcade.Sdk/tools/Publish.proj b/src/Microsoft.DotNet.Arcade.Sdk/tools/Publish.proj
index 558205ec53f..ae754b76748 100644
--- a/src/Microsoft.DotNet.Arcade.Sdk/tools/Publish.proj
+++ b/src/Microsoft.DotNet.Arcade.Sdk/tools/Publish.proj
@@ -264,6 +264,16 @@
+
+
+
+
+
+
+
diff --git a/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj b/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
index 399d129ea5d..8bd296befef 100644
--- a/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
+++ b/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
@@ -6,6 +6,16 @@
+
+
+
+
+
+
+
diff --git a/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props b/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props
index d545816a66e..908cb7a9000 100644
--- a/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props
+++ b/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props
@@ -43,6 +43,14 @@
+
+
+ MicrosoftDotNet500
+ false
+
+
+
true
@@ -45,7 +45,7 @@ There are some required configuration properties that need to be set for XHarnes
-
+
```
@@ -123,7 +123,7 @@ The Helix machines, that have devices attached to them, already contain the sign
When using the Helix SDK and targeting real devices:
- You have to ideally supply a non-signed app bundle - the app will be signed for you on the Helix machine where your job gets executed
- Only the basic set of app permissions are supported at the moment and we cannot re-sign an app that was already signed with a different set of permissions
-- Bundle id has to start with `net.dot.` since we only support those application IDs at the moment
+- App bundle identifier has to start with `net.dot.` since we only support those application IDs at the moment
### Android .apk payloads
diff --git a/src/Microsoft.DotNet.Helix/Sdk/tools/xharness-runner/XHarnessRunner.targets b/src/Microsoft.DotNet.Helix/Sdk/tools/xharness-runner/XHarnessRunner.targets
index cd38f7766b3..d96450e5f79 100644
--- a/src/Microsoft.DotNet.Helix/Sdk/tools/xharness-runner/XHarnessRunner.targets
+++ b/src/Microsoft.DotNet.Helix/Sdk/tools/xharness-runner/XHarnessRunner.targets
@@ -103,7 +103,6 @@
Condition=" '@(XHarnessAppBundleToTest)' != '' "
BeforeTargets="CoreTest">
From 1c6a2d9bb8d111720e69b133bf630a38bb136509 Mon Sep 17 00:00:00 2001
From: "dotnet-maestro[bot]"
<42748379+dotnet-maestro[bot]@users.noreply.github.com>
Date: Tue, 11 May 2021 13:26:10 +0000
Subject: [PATCH 075/699] Update dependencies from
https://github.com/dotnet/arcade build 20210510.1 (#7366)
[main] Update dependencies from dotnet/arcade
---
eng/Version.Details.xml | 20 ++++++++++----------
eng/Versions.props | 6 +++---
global.json | 4 ++--
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 5921ac2eb56..ccafc631ffb 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -11,25 +11,25 @@