diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 1db426b3f1f0ee..3a40a31c8c10d3 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -27,7 +27,7 @@
]
},
"microsoft.dotnet.helix.jobmonitor": {
- "version": "11.0.0-beta.26465.108",
+ "version": "11.0.0-beta.26514.117",
"commands": [
"dotnet-helix-job-monitor"
]
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 193a0cd7065bd9..ea235b6827b289 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -54,7 +54,7 @@
Microsoft%AE .NET
$(ProductVersion)
- $(ProductVersion)
+ $(ProductVersion)
$(ProductVersion)-$(VersionSuffix)
diff --git a/NuGet.config b/NuGet.config
index 5e7e33e4a5838b..247481d71b580c 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -7,6 +7,11 @@
+
+
+
+
+
- 5.12.0-1.26465.108
- 5.12.0-1.26465.108
- 5.12.0-1.26465.108
- 5.12.0-1.26465.108
- 11.0.100-rc.2.26465.108
- 11.0.100-rc.2.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 0.11.5-preview.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
- 11.0.0-beta.26465.108
+ 5.12.0-1.26514.117
+ 5.12.0-1.26514.117
+ 5.12.0-1.26514.117
+ 5.12.0-1.26514.117
+ 11.0.100
+ 11.0.100
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 0.11.5-preview.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
+ 11.0.0-beta.26514.117
3.2.2-beta.26257.113
- 2.9.3-beta.26465.108
- 11.0.0-beta.26465.108
- 5.12.0-1.26465.108
- 11.0.0-rc.2.26465.108
- 11.0.0-rc.2.26465.108
- 11.0.100-rc.2.26465.108
- 11.0.0-rc.2.26465.108
- 11.0.0-rc.2.26465.108
- 7.12.0-rc.46608
- 7.12.0-rc.46608
- 7.12.0-rc.46608
- 7.12.0-rc.46608
- 11.0.0-rc.2.26465.108
- 3.0.0-rc.2.26465.108
- 11.0.0-rc.2.26465.108
- 11.0.0-rc.2.26465.108
- 11.0.0-rc.2.26465.108
+ 2.9.3-beta.26514.117
+ 11.0.0-beta.26514.117
+ 5.12.0-1.26514.117
+ 11.0.0
+ 11.0.0
+ 11.0.100-rtm.26514.117
+ 11.0.0
+ 11.0.0
+ 8.0.0-rc.51617
+ 8.0.0-rc.51617
+ 8.0.0-rc.51617
+ 8.0.0-rc.51617
+ 11.0.0
+ 3.0.0
+ 11.0.0
+ 11.0.0
+ 11.0.0
11.0.0-alpha.0.26180.1
11.0.0-alpha.1.26505.3
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
- 23.1.0-alpha.1.26457.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
+ 23.1.0-alpha.1.26468.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
- 11.0.0-alpha.1.26459.1
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
+ 11.0.0-alpha.1.26471.2
1.0.0-prerelease.26502.1
1.0.0-prerelease.26502.1
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 3dc78e1c28097f..643993fe2efc2c 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,131 +1,131 @@
-
+
https://github.com/dotnet/icu
bbfd5321d1c6897f0b38581e45ba4e8d370d62a3
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
https://github.com/dotnet/dotnet
0eae08ed2f094f44e0151e4815e7cdd1a334fcdf
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
https://github.com/dotnet/runtime-assets
@@ -179,117 +179,117 @@
https://github.com/dotnet/runtime-assets
60aef74b20edf24857020e0b7baeab78233c1196
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/llvm-project
- d9efae02c571d39f4e2a50971af239603c37b0d0
+ 9b4b2ced86ff8333327b17c453433c7472f28db0
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
https://github.com/dotnet/xharness
@@ -303,9 +303,9 @@
https://github.com/dotnet/xharness
91708f0daf7d7ffc3b5d61da591c3e598c1d600e
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -331,33 +331,33 @@
https://github.com/dotnet/runtime-assets
60aef74b20edf24857020e0b7baeab78233c1196
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
https://dev.azure.com/dnceng/internal/_git/dotnet-optimization
@@ -369,53 +369,53 @@
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
-
+
https://github.com/dotnet/node
- 4ae8e1c1d08d09e5025db77e22a832051c56fd28
+ e41b6e9b7c487a5d6f1c9965d61f3bbf503e6e55
https://github.com/dotnet/runtime-assets
@@ -425,9 +425,9 @@
https://github.com/dotnet/runtime-assets
60aef74b20edf24857020e0b7baeab78233c1196
-
+
https://github.com/dotnet/dotnet
- e5abd3f0528a8467c64a855a6ff569566d0daf27
+ a586537b3872e4e2f69c0b1ce7017a97bc3bcd55
diff --git a/eng/Versions.props b/eng/Versions.props
index fd39d847487526..5a7e7c53a61585 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -14,8 +14,8 @@
8.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet9)').Build),11))
7.0.20
6.0.36
- rc
- 2
+ rtm
+
false
release
diff --git a/eng/common/Get-GitHubAppToken.ps1 b/eng/common/Get-GitHubAppToken.ps1
index ea776bd6bc28a8..ec005e487c38e2 100644
--- a/eng/common/Get-GitHubAppToken.ps1
+++ b/eng/common/Get-GitHubAppToken.ps1
@@ -1,13 +1,11 @@
# Mints a short-lived GitHub App installation access token by signing a JWT
-# with a private key stored in Azure Key Vault (RSA, RS256). The signed JWT is
-# exchanged with the GitHub API for a token scoped to a single installation.
+# with an RSA private key (RS256). The signed JWT is exchanged with the GitHub
+# API for a token scoped to a single installation.
#
# Requirements:
-# - A GitHub App whose private key has been uploaded into Key Vault as an RSA
-# key (the PEM converted to a Key Vault *key*, NOT stored as a secret).
-# - The caller (the federated Azure service connection used to run this script)
-# must have the `Key Vault Crypto User` role (or at minimum the `Sign`
-# action) on that key.
+# - A GitHub App ID and PEM private key stored as Azure Key Vault secrets.
+# - The federated Azure service connection running this script must have
+# `Get` access to those two secrets.
# - The App must be installed on the target organization/account
# (`InstallationOwner`) with the permissions/repositories it needs.
#
@@ -16,17 +14,17 @@
[CmdletBinding()]
param(
- # Name of the Key Vault that holds the GitHub App's RSA signing key.
+ # Name of the Key Vault holding the GitHub App credentials.
[Parameter(Mandatory = $true)]
[string] $KeyVaultName,
- # Name of the RSA key inside the Key Vault (the App's private key).
+ # Secret Manager projection containing the GitHub App ID.
[Parameter(Mandatory = $true)]
- [string] $KeyName,
+ [string] $AppIdSecretName,
- # The GitHub App's Client ID (the value to put in the `iss` JWT claim).
+ # Secret Manager projection containing the PEM private key.
[Parameter(Mandatory = $true)]
- [string] $AppClientId,
+ [string] $AppPrivateKeySecretName,
# Login of the organization or user account whose installation we should
# mint the token for (e.g. `dotnet`, `microsoft`).
@@ -39,16 +37,69 @@ param(
[Parameter(Mandatory = $false)]
[string] $OutputVariableName
)
-
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
. $PSScriptRoot\pipeline-logging-functions.ps1
+if ($KeyVaultName -notmatch '^[A-Za-z][A-Za-z0-9-]{1,22}[A-Za-z0-9]$' -or $KeyVaultName.Contains('--')) {
+ Write-PipelineTelemetryError -Category 'Build' -Message "KeyVaultName '$KeyVaultName' is not a valid Azure Key Vault name."
+ exit 1
+}
+
function ConvertTo-Base64Url([byte[]] $bytes) {
return [Convert]::ToBase64String($bytes).TrimEnd('=').Replace('+', '-').Replace('/', '_')
}
+$previousNativeCommandErrorPreference = $PSNativeCommandUseErrorActionPreference
+try {
+ # Azure CLI can emit non-fatal Python warnings to stderr.
+ $PSNativeCommandUseErrorActionPreference = $false
+ $keyVaultAccessToken = az account get-access-token `
+ --resource https://vault.azure.net `
+ --query accessToken `
+ --output tsv `
+ --only-show-errors
+ $tokenExitCode = $LASTEXITCODE
+}
+catch {
+ Write-PipelineTelemetryError -Category 'Build' -Message "Failed to acquire an Azure Key Vault access token: $_"
+ exit 1
+}
+finally {
+ $PSNativeCommandUseErrorActionPreference = $previousNativeCommandErrorPreference
+}
+if ($tokenExitCode -ne 0 -or [string]::IsNullOrWhiteSpace($keyVaultAccessToken)) {
+ Write-PipelineTelemetryError -Category 'Build' -Message "'az account get-access-token' exited with code $tokenExitCode while acquiring an Azure Key Vault access token."
+ exit 1
+}
+
+function Get-KeyVaultSecret([string] $SecretName) {
+ # Use the data-plane REST API because `az keyvault secret show` can fail
+ # with Errno 22 on hosted Windows agents when reading these projections.
+ $escapedSecretName = [Uri]::EscapeDataString($SecretName)
+ $secretUri = "https://$KeyVaultName.vault.azure.net/secrets/$escapedSecretName`?api-version=7.4"
+ try {
+ $response = Invoke-RestMethod `
+ -Uri $secretUri `
+ -Headers @{ Authorization = "Bearer $keyVaultAccessToken" } `
+ -Method Get
+ }
+ catch {
+ Write-PipelineTelemetryError -Category 'Build' -Message "Failed to read secret '$SecretName' from vault '$KeyVaultName': $_. Verify the secret exists and the service connection has 'Key Vault Secrets User' access to it."
+ exit 1
+ }
+ if ([string]::IsNullOrWhiteSpace($response.value)) {
+ Write-PipelineTelemetryError -Category 'Build' -Message "Secret '$SecretName' in vault '$KeyVaultName' is empty."
+ exit 1
+ }
+ return [string] $response.value
+}
+
+Write-Host "Reading GitHub App credentials from vault '$KeyVaultName'..."
+$appId = Get-KeyVaultSecret $AppIdSecretName
+$privateKey = Get-KeyVaultSecret $AppPrivateKeySecretName
+
# Build JWT header and payload. Use [ordered] hashtables so JSON
# serialization is deterministic.
$jwtHeader = [ordered]@{
@@ -59,46 +110,38 @@ $now = [System.DateTimeOffset]::UtcNow
$jwtPayload = [ordered]@{
iat = $now.AddMinutes(-1).ToUnixTimeSeconds()
exp = $now.AddMinutes(5).ToUnixTimeSeconds()
- iss = $AppClientId
+ iss = $appId
}
$headerEncoded = ConvertTo-Base64Url ([System.Text.Encoding]::UTF8.GetBytes(($jwtHeader | ConvertTo-Json -Compress)))
$payloadEncoded = ConvertTo-Base64Url ([System.Text.Encoding]::UTF8.GetBytes(($jwtPayload | ConvertTo-Json -Compress)))
$signingInput = "$headerEncoded.$payloadEncoded"
-# Key Vault `sign` expects the *digest* (base64), not the raw bytes.
-$sha256 = [System.Security.Cryptography.SHA256]::Create()
-$digestBytes = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($signingInput))
-$digestBase64 = [Convert]::ToBase64String($digestBytes)
+$sha256 = [System.Security.Cryptography.SHA256]::Create()
+try {
+ $digestBytes = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($signingInput))
+}
+finally {
+ $sha256.Dispose()
+}
-Write-Host "Signing JWT with key '$KeyName' in vault '$KeyVaultName'..."
-$previousNativeCommandErrorPreference = $PSNativeCommandUseErrorActionPreference
+Write-Host 'Signing JWT with the GitHub App private key...'
+$rsa = [System.Security.Cryptography.RSA]::Create()
try {
- # Azure CLI can emit non-fatal Python warnings to stderr even when signing succeeds.
- # Use the exit code to determine success for this invocation.
- $PSNativeCommandUseErrorActionPreference = $false
- $signatureBase64 = az keyvault key sign `
- --vault-name $KeyVaultName `
- --name $KeyName `
- --algorithm RS256 `
- --digest $digestBase64 `
- --query signature `
- --output tsv `
- --only-show-errors
- $signExitCode = $LASTEXITCODE
+ $rsa.ImportFromPem($privateKey)
+ $signatureBytes = $rsa.SignHash(
+ $digestBytes,
+ [System.Security.Cryptography.HashAlgorithmName]::SHA256,
+ [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
+ $signatureUrl = ConvertTo-Base64Url $signatureBytes
}
catch {
- Write-PipelineTelemetryError -Category 'Build' -Message "Failed to sign the JWT via Key Vault (key '$KeyName', vault '$KeyVaultName'): $_. Verify the service connection identity has the 'Key Vault Crypto User' role (Sign action) on the key."
+ Write-PipelineTelemetryError -Category 'Build' -Message "Failed to sign the GitHub App JWT with the supplied private key: $_"
exit 1
}
finally {
- $PSNativeCommandUseErrorActionPreference = $previousNativeCommandErrorPreference
-}
-if ($signExitCode -ne 0 -or [string]::IsNullOrWhiteSpace($signatureBase64)) {
- Write-PipelineTelemetryError -Category 'Build' -Message "'az keyvault key sign' exited with code $signExitCode for key '$KeyName' in vault '$KeyVaultName'. Verify the service connection identity has the 'Key Vault Crypto User' role (Sign action) on the key."
- exit 1
+ $rsa.Dispose()
}
-$signatureUrl = $signatureBase64.Trim().TrimEnd('=').Replace('+', '-').Replace('/', '_')
$jwt = "$signingInput.$signatureUrl"
$headers = @{
@@ -126,7 +169,7 @@ try {
} while ($pageInstallationCount -eq 100)
}
catch {
- Write-PipelineTelemetryError -Category 'Build' -Message "Failed to list GitHub App installations: $_. The signed JWT may be invalid or the App's Client ID ('$AppClientId') may be incorrect."
+ Write-PipelineTelemetryError -Category 'Build' -Message "Failed to list GitHub App installations: $_. The signed JWT may be invalid or the App ID may be incorrect."
exit 1
}
$matchingInstallations = @($installations | Where-Object { $_.account.login -ieq $InstallationOwner })
diff --git a/eng/common/core-templates/job/helix-job-monitor.yml b/eng/common/core-templates/job/helix-job-monitor.yml
index 7417afdf3ea48d..ef8ee08fbd2298 100644
--- a/eng/common/core-templates/job/helix-job-monitor.yml
+++ b/eng/common/core-templates/job/helix-job-monitor.yml
@@ -63,7 +63,7 @@ parameters:
type: boolean
default: false
-# Azure service connection ID authorized for Helix. Required when
+# Workload identity federation service connection name authorized for Helix. Required when
# useEntraAuthentication is true.
- name: azureSubscription
type: string
@@ -94,13 +94,12 @@ parameters:
type: boolean
default: false
-# When true, test results are reported to Azure DevOps using the fully qualified test name
-# (Namespace.Type.Method) as the stable automatedTestName and the visible title is qualified as
-# well (--use-fully-qualified-test-name). Opt-in because it changes AzDO test identity and display;
-# primarily useful for frameworks like MSTest whose display name is only the method name.
+# When true (the default), test results are reported to Azure DevOps using the fully qualified test
+# name (Namespace.Type.Method) as the stable automatedTestName and the visible title is qualified as
+# well (--use-fully-qualified-test-name). Set to false to preserve framework-provided display names.
- name: useFullyQualifiedTestName
type: boolean
- default: false
+ default: true
# Controls per-test output attachments. Defaults to Failed.
- name: testResultAttachmentMode
@@ -136,6 +135,20 @@ jobs:
displayName: Monitor Helix Jobs
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
continueOnError: ${{ parameters.continueOnError }}
+ variables:
+ HELIX_MONITOR_BASE_URI: ${{ parameters.helixBaseUri }}
+ HELIX_MONITOR_USE_ENTRA_AUTHENTICATION: ${{ parameters.useEntraAuthentication }}
+ HELIX_MONITOR_POLLING_INTERVAL_SECONDS: ${{ parameters.pollingIntervalSeconds }}
+ HELIX_MONITOR_FAIL_ON_FAILED_TESTS: ${{ parameters.failWorkItemsWithFailedTests }}
+ HELIX_MONITOR_ALLOW_NO_HELIX_JOBS: ${{ parameters.allowNoHelixJobs }}
+ HELIX_MONITOR_USE_FULLY_QUALIFIED_TEST_NAME: ${{ parameters.useFullyQualifiedTestName }}
+ HELIX_MONITOR_TIMEOUT_IN_MINUTES: ${{ parameters.timeoutInMinutes }}
+ HELIX_MONITOR_TEST_RESULT_UPLOAD_PARALLELISM: ${{ parameters.testResultUploadParallelism }}
+ HELIX_MONITOR_ORGANIZATION: ${{ parameters.organization }}
+ HELIX_MONITOR_REPOSITORY: ${{ parameters.repository }}
+ HELIX_MONITOR_TEST_RESULT_ATTACHMENT_MODE: ${{ parameters.testResultAttachmentMode }}
+ HELIX_MONITOR_TOOL_NUPKG_ARTIFACT_NAME: ${{ parameters.toolNupkgArtifactName }}
+ HELIX_MONITOR_TOOL_COMMAND: ${{ parameters.toolCommand }}
${{ if ne(length(parameters.dependsOn), 0) }}:
dependsOn: ${{ parameters.dependsOn }}
${{ if ne(parameters.condition, '') }}:
@@ -157,22 +170,6 @@ jobs:
- pwsh: throw "azureSubscription must be set when useEntraAuthentication is true."
displayName: Validate Helix Entra authentication
- - ${{ if eq(parameters.useEntraAuthentication, true) }}:
- - task: AzureCLI@2
- displayName: Initialize Helix Entra authentication
- inputs:
- azureSubscription: ${{ parameters.azureSubscription }}
- addSpnToEnvironment: true
- scriptType: pscore
- scriptLocation: inlineScript
- inlineScript: |
- if ([string]::IsNullOrWhiteSpace($env:servicePrincipalId) -or [string]::IsNullOrWhiteSpace($env:tenantId)) {
- throw "The Helix Azure service connection did not provide a service principal or tenant ID."
- }
-
- Write-Host "##vso[task.setvariable variable=HelixEntraClientId]$env:servicePrincipalId"
- Write-Host "##vso[task.setvariable variable=HelixEntraTenantId]$env:tenantId"
-
- ${{ if ne(parameters.toolNupkgArtifactName, '') }}:
- task: DownloadPipelineArtifact@2
displayName: Download Helix Job Monitor artifact
@@ -241,76 +238,26 @@ jobs:
- bash: ./eng/common/dotnet.sh tool restore
displayName: Restore Helix Job Monitor
- - bash: |
- set -euo pipefail
-
- toolArgs=(
- --helix-base-uri '${{ parameters.helixBaseUri }}'
- --use-entra-authentication '${{ parameters.useEntraAuthentication }}'
- --polling-interval-seconds '${{ parameters.pollingIntervalSeconds }}'
- --fail-on-failed-tests '${{ parameters.failWorkItemsWithFailedTests }}'
- --allow-no-helix-jobs '${{ parameters.allowNoHelixJobs }}'
- --use-fully-qualified-test-name '${{ parameters.useFullyQualifiedTestName }}'
- --max-wait-minutes "$((${{ parameters.timeoutInMinutes }} - 5))" # Set the tool's timeout slightly lower than the Azure DevOps job timeout to allow it to exit gracefully.
- --stage-name '$(System.StageName)'
- --stage-attempt '$(System.StageAttempt)'
- --job-attempt '$(System.JobAttempt)'
- --test-result-upload-parallelism '${{ parameters.testResultUploadParallelism }}'
- )
-
- organization='${{ parameters.organization }}'
- repository='${{ parameters.repository }}'
- testResultAttachmentMode='${{ parameters.testResultAttachmentMode }}'
-
- # Fall back to Azure DevOps-provided environment variables when the caller did not
- # supply organization / repository explicitly. BUILD_REPOSITORY_NAME is typically
- # 'owner/repo' for GitHub-backed builds and 'owner-repo' for internal builds.
- if [ -z "$organization" ] || [ -z "$repository" ]; then
- buildRepoName="${BUILD_REPOSITORY_NAME:-}"
- if [ -n "$buildRepoName" ] && [[ "$buildRepoName" == */* ]]; then
- repoOwner="${buildRepoName%%/*}"
- repoName="${buildRepoName#*/}"
- elif [ -n "$buildRepoName" ] && [[ "$buildRepoName" == *-* ]]; then
- repoOwner="${buildRepoName%%-*}"
- repoName="${buildRepoName#*-}"
- fi
-
- if [ -n "${repoOwner:-}" ] && [ -n "${repoName:-}" ]; then
- if [ -z "$organization" ]; then organization="$repoOwner"; fi
- if [ -z "$repository" ]; then repository="$repoName"; fi
- fi
- fi
-
- if [ -n "$organization" ]; then toolArgs+=( --organization "$organization" ); fi
- if [ -n "$repository" ]; then toolArgs+=( --repository "$repository" ); fi
- if [ -n "$testResultAttachmentMode" ]; then
- toolArgs+=( --test-result-attachment-mode "$testResultAttachmentMode" )
- fi
-
- # Build.Reason and Build.SourceBranch are required to derive the Helix source filter
- # the same way the Helix SDK submitter does (PR -> 'pr', internal -> 'official',
- # otherwise -> 'ci'). Without these, manually-queued / scheduled / CI builds would
- # be looked up under the wrong source prefix and find zero jobs.
- toolArgs+=( --build-reason "$(Build.Reason)" )
- toolArgs+=( --source-branch "$(Build.SourceBranch)" )
-
- if [ -n '${{ parameters.toolNupkgArtifactName }}' ]; then
- # Tool was installed from a local nupkg; run the DLL via the repo-local dotnet.
- export DOTNET_ROOT="$(Build.SourcesDirectory)/.dotnet"
- ./eng/common/dotnet.sh exec "$(HelixJobMonitorDll)" "${toolArgs[@]}"
- else
- # Tool was restored from the local .config/dotnet-tools.json manifest; invoke it
- # through the manifest from the repo root.
- pushd "$BUILD_SOURCESDIRECTORY" > /dev/null
- trap 'popd > /dev/null' EXIT
- ./eng/common/dotnet.sh tool run '${{ parameters.toolCommand }}' -- "${toolArgs[@]}"
- fi
- displayName: Monitor Helix Jobs
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- ${{ if eq(parameters.useEntraAuthentication, false) }}:
+ - ${{ if eq(parameters.useEntraAuthentication, true) }}:
+ - task: AzureCLI@2
+ displayName: Monitor Helix Jobs
+ inputs:
+ azureSubscription: ${{ parameters.azureSubscription }}
+ keepAzSessionActive: true
+ scriptType: bash
+ scriptLocation: inlineScript
+ inlineScript: |
+ set -euo pipefail
+
+ # AzureCLI@2 replaces SYSTEM_ACCESSTOKEN with the service connection token.
+ export SYSTEM_ACCESSTOKEN="$HELIX_AZDO_ACCESSTOKEN"
+ bash "$BUILD_SOURCESDIRECTORY/eng/common/run-helix-job-monitor.sh"
+ env:
+ HELIX_AZDO_ACCESSTOKEN: $(System.AccessToken)
+
+ - ${{ if eq(parameters.useEntraAuthentication, false) }}:
+ - bash: bash "$BUILD_SOURCESDIRECTORY/eng/common/run-helix-job-monitor.sh"
+ displayName: Monitor Helix Jobs
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HELIX_ACCESSTOKEN: ${{ parameters.helixAccessToken }}
- ${{ if eq(parameters.useEntraAuthentication, true) }}:
- AZURESUBSCRIPTION_CLIENT_ID: $(HelixEntraClientId)
- AZURESUBSCRIPTION_TENANT_ID: $(HelixEntraTenantId)
- AZURESUBSCRIPTION_SERVICE_CONNECTION_ID: ${{ parameters.azureSubscription }}
diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml
index 25af2787900719..c859dc2b071bde 100644
--- a/eng/common/core-templates/job/onelocbuild.yml
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -10,9 +10,9 @@ parameters:
# GitHub App authentication for the OneLoc check-in PR.
GitHubAppServiceConnection: 'dnceng-oneloc-githubapp'
- GitHubAppClientId: 'Iv23lijBU8x3gc9lDOc9'
GitHubAppKeyVaultName: 'EngKeyVault'
- GitHubAppKeyName: 'oneloc-localization-app-key'
+ GitHubAppIdSecretName: 'oneloc-localization-app-app-id'
+ GitHubAppPrivateKeySecretName: 'oneloc-localization-app-app-private-key'
SourcesDirectory: $(System.DefaultWorkingDirectory)
CreatePr: true
@@ -102,8 +102,8 @@ jobs:
${{ else }}:
azureSubscription: ${{ parameters.GitHubAppServiceConnection }}
keyVaultName: ${{ parameters.GitHubAppKeyVaultName }}
- keyName: ${{ parameters.GitHubAppKeyName }}
- appClientId: ${{ parameters.GitHubAppClientId }}
+ appIdSecretName: ${{ parameters.GitHubAppIdSecretName }}
+ appPrivateKeySecretName: ${{ parameters.GitHubAppPrivateKeySecretName }}
installationOwner: ${{ parameters.GitHubOrg }}
outputVariableName: 'GitHubAppInstallationToken'
condition: ${{ parameters.condition }}
diff --git a/eng/common/core-templates/steps/get-github-app-token.yml b/eng/common/core-templates/steps/get-github-app-token.yml
index 6d42a48d3c3671..3eeb5a4c1bc94b 100644
--- a/eng/common/core-templates/steps/get-github-app-token.yml
+++ b/eng/common/core-templates/steps/get-github-app-token.yml
@@ -1,13 +1,11 @@
# Mints a short-lived GitHub App installation access token by signing a JWT
-# with a private key stored in Azure Key Vault (RSA, RS256). The JWT is
-# exchanged with the GitHub API for a token scoped to a single installation.
+# with an RSA private key (RS256). The JWT is exchanged with the GitHub API
+# for a token scoped to a single installation.
#
# Requirements (per GitHub App you want to authenticate as):
-# - A GitHub App with its private key uploaded into Key Vault as an RSA key
-# (PEM converted to a key, NOT stored as a secret).
-# - The Azure service connection passed via `azureSubscription` must be
-# granted the `Key Vault Crypto User` role (or at minimum `Sign` action)
-# on that key.
+# - A GitHub App ID and PEM private key stored as Azure Key Vault secrets.
+# - The Azure service connection passed via `azureSubscription` must have
+# `Get` access to those two secrets.
# - The App must be installed on the target organization/account
# (`installationOwner`) with the permissions/repositories you need.
#
@@ -17,23 +15,18 @@
# enterprise classic-PAT lifetime policy.
parameters:
-# Azure DevOps service connection (federated) that can call
-# `az keyvault key sign` on the App's signing key.
+# Azure DevOps service connection (federated) that can read the App credentials.
- name: azureSubscription
type: string
-# Name of the Key Vault that holds the GitHub App's RSA signing key.
+# Name of the Key Vault holding Secret Manager's github-app-secret projections.
- name: keyVaultName
type: string
-# Name of the RSA key inside the Key Vault (the App's private key).
-- name: keyName
+- name: appIdSecretName
type: string
-# The GitHub App's Client ID (the value to put in the `iss` JWT claim).
-# Prefer this over the numeric App ID; GitHub accepts either, but Client ID
-# is the documented form going forward.
-- name: appClientId
+- name: appPrivateKeySecretName
type: string
# Login of the organization or user account whose installation we should
@@ -73,7 +66,7 @@ steps:
inlineScript: |
& "$(System.DefaultWorkingDirectory)/eng/common/Get-GitHubAppToken.ps1" `
-KeyVaultName '${{ parameters.keyVaultName }}' `
- -KeyName '${{ parameters.keyName }}' `
- -AppClientId '${{ parameters.appClientId }}' `
+ -AppIdSecretName '${{ parameters.appIdSecretName }}' `
+ -AppPrivateKeySecretName '${{ parameters.appPrivateKeySecretName }}' `
-InstallationOwner '${{ parameters.installationOwner }}' `
-OutputVariableName '${{ parameters.outputVariableName }}'
diff --git a/eng/common/core-templates/steps/send-to-helix.yml b/eng/common/core-templates/steps/send-to-helix.yml
index 62cce4d4ea2a90..dba2f1b0afadcc 100644
--- a/eng/common/core-templates/steps/send-to-helix.yml
+++ b/eng/common/core-templates/steps/send-to-helix.yml
@@ -6,7 +6,7 @@ parameters:
HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues
HelixAccessToken: '' # optional -- legacy access token; not forwarded when HelixUseEntraAuthentication is true
HelixUseEntraAuthentication: false # optional -- use refreshable Entra authentication instead of a PAT or anonymous access
- HelixAzureSubscription: '' # required when HelixUseEntraAuthentication is true -- Azure service connection ID authorized for Helix
+ HelixAzureSubscription: '' # required when HelixUseEntraAuthentication is true -- workload identity federation service connection name authorized for Helix
HelixProjectPath: 'eng/common/helixpublish.proj' # optional -- path to the project file to build relative to BUILD_SOURCESDIRECTORY
HelixProjectArguments: '' # optional -- arguments passed to the build command
HelixConfiguration: '' # optional -- additional property attached to a job
@@ -41,106 +41,176 @@ steps:
- ${{ if eq(parameters.HelixUseEntraAuthentication, true) }}:
- task: AzureCLI@2
- displayName: Initialize Helix Entra authentication
+ displayName: ${{ parameters.DisplayNamePrefix }} (Windows)
inputs:
azureSubscription: ${{ parameters.HelixAzureSubscription }}
- addSpnToEnvironment: true
+ keepAzSessionActive: true
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
- if ([string]::IsNullOrWhiteSpace($env:servicePrincipalId) -or [string]::IsNullOrWhiteSpace($env:tenantId)) {
- throw "The Helix Azure service connection did not provide a service principal or tenant ID."
- }
+ # AzureCLI@2 replaces SYSTEM_ACCESSTOKEN with the service connection token.
+ $env:SYSTEM_ACCESSTOKEN = $env:HELIX_AZDO_ACCESSTOKEN
- Write-Host "##vso[task.setvariable variable=HelixEntraClientId]$env:servicePrincipalId"
- Write-Host "##vso[task.setvariable variable=HelixEntraTenantId]$env:tenantId"
- condition: ${{ parameters.condition }}
+ $(Build.SourcesDirectory)\eng\common\msbuild.ps1 `
+ $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} `
+ /restore `
+ /p:TreatWarningsAsErrors=false `
+ /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} `
+ /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} `
+ ${{ parameters.HelixProjectArguments }} `
+ /t:Test `
+ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixConfiguration: ${{ parameters.HelixConfiguration }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ WorkItemCommand: ${{ parameters.WorkItemCommand }}
+ WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ XUnitProjects: ${{ parameters.XUnitProjects }}
+ XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
+ XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
+ XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
+ XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ HelixBaseUri: ${{ parameters.HelixBaseUri }}
+ Creator: ${{ parameters.Creator }}
+ HELIX_AZDO_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ - task: AzureCLI@2
+ displayName: ${{ parameters.DisplayNamePrefix }} (Unix)
+ inputs:
+ azureSubscription: ${{ parameters.HelixAzureSubscription }}
+ keepAzSessionActive: true
+ scriptType: bash
+ scriptLocation: inlineScript
+ inlineScript: |
+ # AzureCLI@2 replaces SYSTEM_ACCESSTOKEN with the service connection token.
+ export SYSTEM_ACCESSTOKEN="$HELIX_AZDO_ACCESSTOKEN"
+
+ $(Build.SourcesDirectory)/eng/common/msbuild.sh \
+ $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} \
+ /restore \
+ /p:TreatWarningsAsErrors=false \
+ /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} \
+ /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} \
+ ${{ parameters.HelixProjectArguments }} \
+ /t:Test \
+ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixConfiguration: ${{ parameters.HelixConfiguration }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ WorkItemCommand: ${{ parameters.WorkItemCommand }}
+ WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ XUnitProjects: ${{ parameters.XUnitProjects }}
+ XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
+ XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
+ XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
+ XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ HelixBaseUri: ${{ parameters.HelixBaseUri }}
+ Creator: ${{ parameters.Creator }}
+ HELIX_AZDO_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
- - powershell: >
- $(Build.SourcesDirectory)\eng\common\msbuild.ps1
- $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }}
- /restore
- /p:TreatWarningsAsErrors=false
- /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }}
- /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }}
- ${{ parameters.HelixProjectArguments }}
- /t:Test
- /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog
- displayName: ${{ parameters.DisplayNamePrefix }} (Windows)
- env:
- BuildConfig: $(_BuildConfig)
- HelixSource: ${{ parameters.HelixSource }}
- HelixType: ${{ parameters.HelixType }}
- HelixBuild: ${{ parameters.HelixBuild }}
- HelixConfiguration: ${{ parameters.HelixConfiguration }}
- HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
- ${{ if eq(parameters.HelixUseEntraAuthentication, false) }}:
+ - ${{ if eq(parameters.HelixUseEntraAuthentication, false) }}:
+ - powershell: >
+ $(Build.SourcesDirectory)\eng\common\msbuild.ps1
+ $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }}
+ /restore
+ /p:TreatWarningsAsErrors=false
+ /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }}
+ /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }}
+ ${{ parameters.HelixProjectArguments }}
+ /t:Test
+ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog
+ displayName: ${{ parameters.DisplayNamePrefix }} (Windows)
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixConfiguration: ${{ parameters.HelixConfiguration }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
HelixAccessToken: ${{ parameters.HelixAccessToken }}
- ${{ if eq(parameters.HelixUseEntraAuthentication, true) }}:
- AZURESUBSCRIPTION_CLIENT_ID: $(HelixEntraClientId)
- AZURESUBSCRIPTION_TENANT_ID: $(HelixEntraTenantId)
- AZURESUBSCRIPTION_SERVICE_CONNECTION_ID: ${{ parameters.HelixAzureSubscription }}
- HelixPreCommands: ${{ parameters.HelixPreCommands }}
- HelixPostCommands: ${{ parameters.HelixPostCommands }}
- WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
- WorkItemCommand: ${{ parameters.WorkItemCommand }}
- WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
- CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
- XUnitProjects: ${{ parameters.XUnitProjects }}
- XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
- XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
- XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
- XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
- IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
- DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
- DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
- WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
- HelixBaseUri: ${{ parameters.HelixBaseUri }}
- Creator: ${{ parameters.Creator }}
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))
- continueOnError: ${{ parameters.continueOnError }}
- - script: >
- $(Build.SourcesDirectory)/eng/common/msbuild.sh
- $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }}
- /restore
- /p:TreatWarningsAsErrors=false
- /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }}
- /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }}
- ${{ parameters.HelixProjectArguments }}
- /t:Test
- /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog
- displayName: ${{ parameters.DisplayNamePrefix }} (Unix)
- env:
- BuildConfig: $(_BuildConfig)
- HelixSource: ${{ parameters.HelixSource }}
- HelixType: ${{ parameters.HelixType }}
- HelixBuild: ${{ parameters.HelixBuild }}
- HelixConfiguration: ${{ parameters.HelixConfiguration }}
- HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
- ${{ if eq(parameters.HelixUseEntraAuthentication, false) }}:
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ WorkItemCommand: ${{ parameters.WorkItemCommand }}
+ WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ XUnitProjects: ${{ parameters.XUnitProjects }}
+ XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
+ XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
+ XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
+ XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ HelixBaseUri: ${{ parameters.HelixBaseUri }}
+ Creator: ${{ parameters.Creator }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ - script: >
+ $(Build.SourcesDirectory)/eng/common/msbuild.sh
+ $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }}
+ /restore
+ /p:TreatWarningsAsErrors=false
+ /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }}
+ /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }}
+ ${{ parameters.HelixProjectArguments }}
+ /t:Test
+ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog
+ displayName: ${{ parameters.DisplayNamePrefix }} (Unix)
+ env:
+ BuildConfig: $(_BuildConfig)
+ HelixSource: ${{ parameters.HelixSource }}
+ HelixType: ${{ parameters.HelixType }}
+ HelixBuild: ${{ parameters.HelixBuild }}
+ HelixConfiguration: ${{ parameters.HelixConfiguration }}
+ HelixTargetQueues: ${{ parameters.HelixTargetQueues }}
HelixAccessToken: ${{ parameters.HelixAccessToken }}
- ${{ if eq(parameters.HelixUseEntraAuthentication, true) }}:
- AZURESUBSCRIPTION_CLIENT_ID: $(HelixEntraClientId)
- AZURESUBSCRIPTION_TENANT_ID: $(HelixEntraTenantId)
- AZURESUBSCRIPTION_SERVICE_CONNECTION_ID: ${{ parameters.HelixAzureSubscription }}
- HelixPreCommands: ${{ parameters.HelixPreCommands }}
- HelixPostCommands: ${{ parameters.HelixPostCommands }}
- WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
- WorkItemCommand: ${{ parameters.WorkItemCommand }}
- WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
- CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
- XUnitProjects: ${{ parameters.XUnitProjects }}
- XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
- XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
- XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
- XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
- IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
- DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
- DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
- WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
- HelixBaseUri: ${{ parameters.HelixBaseUri }}
- Creator: ${{ parameters.Creator }}
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT'))
- continueOnError: ${{ parameters.continueOnError }}
+ HelixPreCommands: ${{ parameters.HelixPreCommands }}
+ HelixPostCommands: ${{ parameters.HelixPostCommands }}
+ WorkItemDirectory: ${{ parameters.WorkItemDirectory }}
+ WorkItemCommand: ${{ parameters.WorkItemCommand }}
+ WorkItemTimeout: ${{ parameters.WorkItemTimeout }}
+ CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }}
+ XUnitProjects: ${{ parameters.XUnitProjects }}
+ XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }}
+ XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }}
+ XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }}
+ XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }}
+ IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
+ DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
+ DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
+ WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
+ HelixBaseUri: ${{ parameters.HelixBaseUri }}
+ Creator: ${{ parameters.Creator }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
diff --git a/eng/common/run-helix-job-monitor.sh b/eng/common/run-helix-job-monitor.sh
new file mode 100644
index 00000000000000..dda140bc9a4bcc
--- /dev/null
+++ b/eng/common/run-helix-job-monitor.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+scriptroot="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+. "$scriptroot/pipeline-logging-functions.sh"
+
+toolArgs=(
+ --helix-base-uri "$HELIX_MONITOR_BASE_URI"
+ --use-entra-authentication "$HELIX_MONITOR_USE_ENTRA_AUTHENTICATION"
+ --polling-interval-seconds "$HELIX_MONITOR_POLLING_INTERVAL_SECONDS"
+ --fail-on-failed-tests "$HELIX_MONITOR_FAIL_ON_FAILED_TESTS"
+ --allow-no-helix-jobs "$HELIX_MONITOR_ALLOW_NO_HELIX_JOBS"
+ --use-fully-qualified-test-name "$HELIX_MONITOR_USE_FULLY_QUALIFIED_TEST_NAME"
+ --max-wait-minutes "$((HELIX_MONITOR_TIMEOUT_IN_MINUTES - 5))"
+ --stage-name "$SYSTEM_STAGENAME"
+ --stage-attempt "$SYSTEM_STAGEATTEMPT"
+ --job-attempt "$SYSTEM_JOBATTEMPT"
+ --test-result-upload-parallelism "$HELIX_MONITOR_TEST_RESULT_UPLOAD_PARALLELISM"
+)
+
+organization="${HELIX_MONITOR_ORGANIZATION:-}"
+repository="${HELIX_MONITOR_REPOSITORY:-}"
+
+# Fall back to Azure DevOps-provided environment variables when the caller did not
+# supply organization or repository explicitly.
+if [ -z "$organization" ] || [ -z "$repository" ]; then
+ buildRepoName="${BUILD_REPOSITORY_NAME:-}"
+ if [ -n "$buildRepoName" ] && [[ "$buildRepoName" == */* ]]; then
+ repoOwner="${buildRepoName%%/*}"
+ repoName="${buildRepoName#*/}"
+ elif [ -n "$buildRepoName" ] && [[ "$buildRepoName" == *-* ]]; then
+ repoOwner="${buildRepoName%%-*}"
+ repoName="${buildRepoName#*-}"
+ fi
+
+ if [ -n "${repoOwner:-}" ] && [ -n "${repoName:-}" ]; then
+ if [ -z "$organization" ]; then organization="$repoOwner"; fi
+ if [ -z "$repository" ]; then repository="$repoName"; fi
+ fi
+fi
+
+if [ -n "$organization" ]; then toolArgs+=( --organization "$organization" ); fi
+if [ -n "$repository" ]; then toolArgs+=( --repository "$repository" ); fi
+if [ -n "${HELIX_MONITOR_TEST_RESULT_ATTACHMENT_MODE:-}" ]; then
+ toolArgs+=( --test-result-attachment-mode "$HELIX_MONITOR_TEST_RESULT_ATTACHMENT_MODE" )
+fi
+
+# These values let the monitor derive the same Helix source filter as the SDK submitter.
+toolArgs+=( --build-reason "$BUILD_REASON" )
+toolArgs+=( --source-branch "$BUILD_SOURCEBRANCH" )
+
+cd "$BUILD_SOURCESDIRECTORY"
+exitCode=0
+if [ -n "${HELIX_MONITOR_TOOL_NUPKG_ARTIFACT_NAME:-}" ]; then
+ export DOTNET_ROOT="$BUILD_SOURCESDIRECTORY/.dotnet"
+ ./eng/common/dotnet.sh exec "$HELIXJOBMONITORDLL" "${toolArgs[@]}" || exitCode=$?
+else
+ ./eng/common/dotnet.sh tool run "$HELIX_MONITOR_TOOL_COMMAND" -- "${toolArgs[@]}" || exitCode=$?
+fi
+
+if [ "$exitCode" -ne 0 ]; then
+ Write-PipelineTelemetryError -force -category 'Helix' "Helix job monitor failed (exit code '$exitCode')."
+ exit "$exitCode"
+fi
diff --git a/eng/packaging.targets b/eng/packaging.targets
index e5b1ee774dbbff..2437cb5e79d608 100644
--- a/eng/packaging.targets
+++ b/eng/packaging.targets
@@ -52,7 +52,7 @@
-
+
true
diff --git a/global.json b/global.json
index 1ec0f68f3a6c5c..40861a38336298 100644
--- a/global.json
+++ b/global.json
@@ -13,11 +13,11 @@
"dotnet": "11.0.100-rc.1.26425.128"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26465.108",
- "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.26465.108",
- "Microsoft.DotNet.SharedFramework.Sdk": "11.0.0-beta.26465.108",
+ "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26514.117",
+ "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.26514.117",
+ "Microsoft.DotNet.SharedFramework.Sdk": "11.0.0-beta.26514.117",
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0",
- "Microsoft.NET.Sdk.IL": "11.0.0-rc.2.26465.108"
+ "Microsoft.NET.Sdk.IL": "11.0.0"
}
}
diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets
index dbe74e9c4c4330..5366b60033546d 100644
--- a/src/libraries/Directory.Build.targets
+++ b/src/libraries/Directory.Build.targets
@@ -71,7 +71,7 @@
-
<_IsWindowsDesktopApp Condition="$(WindowsDesktopCoreAppLibrary.Contains('$(AssemblyName);'))">true
<_IsAspNetCoreApp Condition="$(AspNetCoreAppLibrary.Contains('$(AssemblyName);'))">true
diff --git a/src/mono/nuget/Directory.Build.targets b/src/mono/nuget/Directory.Build.targets
index c5a434cbbf9c85..8e2f1b6a5c2e33 100644
--- a/src/mono/nuget/Directory.Build.targets
+++ b/src/mono/nuget/Directory.Build.targets
@@ -2,7 +2,7 @@
- $(ProductVersion)
+ $(ProductVersion)