diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 8f7351101e77..de1c51d3d000 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -21,7 +21,7 @@
]
},
"microsoft.dotnet.xharness.cli": {
- "version": "10.0.0-prerelease.24511.1",
+ "version": "9.0.0-prerelease.24510.3",
"commands": [
"xharness"
]
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 04fe3e69daa7..8b63aa03be17 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -8,3 +8,4 @@
# Blazor Desktop
/src/BlazorWebView/ @dotnet/dotnet-maui-blazor-eng
/src/Templates/src/templates/maui-blazor/ @dotnet/dotnet-maui-blazor-eng
+/src/Templates/src/templates/maui-blazor-solution/ @dotnet/dotnet-maui-blazor-eng
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index b56ed2e76dde..e4e9e48e730c 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -41,6 +41,7 @@ updates:
- "Microsoft.Graphics.Win2D"
- "Microsoft.Windows.SDK.BuildTools"
- "Microsoft.WindowsAppSDK"
+ - "Microsoft.Web.WebView2"
xunit:
patterns:
- "xunit"
@@ -57,7 +58,7 @@ updates:
- dependency-name: "Newtonsoft.Json" # needs to be done manually to match VS
- dependency-name: "Microsoft.Build*" # these packages neet to be kept on old version that supports netstandard2.0
- dependency-name: "Selenium.*" # needs to be done manually because other packages need to be compiled with these new versions
-
+
labels:
- "nuget"
- "dependencies"
diff --git a/.gitignore b/.gitignore
index 69887dd81422..bd1b26cc4f05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -376,3 +376,9 @@ Directory.Build.Override.props
# Only the "snapshots" directory should be added to Git, not the "snapshots-diff" directory
snapshots-diff/
+
+#install of dotnet version
+/.dotnet
+.dotnet
+temp
+.packages
diff --git a/Directory.Build.props b/Directory.Build.props
index e54c3b07725d..409a1aeeef8a 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -2,7 +2,7 @@
-
+
true
portable
true
@@ -11,6 +11,9 @@
false
$(MSBuildThisFileDirectory)
$(MSBuildThisFileDirectory)src/
+ false
+ false
+ false
@@ -40,14 +43,14 @@
all
moderate
-
+
- <_MauiDotNetVersionMajor Condition="'$(_MauiDotNetVersionMajor)' == ''">8
+ <_MauiDotNetVersionMajor Condition="'$(_MauiDotNetVersionMajor)' == ''">9
<_MauiDotNetVersionMinor Condition="'$(_MauiDotNetVersionMinor)' == ''">0
<_MauiDotNetVersion Condition="'$(_MauiDotNetVersion)' == ''">$(_MauiDotNetVersionMajor).$(_MauiDotNetVersionMinor)
<_MauiDotNetTfm Condition="'$(_MauiDotNetTfm)' == ''">net$(_MauiDotNetVersion)
-
- <_MauiPreviousDotNetVersionMajor Condition="'$(_MauiPreviousDotNetVersionMajor)' == ''">7
+
+ <_MauiPreviousDotNetVersionMajor Condition="'$(_MauiPreviousDotNetVersionMajor)' == ''">8
<_MauiPreviousDotNetVersionMinor Condition="'$(_MauiPreviousDotNetVersionMinor)' == ''">0
<_MauiPreviousDotNetVersion Condition="'$(_MauiPreviousDotNetVersion)' == ''">$(_MauiPreviousDotNetVersionMajor).$(_MauiPreviousDotNetVersionMinor)
<_MauiPreviousDotNetVersionNoDot Condition="'$(_MauiPreviousDotNetVersionNoDot)' == ''">$(_MauiPreviousDotNetVersionMajor)$(_MauiPreviousDotNetVersionMinor)
@@ -104,6 +107,7 @@
true
+
true
true
true
@@ -114,7 +118,8 @@
$(DefineConstants);WINDOWS
$(DefineConstants);COMPATIBILITY_ENABLED
- snupkg
+ $(DefineConstants);ENABLE_PREVIOUS_TFM_BUILDS
+
true
@@ -122,29 +127,34 @@
true
+
+
+ 10.0.19041.44
+
+
- 17.5
- 17.5
- 17.5
- 14.5
- 34.0
+ 18.0
+ 18.0
+ 18.0
+ 15.0
+ 35.0
- 17.0
- 17.0
- 17.0
- 14.0
- 34.0
+ 18.0
+ 18.0
+ 18.0
+ 15.0
+ 35.0
10.0.19041.0
10.0.20348.0
7.0
- 16.1
- 16.1
- 16.1
- 13.0
- 33.0
+ 17.5
+ 17.5
+ 17.5
+ 14.5
+ 35.0
10.0.19041.0
10.0.20348.0
7.0
@@ -178,6 +188,11 @@
net$(_MauiDotNetVersion)-android;$(MauiSamplePlatforms)
net$(_MauiDotNetVersion)-maccatalyst;$(MauiSamplePlatforms)
net$(_MauiDotNetVersion)-ios;$(MauiSamplePlatforms)
+ net$(_MauiPreviousDotNetVersion)-tizen;$(MauiSamplePreviousPlatforms)
+ $(WindowsMauiPreviousPlatforms);$(MauiSamplePreviousPlatforms)
+ net$(_MauiPreviousDotNetVersion)-android;$(MauiSamplePreviousPlatforms)
+ net$(_MauiPreviousDotNetVersion)-maccatalyst;$(MauiSamplePreviousPlatforms)
+ net$(_MauiPreviousDotNetVersion)-ios;$(MauiSamplePreviousPlatforms)
$(WindowsMauiPlatforms);$(MauiDeviceTestsPlatforms)
@@ -200,9 +215,8 @@
- $(MSBuildThisFileDirectory)bin/
- $(DotNetOutputPath)temp/
- $(DotNetOutputPath)dotnet/
+ $(RepoRoot)temp/
+ $(RepoRoot).dotnet/
$(DotNetDirectory)dotnet
$(DotNetDirectory)packs/
$(DotNetDirectory)library-packs/
@@ -211,7 +225,7 @@
<_MauiBuildTasksLocation>$(_MauiBuildTasksLocation)
<_MauiBuildTasksLocation Condition="'$(_MauiBuildTasksLocation)' == ''">$(MSBuildThisFileDirectory).buildtasks\
<_MauiAOTProfileLocation>$(MauiSrcDirectory)Controls\src\Build.Tasks\nuget\buildTransitive\netstandard2.0\
- $(MauiRootDirectory)eng/microsoft.maui.controls.snk
+ $(MauiRootDirectory)eng/microsoft.maui.controls.snk
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
True
True
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 7a66bac1ceee..cdfa0ed38f55 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -19,14 +19,20 @@
-
+
True
+
+
+
+ $(NoWarn);MSB4011;NETSDK1206
+
+
- 11.0
- 11.0
+ 13.0
+ 13.0
$(NoWarn);CA1416
@@ -37,14 +43,14 @@
$(NoWarn);CA1416
- 13.1
- 13.1
+ 15.0
+ 15.0
$(NoWarn);CA1416
- 10.14
- 10.14
+ 12.0
+ 12.0
21.0
@@ -55,8 +61,8 @@
6.5
-
@@ -65,7 +71,7 @@
10.0.17763.0
-
@@ -79,9 +85,9 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT
index b93840c3b5c2..3ea5936c902a 100644
--- a/THIRD-PARTY-NOTICES.TXT
+++ b/THIRD-PARTY-NOTICES.TXT
@@ -521,3 +521,63 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
+
+
+License notice for .NET Community Toolkit
+=========================================
+
+(https://github.com/CommunityToolkit/dotnet/blob/main/License.md)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+=========================================
+
+
+License notice for BenchmarkDotNet
+=========================================
+
+(https://github.com/dotnet/BenchmarkDotNet/blob/master/LICENSE.md)
+
+The MIT License (MIT)
+
+Copyright (c) 2013–2024 .NET Foundation and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+=========================================
diff --git a/build.cmd b/build.cmd
index 4dded3f9274a..c70d2b3757e4 100644
--- a/build.cmd
+++ b/build.cmd
@@ -1,6 +1,9 @@
-@ECHO OFF
-SETLOCAL
-PowerShell -NoProfile -NoLogo -ExecutionPolicy Bypass -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = ''; try { & '%~dp0build.ps1' %*; exit $LASTEXITCODE } catch { write-host $_; exit 1 }"
-SET exit_code=%ERRORLEVEL%
-ECHO build.cmd completed
-EXIT /b %exit_code%
\ No newline at end of file
+@echo off
+setlocal
+
+set _args=%*
+if "%~1"=="-?" set _args=-help
+if "%~1"=="/?" set _args=-help
+
+powershell -ExecutionPolicy ByPass -NoProfile -Command "& '%~dp0eng\build.ps1'" %_args%
+exit /b %ERRORLEVEL%
\ No newline at end of file
diff --git a/build.ps1 b/build.ps1
old mode 100644
new mode 100755
diff --git a/build.sh b/build.sh
index 6dbd8964f81b..a5e46e950a35 100755
--- a/build.sh
+++ b/build.sh
@@ -1,30 +1,16 @@
#!/usr/bin/env bash
-# script inspired by https://andrewlock.net/simplifying-the-cake-global-tool-bootstrapper-scripts-in-netcore3-with-local-tools/
+source="${BASH_SOURCE[0]}"
-# Define default arguments.
-SCRIPT="build.cake"
-CAKE_ARGUMENTS=()
+# resolve $SOURCE until the file is no longer a symlink
+while [[ -h $source ]]; do
+ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+ source="$(readlink "$source")"
-# Parse arguments.
-for i in "$@"; do
- case $1 in
- -s|--script) SCRIPT="$2"; shift ;;
- --) shift; CAKE_ARGUMENTS+=("$@"); break ;;
- *) CAKE_ARGUMENTS+=("$1") ;;
- esac
- shift
+ # if $source was a relative symlink, we need to resolve it relative to the path where the
+ # symlink file was located
+ [[ $source != /* ]] && source="$scriptroot/$source"
done
-# Restore Cake tool
-dotnet tool restore
-
-if [ $? -ne 0 ]; then
- echo "An error occurred while installing Cake."
- exit 1
-fi
-
-echo "${CAKE_ARGUMENTS[@]}"
-
-# Start Cake
-dotnet tool run dotnet-cake "$SCRIPT" "${CAKE_ARGUMENTS[@]}"
+scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+"$scriptroot/eng/build.sh" $@
\ No newline at end of file
diff --git a/docs/design/FeatureSwitches.md b/docs/design/FeatureSwitches.md
new file mode 100644
index 000000000000..26a91ad5837f
--- /dev/null
+++ b/docs/design/FeatureSwitches.md
@@ -0,0 +1,73 @@
+# Feature Switches
+
+Certain features of MAUI can be enabled or disabled using feature switches. The easiest way to control the features is by putting the corresponding MSBuild property into the app's project file. Disabling unnecessary features can help reducing the app size when combined with the [`full` trimming mode](https://learn.microsoft.com/dotnet/core/deploying/trimming/trimming-options).
+
+The following switches are toggled for applications running on Mono for `TrimMode=full` as well as NativeAOT.
+
+| MSBuild Property Name | AppContext Setting | Description |
+|-|-|-|
+| MauiEnableIVisualAssemblyScanning | Microsoft.Maui.RuntimeFeature.IsIVisualAssemblyScanningEnabled | When enabled, MAUI will scan assemblies for types implementing `IVisual` and for `[assembly: Visual(...)]` attributes and register these types. |
+| MauiShellSearchResultsRendererDisplayMemberNameSupported | Microsoft.Maui.RuntimeFeature.IsShellSearchResultsRendererDisplayMemberNameSupported | When disabled, it is necessary to always set `ItemTemplate` of any `SearchHandler`. Displaying search results through `DisplayMemberName` will not work. |
+| MauiQueryPropertyAttributeSupport | Microsoft.Maui.RuntimeFeature.IsQueryPropertyAttributeSupported | When disabled, the `[QueryProperty(...)]` attributes won't be used to set values to properties when navigating. |
+| MauiImplicitCastOperatorsUsageViaReflectionSupport | Microsoft.Maui.RuntimeFeature.IsImplicitCastOperatorsUsageViaReflectionSupported | When disabled, MAUI won't look for implicit cast operators when converting values from one type to another. This feature is not trim-compatible. |
+| _MauiBindingInterceptorsSupport | Microsoft.Maui.RuntimeFeature.AreBindingInterceptorsSupported | When disabled, MAUI won't intercept any calls to `SetBinding` methods and try to compile them. Enabled by default. |
+| MauiEnableXamlCBindingWithSourceCompilation | Microsoft.Maui.RuntimeFeature.XamlCBindingWithSourceCompilationEnabled | When enabled, MAUI will compile all bindings, including those where the `Source` property is used. |
+
+## MauiEnableIVisualAssemblyScanning
+
+When this feature is not enabled, custom and third party `IVisual` types will not be automatically discovered and registered.
+
+## MauiShellSearchResultsRendererDisplayMemberNameSupported
+
+When this feature is disabled, any value set to [`SearchHandler.DisplayMemberName`](https://learn.microsoft.com/dotnet/api/microsoft.maui.controls.searchhandler.displaymembername) will be ignored. Consider implementing a custom `ItemTemplate` to define the appearance of search results (see [Shell search documentation](https://learn.microsoft.com/dotnet/maui/fundamentals/shell/search#define-search-results-item-appearance)).
+
+## MauiQueryPropertyAttributeSupport
+
+When disabled, the `[QueryProperty(...)]` attributes won't be used to set values to properties when navigating. Instead, implement the [`IQueryAttributable`](https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation#process-navigation-data-using-a-single-method) interface whenever you need to accept query parameters.
+
+## MauiImplicitCastOperatorsUsageViaReflectionSupport
+
+When disabled, MAUI won't look for implicit cast operators when converting values from one type to another. This can affect the following scenarios:
+- bindings between properties with different types,
+- setting a property value of a bindable object with a value of different type.
+
+If your library or your app defines an implicit operator on a type that can be used in one of the previous scenarios, you should define a custom `TypeConverter` for your type and attach it to the type using the `[TypeConverter(typeof(MyTypeConverter))]` attribute.
+
+_Note: Prefer using the `TypeConverterAttribute` as it can help the trimmer achieve better binary size in certain scenarios._
+
+## _MauiBindingInterceptorsSupport
+
+When enabled, MAUI will enable a source generator which will identify calls to the `SetBinding(this BindableObject target, BindableProperty property, Func getter, ...)` methods and generate optimized bindings based on the lambda expression passed as the `getter` parameter.
+
+This feature is a counterpart of [XAML Compiled bindings](https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings).
+
+It is necessary to use this feature instead of the string-based bindings in NativeAOT apps and in apps with full trimming enabled.
+
+### Example use-case
+
+String-based binding in code:
+```c#
+label.BindingContext = new PageViewModel { Customer = new CustomerViewModel { Name = "John" } };
+label.SetBinding(Label.TextProperty, "Customer.Name");
+```
+
+Compiled binding in code:
+```csharp
+label.SetBinding(Label.TextProperty, static vm => vm.Customer.Name);
+// or with type inference:
+label.SetBinding(Label.TextProperty, static (PageViewModel vm) => vm.Customer.Name);
+```
+
+Compiled binding in XAML:
+```xml
+
+```
+
+## MauiEnableXamlCBindingWithSourceCompilation
+
+XamlC skipped compilation of bindings with the `Source` property set to any value in previous releases. Some bindings might start producing build errors or start failing at runtime after this feature is enabled. After enabling this feature, make sure all bindings have the right `x:DataType` so they are compiled correctly. For bindings which should not be compiled, clear the data type like this:
+```
+{Binding MyProperty, Source={x:Reference MyTarget}, x:DataType={x:Null}}
+```
+
+This feature is disabled by default, unless `TrimMode=true` or `PublishAot=true`. For fully trimmed and NativeAOT apps, the feature is enabled.
diff --git a/dotnet-local.sh b/dotnet-local.sh
index 83680609537d..4df2bde89ca0 100755
--- a/dotnet-local.sh
+++ b/dotnet-local.sh
@@ -2,11 +2,11 @@
ROOT="$(dirname "${BASH_SOURCE}")"
FULLROOT="$(cd "${ROOT}"; pwd)"
-if [[ ! -x "${ROOT}/bin/dotnet/dotnet" ]] ; then
+if [[ ! -x "${ROOT}/.dotnet/dotnet" ]] ; then
echo 'You must build MAUI first. Please see `.github/DEVELOPMENT.md` for details.' 1>&2
exit 1
fi
-export DOTNET_ROOT="${FULLROOT}/bin/dotnet"
+export DOTNET_ROOT="${FULLROOT}/.dotnet"
export PATH="${DOTNET_ROOT}:${PATH}"
-exec "${ROOT}/bin/dotnet/dotnet" "$@"
+exec "${ROOT}/.dotnet/dotnet" "$@"
diff --git a/eng/AndroidX.targets b/eng/AndroidX.targets
index 9860c0733d4c..5b59227dd375 100644
--- a/eng/AndroidX.targets
+++ b/eng/AndroidX.targets
@@ -2,47 +2,47 @@
\ No newline at end of file
diff --git a/eng/Build.props b/eng/Build.props
new file mode 100644
index 000000000000..8a4db891eddb
--- /dev/null
+++ b/eng/Build.props
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/NuGetVersions.targets b/eng/NuGetVersions.targets
index bf7e32f6f4ab..a1377e3bb6b5 100644
--- a/eng/NuGetVersions.targets
+++ b/eng/NuGetVersions.targets
@@ -137,6 +137,11 @@
Version="$(MicrosoftWindowsAppSDKPackageVersion)"
NoWarn="NU1605"
/>
+
-
+ Version="$(MicrosoftAspNetCoreComponentsWebPackageVersion)"
+ />
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
diff --git a/eng/Publishing.props b/eng/Publishing.props
index a2ad98846735..388a242f3906 100644
--- a/eng/Publishing.props
+++ b/eng/Publishing.props
@@ -1,5 +1,6 @@
+ 3
true
\ No newline at end of file
diff --git a/eng/Signing.props b/eng/Signing.props
index 3eb8ded367d9..559e2aab3604 100644
--- a/eng/Signing.props
+++ b/eng/Signing.props
@@ -1,44 +1,26 @@
-
- true
true
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
- -->
diff --git a/eng/Tools.props b/eng/Tools.props
new file mode 100644
index 000000000000..3e275b8d8e3f
--- /dev/null
+++ b/eng/Tools.props
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 6e3506c7151f..adbf2d69c3b9 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,27 +1,50 @@
-
+
https://github.com/dotnet/xharness
- 8c6d5afd99c713777165f4378462085a5679c223
+ 8c0dc6866c1b786baf476dd767323b24f102bee4
-
+
https://github.com/dotnet/xharness
- 8c6d5afd99c713777165f4378462085a5679c223
+ 8c0dc6866c1b786baf476dd767323b24f102bee4
-
+
https://github.com/dotnet/xharness
- 8c6d5afd99c713777165f4378462085a5679c223
+ 8c0dc6866c1b786baf476dd767323b24f102bee4
-
+
https://github.com/dotnet/arcade
- 60ae233c3d77f11c5fdb53e570b64d503b13ba59
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
-
+
https://github.com/dotnet/arcade
- 9f6799fdc16ae19b3e9478c55b997a6aab839d09
-
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
+
+
+ https://github.com/dotnet/arcade
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
+
+
+ https://github.com/dotnet/arcade
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
+
+
+ https://github.com/dotnet/arcade
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
+
+
+ https://github.com/dotnet/arcade
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
+
+
+ https://github.com/dotnet/arcade
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
+
+
+ https://github.com/dotnet/arcade
+ 05c72bb3c9b38138276a8029017f2ef905dcc7fa
diff --git a/eng/Versions.props b/eng/Versions.props
index 550a08d780a7..fe15f4ded00d 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -1,12 +1,14 @@
- 8.0.99
- 8
+ 9.0.0
+ 9
0
- 99
- 8.0.100
- ci.net8
+ 10
+ 9.0.100
+ ci.net9
+
+
true
@@ -18,8 +20,7 @@
true
+ as for the patches and revisions should be manually updated per assembly if it is serviced. -->
1.0.0.0
false
@@ -27,56 +28,76 @@
- 7.0.101
+ 8.0.82
- 8.0.100
+ 9.0.100-rc.2.24474.11
+ $(MicrosoftNETSdkPackageVersion)
- 8.0.0
+ 9.0.0-rc.2.24473.5
$(MicrosoftNETCoreAppRefPackageVersion)
$(MicrosoftNETCoreAppRefPackageVersion)
$(MicrosoftNETCoreAppRefPackageVersion)
$(MicrosoftNETCoreAppRefPackageVersion)
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24473.5
- 34.0.113
+ 35.0.0-rc.2.152
- 17.5.8020
- 14.5.8020
- 17.5.8020
- 17.5.8020
+ 18.0.9600-net9-rc2
+ 15.0.9600-net9-rc2
+ 18.0.9600-net9-rc2
+ 18.0.9600-net9-rc2
- 8.0.130
+ 8.0.148
- 8.0.0
+ 9.0.0-rc.2.24468.8
+ $(MicrosoftNETWorkloadEmscriptenCurrentManifest90100TransportVersion)
- 1.5.240802000
+ 1.6.240923002
10.0.22621.756
1.2.0
+ 1.0.2792.45
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
- 8.0.0
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24474.3
+
+ 8.0.7
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
+ $(MicrosoftAspNetCorePackageVersion)
- 8.0.0
+ 9.0.0-preview*
3.3.4
3.3.4
3.0.1
@@ -86,14 +107,13 @@
4.3.0
4.3.0
6.0.0
- <_MicrosoftWebWebView2Version>1.0.2592.51
- <_XamarinAndroidGlideVersion>4.15.1.2
- <_XamarinAndroidXSecurityVersion>1.1.0.1-alpha06
- <_XamarinGoogleCryptoTinkAndroidVersion>1.10.0
+ <_XamarinAndroidGlideVersion>4.16.0.6
+ <_XamarinAndroidXSecurityVersion>1.1.0.2-alpha06
+ <_XamarinGoogleCryptoTinkAndroidVersion>1.15.0.1
- 118.1.0.3
+ 119.0.0.2
diff --git a/eng/build.ps1 b/eng/build.ps1
new file mode 100644
index 000000000000..da8194d920c1
--- /dev/null
+++ b/eng/build.ps1
@@ -0,0 +1,146 @@
+[CmdletBinding(PositionalBinding=$false)]
+Param(
+ [switch][Alias('h')]$help,
+ [switch][Alias('t')]$test,
+ [ValidateSet("Debug","Release")][string[]][Alias('c')]$configuration = @("Debug"),
+ [string][Alias('v')]$verbosity = "minimal",
+ [switch]$vs,
+ [ValidateSet("windows","linux","osx")][string]$os,
+ [switch]$testnobuild,
+ [ValidateSet("x86","x64","arm","arm64")][string[]][Alias('a')]$arch = @([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()),
+
+ # Run tests with code coverage
+ [Parameter(ParameterSetName='CommandLine')]
+ [switch] $testCoverage,
+
+ [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties
+)
+
+function Get-Help() {
+ Write-Host "Common settings:"
+ Write-Host " -arch (-a) Target platform: x86, x64, arm or arm64."
+ Write-Host " [Default: Your machine's architecture.]"
+ Write-Host " -binaryLog (-bl) Output binary log."
+ Write-Host " -configuration (-c) Build configuration: Debug or Release."
+ Write-Host " [Default: Debug]"
+ Write-Host " -help (-h) Print help and exit."
+ Write-Host " -os Target operating system: windows, linux or osx."
+ Write-Host " [Default: Your machine's OS.]"
+ Write-Host " -verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]."
+ Write-Host " [Default: Minimal]"
+ Write-Host " -vs Open the solution with Visual Studio using the locally acquired SDK."
+ Write-Host ""
+
+ Write-Host "Actions (defaults to -restore -build):"
+ Write-Host " -build (-b) Build all source projects."
+ Write-Host " This assumes -restore has been run already."
+ Write-Host " -clean Clean the solution."
+ Write-Host " -pack Package build outputs into NuGet packages."
+ Write-Host " -publish Publish artifacts (e.g. symbols)."
+ Write-Host " This assumes -build has been run already."
+ Write-Host " -rebuild Rebuild all source projects."
+ Write-Host " -restore Restore dependencies."
+ Write-Host " -sign Sign build outputs."
+ Write-Host " -test (-t) Incrementally builds and runs tests."
+ Write-Host " Use in conjunction with -testnobuild to only run tests."
+ Write-Host " -testCoverage Run unit tests and capture code coverage information."
+ Write-Host ""
+
+ Write-Host "Libraries settings:"
+ Write-Host " -testnobuild Skip building tests when invoking -test."
+ Write-Host ""
+
+ Write-Host "Command-line arguments not listed above are passed through to MSBuild."
+ Write-Host "The above arguments can be shortened as much as to be unambiguous."
+ Write-Host "(Example: -con for configuration, -t for test, etc.)."
+ Write-Host ""
+}
+
+if ($help) {
+ Get-Help
+ exit 0
+}
+
+if ($vs) {
+ $solution = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "xcsync.sln"
+
+ . $PSScriptRoot\common\tools.ps1
+
+ # This tells .NET Core to use the bootstrapped runtime
+ $env:DOTNET_ROOT=InitializeDotNetCli -install:$true -createSdkLocationFile:$true
+
+ # This tells MSBuild to load the SDK from the directory of the bootstrapped SDK
+ $env:DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=$env:DOTNET_ROOT
+
+ # Put our local dotnet.exe on PATH first so Visual Studio knows which one to use
+ $env:PATH=($env:DOTNET_ROOT + ";" + $env:PATH);
+
+ # Launch Visual Studio with the locally defined environment variables
+ ."$solution"
+
+ exit 0
+}
+
+# Check if an action is passed in
+$actions = "b","build","r","restore","rebuild","sign","testnobuild","publish","clean"
+$actionPassedIn = @(Compare-Object -ReferenceObject @($PSBoundParameters.Keys) -DifferenceObject $actions -ExcludeDifferent -IncludeEqual).Length -ne 0
+if ($null -ne $properties -and $actionPassedIn -ne $true) {
+ $actionPassedIn = @(Compare-Object -ReferenceObject $properties -DifferenceObject $actions.ForEach({ "-" + $_ }) -ExcludeDifferent -IncludeEqual).Length -ne 0
+}
+
+if (!$actionPassedIn) {
+ $arguments = "-restore -build"
+}
+
+foreach ($argument in $PSBoundParameters.Keys)
+{
+ switch($argument)
+ {
+ "testCoverage" { <# this argument is handled in this script only #> }
+ "os" { $arguments += " /p:TargetOS=$($PSBoundParameters[$argument])" }
+ "properties" { $arguments += " " + $properties }
+ "verbosity" { $arguments += " -$argument " + $($PSBoundParameters[$argument]) }
+ "configuration" { $configuration = (Get-Culture).TextInfo.ToTitleCase($($PSBoundParameters[$argument])); $arguments += " -configuration $configuration" }
+ "arch" { $arguments += " /p:TargetArchitecture=$($PSBoundParameters[$argument])" }
+ default { $arguments += " /p:$argument=$($PSBoundParameters[$argument])" }
+ }
+}
+
+if ($env:TreatWarningsAsErrors -eq 'false') {
+ $arguments += " -warnAsError 0"
+}
+
+Write-Host "& `"$PSScriptRoot/common/build.ps1`" $arguments"
+Invoke-Expression "& `"$PSScriptRoot/common/build.ps1`" $arguments"
+
+
+# Perform code coverage as the last operation, this enables the following scenarios:
+# .\build.cmd -restore -build -c Release -testCoverage
+if ($testCoverage) {
+ try {
+ # Install required toolset
+ . $PSScriptRoot/common/tools.ps1
+ InitializeDotNetCli -install $true | Out-Null
+
+ Push-Location $PSScriptRoot/../
+
+ $testResultPath = "./artifacts/TestResults/$configuration";
+
+ # Run tests and collect code coverage
+ ./.dotnet/dotnet dotnet-coverage collect --settings ./eng/CodeCoverage.config --output $testResultPath/local.cobertura.xml "build.cmd -test -configuration $configuration"
+
+ # Generate the code coverage report and open it in the browser
+ ./.dotnet/dotnet reportgenerator -reports:$testResultPath/*.cobertura.xml -targetdir:$testResultPath/CoverageResultsHtml -reporttypes:HtmlInline_AzurePipelines
+ Start-Process $testResultPath/CoverageResultsHtml/index.html
+ }
+ catch {
+ Write-Host $_.Exception.Message -Foreground "Red"
+ Write-Host $_.ScriptStackTrace -Foreground "DarkGray"
+ exit $global:LASTEXITCODE;
+ }
+ finally {
+ Pop-Location
+ }
+}
+
+exit 0
\ No newline at end of file
diff --git a/eng/build.sh b/eng/build.sh
new file mode 100755
index 000000000000..e1883c70e83c
--- /dev/null
+++ b/eng/build.sh
@@ -0,0 +1,182 @@
+#!/usr/bin/env bash
+
+set -ue
+
+source="${BASH_SOURCE[0]}"
+
+# resolve $source until the file is no longer a symlink
+while [[ -h "$source" ]]; do
+ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+ source="$(readlink "$source")"
+ # if $source was a relative symlink, we need to resolve it relative to the path where the
+ # symlink file was located
+ [[ $source != /* ]] && source="$scriptroot/$source"
+done
+scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
+
+usage()
+{
+ echo "Common settings:"
+ echo " --arch (-a) Target platform: x86, x64, arm or arm64."
+ echo " [Default: Your machine's architecture.]"
+ echo " --binaryLog (-bl) Output binary log."
+ echo " --configuration (-c) Build configuration: Debug or Release."
+ echo " [Default: Debug]"
+ echo " --help (-h) Print help and exit."
+ echo " --os Target operating system: windows, linux, or osx."
+ echo " [Default: Your machine's OS.]"
+ echo " --verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]."
+ echo " [Default: Minimal]"
+ echo ""
+
+ echo "Actions (defaults to --restore --build):"
+ echo " --build (-b) Build all source projects."
+ echo " This assumes --restore has been run already."
+ echo " --clean Clean the solution."
+ echo " --pack Package build outputs into NuGet packages."
+ echo " --publish Publish artifacts (e.g. symbols)."
+ echo " This assumes --build has been run already."
+ echo " --rebuild Rebuild all source projects."
+ echo " --restore (-r) Restore dependencies."
+ echo " --sign Sign build outputs."
+ echo " --test (-t) Incrementally builds and runs tests."
+ echo " Use in conjunction with --testnobuild to only run tests."
+ echo " --testCoverage Run unit tests and capture code coverage information."
+ echo ""
+
+ echo "Libraries settings:"
+ echo " --testnobuild Skip building tests when invoking -test."
+ echo ""
+
+ echo "Command line arguments starting with '/p:' are passed through to MSBuild."
+ echo "Arguments can also be passed in with a single hyphen."
+ echo ""
+}
+
+arguments=''
+extraargs=''
+testCoverage=false
+
+# Check if an action is passed in
+declare -a actions=("b" "build" "r" "restore" "rebuild" "testnobuild" "sign" "publish" "clean")
+actInt=($(comm -12 <(printf '%s\n' "${actions[@]/#/-}" | sort) <(printf '%s\n' "${@/#--/-}" | sort)))
+
+while [[ $# > 0 ]]; do
+ opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")"
+
+ case "$opt" in
+ -help|-h|-\?|/?)
+ usage
+ exit 0
+ ;;
+
+ -arch|-a)
+ if [ -z ${2+x} ]; then
+ echo "No architecture supplied. See help (--help) for supported architectures." 1>&2
+ exit 1
+ fi
+ passedArch="$(echo "$2" | tr "[:upper:]" "[:lower:]")"
+ case "$passedArch" in
+ x64|x86|arm|arm64)
+ arch=$passedArch
+ ;;
+ *)
+ echo "Unsupported target architecture '$2'."
+ echo "The allowed values are x86, x64, arm, arm64."
+ exit 1
+ ;;
+ esac
+ arguments="$arguments /p:TargetArchitecture=$arch"
+ shift 2
+ ;;
+
+ -configuration|-c)
+ if [ -z ${2+x} ]; then
+ echo "No configuration supplied. See help (--help) for supported configurations." 1>&2
+ exit 1
+ fi
+ passedConfig="$(echo "$2" | tr "[:upper:]" "[:lower:]")"
+ case "$passedConfig" in
+ debug|release)
+ val="$(tr '[:lower:]' '[:upper:]' <<< ${passedConfig:0:1})${passedConfig:1}"
+ ;;
+ *)
+ echo "Unsupported target configuration '$2'."
+ echo "The allowed values are Debug and Release."
+ exit 1
+ ;;
+ esac
+ arguments="$arguments -configuration $val"
+ shift 2
+ ;;
+
+ -os)
+ if [ -z ${2+x} ]; then
+ echo "No target operating system supplied. See help (--help) for supported target operating systems." 1>&2
+ exit 1
+ fi
+ passedOS="$(echo "$2" | tr "[:upper:]" "[:lower:]")"
+ case "$passedOS" in
+ windows)
+ os="windows" ;;
+ linux)
+ os="linux" ;;
+ osx)
+ os="osx" ;;
+ *)
+ echo "Unsupported target OS '$2'."
+ echo "Try 'build.sh --help' for values supported by '--os'."
+ exit 1
+ ;;
+ esac
+ arguments="$arguments /p:TargetOS=$os"
+ shift 2
+ ;;
+
+ -testnobuild)
+ arguments="$arguments /p:TestNoBuild=true"
+ shift 1
+ ;;
+
+ -testcoverage)
+ testCoverage=true
+ ;;
+
+ *)
+ extraargs="$extraargs $1"
+ shift 1
+ ;;
+ esac
+done
+
+if [ ${#actInt[@]} -eq 0 ]; then
+ arguments="-restore -build $arguments"
+fi
+
+if [[ "${TreatWarningsAsErrors:-}" == "false" ]]; then
+ arguments="$arguments -warnAsError 0"
+fi
+
+arguments="$arguments $extraargs"
+"$scriptroot/common/build.sh" $arguments
+
+
+# Perform code coverage as the last operation, this enables the following scenarios:
+# .\build.sh --restore --build --c Release --testCoverage
+if [[ "$testCoverage" == true ]]; then
+ # Install required toolset
+ . "$DIR/common/tools.sh"
+ InitializeDotNetCli true > /dev/null
+
+ repoRoot=$(realpath $DIR/../)
+ testResultPath="$repoRoot/artifacts/TestResults/$configuration"
+
+ # Run tests and collect code coverage
+ $repoRoot/.dotnet/dotnet 'dotnet-coverage' collect --settings $repoRoot/eng/CodeCoverage.config --output $testResultPath/local.cobertura.xml "$repoRoot/build.sh --test --configuration $configuration"
+
+ # Generate the code coverage report and open it in the browser
+ $repoRoot/.dotnet/dotnet reportgenerator -reports:$testResultPath/*.cobertura.xml -targetdir:$testResultPath/CoverageResultsHtml -reporttypes:HtmlInline_AzurePipelines
+ echo ""
+ echo -e "\e[32mCode coverage results:\e[0m $testResultPath/CoverageResultsHtml/index.html"
+ echo ""
+fi
\ No newline at end of file
diff --git a/eng/cake/dotnet.cake b/eng/cake/dotnet.cake
index b44ec9b05e4a..2ea746497bbf 100644
--- a/eng/cake/dotnet.cake
+++ b/eng/cake/dotnet.cake
@@ -3,7 +3,7 @@
// Contains .NET - related Cake targets
var ext = IsRunningOnWindows() ? ".exe" : "";
-var dotnetPath = $"./bin/dotnet/dotnet{ext}";
+var dotnetPath = $"./.dotnet/dotnet{ext}";
string configuration = GetBuildVariable("configuration", GetBuildVariable("BUILD_CONFIGURATION", "DEBUG"));
var localDotnet = GetBuildVariable("workloads", "local") == "local";
var vsVersion = GetBuildVariable("VS", "");
@@ -36,6 +36,14 @@ var NuGetOnlyPackages = new string[] {
"Microsoft.Maui.Resizetizer.*.{nupkg,snupkg}",
"Microsoft.AspNetCore.Components.WebView.*.{nupkg,snupkg}",
};
+public enum RuntimeVariant
+{
+ Mono,
+ NativeAOT
+}
+
+RuntimeVariant RUNTIME_VARIANT = Argument("runtimevariant", RuntimeVariant.Mono);
+bool USE_NATIVE_AOT = RUNTIME_VARIANT == RuntimeVariant.NativeAOT ? true : false;
ProcessTFMSwitches();
@@ -178,7 +186,27 @@ Task("dotnet-samples")
["RestoreConfigFile"] = tempDir.CombineWithFilePath("NuGet.config").FullPath,
};
}
- RunMSBuildWithDotNet("./Microsoft.Maui.Samples.slnf", properties, binlogPrefix: "sample-");
+
+ string projectsToBuild;
+ if (USE_NATIVE_AOT)
+ {
+ if (configuration.Equals("Debug", StringComparison.OrdinalIgnoreCase))
+ {
+ var errMsg = $"Error: Building dotnet-samples with NativeAOT is only supported in Release configuration";
+ Error(errMsg);
+ throw new Exception(errMsg);
+ }
+ projectsToBuild = "./src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj";
+ properties["_UseNativeAot"] = "true";
+ properties["RuntimeIdentifier"] = "iossimulator-x64";
+ properties["BuildIpa"] = "true";
+ }
+ else
+ {
+ projectsToBuild = "./Microsoft.Maui.Samples.slnf";
+ }
+
+ RunMSBuildWithDotNet(projectsToBuild, properties, binlogPrefix: "sample-");
});
// Builds the host app for the UI Tests
@@ -247,9 +275,10 @@ Task("dotnet-test")
var tests = new []
{
"**/Controls.Core.UnitTests.csproj",
- "**/Controls.Core.Design.UnitTests.csproj",
+ // "**/Controls.Core.Design.UnitTests.csproj",
"**/Controls.Xaml.UnitTests.csproj",
"**/SourceGen.UnitTests.csproj",
+ "**/Controls.BindingSourceGen.UnitTests.csproj",
"**/Core.UnitTests.csproj",
"**/Essentials.UnitTests.csproj",
"**/Resizetizer.UnitTests.csproj",
@@ -269,11 +298,12 @@ Task("dotnet-test")
{
try
{
- RunTestWithLocalDotNet(project.FullPath);
+ RunTestWithLocalDotNet(project.FullPath, configuration, dotnetPath);
}
catch
{
success = false;
+ Error($"Test project failed: {project}");
}
}
}
@@ -549,7 +579,7 @@ bool RunPackTarget()
Dictionary GetDotNetEnvironmentVariables()
{
Dictionary envVariables = new Dictionary();
- var dotnet = MakeAbsolute(Directory("./bin/dotnet/")).ToString();
+ var dotnet = MakeAbsolute(Directory("./.dotnet/")).ToString();
envVariables.Add("DOTNET_INSTALL_DIR", dotnet);
envVariables.Add("DOTNET_ROOT", dotnet);
@@ -568,10 +598,11 @@ Dictionary GetDotNetEnvironmentVariables()
return envVariables;
}
-void SetDotNetEnvironmentVariables()
+void SetDotNetEnvironmentVariables(string dotnetDir = null)
{
- var dotnet = MakeAbsolute(Directory("./bin/dotnet/")).ToString();
+ var dotnet = dotnetDir ?? MakeAbsolute(Directory("./.dotnet/")).ToString();
+ SetEnvironmentVariable("VSDebugger_ValidateDotnetDebugLibSignatures", "0");
SetEnvironmentVariable("DOTNET_INSTALL_DIR", dotnet);
SetEnvironmentVariable("DOTNET_ROOT", dotnet);
SetEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR", dotnet);
@@ -693,7 +724,10 @@ void RunMSBuildWithDotNet(
.SetConfiguration(configuration)
.SetMaxCpuCount(maxCpuCount)
.WithTarget(target)
- .EnableBinaryLogger(binlog);
+ .EnableBinaryLogger(binlog)
+
+ // .SetVerbosity(Verbosity.Diagnostic)
+ ;
if (warningsAsError)
{
@@ -720,9 +754,7 @@ void RunMSBuildWithDotNet(
if (!string.IsNullOrEmpty(targetFramework))
args.Append($"-f {targetFramework}");
-
- //args.Append("/tl");
-
+
return args;
};
@@ -732,15 +764,7 @@ void RunMSBuildWithDotNet(
DotNetBuild(sln, dotnetBuildSettings);
}
-void RunTestWithLocalDotNet(string csproj)
-{
- if(localDotnet)
- SetDotNetEnvironmentVariables();
-
- RunTestWithLocalDotNet(csproj, configuration, dotnetPath, argsExtra: null, noBuild: true, resultsFileNameWithoutExtension: null);
-}
-
-void RunTestWithLocalDotNet(string csproj, string config, string pathDotnet = null, Dictionary argsExtra = null, bool noBuild = false, string resultsFileNameWithoutExtension = null, string filter = "")
+void RunTestWithLocalDotNet(string csproj, string config, string pathDotnet = null, Dictionary argsExtra = null, bool noBuild = false, string resultsFileNameWithoutExtension = null, string filter = "", int maxCpuCount = 0)
{
if (string.IsNullOrWhiteSpace(filter))
{
@@ -757,6 +781,15 @@ void RunTestWithLocalDotNet(string csproj, string config, string pathDotnet = nu
var name = System.IO.Path.GetFileNameWithoutExtension(csproj);
var logDirectory = GetLogDirectory();
+ if (!string.IsNullOrWhiteSpace(pathDotnet) && localDotnet)
+ {
+ // Make sure the path doesn't refer to the dotnet executable and make path absolute
+ var localDotnetRoot = MakeAbsolute(Directory(System.IO.Path.GetDirectoryName(pathDotnet)));
+ Information("new dotnet root: {0}", localDotnetRoot);
+
+ SetDotNetEnvironmentVariables(localDotnetRoot.FullPath);
+ }
+
if (string.IsNullOrWhiteSpace(resultsFileNameWithoutExtension))
{
binlog = $"{logDirectory}/{name}-{config}.binlog";
@@ -780,18 +813,26 @@ void RunTestWithLocalDotNet(string csproj, string config, string pathDotnet = nu
$"console;verbosity=normal"
},
ResultsDirectory = GetTestResultsDirectory(),
- //Verbosity = Cake.Common.Tools.DotNetCore.DotNetCoreVerbosity.Diagnostic,
+ // Verbosity = Cake.Common.Tools.DotNetCore.DotNetCoreVerbosity.Diagnostic,
ArgumentCustomization = args =>
{
args.Append($"-bl:{binlog}");
- // args.Append($"/tl");
+ if(maxCpuCount > 0)
+ {
+ args.Append($"-maxcpucount:{maxCpuCount}");
+ }
+
if(argsExtra != null)
{
foreach(var prop in argsExtra)
{
args.Append($"/p:{prop.Key}={prop.Value}");
- }
- }
+ }
+ }
+
+ // https://github.com/microsoft/vstest/issues/5112
+ args.Append($"/p:VStestUseMSBuildOutput=false");
+
return args;
}
};
@@ -801,7 +842,11 @@ void RunTestWithLocalDotNet(string csproj, string config, string pathDotnet = nu
settings.ToolPath = pathDotnet;
}
- DotNetTest(csproj, settings);
+ try {
+ DotNetTest(csproj, settings);
+ } finally {
+ Information("Test Run complete: {0}", results);
+ }
}
DirectoryPath PrepareSeparateBuildContext(string dirName, string props = null, string targets = null)
diff --git a/eng/cake/helpers.cake b/eng/cake/helpers.cake
index 3037497718af..d299c3d7421c 100644
--- a/eng/cake/helpers.cake
+++ b/eng/cake/helpers.cake
@@ -92,18 +92,6 @@ public void PrintEnvironmentVariables()
};
}
-void SetDotNetEnvironmentVariables(string dotnetDir)
-{
- var dotnet = dotnetDir ?? MakeAbsolute(Directory("./bin/dotnet/")).ToString();
-
- SetEnvironmentVariable("DOTNET_INSTALL_DIR", dotnet);
- SetEnvironmentVariable("DOTNET_ROOT", dotnet);
- SetEnvironmentVariable("DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR", dotnet);
- SetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0");
- SetEnvironmentVariable("MSBuildEnableWorkloadResolver", "true");
- SetEnvironmentVariable("PATH", dotnet, prepend: true);
-}
-
void SetEnvironmentVariable(string name, string value, bool prepend = false)
{
var target = EnvironmentVariableTarget.Process;
diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1
index efa2fd72bfaa..5db4ad71ee2f 100644
--- a/eng/common/SetupNugetSources.ps1
+++ b/eng/common/SetupNugetSources.ps1
@@ -1,17 +1,10 @@
-# This file is a temporary workaround for internal builds to be able to restore from private AzDO feeds.
-# This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080
+# This script adds internal feeds required to build commits that depend on internal package sources. For instance,
+# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables
+# disabled internal Maestro (darc-int*) feeds.
#
-# What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry
-# under for each Maestro managed private feed. Two additional credential
-# entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport.
+# Optionally, this script also adds a credential entry for each of the internal feeds if supplied.
#
-# This script needs to be called in every job that will restore packages and which the base repo has
-# private AzDO feeds in the NuGet.config.
-#
-# See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)`
-# from the AzureDevOps-Artifact-Feeds-Pats variable group.
-#
-# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing
+# See example call for this script below.
#
# - task: PowerShell@2
# displayName: Setup Private Feeds Credentials
@@ -21,11 +14,18 @@
# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
# env:
# Token: $(dn-bot-dnceng-artifact-feeds-rw)
+#
+# Note that the NuGetAuthenticate task should be called after SetupNugetSources.
+# This ensures that:
+# - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt)
+# - The credential provider is installed.
+#
+# This logic is also abstracted into enable-internal-sources.yml.
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)][string]$ConfigFile,
- [Parameter(Mandatory = $true)][string]$Password
+ $Password
)
$ErrorActionPreference = "Stop"
@@ -48,11 +48,17 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Usern
else {
Write-Host "Package source $SourceName already present."
}
+
AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd
}
# Add a credential node for the specified source
function AddCredential($creds, $source, $username, $pwd) {
+ # If no cred supplied, don't do anything.
+ if (!$pwd) {
+ return;
+ }
+
# Looks for credential configuration for the given SourceName. Create it if none is found.
$sourceElement = $creds.SelectSingleNode($Source)
if ($sourceElement -eq $null)
@@ -110,11 +116,6 @@ if (!(Test-Path $ConfigFile -PathType Leaf)) {
ExitWithExitCode 1
}
-if (!$Password) {
- Write-PipelineTelemetryError -Category 'Build' -Message 'Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Please supply a valid PAT'
- ExitWithExitCode 1
-}
-
# Load NuGet.config
$doc = New-Object System.Xml.XmlDocument
$filename = (Get-Item $ConfigFile).FullName
@@ -127,11 +128,14 @@ if ($sources -eq $null) {
$doc.DocumentElement.AppendChild($sources) | Out-Null
}
-# Looks for a node. Create it if none is found.
-$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
-if ($creds -eq $null) {
- $creds = $doc.CreateElement("packageSourceCredentials")
- $doc.DocumentElement.AppendChild($creds) | Out-Null
+$creds = $null
+if ($Password) {
+ # Looks for a node. Create it if none is found.
+ $creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
+ if ($creds -eq $null) {
+ $creds = $doc.CreateElement("packageSourceCredentials")
+ $doc.DocumentElement.AppendChild($creds) | Out-Null
+ }
}
# Check for disabledPackageSources; we'll enable any darc-int ones we find there
@@ -153,7 +157,7 @@ if ($dotnet31Source -ne $null) {
AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password
}
-$dotnetVersions = @('5','6','7','8')
+$dotnetVersions = @('5','6','7','8','9')
foreach ($dotnetVersion in $dotnetVersions) {
$feedPrefix = "dotnet" + $dotnetVersion;
@@ -164,4 +168,4 @@ foreach ($dotnetVersion in $dotnetVersions) {
}
}
-$doc.Save($filename)
\ No newline at end of file
+$doc.Save($filename)
diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh
index d387c7eac95e..4604b61b0323 100755
--- a/eng/common/SetupNugetSources.sh
+++ b/eng/common/SetupNugetSources.sh
@@ -1,28 +1,27 @@
#!/usr/bin/env bash
-# This file is a temporary workaround for internal builds to be able to restore from private AzDO feeds.
-# This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080
+# This script adds internal feeds required to build commits that depend on internal package sources. For instance,
+# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables
+# disabled internal Maestro (darc-int*) feeds.
+#
+# Optionally, this script also adds a credential entry for each of the internal feeds if supplied.
#
-# What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry
-# under for each Maestro's managed private feed. Two additional credential
-# entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport.
-#
-# This script needs to be called in every job that will restore packages and which the base repo has
-# private AzDO feeds in the NuGet.config.
-#
-# See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)`
-# from the AzureDevOps-Artifact-Feeds-Pats variable group.
-#
-# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing.
+# See example call for this script below.
#
# - task: Bash@3
-# displayName: Setup Private Feeds Credentials
+# displayName: Setup Internal Feeds
# inputs:
# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
-# arguments: $(Build.SourcesDirectory)/NuGet.config $Token
+# arguments: $(Build.SourcesDirectory)/NuGet.config
# condition: ne(variables['Agent.OS'], 'Windows_NT')
-# env:
-# Token: $(dn-bot-dnceng-artifact-feeds-rw)
+# - task: NuGetAuthenticate@1
+#
+# Note that the NuGetAuthenticate task should be called after SetupNugetSources.
+# This ensures that:
+# - Appropriate creds are set for the added internal feeds (if not supplied to the scrupt)
+# - The credential provider is installed.
+#
+# This logic is also abstracted into enable-internal-sources.yml.
ConfigFile=$1
CredToken=$2
@@ -48,11 +47,6 @@ if [ ! -f "$ConfigFile" ]; then
ExitWithExitCode 1
fi
-if [ -z "$CredToken" ]; then
- Write-PipelineTelemetryError -category 'Build' "Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. Please supply a valid PAT"
- ExitWithExitCode 1
-fi
-
if [[ `uname -s` == "Darwin" ]]; then
NL=$'\\\n'
TB=''
@@ -105,7 +99,7 @@ if [ "$?" == "0" ]; then
PackageSources+=('dotnet3.1-internal-transport')
fi
-DotNetVersions=('5' '6' '7' '8')
+DotNetVersions=('5' '6' '7' '8' '9')
for DotNetVersion in ${DotNetVersions[@]} ; do
FeedPrefix="dotnet${DotNetVersion}";
@@ -140,18 +134,20 @@ PackageSources+="$IFS"
PackageSources+=$(grep -oh '"darc-int-[^"]*"' $ConfigFile | tr -d '"')
IFS=$PrevIFS
-for FeedName in ${PackageSources[@]} ; do
- # Check if there is no existing credential for this FeedName
- grep -i "<$FeedName>" $ConfigFile
- if [ "$?" != "0" ]; then
- echo "Adding credentials for $FeedName."
+if [ "$CredToken" ]; then
+ for FeedName in ${PackageSources[@]} ; do
+ # Check if there is no existing credential for this FeedName
+ grep -i "<$FeedName>" $ConfigFile
+ if [ "$?" != "0" ]; then
+ echo "Adding credentials for $FeedName."
- PackageSourceCredentialsNodeFooter=""
- NewCredential="${TB}${TB}<$FeedName>${NL}${NL}${NL}$FeedName>"
+ PackageSourceCredentialsNodeFooter=""
+ NewCredential="${TB}${TB}<$FeedName>${NL}${NL}${NL}$FeedName>"
- sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile
- fi
-done
+ sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile
+ fi
+ done
+fi
# Re-enable any entries in disabledPackageSources where the feed name contains darc-int
grep -i "" $ConfigFile
diff --git a/eng/common/build.cmd b/eng/common/build.cmd
new file mode 100644
index 000000000000..99daf368abae
--- /dev/null
+++ b/eng/common/build.cmd
@@ -0,0 +1,3 @@
+@echo off
+powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0build.ps1""" %*"
+exit /b %ErrorLevel%
diff --git a/eng/common/build.ps1 b/eng/common/build.ps1
index 33a6f2d0e248..438f9920c43e 100644
--- a/eng/common/build.ps1
+++ b/eng/common/build.ps1
@@ -19,6 +19,7 @@ Param(
[switch] $pack,
[switch] $publish,
[switch] $clean,
+ [switch][Alias('pb')]$productBuild,
[switch][Alias('bl')]$binaryLog,
[switch][Alias('nobl')]$excludeCIBinarylog,
[switch] $ci,
@@ -58,6 +59,7 @@ function Print-Usage() {
Write-Host " -sign Sign build outputs"
Write-Host " -publish Publish artifacts (e.g. symbols)"
Write-Host " -clean Clean the solution"
+ Write-Host " -productBuild Build the solution in the way it will be built in the full .NET product (VMR) build (short: -pb)"
Write-Host ""
Write-Host "Advanced settings:"
@@ -120,6 +122,7 @@ function Build {
/p:Deploy=$deploy `
/p:Test=$test `
/p:Pack=$pack `
+ /p:DotNetBuildRepo=$productBuild `
/p:IntegrationTest=$integrationTest `
/p:PerformanceTest=$performanceTest `
/p:Sign=$sign `
diff --git a/eng/common/build.sh b/eng/common/build.sh
index 50af40cdd2ce..ac1ee8620cd2 100755
--- a/eng/common/build.sh
+++ b/eng/common/build.sh
@@ -22,6 +22,9 @@ usage()
echo " --sourceBuild Source-build the solution (short: -sb)"
echo " Will additionally trigger the following actions: --restore, --build, --pack"
echo " If --configuration is not set explicitly, will also set it to 'Release'"
+ echo " --productBuild Build the solution in the way it will be built in the full .NET product (VMR) build (short: -pb)"
+ echo " Will additionally trigger the following actions: --restore, --build, --pack"
+ echo " If --configuration is not set explicitly, will also set it to 'Release'"
echo " --rebuild Rebuild solution"
echo " --test Run all unit tests in the solution (short: -t)"
echo " --integrationTest Run all integration tests in the solution"
@@ -59,6 +62,7 @@ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
restore=false
build=false
source_build=false
+product_build=false
rebuild=false
test=false
integration_test=false
@@ -105,7 +109,7 @@ while [[ $# > 0 ]]; do
-binarylog|-bl)
binary_log=true
;;
- -excludeCIBinarylog|-nobl)
+ -excludecibinarylog|-nobl)
exclude_ci_binary_log=true
;;
-pipelineslog|-pl)
@@ -126,6 +130,13 @@ while [[ $# > 0 ]]; do
-sourcebuild|-sb)
build=true
source_build=true
+ product_build=true
+ restore=true
+ pack=true
+ ;;
+ -productBuild|-pb)
+ build=true
+ product_build=true
restore=true
pack=true
;;
@@ -219,7 +230,9 @@ function Build {
/p:RepoRoot="$repo_root" \
/p:Restore=$restore \
/p:Build=$build \
+ /p:DotNetBuildRepo=$product_build \
/p:ArcadeBuildFromSource=$source_build \
+ /p:DotNetBuildSourceOnly=$source_build \
/p:Rebuild=$rebuild \
/p:Test=$test \
/p:Pack=$pack \
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
new file mode 100644
index 000000000000..ba53ebfbd513
--- /dev/null
+++ b/eng/common/core-templates/job/job.yml
@@ -0,0 +1,247 @@
+parameters:
+# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ cancelTimeoutInMinutes: ''
+ condition: ''
+ container: ''
+ continueOnError: false
+ dependsOn: ''
+ displayName: ''
+ pool: ''
+ steps: []
+ strategy: ''
+ timeoutInMinutes: ''
+ variables: []
+ workspace: ''
+ templateContext: {}
+
+# Job base template specific parameters
+ # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md
+ # publishing defaults
+ artifacts: ''
+ enableMicrobuild: false
+ enablePublishBuildArtifacts: false
+ enablePublishBuildAssets: false
+ enablePublishTestResults: false
+ enablePublishUsingPipelines: false
+ enableBuildRetry: false
+ mergeTestResults: false
+ testRunTitle: ''
+ testResultsFormat: ''
+ name: ''
+ componentGovernanceSteps: []
+ preSteps: []
+ artifactPublishSteps: []
+ runAsPublic: false
+
+# 1es specific parameters
+ is1ESPipeline: ''
+
+jobs:
+- job: ${{ parameters.name }}
+
+ ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}:
+ cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
+
+ ${{ if ne(parameters.condition, '') }}:
+ condition: ${{ parameters.condition }}
+
+ ${{ if ne(parameters.container, '') }}:
+ container: ${{ parameters.container }}
+
+ ${{ if ne(parameters.continueOnError, '') }}:
+ continueOnError: ${{ parameters.continueOnError }}
+
+ ${{ if ne(parameters.dependsOn, '') }}:
+ dependsOn: ${{ parameters.dependsOn }}
+
+ ${{ if ne(parameters.displayName, '') }}:
+ displayName: ${{ parameters.displayName }}
+
+ ${{ if ne(parameters.pool, '') }}:
+ pool: ${{ parameters.pool }}
+
+ ${{ if ne(parameters.strategy, '') }}:
+ strategy: ${{ parameters.strategy }}
+
+ ${{ if ne(parameters.timeoutInMinutes, '') }}:
+ timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
+
+ ${{ if ne(parameters.templateContext, '') }}:
+ templateContext: ${{ parameters.templateContext }}
+
+ variables:
+ - ${{ if ne(parameters.enableTelemetry, 'false') }}:
+ - name: DOTNET_CLI_TELEMETRY_PROFILE
+ value: '$(Build.Repository.Uri)'
+ - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}:
+ - name: EnableRichCodeNavigation
+ value: 'true'
+ # Retry signature validation up to three times, waiting 2 seconds between attempts.
+ # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
+ - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY
+ value: 3,2000
+ - ${{ each variable in parameters.variables }}:
+ # handle name-value variable syntax
+ # example:
+ # - name: [key]
+ # value: [value]
+ - ${{ if ne(variable.name, '') }}:
+ - name: ${{ variable.name }}
+ value: ${{ variable.value }}
+
+ # handle variable groups
+ - ${{ if ne(variable.group, '') }}:
+ - group: ${{ variable.group }}
+
+ # handle template variable syntax
+ # example:
+ # - template: path/to/template.yml
+ # parameters:
+ # [key]: [value]
+ - ${{ if ne(variable.template, '') }}:
+ - template: ${{ variable.template }}
+ ${{ if ne(variable.parameters, '') }}:
+ parameters: ${{ variable.parameters }}
+
+ # handle key-value variable syntax.
+ # example:
+ # - [key]: [value]
+ - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}:
+ - ${{ each pair in variable }}:
+ - name: ${{ pair.key }}
+ value: ${{ pair.value }}
+
+ # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds
+ - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - group: DotNet-HelixApi-Access
+
+ ${{ if ne(parameters.workspace, '') }}:
+ workspace: ${{ parameters.workspace }}
+
+ steps:
+ - ${{ if eq(parameters.is1ESPipeline, '') }}:
+ - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+
+ - ${{ if ne(parameters.preSteps, '') }}:
+ - ${{ each preStep in parameters.preSteps }}:
+ - ${{ preStep }}
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
+ - task: MicroBuildSigningPlugin@4
+ displayName: Install MicroBuild plugin
+ inputs:
+ signType: $(_SignType)
+ zipSources: false
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ env:
+ TeamName: $(_TeamName)
+ MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)'
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
+ - task: NuGetAuthenticate@1
+
+ - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}:
+ - task: DownloadPipelineArtifact@2
+ inputs:
+ buildType: current
+ artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }}
+ targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }}
+ itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }}
+
+ - ${{ each step in parameters.steps }}:
+ - ${{ step }}
+
+ - ${{ if eq(parameters.enableRichCodeNavigation, true) }}:
+ - task: RichCodeNavIndexer@0
+ displayName: RichCodeNav Upload
+ inputs:
+ languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }}
+ environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'internal') }}
+ richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin
+ uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }}
+ continueOnError: true
+
+ - ${{ each step in parameters.componentGovernanceSteps }}:
+ - ${{ step }}
+
+ - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - task: MicroBuildCleanup@1
+ displayName: Execute Microbuild cleanup tasks
+ condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
+ continueOnError: ${{ parameters.continueOnError }}
+ env:
+ TeamName: $(_TeamName)
+
+ # Publish test results
+ - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:
+ - task: PublishTestResults@2
+ displayName: Publish XUnit Test Results
+ inputs:
+ testResultsFormat: 'xUnit'
+ testResultsFiles: '*.xml'
+ searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
+ mergeTestResults: ${{ parameters.mergeTestResults }}
+ continueOnError: true
+ condition: always()
+ - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}:
+ - task: PublishTestResults@2
+ displayName: Publish TRX Test Results
+ inputs:
+ testResultsFormat: 'VSTest'
+ testResultsFiles: '*.trx'
+ searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
+ mergeTestResults: ${{ parameters.mergeTestResults }}
+ continueOnError: true
+ condition: always()
+
+ # gather artifacts
+ - ${{ if ne(parameters.artifacts.publish, '') }}:
+ - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
+ - task: CopyFiles@2
+ displayName: Gather binaries for publish to artifacts
+ inputs:
+ SourceFolder: 'artifacts/bin'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin'
+ - task: CopyFiles@2
+ displayName: Gather packages for publish to artifacts
+ inputs:
+ SourceFolder: 'artifacts/packages'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages'
+ - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
+ - task: CopyFiles@2
+ displayName: Gather logs for publish to artifacts
+ inputs:
+ SourceFolder: 'artifacts/log'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log'
+ continueOnError: true
+ condition: always()
+
+ - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
+ - task: CopyFiles@2
+ displayName: Gather logs for publish to artifacts
+ inputs:
+ SourceFolder: 'artifacts/log/$(_BuildConfig)'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
+ continueOnError: true
+ condition: always()
+ - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
+ - task: CopyFiles@2
+ displayName: Gather buildconfiguration for build retry
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration'
+ continueOnError: true
+ condition: always()
+ - ${{ each step in parameters.artifactPublishSteps }}:
+ - ${{ step }}
diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml
new file mode 100644
index 000000000000..00feec8ebbc3
--- /dev/null
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -0,0 +1,121 @@
+parameters:
+ # Optional: dependencies of the job
+ dependsOn: ''
+
+ # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
+ pool: ''
+
+ CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex
+ GithubPat: $(BotAccount-dotnet-bot-repo-PAT)
+
+ SourcesDirectory: $(Build.SourcesDirectory)
+ CreatePr: true
+ AutoCompletePr: false
+ ReusePr: true
+ UseLfLineEndings: true
+ UseCheckedInLocProjectJson: false
+ SkipLocProjectJsonGeneration: false
+ LanguageSet: VS_Main_Languages
+ LclSource: lclFilesInRepo
+ LclPackageId: ''
+ RepoType: gitHub
+ GitHubOrg: dotnet
+ MirrorRepo: ''
+ MirrorBranch: main
+ condition: ''
+ JobNameSuffix: ''
+ is1ESPipeline: ''
+jobs:
+- job: OneLocBuild${{ parameters.JobNameSuffix }}
+
+ dependsOn: ${{ parameters.dependsOn }}
+
+ displayName: OneLocBuild${{ parameters.JobNameSuffix }}
+
+ variables:
+ - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat
+ - name: _GenerateLocProjectArguments
+ value: -SourcesDirectory ${{ parameters.SourcesDirectory }}
+ -LanguageSet "${{ parameters.LanguageSet }}"
+ -CreateNeutralXlfs
+ - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}:
+ - name: _GenerateLocProjectArguments
+ value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson
+ - template: /eng/common/core-templates/variables/pool-providers.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ ${{ if ne(parameters.pool, '') }}:
+ pool: ${{ parameters.pool }}
+ ${{ if eq(parameters.pool, '') }}:
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022
+ os: windows
+
+ steps:
+ - ${{ if eq(parameters.is1ESPipeline, '') }}:
+ - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+
+ - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:
+ - task: Powershell@2
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1
+ arguments: $(_GenerateLocProjectArguments)
+ displayName: Generate LocProject.json
+ condition: ${{ parameters.condition }}
+
+ - task: OneLocBuild@2
+ displayName: OneLocBuild
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ inputs:
+ locProj: eng/Localize/LocProject.json
+ outDir: $(Build.ArtifactStagingDirectory)
+ lclSource: ${{ parameters.LclSource }}
+ lclPackageId: ${{ parameters.LclPackageId }}
+ isCreatePrSelected: ${{ parameters.CreatePr }}
+ isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }}
+ ${{ if eq(parameters.CreatePr, true) }}:
+ isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }}
+ ${{ if eq(parameters.RepoType, 'gitHub') }}:
+ isShouldReusePrSelected: ${{ parameters.ReusePr }}
+ packageSourceAuth: patAuth
+ patVariable: ${{ parameters.CeapexPat }}
+ ${{ if eq(parameters.RepoType, 'gitHub') }}:
+ repoType: ${{ parameters.RepoType }}
+ gitHubPatVariable: "${{ parameters.GithubPat }}"
+ ${{ if ne(parameters.MirrorRepo, '') }}:
+ isMirrorRepoSelected: true
+ gitHubOrganization: ${{ parameters.GitHubOrg }}
+ mirrorRepo: ${{ parameters.MirrorRepo }}
+ mirrorBranch: ${{ parameters.MirrorBranch }}
+ condition: ${{ parameters.condition }}
+
+ - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ args:
+ displayName: Publish Localization Files
+ pathToPublish: '$(Build.ArtifactStagingDirectory)/loc'
+ publishLocation: Container
+ artifactName: Loc
+ condition: ${{ parameters.condition }}
+
+ - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ args:
+ displayName: Publish LocProject.json
+ pathToPublish: '$(Build.SourcesDirectory)/eng/Localize/'
+ publishLocation: Container
+ artifactName: Loc
+ condition: ${{ parameters.condition }}
\ No newline at end of file
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
new file mode 100644
index 000000000000..3d3356e31967
--- /dev/null
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -0,0 +1,158 @@
+parameters:
+ configuration: 'Debug'
+
+ # Optional: condition for the job to run
+ condition: ''
+
+ # Optional: 'true' if future jobs should run even if this job fails
+ continueOnError: false
+
+ # Optional: dependencies of the job
+ dependsOn: ''
+
+ # Optional: Include PublishBuildArtifacts task
+ enablePublishBuildArtifacts: false
+
+ # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
+ pool: {}
+
+ # Optional: should run as a public build even in the internal project
+ # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
+ runAsPublic: false
+
+ # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
+ publishUsingPipelines: false
+
+ # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
+ publishAssetsImmediately: false
+
+ artifactsPublishingAdditionalParameters: ''
+
+ signingValidationAdditionalParameters: ''
+
+ is1ESPipeline: ''
+
+jobs:
+- job: Asset_Registry_Publish
+
+ dependsOn: ${{ parameters.dependsOn }}
+ timeoutInMinutes: 150
+
+ ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
+ displayName: Publish Assets
+ ${{ else }}:
+ displayName: Publish to Build Asset Registry
+
+ variables:
+ - template: /eng/common/core-templates/variables/pool-providers.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - group: Publish-Build-Assets
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: runCodesignValidationInjection
+ value: false
+ # unconditional - needed for logs publishing (redactor tool version)
+ - template: /eng/common/core-templates/post-build/common-variables.yml
+
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
+ name: NetCore1ESPool-Publishing-Internal
+ image: windows.vs2019.amd64
+ os: windows
+ steps:
+ - ${{ if eq(parameters.is1ESPipeline, '') }}:
+ - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - checkout: self
+ fetchDepth: 3
+ clean: true
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download artifact
+ inputs:
+ artifactName: AssetManifests
+ downloadPath: '$(Build.StagingDirectory)/Download'
+ checkDownloadedFiles: true
+ condition: ${{ parameters.condition }}
+ continueOnError: ${{ parameters.continueOnError }}
+
+ - task: NuGetAuthenticate@1
+
+ - task: AzureCLI@2
+ displayName: Publish Build Assets
+ inputs:
+ azureSubscription: "Darc: Maestro Production"
+ scriptType: ps
+ scriptLocation: scriptPath
+ scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
+ arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet
+ /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'
+ /p:MaestroApiEndpoint=https://maestro.dot.net
+ /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}
+ /p:OfficialBuildId=$(Build.BuildNumber)
+ condition: ${{ parameters.condition }}
+ continueOnError: ${{ parameters.continueOnError }}
+
+ - task: powershell@2
+ displayName: Create ReleaseConfigs Artifact
+ inputs:
+ targetType: inline
+ script: |
+ New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force
+ $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt"
+ Add-Content -Path $filePath -Value $(BARBuildId)
+ Add-Content -Path $filePath -Value "$(DefaultChannels)"
+ Add-Content -Path $filePath -Value $(IsStableBuild)
+
+ $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt"
+ if (Test-Path -Path $symbolExclusionfile)
+ {
+ Write-Host "SymbolExclusionFile exists"
+ Copy-Item -Path $symbolExclusionfile -Destination "$(Build.StagingDirectory)/ReleaseConfigs"
+ }
+
+ - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ args:
+ displayName: Publish ReleaseConfigs Artifact
+ pathToPublish: '$(Build.StagingDirectory)/ReleaseConfigs'
+ publishLocation: Container
+ artifactName: ReleaseConfigs
+
+ - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: AzureCLI@2
+ displayName: Publish Using Darc
+ inputs:
+ azureSubscription: "Darc: Maestro Production"
+ scriptType: ps
+ scriptLocation: scriptPath
+ scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: >
+ -BuildId $(BARBuildId)
+ -PublishingInfraVersion 3
+ -AzdoToken '$(System.AccessToken)'
+ -WaitPublishingFinish true
+ -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
+ -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+
+ - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
+ - template: /eng/common/core-templates/steps/publish-logs.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ JobLabel: 'Publish_Artifacts_Logs'
diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml
new file mode 100644
index 000000000000..c4713c8b6ede
--- /dev/null
+++ b/eng/common/core-templates/job/source-build.yml
@@ -0,0 +1,93 @@
+parameters:
+ # This template adds arcade-powered source-build to CI. The template produces a server job with a
+ # default ID 'Source_Build_Complete' to put in a dependency list if necessary.
+
+ # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed.
+ jobNamePrefix: 'Source_Build'
+
+ # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for
+ # managed-only repositories. This is an object with these properties:
+ #
+ # name: ''
+ # The name of the job. This is included in the job ID.
+ # targetRID: ''
+ # The name of the target RID to use, instead of the one auto-detected by Arcade.
+ # nonPortable: false
+ # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than
+ # linux-x64), and compiling against distro-provided packages rather than portable ones.
+ # skipPublishValidation: false
+ # Disables publishing validation. By default, a check is performed to ensure no packages are
+ # published by source-build.
+ # container: ''
+ # A container to use. Runs in docker.
+ # pool: {}
+ # A pool to use. Runs directly on an agent.
+ # buildScript: ''
+ # Specifies the build script to invoke to perform the build in the repo. The default
+ # './build.sh' should work for typical Arcade repositories, but this is customizable for
+ # difficult situations.
+ # jobProperties: {}
+ # A list of job properties to inject at the top level, for potential extensibility beyond
+ # container and pool.
+ platform: {}
+
+ is1ESPipeline: ''
+
+ # If set to true and running on a non-public project,
+ # Internal nuget and blob storage locations will be enabled.
+ # This is not enabled by default because many repositories do not need internal sources
+ # and do not need to have the required service connections approved in the pipeline.
+ enableInternalSources: false
+
+jobs:
+- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }}
+ displayName: Source-Build (${{ parameters.platform.name }})
+
+ ${{ each property in parameters.platform.jobProperties }}:
+ ${{ property.key }}: ${{ property.value }}
+
+ ${{ if ne(parameters.platform.container, '') }}:
+ container: ${{ parameters.platform.container }}
+
+ ${{ if eq(parameters.platform.pool, '') }}:
+ # The default VM host AzDO pool. This should be capable of running Docker containers: almost all
+ # source-build builds run in Docker, including the default managed platform.
+ # /eng/common/core-templates/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic
+ ${{ if eq(parameters.is1ESPipeline, 'true') }}:
+ pool:
+ ${{ if eq(variables['System.TeamProject'], 'public') }}:
+ name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]
+ demands: ImageOverride -equals build.ubuntu.2004.amd64
+ ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]
+ image: 1es-mariner-2
+ os: linux
+ ${{ else }}:
+ pool:
+ ${{ if eq(variables['System.TeamProject'], 'public') }}:
+ name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]
+ demands: ImageOverride -equals Build.Ubuntu.2204.Amd64.Open
+ ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]
+ demands: ImageOverride -equals Build.Ubuntu.2204.Amd64
+ ${{ if ne(parameters.platform.pool, '') }}:
+ pool: ${{ parameters.platform.pool }}
+
+ workspace:
+ clean: all
+
+ steps:
+ - ${{ if eq(parameters.is1ESPipeline, '') }}:
+ - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+
+ - ${{ if eq(parameters.enableInternalSources, true) }}:
+ - template: /eng/common/core-templates/steps/enable-internal-sources.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ - template: /eng/common/core-templates/steps/source-build.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ platform: ${{ parameters.platform }}
diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml
new file mode 100644
index 000000000000..205fb5b3a395
--- /dev/null
+++ b/eng/common/core-templates/job/source-index-stage1.yml
@@ -0,0 +1,81 @@
+parameters:
+ runAsPublic: false
+ sourceIndexUploadPackageVersion: 2.0.0-20240522.1
+ sourceIndexProcessBinlogPackageVersion: 1.0.1-20240522.1
+ sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
+ sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
+ preSteps: []
+ binlogPath: artifacts/log/Debug/Build.binlog
+ condition: ''
+ dependsOn: ''
+ pool: ''
+ is1ESPipeline: ''
+
+jobs:
+- job: SourceIndexStage1
+ dependsOn: ${{ parameters.dependsOn }}
+ condition: ${{ parameters.condition }}
+ variables:
+ - name: SourceIndexUploadPackageVersion
+ value: ${{ parameters.sourceIndexUploadPackageVersion }}
+ - name: SourceIndexProcessBinlogPackageVersion
+ value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }}
+ - name: SourceIndexPackageSource
+ value: ${{ parameters.sourceIndexPackageSource }}
+ - name: BinlogPath
+ value: ${{ parameters.binlogPath }}
+ - template: /eng/common/core-templates/variables/pool-providers.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ ${{ if ne(parameters.pool, '') }}:
+ pool: ${{ parameters.pool }}
+ ${{ if eq(parameters.pool, '') }}:
+ pool:
+ ${{ if eq(variables['System.TeamProject'], 'public') }}:
+ name: $(DncEngPublicBuildPool)
+ image: 1es-windows-2022-open
+ os: windows
+ ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022
+ os: windows
+
+ steps:
+ - ${{ if eq(parameters.is1ESPipeline, '') }}:
+ - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+
+ - ${{ each preStep in parameters.preSteps }}:
+ - ${{ preStep }}
+
+ - task: UseDotNet@2
+ displayName: Use .NET 8 SDK
+ inputs:
+ packageType: sdk
+ version: 8.0.x
+ installationPath: $(Agent.TempDirectory)/dotnet
+ workingDirectory: $(Agent.TempDirectory)
+
+ - script: |
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
+ displayName: Download Tools
+ # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
+ workingDirectory: $(Agent.TempDirectory)
+
+ - script: ${{ parameters.sourceIndexBuildCommand }}
+ displayName: Build Repository
+
+ - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
+ displayName: Process Binlog into indexable sln
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - task: AzureCLI@2
+ displayName: Log in to Azure and upload stage1 artifacts to source index
+ inputs:
+ azureSubscription: 'SourceDotNet Stage1 Publish'
+ addSpnToEnvironment: true
+ scriptType: 'ps'
+ scriptLocation: 'inlineScript'
+ inlineScript: |
+ $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml
new file mode 100644
index 000000000000..f2144252cc65
--- /dev/null
+++ b/eng/common/core-templates/jobs/codeql-build.yml
@@ -0,0 +1,33 @@
+parameters:
+ # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
+ continueOnError: false
+ # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ jobs: []
+ # Optional: if specified, restore and use this version of Guardian instead of the default.
+ overrideGuardianVersion: ''
+ is1ESPipeline: ''
+
+jobs:
+- template: /eng/common/core-templates/jobs/jobs.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ enableMicrobuild: false
+ enablePublishBuildArtifacts: false
+ enablePublishTestResults: false
+ enablePublishBuildAssets: false
+ enablePublishUsingPipelines: false
+ enableTelemetry: true
+
+ variables:
+ - group: Publish-Build-Assets
+ # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
+ # sync with the packages.config file.
+ - name: DefaultGuardianVersion
+ value: 0.109.0
+ - name: GuardianPackagesConfigFile
+ value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
+ - name: GuardianVersion
+ value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
+
+ jobs: ${{ parameters.jobs }}
+
diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml
new file mode 100644
index 000000000000..ea69be4341c6
--- /dev/null
+++ b/eng/common/core-templates/jobs/jobs.yml
@@ -0,0 +1,119 @@
+parameters:
+ # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
+ continueOnError: false
+
+ # Optional: Include PublishBuildArtifacts task
+ enablePublishBuildArtifacts: false
+
+ # Optional: Enable publishing using release pipelines
+ enablePublishUsingPipelines: false
+
+ # Optional: Enable running the source-build jobs to build repo from source
+ enableSourceBuild: false
+
+ # Optional: Parameters for source-build template.
+ # See /eng/common/core-templates/jobs/source-build.yml for options
+ sourceBuildParameters: []
+
+ graphFileGeneration:
+ # Optional: Enable generating the graph files at the end of the build
+ enabled: false
+ # Optional: Include toolset dependencies in the generated graph files
+ includeToolset: false
+
+ # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
+ jobs: []
+
+ # Optional: Override automatically derived dependsOn value for "publish build assets" job
+ publishBuildAssetsDependsOn: ''
+
+ # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage.
+ publishAssetsImmediately: false
+
+ # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml)
+ artifactsPublishingAdditionalParameters: ''
+ signingValidationAdditionalParameters: ''
+
+ # Optional: should run as a public build even in the internal project
+ # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
+ runAsPublic: false
+
+ enableSourceIndex: false
+ sourceIndexParams: {}
+
+ artifacts: {}
+ is1ESPipeline: ''
+
+# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
+# and some (Microbuild) should only be applied to non-PR cases for internal builds.
+
+jobs:
+- ${{ each job in parameters.jobs }}:
+ - ${{ if eq(parameters.is1ESPipeline, 'true') }}:
+ - template: /eng/common/templates-official/job/job.yml
+ parameters:
+ # pass along parameters
+ ${{ each parameter in parameters }}:
+ ${{ if ne(parameter.key, 'jobs') }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+ # pass along job properties
+ ${{ each property in job }}:
+ ${{ if ne(property.key, 'job') }}:
+ ${{ property.key }}: ${{ property.value }}
+
+ name: ${{ job.job }}
+
+ - ${{ else }}:
+ - template: /eng/common/templates/job/job.yml
+ parameters:
+ # pass along parameters
+ ${{ each parameter in parameters }}:
+ ${{ if ne(parameter.key, 'jobs') }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+ # pass along job properties
+ ${{ each property in job }}:
+ ${{ if ne(property.key, 'job') }}:
+ ${{ property.key }}: ${{ property.value }}
+
+ name: ${{ job.job }}
+
+- ${{ if eq(parameters.enableSourceBuild, true) }}:
+ - template: /eng/common/core-templates/jobs/source-build.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ allCompletedJobId: Source_Build_Complete
+ ${{ each parameter in parameters.sourceBuildParameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+- ${{ if eq(parameters.enableSourceIndex, 'true') }}:
+ - template: ../job/source-index-stage1.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ runAsPublic: ${{ parameters.runAsPublic }}
+ ${{ each parameter in parameters.sourceIndexParams }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+
+- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}:
+ - template: ../job/publish-build-assets.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ continueOnError: ${{ parameters.continueOnError }}
+ dependsOn:
+ - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:
+ - ${{ each job in parameters.publishBuildAssetsDependsOn }}:
+ - ${{ job.job }}
+ - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}:
+ - ${{ each job in parameters.jobs }}:
+ - ${{ job.job }}
+ - ${{ if eq(parameters.enableSourceBuild, true) }}:
+ - Source_Build_Complete
+
+ runAsPublic: ${{ parameters.runAsPublic }}
+ publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}
+ publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }}
+ enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
+ artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
+ signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
diff --git a/eng/common/core-templates/jobs/source-build.yml b/eng/common/core-templates/jobs/source-build.yml
new file mode 100644
index 000000000000..a10ccfbee6de
--- /dev/null
+++ b/eng/common/core-templates/jobs/source-build.yml
@@ -0,0 +1,58 @@
+parameters:
+ # This template adds arcade-powered source-build to CI. A job is created for each platform, as
+ # well as an optional server job that completes when all platform jobs complete.
+
+ # The name of the "join" job for all source-build platforms. If set to empty string, the job is
+ # not included. Existing repo pipelines can use this job depend on all source-build jobs
+ # completing without maintaining a separate list of every single job ID: just depend on this one
+ # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'.
+ allCompletedJobId: ''
+
+ # See /eng/common/core-templates/job/source-build.yml
+ jobNamePrefix: 'Source_Build'
+
+ # This is the default platform provided by Arcade, intended for use by a managed-only repo.
+ defaultManagedPlatform:
+ name: 'Managed'
+ container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream9'
+
+ # Defines the platforms on which to run build jobs. One job is created for each platform, and the
+ # object in this array is sent to the job template as 'platform'. If no platforms are specified,
+ # one job runs on 'defaultManagedPlatform'.
+ platforms: []
+
+ is1ESPipeline: ''
+
+ # If set to true and running on a non-public project,
+ # Internal nuget and blob storage locations will be enabled.
+ # This is not enabled by default because many repositories do not need internal sources
+ # and do not need to have the required service connections approved in the pipeline.
+ enableInternalSources: false
+
+jobs:
+
+- ${{ if ne(parameters.allCompletedJobId, '') }}:
+ - job: ${{ parameters.allCompletedJobId }}
+ displayName: Source-Build Complete
+ pool: server
+ dependsOn:
+ - ${{ each platform in parameters.platforms }}:
+ - ${{ parameters.jobNamePrefix }}_${{ platform.name }}
+ - ${{ if eq(length(parameters.platforms), 0) }}:
+ - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }}
+
+- ${{ each platform in parameters.platforms }}:
+ - template: /eng/common/core-templates/job/source-build.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ jobNamePrefix: ${{ parameters.jobNamePrefix }}
+ platform: ${{ platform }}
+ enableInternalSources: ${{ parameters.enableInternalSources }}
+
+- ${{ if eq(length(parameters.platforms), 0) }}:
+ - template: /eng/common/core-templates/job/source-build.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ jobNamePrefix: ${{ parameters.jobNamePrefix }}
+ platform: ${{ parameters.defaultManagedPlatform }}
+ enableInternalSources: ${{ parameters.enableInternalSources }}
diff --git a/eng/common/core-templates/post-build/common-variables.yml b/eng/common/core-templates/post-build/common-variables.yml
new file mode 100644
index 000000000000..d5627a994ae5
--- /dev/null
+++ b/eng/common/core-templates/post-build/common-variables.yml
@@ -0,0 +1,22 @@
+variables:
+ - group: Publish-Build-Assets
+
+ # Whether the build is internal or not
+ - name: IsInternalBuild
+ value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
+
+ # Default Maestro++ API Endpoint and API Version
+ - name: MaestroApiEndPoint
+ value: "https://maestro.dot.net"
+ - name: MaestroApiVersion
+ value: "2020-02-20"
+
+ - name: SourceLinkCLIVersion
+ value: 3.0.0
+ - name: SymbolToolVersion
+ value: 1.0.1
+ - name: BinlogToolVersion
+ value: 1.0.11
+
+ - name: runCodesignValidationInjection
+ value: false
diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml
new file mode 100644
index 000000000000..454fd75c7aff
--- /dev/null
+++ b/eng/common/core-templates/post-build/post-build.yml
@@ -0,0 +1,316 @@
+parameters:
+ # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.
+ # Publishing V1 is no longer supported
+ # Publishing V2 is no longer supported
+ # Publishing V3 is the default
+ - name: publishingInfraVersion
+ displayName: Which version of publishing should be used to promote the build definition?
+ type: number
+ default: 3
+ values:
+ - 3
+
+ - name: BARBuildId
+ displayName: BAR Build Id
+ type: number
+ default: 0
+
+ - name: PromoteToChannelIds
+ displayName: Channel to promote BARBuildId to
+ type: string
+ default: ''
+
+ - name: enableSourceLinkValidation
+ displayName: Enable SourceLink validation
+ type: boolean
+ default: false
+
+ - name: enableSigningValidation
+ displayName: Enable signing validation
+ type: boolean
+ default: true
+
+ - name: enableSymbolValidation
+ displayName: Enable symbol validation
+ type: boolean
+ default: false
+
+ - name: enableNugetValidation
+ displayName: Enable NuGet validation
+ type: boolean
+ default: true
+
+ - name: publishInstallersAndChecksums
+ displayName: Publish installers and checksums
+ type: boolean
+ default: true
+
+ - name: SDLValidationParameters
+ type: object
+ default:
+ enable: false
+ publishGdn: false
+ continueOnError: false
+ params: ''
+ artifactNames: ''
+ downloadArtifacts: true
+
+ # These parameters let the user customize the call to sdk-task.ps1 for publishing
+ # symbols & general artifacts as well as for signing validation
+ - name: symbolPublishingAdditionalParameters
+ displayName: Symbol publishing additional parameters
+ type: string
+ default: ''
+
+ - name: artifactsPublishingAdditionalParameters
+ displayName: Artifact publishing additional parameters
+ type: string
+ default: ''
+
+ - name: signingValidationAdditionalParameters
+ displayName: Signing validation additional parameters
+ type: string
+ default: ''
+
+ # Which stages should finish execution before post-build stages start
+ - name: validateDependsOn
+ type: object
+ default:
+ - build
+
+ - name: publishDependsOn
+ type: object
+ default:
+ - Validate
+
+ # Optional: Call asset publishing rather than running in a separate stage
+ - name: publishAssetsImmediately
+ type: boolean
+ default: false
+
+ - name: is1ESPipeline
+ type: boolean
+ default: false
+
+stages:
+- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
+ - stage: Validate
+ dependsOn: ${{ parameters.validateDependsOn }}
+ displayName: Validate Build Assets
+ variables:
+ - template: /eng/common/core-templates/post-build/common-variables.yml
+ - template: /eng/common/core-templates/variables/pool-providers.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ jobs:
+ - job:
+ displayName: NuGet Validation
+ condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true'))
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
+ name: $(DncEngInternalBuildPool)
+ image: windows.vs2022.amd64
+ os: windows
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ demands: ImageOverride -equals windows.vs2022.amd64
+
+ steps:
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: PackageArtifacts
+ checkDownloadedFiles: true
+
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1
+ arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
+
+ - job:
+ displayName: Signing Validation
+ condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true'))
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022
+ os: windows
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ demands: ImageOverride -equals windows.vs2022.amd64
+ steps:
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: PackageArtifacts
+ checkDownloadedFiles: true
+ itemPattern: |
+ **
+ !**/Microsoft.SourceBuild.Intermediate.*.nupkg
+
+ # This is necessary whenever we want to publish/restore to an AzDO private feed
+ # Since sdk-task.ps1 tries to restore packages we need to do this authentication here
+ # otherwise it'll complain about accessing a private feed.
+ - task: NuGetAuthenticate@1
+ displayName: 'Authenticate to AzDO Feeds'
+
+ # Signing validation will optionally work with the buildmanifest file which is downloaded from
+ # Azure DevOps above.
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: eng\common\sdk-task.ps1
+ arguments: -task SigningValidation -restore -msbuildEngine vs
+ /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+ /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt'
+ ${{ parameters.signingValidationAdditionalParameters }}
+
+ - template: /eng/common/core-templates/steps/publish-logs.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ StageLabel: 'Validation'
+ JobLabel: 'Signing'
+ BinlogToolVersion: $(BinlogToolVersion)
+
+ - job:
+ displayName: SourceLink Validation
+ condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022
+ os: windows
+ ${{ else }}:
+ name: $(DncEngInternalBuildPool)
+ demands: ImageOverride -equals windows.vs2022.amd64
+ steps:
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: BlobArtifacts
+ checkDownloadedFiles: true
+
+ - task: PowerShell@2
+ displayName: Validate
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1
+ arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/
+ -ExtractPath $(Agent.BuildDirectory)/Extract/
+ -GHRepoName $(Build.Repository.Name)
+ -GHCommit $(Build.SourceVersion)
+ -SourcelinkCliVersion $(SourceLinkCLIVersion)
+ continueOnError: true
+
+- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}:
+ - stage: publish_using_darc
+ ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
+ dependsOn: ${{ parameters.publishDependsOn }}
+ ${{ else }}:
+ dependsOn: ${{ parameters.validateDependsOn }}
+ displayName: Publish using Darc
+ variables:
+ - template: /eng/common/core-templates/post-build/common-variables.yml
+ - template: /eng/common/core-templates/variables/pool-providers.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ jobs:
+ - job:
+ displayName: Publish Using Darc
+ timeoutInMinutes: 120
+ pool:
+ # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ name: AzurePipelines-EO
+ image: 1ESPT-Windows2022
+ demands: Cmd
+ os: windows
+ # If it's not devdiv, it's dnceng
+ ${{ else }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
+ name: NetCore1ESPool-Publishing-Internal
+ image: windows.vs2019.amd64
+ os: windows
+ ${{ else }}:
+ name: NetCore1ESPool-Publishing-Internal
+ demands: ImageOverride -equals windows.vs2019.amd64
+ steps:
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: NuGetAuthenticate@1
+
+ - task: AzureCLI@2
+ displayName: Publish Using Darc
+ inputs:
+ azureSubscription: "Darc: Maestro Production"
+ scriptType: ps
+ scriptLocation: scriptPath
+ scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: >
+ -BuildId $(BARBuildId)
+ -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
+ -AzdoToken '$(System.AccessToken)'
+ -WaitPublishingFinish true
+ -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
+ -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml
new file mode 100644
index 000000000000..f7602980dbe7
--- /dev/null
+++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -0,0 +1,74 @@
+parameters:
+ BARBuildId: ''
+ PromoteToChannelIds: ''
+ is1ESPipeline: ''
+
+steps:
+ - ${{ if eq(parameters.is1ESPipeline, '') }}:
+ - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
+
+ - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Release Configs
+ inputs:
+ buildType: current
+ artifactName: ReleaseConfigs
+ checkDownloadedFiles: true
+
+ - task: AzureCLI@2
+ name: setReleaseVars
+ displayName: Set Release Configs Vars
+ inputs:
+ azureSubscription: "Darc: Maestro Production"
+ scriptType: pscore
+ scriptLocation: inlineScript
+ inlineScript: |
+ try {
+ if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
+ $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
+
+ $BarId = $Content | Select -Index 0
+ $Channels = $Content | Select -Index 1
+ $IsStableBuild = $Content | Select -Index 2
+
+ $AzureDevOpsProject = $Env:System_TeamProject
+ $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
+ $AzureDevOpsBuildId = $Env:Build_BuildId
+ }
+ else {
+ . $(Build.SourcesDirectory)\eng\common\tools.ps1
+ $darc = Get-Darc
+ $buildInfo = & $darc get-build `
+ --id ${{ parameters.BARBuildId }} `
+ --extended `
+ --output-format json `
+ --ci `
+ | convertFrom-Json
+
+ $BarId = ${{ parameters.BARBuildId }}
+ $Channels = $Env:PromoteToMaestroChannels -split ","
+ $Channels = $Channels -join "]["
+ $Channels = "[$Channels]"
+
+ $IsStableBuild = $buildInfo.stable
+ $AzureDevOpsProject = $buildInfo.azureDevOpsProject
+ $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
+ $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
+ }
+
+ Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId"
+ Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels"
+ Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild"
+
+ Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject"
+ Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId"
+ Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId"
+ }
+ catch {
+ Write-Host $_
+ Write-Host $_.Exception
+ Write-Host $_.ScriptStackTrace
+ exit 1
+ }
+ env:
+ PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
diff --git a/eng/common/core-templates/steps/component-governance.yml b/eng/common/core-templates/steps/component-governance.yml
new file mode 100644
index 000000000000..cf0649aa9565
--- /dev/null
+++ b/eng/common/core-templates/steps/component-governance.yml
@@ -0,0 +1,16 @@
+parameters:
+ disableComponentGovernance: false
+ componentGovernanceIgnoreDirectories: ''
+ is1ESPipeline: false
+ displayName: 'Component Detection'
+
+steps:
+- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
+ - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
+ displayName: Set skipComponentGovernanceDetection variable
+- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
+ - task: ComponentGovernanceComponentDetection@0
+ continueOnError: true
+ displayName: ${{ parameters.displayName }}
+ inputs:
+ ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
diff --git a/eng/common/core-templates/steps/enable-internal-runtimes.yml b/eng/common/core-templates/steps/enable-internal-runtimes.yml
new file mode 100644
index 000000000000..6bdbf62ac500
--- /dev/null
+++ b/eng/common/core-templates/steps/enable-internal-runtimes.yml
@@ -0,0 +1,32 @@
+# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
+# variable with the base64-encoded SAS token, by default
+
+parameters:
+- name: federatedServiceConnection
+ type: string
+ default: 'dotnetbuilds-internal-read'
+- name: outputVariableName
+ type: string
+ default: 'dotnetbuilds-internal-container-read-token-base64'
+- name: expiryInHours
+ type: number
+ default: 1
+- name: base64Encode
+ type: boolean
+ default: true
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+steps:
+- ${{ if ne(variables['System.TeamProject'], 'public') }}:
+ - template: /eng/common/core-templates/steps/get-delegation-sas.yml
+ parameters:
+ federatedServiceConnection: ${{ parameters.federatedServiceConnection }}
+ outputVariableName: ${{ parameters.outputVariableName }}
+ expiryInHours: ${{ parameters.expiryInHours }}
+ base64Encode: ${{ parameters.base64Encode }}
+ storageAccount: dotnetbuilds
+ container: internal
+ permissions: rl
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
\ No newline at end of file
diff --git a/eng/common/core-templates/steps/enable-internal-sources.yml b/eng/common/core-templates/steps/enable-internal-sources.yml
new file mode 100644
index 000000000000..64f881bffc3c
--- /dev/null
+++ b/eng/common/core-templates/steps/enable-internal-sources.yml
@@ -0,0 +1,47 @@
+parameters:
+# This is the Azure federated service connection that we log into to get an access token.
+- name: nugetFederatedServiceConnection
+ type: string
+ default: 'dnceng-artifacts-feeds-read'
+- name: is1ESPipeline
+ type: boolean
+ default: false
+# Legacy parameters to allow for PAT usage
+- name: legacyCredential
+ type: string
+ default: ''
+
+steps:
+- ${{ if ne(variables['System.TeamProject'], 'public') }}:
+ - ${{ if ne(parameters.legacyCredential, '') }}:
+ - task: PowerShell@2
+ displayName: Setup Internal Feeds
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
+ env:
+ Token: ${{ parameters.legacyCredential }}
+ # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate.
+ # If running on DevDiv, NuGetAuthenticate is not really an option. It's scoped to a single feed, and we have many feeds that
+ # may be added. Instead, we'll use the traditional approach (add cred to nuget.config), but use an account token.
+ - ${{ else }}:
+ - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ - task: PowerShell@2
+ displayName: Setup Internal Feeds
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config
+ - ${{ else }}:
+ - template: /eng/common/templates/steps/get-federated-access-token.yml
+ parameters:
+ federatedServiceConnection: ${{ parameters.nugetFederatedServiceConnection }}
+ outputVariableName: 'dnceng-artifacts-feeds-read-access-token'
+ - task: PowerShell@2
+ displayName: Setup Internal Feeds
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token)
+ # This is required in certain scenarios to install the ADO credential provider.
+ # It installed by default in some msbuild invocations (e.g. VS msbuild), but needs to be installed for others
+ # (e.g. dotnet msbuild).
+ - task: NuGetAuthenticate@1
diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml
new file mode 100644
index 000000000000..d938b60e1bb5
--- /dev/null
+++ b/eng/common/core-templates/steps/generate-sbom.yml
@@ -0,0 +1,54 @@
+# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
+# PackageName - The name of the package this SBOM represents.
+# PackageVersion - The version of the package this SBOM represents.
+# ManifestDirPath - The path of the directory where the generated manifest files will be placed
+# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
+
+parameters:
+ PackageVersion: 9.0.0
+ BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ PackageName: '.NET'
+ ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
+ IgnoreDirectories: ''
+ sbomContinueOnError: true
+ is1ESPipeline: false
+ # disable publishArtifacts if some other step is publishing the artifacts (like job.yml).
+ publishArtifacts: true
+
+steps:
+- task: PowerShell@2
+ displayName: Prep for SBOM generation in (Non-linux)
+ condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
+ inputs:
+ filePath: ./eng/common/generate-sbom-prep.ps1
+ arguments: ${{parameters.manifestDirPath}}
+
+# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
+- script: |
+ chmod +x ./eng/common/generate-sbom-prep.sh
+ ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
+ displayName: Prep for SBOM generation in (Linux)
+ condition: eq(variables['Agent.Os'], 'Linux')
+ continueOnError: ${{ parameters.sbomContinueOnError }}
+
+- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
+ displayName: 'Generate SBOM manifest'
+ continueOnError: ${{ parameters.sbomContinueOnError }}
+ inputs:
+ PackageName: ${{ parameters.packageName }}
+ BuildDropPath: ${{ parameters.buildDropPath }}
+ PackageVersion: ${{ parameters.packageVersion }}
+ ManifestDirPath: ${{ parameters.manifestDirPath }}
+ ${{ if ne(parameters.IgnoreDirectories, '') }}:
+ AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
+
+- ${{ if eq(parameters.publishArtifacts, 'true')}}:
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ args:
+ displayName: Publish SBOM manifest
+ continueOnError: ${{parameters.sbomContinueOnError}}
+ targetPath: '${{ parameters.manifestDirPath }}'
+ artifactName: $(ARTIFACT_NAME)
+
diff --git a/eng/common/core-templates/steps/get-delegation-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml
new file mode 100644
index 000000000000..d2901470a7f0
--- /dev/null
+++ b/eng/common/core-templates/steps/get-delegation-sas.yml
@@ -0,0 +1,46 @@
+parameters:
+- name: federatedServiceConnection
+ type: string
+- name: outputVariableName
+ type: string
+- name: expiryInHours
+ type: number
+ default: 1
+- name: base64Encode
+ type: boolean
+ default: false
+- name: storageAccount
+ type: string
+- name: container
+ type: string
+- name: permissions
+ type: string
+ default: 'rl'
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+steps:
+- task: AzureCLI@2
+ displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}'
+ inputs:
+ azureSubscription: ${{ parameters.federatedServiceConnection }}
+ scriptType: 'pscore'
+ scriptLocation: 'inlineScript'
+ inlineScript: |
+ # Calculate the expiration of the SAS token and convert to UTC
+ $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
+
+ $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv
+
+ if ($LASTEXITCODE -ne 0) {
+ Write-Error "Failed to generate SAS token."
+ exit 1
+ }
+
+ if ('${{ parameters.base64Encode }}' -eq 'true') {
+ $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas))
+ }
+
+ Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
+ Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas"
diff --git a/eng/common/core-templates/steps/get-federated-access-token.yml b/eng/common/core-templates/steps/get-federated-access-token.yml
new file mode 100644
index 000000000000..3a4d4410c482
--- /dev/null
+++ b/eng/common/core-templates/steps/get-federated-access-token.yml
@@ -0,0 +1,42 @@
+parameters:
+- name: federatedServiceConnection
+ type: string
+- name: outputVariableName
+ type: string
+- name: is1ESPipeline
+ type: boolean
+- name: stepName
+ type: string
+ default: 'getFederatedAccessToken'
+- name: condition
+ type: string
+ default: ''
+# Resource to get a token for. Common values include:
+# - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps
+# - 'https://storage.azure.com/' for storage
+# Defaults to Azure DevOps
+- name: resource
+ type: string
+ default: '499b84ac-1321-427f-aa17-267ca6975798'
+- name: isStepOutputVariable
+ type: boolean
+ default: false
+
+steps:
+- task: AzureCLI@2
+ displayName: 'Getting federated access token for feeds'
+ name: ${{ parameters.stepName }}
+ ${{ if ne(parameters.condition, '') }}:
+ condition: ${{ parameters.condition }}
+ inputs:
+ azureSubscription: ${{ parameters.federatedServiceConnection }}
+ scriptType: 'pscore'
+ scriptLocation: 'inlineScript'
+ inlineScript: |
+ $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv
+ if ($LASTEXITCODE -ne 0) {
+ Write-Error "Failed to get access token for resource '${{ parameters.resource }}'"
+ exit 1
+ }
+ Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
+ Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken"
\ No newline at end of file
diff --git a/eng/common/core-templates/steps/publish-build-artifacts.yml b/eng/common/core-templates/steps/publish-build-artifacts.yml
new file mode 100644
index 000000000000..f24ce346684e
--- /dev/null
+++ b/eng/common/core-templates/steps/publish-build-artifacts.yml
@@ -0,0 +1,20 @@
+parameters:
+- name: is1ESPipeline
+ type: boolean
+ default: false
+- name: args
+ type: object
+ default: {}
+steps:
+- ${{ if ne(parameters.is1ESPipeline, true) }}:
+ - template: /eng/common/templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ ${{ each parameter in parameters.args }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+- ${{ else }}:
+ - template: /eng/common/templates-official/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ ${{ each parameter in parameters.args }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml
new file mode 100644
index 000000000000..80788c523191
--- /dev/null
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -0,0 +1,58 @@
+parameters:
+ StageLabel: ''
+ JobLabel: ''
+ CustomSensitiveDataList: ''
+ # A default - in case value from eng/common/core-templates/post-build/common-variables.yml is not passed
+ BinlogToolVersion: '1.0.11'
+ is1ESPipeline: false
+
+steps:
+- task: Powershell@2
+ displayName: Prepare Binlogs to Upload
+ inputs:
+ targetType: inline
+ script: |
+ New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
+ Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
+ continueOnError: true
+ condition: always()
+
+- task: PowerShell@2
+ displayName: Redact Logs
+ inputs:
+ filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1
+ # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml
+ # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt'
+ # If the file exists - sensitive data for redaction will be sourced from it
+ # (single entry per line, lines starting with '# ' are considered comments and skipped)
+ arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs'
+ -BinlogToolVersion ${{parameters.BinlogToolVersion}}
+ -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt'
+ '$(publishing-dnceng-devdiv-code-r-build-re)'
+ '$(MaestroAccessToken)'
+ '$(dn-bot-all-orgs-artifact-feeds-rw)'
+ '$(akams-client-id)'
+ '$(microsoft-symbol-server-pat)'
+ '$(symweb-symbol-server-pat)'
+ '$(dn-bot-all-orgs-build-rw-code-rw)'
+ ${{parameters.CustomSensitiveDataList}}
+ continueOnError: true
+ condition: always()
+
+- task: CopyFiles@2
+ displayName: Gather post build logs
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
+
+- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ args:
+ displayName: Publish Logs
+ pathToPublish: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
+ publishLocation: Container
+ artifactName: PostBuildLogs
+ continueOnError: true
+ condition: always()
diff --git a/eng/common/core-templates/steps/publish-pipeline-artifacts.yml b/eng/common/core-templates/steps/publish-pipeline-artifacts.yml
new file mode 100644
index 000000000000..2efec04dc2c1
--- /dev/null
+++ b/eng/common/core-templates/steps/publish-pipeline-artifacts.yml
@@ -0,0 +1,20 @@
+parameters:
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+- name: args
+ type: object
+ default: {}
+
+steps:
+- ${{ if ne(parameters.is1ESPipeline, true) }}:
+ - template: /eng/common/templates/steps/publish-pipeline-artifacts.yml
+ parameters:
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
+- ${{ else }}:
+ - template: /eng/common/templates-official/steps/publish-pipeline-artifacts.yml
+ parameters:
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/core-templates/steps/retain-build.yml b/eng/common/core-templates/steps/retain-build.yml
new file mode 100644
index 000000000000..83d97a26a01f
--- /dev/null
+++ b/eng/common/core-templates/steps/retain-build.yml
@@ -0,0 +1,28 @@
+parameters:
+ # Optional azure devops PAT with build execute permissions for the build's organization,
+ # only needed if the build that should be retained ran on a different organization than
+ # the pipeline where this template is executing from
+ Token: ''
+ # Optional BuildId to retain, defaults to the current running build
+ BuildId: ''
+ # Azure devops Organization URI for the build in the https://dev.azure.com/ format.
+ # Defaults to the organization the current pipeline is running on
+ AzdoOrgUri: '$(System.CollectionUri)'
+ # Azure devops project for the build. Defaults to the project the current pipeline is running on
+ AzdoProject: '$(System.TeamProject)'
+
+steps:
+ - task: powershell@2
+ inputs:
+ targetType: 'filePath'
+ filePath: eng/common/retain-build.ps1
+ pwsh: true
+ arguments: >
+ -AzdoOrgUri: ${{parameters.AzdoOrgUri}}
+ -AzdoProject ${{parameters.AzdoProject}}
+ -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }}
+ -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}}
+ displayName: Enable permanent build retention
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ BUILD_ID: $(Build.BuildId)
\ No newline at end of file
diff --git a/eng/common/core-templates/steps/send-to-helix.yml b/eng/common/core-templates/steps/send-to-helix.yml
new file mode 100644
index 000000000000..68fa739c4ab2
--- /dev/null
+++ b/eng/common/core-templates/steps/send-to-helix.yml
@@ -0,0 +1,93 @@
+# Please remember to update the documentation if you make changes to these parameters!
+parameters:
+ HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/
+ HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/'
+ HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number
+ HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues
+ HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group
+ 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
+ HelixPreCommands: '' # optional -- commands to run before Helix work item execution
+ HelixPostCommands: '' # optional -- commands to run after Helix work item execution
+ WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects
+ WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects
+ WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects
+ CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload
+ XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true
+ XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects
+ XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects
+ XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner
+ XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects
+ IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion
+ DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
+ DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
+ WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget."
+ IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set
+ HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net )
+ Creator: '' # optional -- if the build is external, use this to specify who is sending the job
+ DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO
+ condition: succeeded() # optional -- condition for step to execute; defaults to succeeded()
+ continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false
+
+steps:
+ - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env: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 }}
+ 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 ${{ 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 }}
+ 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/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml
new file mode 100644
index 000000000000..2915d29bb7f6
--- /dev/null
+++ b/eng/common/core-templates/steps/source-build.yml
@@ -0,0 +1,129 @@
+parameters:
+ # This template adds arcade-powered source-build to CI.
+
+ # This is a 'steps' template, and is intended for advanced scenarios where the existing build
+ # infra has a careful build methodology that must be followed. For example, a repo
+ # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline
+ # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to
+ # GitHub. Using this steps template leaves room for that infra to be included.
+
+ # Defines the platform on which to run the steps. See 'eng/common/core-templates/job/source-build.yml'
+ # for details. The entire object is described in the 'job' template for simplicity, even though
+ # the usage of the properties on this object is split between the 'job' and 'steps' templates.
+ platform: {}
+ is1ESPipeline: false
+
+steps:
+# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.)
+- script: |
+ set -x
+ df -h
+
+ # If file changes are detected, set CopyWipIntoInnerSourceBuildRepo to copy the WIP changes into the inner source build repo.
+ internalRestoreArgs=
+ if ! git diff --quiet; then
+ internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'
+ # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.
+ # This only works if there is a username/email configured, which won't be the case in most CI runs.
+ git config --get user.email
+ if [ $? -ne 0 ]; then
+ git config user.email dn-bot@microsoft.com
+ git config user.name dn-bot
+ fi
+ fi
+
+ # If building on the internal project, the internal storage variable may be available (usually only if needed)
+ # In that case, add variables to allow the download of internal runtimes if the specified versions are not found
+ # in the default public locations.
+ internalRuntimeDownloadArgs=
+ if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
+ internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
+ fi
+
+ buildConfig=Release
+ # Check if AzDO substitutes in a build config from a variable, and use it if so.
+ if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then
+ buildConfig='$(_BuildConfig)'
+ fi
+
+ officialBuildArgs=
+ if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then
+ officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'
+ fi
+
+ targetRidArgs=
+ if [ '${{ parameters.platform.targetRID }}' != '' ]; then
+ targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
+ fi
+
+ runtimeOsArgs=
+ if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then
+ runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'
+ fi
+
+ baseOsArgs=
+ if [ '${{ parameters.platform.baseOS }}' != '' ]; then
+ baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}'
+ fi
+
+ publishArgs=
+ if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then
+ publishArgs='--publish'
+ fi
+
+ assetManifestFileName=SourceBuild_RidSpecific.xml
+ if [ '${{ parameters.platform.name }}' != '' ]; then
+ assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml
+ fi
+
+ ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \
+ --configuration $buildConfig \
+ --restore --build --pack $publishArgs -bl \
+ $officialBuildArgs \
+ $internalRuntimeDownloadArgs \
+ $internalRestoreArgs \
+ $targetRidArgs \
+ $runtimeOsArgs \
+ $baseOsArgs \
+ /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
+ /p:ArcadeBuildFromSource=true \
+ /p:DotNetBuildSourceOnly=true \
+ /p:DotNetBuildRepo=true \
+ /p:AssetManifestFileName=$assetManifestFileName
+ displayName: Build
+
+# Upload build logs for diagnosis.
+- task: CopyFiles@2
+ displayName: Prepare BuildLogs staging directory
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)'
+ Contents: |
+ **/*.log
+ **/*.binlog
+ artifacts/sb/prebuilt-report/**
+ TargetFolder: '$(Build.StagingDirectory)/BuildLogs'
+ CleanTargetFolder: true
+ continueOnError: true
+ condition: succeededOrFailed()
+
+- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
+ parameters:
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ args:
+ displayName: Publish BuildLogs
+ targetPath: '$(Build.StagingDirectory)/BuildLogs'
+ artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
+ continueOnError: true
+ condition: succeededOrFailed()
+ sbomEnabled: false # we don't need SBOM for logs
+
+# Manually inject component detection so that we can ignore the source build upstream cache, which contains
+# a nupkg cache of input packages (a local feed).
+# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir'
+# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets
+- template: /eng/common/core-templates/steps/component-governance.yml
+ parameters:
+ displayName: Component Detection (Exclude upstream cache)
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ componentGovernanceIgnoreDirectories: '$(Build.SourcesDirectory)/artifacts/sb/src/artifacts/obj/source-built-upstream-cache'
+ disableComponentGovernance: ${{ eq(variables['System.TeamProject'], 'public') }}
diff --git a/eng/common/core-templates/variables/pool-providers.yml b/eng/common/core-templates/variables/pool-providers.yml
new file mode 100644
index 000000000000..41053d382a2e
--- /dev/null
+++ b/eng/common/core-templates/variables/pool-providers.yml
@@ -0,0 +1,8 @@
+parameters:
+ is1ESPipeline: false
+
+variables:
+ - ${{ if eq(parameters.is1ESPipeline, 'true') }}:
+ - template: /eng/common/templates-official/variables/pool-providers.yml
+ - ${{ else }}:
+ - template: /eng/common/templates/variables/pool-providers.yml
\ No newline at end of file
diff --git a/eng/common/cross/armel/sources.list.jessie b/eng/common/cross/armel/sources.list.jessie
deleted file mode 100644
index 3d9c3059d897..000000000000
--- a/eng/common/cross/armel/sources.list.jessie
+++ /dev/null
@@ -1,3 +0,0 @@
-# Debian (jessie) # Stable
-deb http://ftp.debian.org/debian/ jessie main contrib non-free
-deb-src http://ftp.debian.org/debian/ jessie main contrib non-free
diff --git a/eng/common/cross/armv6/sources.list.buster b/eng/common/cross/armv6/sources.list.buster
deleted file mode 100644
index f27fc4fb346b..000000000000
--- a/eng/common/cross/armv6/sources.list.buster
+++ /dev/null
@@ -1,2 +0,0 @@
-deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
-deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
diff --git a/eng/common/cross/build-android-rootfs.sh b/eng/common/cross/build-android-rootfs.sh
index f163fb9dae96..7e9ba2b75ed3 100755
--- a/eng/common/cross/build-android-rootfs.sh
+++ b/eng/common/cross/build-android-rootfs.sh
@@ -5,15 +5,15 @@ __NDK_Version=r21
usage()
{
echo "Creates a toolchain and sysroot used for cross-compiling for Android."
- echo.
+ echo
echo "Usage: $0 [BuildArch] [ApiLevel]"
- echo.
+ echo
echo "BuildArch is the target architecture of Android. Currently only arm64 is supported."
echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html"
- echo.
+ echo
echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior"
echo "by setting the TOOLCHAIN_DIR environment variable"
- echo.
+ echo
echo "By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-$__NDK_Version directory. If you already have an NDK installation,"
echo "you can set the NDK_DIR environment variable to have this script use that installation of the NDK."
echo "By default, this script will generate a file, android_platform, in the root of the ROOTFS_DIR directory that contains the RID for the supported and tested Android build: android.28-arm64. This file is to replace '/etc/os-release', which is not available for Android."
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index 9caf9b021dbd..4b5e8d7166bd 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -8,7 +8,7 @@ usage()
echo "BuildArch can be: arm(default), arm64, armel, armv6, ppc64le, riscv64, s390x, x64, x86"
echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine"
echo " for alpine can be specified with version: alpineX.YY or alpineedge"
- echo " for FreeBSD can be: freebsd12, freebsd13"
+ echo " for FreeBSD can be: freebsd13, freebsd14"
echo " for illumos can be: illumos"
echo " for Haiku can be: haiku."
echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD"
@@ -30,7 +30,8 @@ __IllumosArch=arm7
__HaikuArch=arm
__QEMUArch=arm
__UbuntuArch=armhf
-__UbuntuRepo="http://ports.ubuntu.com/"
+__UbuntuRepo=
+__UbuntuSuites="updates security backports"
__LLDB_Package="liblldb-3.9-dev"
__SkipUnmount=0
@@ -71,9 +72,9 @@ __AlpinePackages+=" krb5-dev"
__AlpinePackages+=" openssl-dev"
__AlpinePackages+=" zlib-dev"
-__FreeBSDBase="12.4-RELEASE"
+__FreeBSDBase="13.3-RELEASE"
__FreeBSDPkg="1.17.0"
-__FreeBSDABI="12"
+__FreeBSDABI="13"
__FreeBSDPackages="libunwind"
__FreeBSDPackages+=" icu"
__FreeBSDPackages+=" libinotify"
@@ -129,6 +130,7 @@ __AlpineKeys='
616db30d:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0\nlIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm\na6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw\ntO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C\nUS/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP\nhP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv\nLSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0\nx9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF\nwmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG\nLPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV\nGZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C\n8CM1S15HxV78s9dFntEqIokCAwEAAQ==
'
__Keyring=
+__KeyringFile="/usr/share/keyrings/ubuntu-archive-keyring.gpg"
__SkipSigCheck=0
__UseMirror=0
@@ -142,7 +144,6 @@ while :; do
case $lowerI in
-\?|-h|--help)
usage
- exit 1
;;
arm)
__BuildArch=arm
@@ -163,6 +164,7 @@ while :; do
__UbuntuArch=armel
__UbuntuRepo="http://ftp.debian.org/debian/"
__CodeName=jessie
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
;;
armv6)
__BuildArch=armv6
@@ -170,10 +172,12 @@ while :; do
__QEMUArch=arm
__UbuntuRepo="http://raspbian.raspberrypi.org/raspbian/"
__CodeName=buster
+ __KeyringFile="/usr/share/keyrings/raspbian-archive-keyring.gpg"
__LLDB_Package="liblldb-6.0-dev"
+ __UbuntuSuites=
- if [[ -e "/usr/share/keyrings/raspbian-archive-keyring.gpg" ]]; then
- __Keyring="--keyring /usr/share/keyrings/raspbian-archive-keyring.gpg"
+ if [[ -e "$__KeyringFile" ]]; then
+ __Keyring="--keyring $__KeyringFile"
fi
;;
riscv64)
@@ -182,13 +186,8 @@ while :; do
__AlpinePackages="${__AlpinePackages// lldb-dev/}"
__QEMUArch=riscv64
__UbuntuArch=riscv64
- __UbuntuRepo="http://deb.debian.org/debian-ports"
__UbuntuPackages="${__UbuntuPackages// libunwind8-dev/}"
unset __LLDB_Package
-
- if [[ -e "/usr/share/keyrings/debian-ports-archive-keyring.gpg" ]]; then
- __Keyring="--keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg --include=debian-ports-archive-keyring"
- fi
;;
ppc64le)
__BuildArch=ppc64le
@@ -229,12 +228,19 @@ while :; do
__UbuntuRepo="http://archive.ubuntu.com/ubuntu/"
;;
lldb*)
- version="${lowerI/lldb/}"
- parts=(${version//./ })
+ version="$(echo "$lowerI" | tr -d '[:alpha:]-=')"
+ majorVersion="${version%%.*}"
+
+ [ -z "${version##*.*}" ] && minorVersion="${version#*.}"
+ if [ -z "$minorVersion" ]; then
+ minorVersion=0
+ fi
# for versions > 6.0, lldb has dropped the minor version
- if [[ "${parts[0]}" -gt 6 ]]; then
- version="${parts[0]}"
+ if [ "$majorVersion" -le 6 ]; then
+ version="$majorVersion.$minorVersion"
+ else
+ version="$majorVersion"
fi
__LLDB_Package="liblldb-${version}-dev"
@@ -243,15 +249,19 @@ while :; do
unset __LLDB_Package
;;
llvm*)
- version="${lowerI/llvm/}"
- parts=(${version//./ })
- __LLVM_MajorVersion="${parts[0]}"
- __LLVM_MinorVersion="${parts[1]}"
-
- # for versions > 6.0, llvm has dropped the minor version
- if [[ -z "$__LLVM_MinorVersion" && "$__LLVM_MajorVersion" -le 6 ]]; then
- __LLVM_MinorVersion=0;
+ version="$(echo "$lowerI" | tr -d '[:alpha:]-=')"
+ __LLVM_MajorVersion="${version%%.*}"
+
+ [ -z "${version##*.*}" ] && __LLVM_MinorVersion="${version#*.}"
+ if [ -z "$__LLVM_MinorVersion" ]; then
+ __LLVM_MinorVersion=0
+ fi
+
+ # for versions > 6.0, lldb has dropped the minor version
+ if [ "$__LLVM_MajorVersion" -gt 6 ]; then
+ __LLVM_MinorVersion=
fi
+
;;
xenial) # Ubuntu 16.04
if [[ "$__CodeName" != "jessie" ]]; then
@@ -278,8 +288,17 @@ while :; do
__CodeName=jammy
fi
;;
+ noble) # Ubuntu 24.04
+ if [[ "$__CodeName" != "jessie" ]]; then
+ __CodeName=noble
+ fi
+ if [[ -n "$__LLDB_Package" ]]; then
+ __LLDB_Package="liblldb-18-dev"
+ fi
+ ;;
jessie) # Debian 8
__CodeName=jessie
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
__UbuntuRepo="http://ftp.debian.org/debian/"
@@ -288,6 +307,7 @@ while :; do
stretch) # Debian 9
__CodeName=stretch
__LLDB_Package="liblldb-6.0-dev"
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
__UbuntuRepo="http://ftp.debian.org/debian/"
@@ -296,6 +316,7 @@ while :; do
buster) # Debian 10
__CodeName=buster
__LLDB_Package="liblldb-6.0-dev"
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
__UbuntuRepo="http://ftp.debian.org/debian/"
@@ -303,6 +324,15 @@ while :; do
;;
bullseye) # Debian 11
__CodeName=bullseye
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
+
+ if [[ -z "$__UbuntuRepo" ]]; then
+ __UbuntuRepo="http://ftp.debian.org/debian/"
+ fi
+ ;;
+ bookworm) # Debian 12
+ __CodeName=bookworm
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
__UbuntuRepo="http://ftp.debian.org/debian/"
@@ -310,6 +340,7 @@ while :; do
;;
sid) # Debian sid
__CodeName=sid
+ __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
__UbuntuRepo="http://ftp.debian.org/debian/"
@@ -323,25 +354,24 @@ while :; do
alpine*)
__CodeName=alpine
__UbuntuRepo=
- version="${lowerI/alpine/}"
- if [[ "$version" == "edge" ]]; then
+ if [[ "$lowerI" == "alpineedge" ]]; then
__AlpineVersion=edge
else
- parts=(${version//./ })
- __AlpineMajorVersion="${parts[0]}"
- __AlpineMinoVersion="${parts[1]}"
- __AlpineVersion="$__AlpineMajorVersion.$__AlpineMinoVersion"
+ version="$(echo "$lowerI" | tr -d '[:alpha:]-=')"
+ __AlpineMajorVersion="${version%%.*}"
+ __AlpineMinorVersion="${version#*.}"
+ __AlpineVersion="$__AlpineMajorVersion.$__AlpineMinorVersion"
fi
;;
- freebsd12)
+ freebsd13)
__CodeName=freebsd
__SkipUnmount=1
;;
- freebsd13)
+ freebsd14)
__CodeName=freebsd
- __FreeBSDBase="13.2-RELEASE"
- __FreeBSDABI="13"
+ __FreeBSDBase="14.0-RELEASE"
+ __FreeBSDABI="14"
__SkipUnmount=1
;;
illumos)
@@ -420,6 +450,10 @@ fi
__UbuntuPackages+=" ${__LLDB_Package:-}"
+if [[ -z "$__UbuntuRepo" ]]; then
+ __UbuntuRepo="http://ports.ubuntu.com/"
+fi
+
if [[ -n "$__LLVM_MajorVersion" ]]; then
__UbuntuPackages+=" libclang-common-${__LLVM_MajorVersion}${__LLVM_MinorVersion:+.$__LLVM_MinorVersion}-dev"
fi
@@ -442,13 +476,39 @@ fi
mkdir -p "$__RootfsDir"
__RootfsDir="$( cd "$__RootfsDir" && pwd )"
+__hasWget=
+ensureDownloadTool()
+{
+ if command -v wget &> /dev/null; then
+ __hasWget=1
+ elif command -v curl &> /dev/null; then
+ __hasWget=0
+ else
+ >&2 echo "ERROR: either wget or curl is required by this script."
+ exit 1
+ fi
+}
+
if [[ "$__CodeName" == "alpine" ]]; then
__ApkToolsVersion=2.12.11
- __ApkToolsSHA512SUM=53e57b49230da07ef44ee0765b9592580308c407a8d4da7125550957bb72cb59638e04f8892a18b584451c8d841d1c7cb0f0ab680cc323a3015776affaa3be33
__ApkToolsDir="$(mktemp -d)"
__ApkKeysDir="$(mktemp -d)"
+ arch="$(uname -m)"
- wget "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic//v$__ApkToolsVersion/x86_64/apk.static" -P "$__ApkToolsDir"
+ ensureDownloadTool
+
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -P "$__ApkToolsDir" "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static"
+ else
+ curl -SLO --create-dirs --output-dir "$__ApkToolsDir" "https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v$__ApkToolsVersion/$arch/apk.static"
+ fi
+ if [[ "$arch" == "x86_64" ]]; then
+ __ApkToolsSHA512SUM="53e57b49230da07ef44ee0765b9592580308c407a8d4da7125550957bb72cb59638e04f8892a18b584451c8d841d1c7cb0f0ab680cc323a3015776affaa3be33"
+ elif [[ "$arch" == "aarch64" ]]; then
+ __ApkToolsSHA512SUM="9e2b37ecb2b56c05dad23d379be84fd494c14bd730b620d0d576bda760588e1f2f59a7fcb2f2080577e0085f23a0ca8eadd993b4e61c2ab29549fdb71969afd0"
+ else
+ echo "WARNING: add missing hash for your host architecture. To find the value, use: 'find /tmp -name apk.static -exec sha512sum {} \;'"
+ fi
echo "$__ApkToolsSHA512SUM $__ApkToolsDir/apk.static" | sha512sum -c
chmod +x "$__ApkToolsDir/apk.static"
@@ -477,20 +537,23 @@ if [[ "$__CodeName" == "alpine" ]]; then
fi
# initialize DB
+ # shellcheck disable=SC2086
"$__ApkToolsDir/apk.static" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
-U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" --initdb add
if [[ "$__AlpineLlvmLibsLookup" == 1 ]]; then
+ # shellcheck disable=SC2086
__AlpinePackages+=" $("$__ApkToolsDir/apk.static" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
-U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" \
- search 'llvm*-libs' | sort | tail -1 | sed 's/-[^-]*//2g')"
+ search 'llvm*-libs' | grep -E '^llvm' | sort | tail -1 | sed 's/-[^-]*//2g')"
fi
# install all packages in one go
+ # shellcheck disable=SC2086
"$__ApkToolsDir/apk.static" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
-X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
@@ -501,12 +564,23 @@ if [[ "$__CodeName" == "alpine" ]]; then
elif [[ "$__CodeName" == "freebsd" ]]; then
mkdir -p "$__RootfsDir"/usr/local/etc
JOBS=${MAXJOBS:="$(getconf _NPROCESSORS_ONLN)"}
- wget -O - "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version
+
+ ensureDownloadTool
+
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version
+ else
+ curl -SL "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version
+ fi
echo "ABI = \"FreeBSD:${__FreeBSDABI}:${__FreeBSDMachineArch}\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > "${__RootfsDir}"/usr/local/etc/pkg.conf
echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"${__RootfsDir}/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf
mkdir -p "$__RootfsDir"/tmp
# get and build package manager
- wget -O - "https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz" | tar -C "$__RootfsDir"/tmp -zxf -
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- "https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz" | tar -C "$__RootfsDir"/tmp -zxf -
+ else
+ curl -SL "https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz" | tar -C "$__RootfsDir"/tmp -zxf -
+ fi
cd "$__RootfsDir/tmp/pkg-${__FreeBSDPkg}"
# needed for install to succeed
mkdir -p "$__RootfsDir"/host/etc
@@ -514,27 +588,43 @@ elif [[ "$__CodeName" == "freebsd" ]]; then
rm -rf "$__RootfsDir/tmp/pkg-${__FreeBSDPkg}"
# install packages we need.
INSTALL_AS_USER=$(whoami) "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf update
+ # shellcheck disable=SC2086
INSTALL_AS_USER=$(whoami) "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf install --yes $__FreeBSDPackages
elif [[ "$__CodeName" == "illumos" ]]; then
mkdir "$__RootfsDir/tmp"
pushd "$__RootfsDir/tmp"
JOBS=${MAXJOBS:="$(getconf _NPROCESSORS_ONLN)"}
+
+ ensureDownloadTool
+
echo "Downloading sysroot."
- wget -O - https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C "$__RootfsDir" -xzf -
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C "$__RootfsDir" -xzf -
+ else
+ curl -SL https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C "$__RootfsDir" -xzf -
+ fi
echo "Building binutils. Please wait.."
- wget -O - https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.bz2 | tar -xjf -
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- https://ftp.gnu.org/gnu/binutils/binutils-2.42.tar.xz | tar -xJf -
+ else
+ curl -SL https://ftp.gnu.org/gnu/binutils/binutils-2.42.tar.xz | tar -xJf -
+ fi
mkdir build-binutils && cd build-binutils
- ../binutils-2.33.1/configure --prefix="$__RootfsDir" --target="${__illumosArch}-sun-solaris2.10" --program-prefix="${__illumosArch}-illumos-" --with-sysroot="$__RootfsDir"
+ ../binutils-2.42/configure --prefix="$__RootfsDir" --target="${__illumosArch}-sun-solaris2.11" --program-prefix="${__illumosArch}-illumos-" --with-sysroot="$__RootfsDir"
make -j "$JOBS" && make install && cd ..
echo "Building gcc. Please wait.."
- wget -O - https://ftp.gnu.org/gnu/gcc/gcc-8.4.0/gcc-8.4.0.tar.xz | tar -xJf -
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- https://ftp.gnu.org/gnu/gcc/gcc-13.3.0/gcc-13.3.0.tar.xz | tar -xJf -
+ else
+ curl -SL https://ftp.gnu.org/gnu/gcc/gcc-13.3.0/gcc-13.3.0.tar.xz | tar -xJf -
+ fi
CFLAGS="-fPIC"
CXXFLAGS="-fPIC"
CXXFLAGS_FOR_TARGET="-fPIC"
CFLAGS_FOR_TARGET="-fPIC"
export CFLAGS CXXFLAGS CXXFLAGS_FOR_TARGET CFLAGS_FOR_TARGET
mkdir build-gcc && cd build-gcc
- ../gcc-8.4.0/configure --prefix="$__RootfsDir" --target="${__illumosArch}-sun-solaris2.10" --program-prefix="${__illumosArch}-illumos-" --with-sysroot="$__RootfsDir" --with-gnu-as \
+ ../gcc-13.3.0/configure --prefix="$__RootfsDir" --target="${__illumosArch}-sun-solaris2.11" --program-prefix="${__illumosArch}-illumos-" --with-sysroot="$__RootfsDir" --with-gnu-as \
--with-gnu-ld --disable-nls --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libcilkrts --disable-libada --disable-libsanitizer \
--disable-libquadmath-support --disable-shared --enable-tls
make -j "$JOBS" && make install && cd ..
@@ -542,9 +632,13 @@ elif [[ "$__CodeName" == "illumos" ]]; then
if [[ "$__UseMirror" == 1 ]]; then
BaseUrl=https://pkgsrc.smartos.skylime.net
fi
- BaseUrl="$BaseUrl/packages/SmartOS/trunk/${__illumosArch}/All"
+ BaseUrl="$BaseUrl/packages/SmartOS/2019Q4/${__illumosArch}/All"
echo "Downloading manifest"
- wget "$BaseUrl"
+ if [[ "$__hasWget" == 1 ]]; then
+ wget "$BaseUrl"
+ else
+ curl -SLO "$BaseUrl"
+ fi
echo "Downloading dependencies."
read -ra array <<<"$__IllumosPackages"
for package in "${array[@]}"; do
@@ -552,7 +646,11 @@ elif [[ "$__CodeName" == "illumos" ]]; then
# find last occurrence of package in listing and extract its name
package="$(sed -En '/.*href="('"$package"'-[0-9].*).tgz".*/h;$!d;g;s//\1/p' All)"
echo "Resolved name '$package'"
- wget "$BaseUrl"/"$package".tgz
+ if [[ "$__hasWget" == 1 ]]; then
+ wget "$BaseUrl"/"$package".tgz
+ else
+ curl -SLO "$BaseUrl"/"$package".tgz
+ fi
ar -x "$package".tgz
tar --skip-old-files -xzf "$package".tmp.tg* -C "$__RootfsDir" 2>/dev/null
done
@@ -561,10 +659,17 @@ elif [[ "$__CodeName" == "illumos" ]]; then
rm -rf "$__RootfsDir"/{tmp,+*}
mkdir -p "$__RootfsDir"/usr/include/net
mkdir -p "$__RootfsDir"/usr/include/netpacket
- wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h
- wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h
- wget -P "$__RootfsDir"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h
- wget -P "$__RootfsDir"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h
+ wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h
+ wget -P "$__RootfsDir"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h
+ wget -P "$__RootfsDir"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h
+ else
+ curl -SLO --create-dirs --output-dir "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h
+ curl -SLO --create-dirs --output-dir "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h
+ curl -SLO --create-dirs --output-dir "$__RootfsDir"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h
+ curl -SLO --create-dirs --output-dir "$__RootfsDir"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h
+ fi
elif [[ "$__CodeName" == "haiku" ]]; then
JOBS=${MAXJOBS:="$(getconf _NPROCESSORS_ONLN)"}
@@ -574,9 +679,16 @@ elif [[ "$__CodeName" == "haiku" ]]; then
mkdir "$__RootfsDir/tmp/download"
+ ensureDownloadTool
+
echo "Downloading Haiku package tool"
- git clone https://github.com/haiku/haiku-toolchains-ubuntu --depth 1 $__RootfsDir/tmp/script
- wget -O "$__RootfsDir/tmp/download/hosttools.zip" $($__RootfsDir/tmp/script/fetch.sh --hosttools)
+ git clone https://github.com/haiku/haiku-toolchains-ubuntu --depth 1 "$__RootfsDir/tmp/script"
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O "$__RootfsDir/tmp/download/hosttools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --hosttools)"
+ else
+ curl -SLo "$__RootfsDir/tmp/download/hosttools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --hosttools)"
+ fi
+
unzip -o "$__RootfsDir/tmp/download/hosttools.zip" -d "$__RootfsDir/tmp/bin"
DepotBaseUrl="https://depot.haiku-os.org/__api/v2/pkg/get-pkg"
@@ -589,14 +701,25 @@ elif [[ "$__CodeName" == "haiku" ]]; then
echo "Downloading $package..."
# API documented here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L60
# The schema here: https://github.com/haiku/haikudepotserver/blob/master/haikudepotserver-api2/src/main/resources/api2/pkg.yaml#L598
- hpkgDownloadUrl="$(wget -qO- --post-data='{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \
- --header='Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')"
- wget -P "$__RootfsDir/tmp/download" "$hpkgDownloadUrl"
+ if [[ "$__hasWget" == 1 ]]; then
+ hpkgDownloadUrl="$(wget -qO- --post-data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \
+ --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')"
+ wget -P "$__RootfsDir/tmp/download" "$hpkgDownloadUrl"
+ else
+ hpkgDownloadUrl="$(curl -sSL -XPOST --data '{"name":"'"$package"'","repositorySourceCode":"haikuports_'$__HaikuArch'","versionType":"LATEST","naturalLanguageCode":"en"}' \
+ --header 'Content-Type:application/json' "$DepotBaseUrl" | jq -r '.result.versions[].hpkgDownloadURL')"
+ curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$hpkgDownloadUrl"
+ fi
done
for package in haiku haiku_devel; do
echo "Downloading $package..."
- hpkgVersion="$(wget -qO- $HpkgBaseUrl | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
- wget -P "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
+ if [[ "$__hasWget" == 1 ]]; then
+ hpkgVersion="$(wget -qO- "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
+ wget -P "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
+ else
+ hpkgVersion="$(curl -sSL "$HpkgBaseUrl" | sed -n 's/^.*version: "\([^"]*\)".*$/\1/p')"
+ curl -SLO --create-dirs --output-dir "$__RootfsDir/tmp/download" "$HpkgBaseUrl/packages/$package-$hpkgVersion-1-$__HaikuArch.hpkg"
+ fi
done
# Set up the sysroot
@@ -609,7 +732,11 @@ elif [[ "$__CodeName" == "haiku" ]]; then
# Download buildtools
echo "Downloading Haiku buildtools"
- wget -O "$__RootfsDir/tmp/download/buildtools.zip" $($__RootfsDir/tmp/script/fetch.sh --buildtools --arch=$__HaikuArch)
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O "$__RootfsDir/tmp/download/buildtools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --buildtools --arch=$__HaikuArch)"
+ else
+ curl -SLo "$__RootfsDir/tmp/download/buildtools.zip" "$("$__RootfsDir/tmp/script/fetch.sh" --buildtools --arch=$__HaikuArch)"
+ fi
unzip -o "$__RootfsDir/tmp/download/buildtools.zip" -d "$__RootfsDir"
# Cleaning up temporary files
@@ -622,10 +749,22 @@ elif [[ -n "$__CodeName" ]]; then
__Keyring="$__Keyring --force-check-gpg"
fi
+ # shellcheck disable=SC2086
+ echo running debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"
debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"
- cp "$__CrossDir/$__BuildArch/sources.list.$__CodeName" "$__RootfsDir/etc/apt/sources.list"
+
+ mkdir -p "$__RootfsDir/etc/apt/sources.list.d/"
+ cat > "$__RootfsDir/etc/apt/sources.list.d/$__CodeName.sources" <>Start configuring Tizen rootfs"
ln -sfn asm-${LINK_ARCH} ./usr/include/asm
patch -p1 < $__TIZEN_CROSSDIR/tizen.patch
+if [[ "$TIZEN_ARCH" == "riscv64" ]]; then
+ echo "Fixing broken symlinks in $PWD"
+ rm ./usr/lib64/libresolv.so
+ ln -s ../../lib64/libresolv.so.2 ./usr/lib64/libresolv.so
+ rm ./usr/lib64/libpthread.so
+ ln -s ../../lib64/libpthread.so.0 ./usr/lib64/libpthread.so
+ rm ./usr/lib64/libdl.so
+ ln -s ../../lib64/libdl.so.2 ./usr/lib64/libdl.so
+ rm ./usr/lib64/libutil.so
+ ln -s ../../lib64/libutil.so.1 ./usr/lib64/libutil.so
+ rm ./usr/lib64/libm.so
+ ln -s ../../lib64/libm.so.6 ./usr/lib64/libm.so
+ rm ./usr/lib64/librt.so
+ ln -s ../../lib64/librt.so.1 ./usr/lib64/librt.so
+ rm ./lib/ld-linux-riscv64-lp64d.so.1
+ ln -s ../lib64/ld-linux-riscv64-lp64d.so.1 ./lib/ld-linux-riscv64-lp64d.so.1
+fi
echo "<:--stdlib=${CLR_CMAKE_CXX_STANDARD_LIBRARY}>)
+ add_link_options($<$:--stdlib=${CLR_CMAKE_CXX_STANDARD_LIBRARY}>)
+endif()
+
+option(CLR_CMAKE_CXX_STANDARD_LIBRARY_STATIC "Statically link against the C++ standard library" OFF)
+if(CLR_CMAKE_CXX_STANDARD_LIBRARY_STATIC)
+ add_link_options($<$:-static-libstdc++>)
+endif()
+
+set(CLR_CMAKE_CXX_ABI_LIBRARY "" CACHE STRING "C++ ABI implementation library to link against. Only supported with the Clang compiler.")
+if (CLR_CMAKE_CXX_ABI_LIBRARY)
+ # The user may specify the ABI library with the 'lib' prefix, like 'libstdc++'. Strip the prefix here so the linker finds the right library.
+ string(REGEX REPLACE "^lib(.+)" "\\1" CLR_CMAKE_CXX_ABI_LIBRARY ${CLR_CMAKE_CXX_ABI_LIBRARY})
+ # We need to specify this as a linker-backend option as Clang will filter this option out when linking to libc++.
+ add_link_options("LINKER:-l${CLR_CMAKE_CXX_ABI_LIBRARY}")
+endif()
+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1
index 8fda30bdce2b..e33743105635 100644
--- a/eng/common/darc-init.ps1
+++ b/eng/common/darc-init.ps1
@@ -1,6 +1,6 @@
param (
$darcVersion = $null,
- $versionEndpoint = 'https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16',
+ $versionEndpoint = 'https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20',
$verbosity = 'minimal',
$toolpath = $null
)
diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh
index c305ae6bd771..36dbd45e1ce8 100755
--- a/eng/common/darc-init.sh
+++ b/eng/common/darc-init.sh
@@ -2,7 +2,7 @@
source="${BASH_SOURCE[0]}"
darcVersion=''
-versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2019-01-16'
+versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20'
verbosity='minimal'
while [[ $# > 0 ]]; do
diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh
index 7e69e3a9e24a..7b9d97e3bd4d 100755
--- a/eng/common/dotnet-install.sh
+++ b/eng/common/dotnet-install.sh
@@ -71,6 +71,9 @@ case $cpuname in
i[3-6]86)
buildarch=x86
;;
+ riscv64)
+ buildarch=riscv64
+ ;;
*)
echo "Unknown CPU $cpuname detected, treating it as x64"
buildarch=x64
@@ -82,7 +85,7 @@ if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then
dotnetRoot="$dotnetRoot/$architecture"
fi
-InstallDotNet $dotnetRoot $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {
+InstallDotNet "$dotnetRoot" $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {
local exit_code=$?
Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "dotnet-install.sh failed (exit code '$exit_code')." >&2
ExitWithExitCode $exit_code
diff --git a/eng/common/helixpublish.proj b/eng/common/helixpublish.proj
index d7f185856e79..c1323bf41210 100644
--- a/eng/common/helixpublish.proj
+++ b/eng/common/helixpublish.proj
@@ -1,3 +1,4 @@
+
diff --git a/eng/common/internal/Directory.Build.props b/eng/common/internal/Directory.Build.props
index dbf99d82a5c2..f1d041c33da5 100644
--- a/eng/common/internal/Directory.Build.props
+++ b/eng/common/internal/Directory.Build.props
@@ -1,4 +1,11 @@
+
+
+ false
+ false
+
+
+
diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj
index 7f5ce6d60813..32f79dfb3402 100644
--- a/eng/common/internal/Tools.csproj
+++ b/eng/common/internal/Tools.csproj
@@ -1,9 +1,10 @@
+
net472
- false
false
+ false
@@ -27,4 +28,5 @@
+
diff --git a/eng/common/native/CommonLibrary.psm1 b/eng/common/native/CommonLibrary.psm1
index ca38268c44d8..f71f6af6cdbc 100644
--- a/eng/common/native/CommonLibrary.psm1
+++ b/eng/common/native/CommonLibrary.psm1
@@ -277,7 +277,8 @@ function Get-MachineArchitecture {
if (($ProcessorArchitecture -Eq "AMD64") -Or
($ProcessorArchitecture -Eq "IA64") -Or
($ProcessorArchitecture -Eq "ARM64") -Or
- ($ProcessorArchitecture -Eq "LOONGARCH64")) {
+ ($ProcessorArchitecture -Eq "LOONGARCH64") -Or
+ ($ProcessorArchitecture -Eq "RISCV64")) {
return "x64"
}
return "x86"
diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh
index 2d5660642b8d..9a0e1f2b4567 100644
--- a/eng/common/native/init-compiler.sh
+++ b/eng/common/native/init-compiler.sh
@@ -2,7 +2,9 @@
#
# This file detects the C/C++ compiler and exports it to the CC/CXX environment variables
#
-# NOTE: some scripts source this file and rely on stdout being empty, make sure to not output anything here!
+# NOTE: some scripts source this file and rely on stdout being empty, make sure
+# to not output *anything* here, unless it is an error message that fails the
+# build.
if [ -z "$build_arch" ] || [ -z "$compiler" ]; then
echo "Usage..."
@@ -17,11 +19,9 @@ case "$compiler" in
# clangx.y or clang-x.y
version="$(echo "$compiler" | tr -d '[:alpha:]-=')"
majorVersion="${version%%.*}"
- [ -z "${version##*.*}" ] && minorVersion="${version#*.}"
- if [ -z "$minorVersion" ] && [ -n "$majorVersion" ] && [ "$majorVersion" -le 6 ]; then
- minorVersion=0;
- fi
+ # LLVM based on v18 released in early 2024, with two releases per year
+ maxVersion="$((18 + ((($(date +%Y) - 2024) * 12 + $(date +%-m) - 3) / 6)))"
compiler=clang
;;
@@ -29,7 +29,9 @@ case "$compiler" in
# gccx.y or gcc-x.y
version="$(echo "$compiler" | tr -d '[:alpha:]-=')"
majorVersion="${version%%.*}"
- [ -z "${version##*.*}" ] && minorVersion="${version#*.}"
+
+ # GCC based on v14 released in early 2024, with one release per year
+ maxVersion="$((14 + ((($(date +%Y) - 2024) * 12 + $(date +%-m) - 3) / 12)))"
compiler=gcc
;;
esac
@@ -47,91 +49,98 @@ check_version_exists() {
desired_version=-1
# Set up the environment to be used for building with the desired compiler.
- if command -v "$compiler-$1.$2" > /dev/null; then
- desired_version="-$1.$2"
- elif command -v "$compiler$1$2" > /dev/null; then
- desired_version="$1$2"
- elif command -v "$compiler-$1$2" > /dev/null; then
- desired_version="-$1$2"
+ if command -v "$compiler-$1" > /dev/null; then
+ desired_version="-$1"
+ elif command -v "$compiler$1" > /dev/null; then
+ desired_version="$1"
fi
echo "$desired_version"
}
+__baseOS="$(uname)"
+set_compiler_version_from_CC() {
+ if [ "$__baseOS" = "Darwin" ]; then
+ # On Darwin, the versions from -version/-dumpversion refer to Xcode
+ # versions, not llvm versions, so we can't rely on them.
+ return
+ fi
+
+ version="$("$CC" -dumpversion)"
+ if [ -z "$version" ]; then
+ echo "Error: $CC -dumpversion didn't provide a version"
+ exit 1
+ fi
+
+ # gcc and clang often display 3 part versions. However, gcc can show only 1 part in some environments.
+ IFS=. read -r majorVersion _ < /dev/null; then
- if [ "$(uname)" != "Darwin" ]; then
- echo "Warning: Specific version of $compiler not found, falling back to use the one in PATH."
- fi
- CC="$(command -v "$compiler")"
- CXX="$(command -v "$cxxCompiler")"
- else
- echo "No usable version of $compiler found."
+ if ! command -v "$compiler" > /dev/null; then
+ echo "Error: No compatible version of $compiler was found within the range of $minVersion to $maxVersion. Please upgrade your toolchain or specify the compiler explicitly using CLR_CC and CLR_CXX environment variables."
exit 1
fi
- else
- if [ "$compiler" = "clang" ] && [ "$majorVersion" -lt 5 ]; then
- if [ "$build_arch" = "arm" ] || [ "$build_arch" = "armel" ]; then
- if command -v "$compiler" > /dev/null; then
- echo "Warning: Found clang version $majorVersion which is not supported on arm/armel architectures, falling back to use clang from PATH."
- CC="$(command -v "$compiler")"
- CXX="$(command -v "$cxxCompiler")"
- else
- echo "Found clang version $majorVersion which is not supported on arm/armel architectures, and there is no clang in PATH."
- exit 1
- fi
- fi
- fi
+
+ CC="$(command -v "$compiler" 2> /dev/null)"
+ CXX="$(command -v "$cxxCompiler" 2> /dev/null)"
+ set_compiler_version_from_CC
fi
else
- desired_version="$(check_version_exists "$majorVersion" "$minorVersion")"
+ desired_version="$(check_version_exists "$majorVersion")"
if [ "$desired_version" = "-1" ]; then
- echo "Could not find specific version of $compiler: $majorVersion $minorVersion."
+ echo "Error: Could not find specific version of $compiler: $majorVersion."
exit 1
fi
fi
if [ -z "$CC" ]; then
- CC="$(command -v "$compiler$desired_version")"
- CXX="$(command -v "$cxxCompiler$desired_version")"
- if [ -z "$CXX" ]; then CXX="$(command -v "$cxxCompiler")"; fi
+ CC="$(command -v "$compiler$desired_version" 2> /dev/null)"
+ CXX="$(command -v "$cxxCompiler$desired_version" 2> /dev/null)"
+ if [ -z "$CXX" ]; then CXX="$(command -v "$cxxCompiler" 2> /dev/null)"; fi
+ set_compiler_version_from_CC
fi
else
if [ ! -f "$CLR_CC" ]; then
- echo "CLR_CC is set but path '$CLR_CC' does not exist"
+ echo "Error: CLR_CC is set but path '$CLR_CC' does not exist"
exit 1
fi
CC="$CLR_CC"
CXX="$CLR_CXX"
+ set_compiler_version_from_CC
fi
if [ -z "$CC" ]; then
- echo "Unable to find $compiler."
+ echo "Error: Unable to find $compiler."
exit 1
fi
-# Only lld version >= 9 can be considered stable. lld doesn't support s390x.
-if [ "$compiler" = "clang" ] && [ -n "$majorVersion" ] && [ "$majorVersion" -ge 9 ] && [ "$build_arch" != "s390x" ]; then
- if "$CC" -fuse-ld=lld -Wl,--version >/dev/null 2>&1; then
- LDFLAGS="-fuse-ld=lld"
+if [ "$__baseOS" != "Darwin" ]; then
+ # On Darwin, we always want to use the Apple linker.
+
+ # Only lld version >= 9 can be considered stable. lld supports s390x starting from 18.0.
+ if [ "$compiler" = "clang" ] && [ -n "$majorVersion" ] && [ "$majorVersion" -ge 9 ] && { [ "$build_arch" != "s390x" ] || [ "$majorVersion" -ge 18 ]; }; then
+ if "$CC" -fuse-ld=lld -Wl,--version >/dev/null 2>&1; then
+ LDFLAGS="-fuse-ld=lld"
+ fi
fi
fi
-SCAN_BUILD_COMMAND="$(command -v "scan-build$desired_version")"
+SCAN_BUILD_COMMAND="$(command -v "scan-build$desired_version" 2> /dev/null)"
export CC CXX LDFLAGS SCAN_BUILD_COMMAND
diff --git a/eng/common/native/init-distro-rid.sh b/eng/common/native/init-distro-rid.sh
index de1687b2ccbe..83ea7aab0e08 100644
--- a/eng/common/native/init-distro-rid.sh
+++ b/eng/common/native/init-distro-rid.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/sh
# getNonPortableDistroRid
#
@@ -11,21 +11,16 @@
# non-portable rid
getNonPortableDistroRid()
{
- local targetOs="$1"
- local targetArch="$2"
- local rootfsDir="$3"
- local nonPortableRid=""
+ targetOs="$1"
+ targetArch="$2"
+ rootfsDir="$3"
+ nonPortableRid=""
if [ "$targetOs" = "linux" ]; then
+ # shellcheck disable=SC1091
if [ -e "${rootfsDir}/etc/os-release" ]; then
- source "${rootfsDir}/etc/os-release"
-
- if [[ "${ID}" == "rhel" || "${ID}" == "rocky" || "${ID}" == "alpine" ]]; then
- # remove the last version digit
- VERSION_ID="${VERSION_ID%.*}"
- fi
-
- if [[ "${VERSION_ID:-}" =~ ^([[:digit:]]|\.)+$ ]]; then
+ . "${rootfsDir}/etc/os-release"
+ if echo "${VERSION_ID:-}" | grep -qE '^([[:digit:]]|\.)+$'; then
nonPortableRid="${ID}.${VERSION_ID}-${targetArch}"
else
# Rolling release distros either do not set VERSION_ID, set it as blank or
@@ -33,45 +28,33 @@ getNonPortableDistroRid()
# so omit it here to be consistent with everything else.
nonPortableRid="${ID}-${targetArch}"
fi
-
elif [ -e "${rootfsDir}/android_platform" ]; then
- source "$rootfsDir"/android_platform
+ # shellcheck disable=SC1091
+ . "${rootfsDir}/android_platform"
nonPortableRid="$RID"
fi
fi
if [ "$targetOs" = "freebsd" ]; then
- # $rootfsDir can be empty. freebsd-version is shell script and it should always work.
- __freebsd_major_version=$($rootfsDir/bin/freebsd-version | { read v; echo "${v%%.*}"; })
+ # $rootfsDir can be empty. freebsd-version is a shell script and should always work.
+ __freebsd_major_version=$("$rootfsDir"/bin/freebsd-version | cut -d'.' -f1)
nonPortableRid="freebsd.$__freebsd_major_version-${targetArch}"
- elif command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then
+ elif command -v getprop >/dev/null && getprop ro.product.system.model | grep -qi android; then
__android_sdk_version=$(getprop ro.build.version.sdk)
nonPortableRid="android.$__android_sdk_version-${targetArch}"
elif [ "$targetOs" = "illumos" ]; then
__uname_version=$(uname -v)
- case "$__uname_version" in
- omnios-*)
- __omnios_major_version=$(echo "${__uname_version:8:2}")
- nonPortableRid=omnios."$__omnios_major_version"-"$targetArch"
- ;;
- joyent_*)
- __smartos_major_version=$(echo "${__uname_version:7:4}")
- nonPortableRid=smartos."$__smartos_major_version"-"$targetArch"
- ;;
- illumos_*)
- nonPortableRid=openindiana-"$targetArch"
- ;;
- esac
+ nonPortableRid="illumos-${targetArch}"
elif [ "$targetOs" = "solaris" ]; then
__uname_version=$(uname -v)
- __solaris_major_version=$(echo "${__uname_version%.*}")
- nonPortableRid=solaris."$__solaris_major_version"-"$targetArch"
+ __solaris_major_version=$(echo "$__uname_version" | cut -d'.' -f1)
+ nonPortableRid="solaris.$__solaris_major_version-${targetArch}"
elif [ "$targetOs" = "haiku" ]; then
- __uname_release=$(uname -r)
+ __uname_release="$(uname -r)"
nonPortableRid=haiku.r"$__uname_release"-"$targetArch"
fi
- echo "$(echo $nonPortableRid | tr '[:upper:]' '[:lower:]')"
+ echo "$nonPortableRid" | tr '[:upper:]' '[:lower:]'
}
# initDistroRidGlobal
@@ -85,26 +68,23 @@ getNonPortableDistroRid()
# None
#
# Notes:
-#
-# It is important to note that the function does not return anything, but it
-# exports the following variables on success:
-#
-# __DistroRid : Non-portable rid of the target platform.
-# __PortableTargetOS : OS-part of the portable rid that corresponds to the target platform.
-#
+# It is important to note that the function does not return anything, but it
+# exports the following variables on success:
+# __DistroRid : Non-portable rid of the target platform.
+# __PortableTargetOS : OS-part of the portable rid that corresponds to the target platform.
initDistroRidGlobal()
{
- local targetOs="$1"
- local targetArch="$2"
- local rootfsDir=""
- if [ "$#" -ge 3 ]; then
+ targetOs="$1"
+ targetArch="$2"
+ rootfsDir=""
+ if [ $# -ge 3 ]; then
rootfsDir="$3"
fi
if [ -n "${rootfsDir}" ]; then
# We may have a cross build. Check for the existence of the rootfsDir
if [ ! -e "${rootfsDir}" ]; then
- echo "Error rootfsDir has been passed, but the location is not valid."
+ echo "Error: rootfsDir has been passed, but the location is not valid."
exit 1
fi
fi
@@ -119,7 +99,7 @@ initDistroRidGlobal()
STRINGS="$(command -v llvm-strings || true)"
fi
- # Check for musl-based distros (e.g Alpine Linux, Void Linux).
+ # Check for musl-based distros (e.g. Alpine Linux, Void Linux).
if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl ||
( [ -n "$STRINGS" ] && "$STRINGS" "${rootfsDir}/usr/bin/ldd" 2>&1 | grep -q musl ); then
__PortableTargetOS="linux-musl"
diff --git a/eng/common/native/init-os-and-arch.sh b/eng/common/native/init-os-and-arch.sh
index e693617a6c2b..38921d4338f7 100644
--- a/eng/common/native/init-os-and-arch.sh
+++ b/eng/common/native/init-os-and-arch.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/sh
# Use uname to determine what the OS is.
OSName=$(uname -s | tr '[:upper:]' '[:lower:]')
@@ -35,6 +35,10 @@ fi
case "$CPUName" in
arm64|aarch64)
arch=arm64
+ if [ "$(getconf LONG_BIT)" -lt 64 ]; then
+ # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
+ arch=arm
+ fi
;;
loongarch64)
@@ -50,6 +54,7 @@ case "$CPUName" in
;;
armv7l|armv8l)
+ # shellcheck disable=SC1091
if (NAME=""; . /etc/os-release; test "$NAME" = "Tizen"); then
arch=armel
else
diff --git a/eng/common/post-build/add-build-to-channel.ps1 b/eng/common/post-build/add-build-to-channel.ps1
deleted file mode 100644
index 49938f0c89f7..000000000000
--- a/eng/common/post-build/add-build-to-channel.ps1
+++ /dev/null
@@ -1,48 +0,0 @@
-param(
- [Parameter(Mandatory=$true)][int] $BuildId,
- [Parameter(Mandatory=$true)][int] $ChannelId,
- [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken,
- [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net',
- [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16'
-)
-
-try {
- . $PSScriptRoot\post-build-utils.ps1
-
- # Check that the channel we are going to promote the build to exist
- $channelInfo = Get-MaestroChannel -ChannelId $ChannelId
-
- if (!$channelInfo) {
- Write-PipelineTelemetryCategory -Category 'PromoteBuild' -Message "Channel with BAR ID $ChannelId was not found in BAR!"
- ExitWithExitCode 1
- }
-
- # Get info about which channel(s) the build has already been promoted to
- $buildInfo = Get-MaestroBuild -BuildId $BuildId
-
- if (!$buildInfo) {
- Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "Build with BAR ID $BuildId was not found in BAR!"
- ExitWithExitCode 1
- }
-
- # Find whether the build is already assigned to the channel or not
- if ($buildInfo.channels) {
- foreach ($channel in $buildInfo.channels) {
- if ($channel.Id -eq $ChannelId) {
- Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!"
- ExitWithExitCode 0
- }
- }
- }
-
- Write-Host "Promoting build '$BuildId' to channel '$ChannelId'."
-
- Assign-BuildToChannel -BuildId $BuildId -ChannelId $ChannelId
-
- Write-Host 'done.'
-}
-catch {
- Write-Host $_
- Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'"
- ExitWithExitCode 1
-}
diff --git a/eng/common/post-build/check-channel-consistency.ps1 b/eng/common/post-build/check-channel-consistency.ps1
index 63f3464c986a..61208d2d1351 100644
--- a/eng/common/post-build/check-channel-consistency.ps1
+++ b/eng/common/post-build/check-channel-consistency.ps1
@@ -4,10 +4,18 @@ param(
)
try {
- . $PSScriptRoot\post-build-utils.ps1
+ $ErrorActionPreference = 'Stop'
+ Set-StrictMode -Version 2.0
+
+ # `tools.ps1` checks $ci to perform some actions. Since the post-build
+ # scripts don't necessarily execute in the same agent that run the
+ # build.ps1/sh script this variable isn't automatically set.
+ $ci = $true
+ $disableConfigureToolsetImport = $true
+ . $PSScriptRoot\..\tools.ps1
if ($PromoteToChannels -eq "") {
- Write-PipelineTaskError -Type 'warning' -Message "This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/master/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info."
+ Write-PipelineTaskError -Type 'warning' -Message "This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/main/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info."
ExitWithExitCode 0
}
diff --git a/eng/common/post-build/nuget-validation.ps1 b/eng/common/post-build/nuget-validation.ps1
index dab3534ab538..e5de00c89836 100644
--- a/eng/common/post-build/nuget-validation.ps1
+++ b/eng/common/post-build/nuget-validation.ps1
@@ -2,20 +2,18 @@
# tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage
param(
- [Parameter(Mandatory=$true)][string] $PackagesPath, # Path to where the packages to be validated are
- [Parameter(Mandatory=$true)][string] $ToolDestinationPath # Where the validation tool should be downloaded to
+ [Parameter(Mandatory=$true)][string] $PackagesPath # Path to where the packages to be validated are
)
-try {
- . $PSScriptRoot\post-build-utils.ps1
-
- $url = 'https://raw.githubusercontent.com/NuGet/NuGetGallery/3e25ad135146676bcab0050a516939d9958bfa5d/src/VerifyMicrosoftPackage/verify.ps1'
-
- New-Item -ItemType 'directory' -Path ${ToolDestinationPath} -Force
+# `tools.ps1` checks $ci to perform some actions. Since the post-build
+# scripts don't necessarily execute in the same agent that run the
+# build.ps1/sh script this variable isn't automatically set.
+$ci = $true
+$disableConfigureToolsetImport = $true
+. $PSScriptRoot\..\tools.ps1
- Invoke-WebRequest $url -OutFile ${ToolDestinationPath}\verify.ps1
-
- & ${ToolDestinationPath}\verify.ps1 ${PackagesPath}\*.nupkg
+try {
+ & $PSScriptRoot\nuget-verification.ps1 ${PackagesPath}\*.nupkg
}
catch {
Write-Host $_.ScriptStackTrace
diff --git a/eng/common/post-build/nuget-verification.ps1 b/eng/common/post-build/nuget-verification.ps1
new file mode 100644
index 000000000000..a365194a9389
--- /dev/null
+++ b/eng/common/post-build/nuget-verification.ps1
@@ -0,0 +1,121 @@
+<#
+.SYNOPSIS
+ Verifies that Microsoft NuGet packages have proper metadata.
+.DESCRIPTION
+ Downloads a verification tool and runs metadata validation on the provided NuGet packages. This script writes an
+ error if any of the provided packages fail validation. All arguments provided to this PowerShell script that do not
+ match PowerShell parameters are passed on to the verification tool downloaded during the execution of this script.
+.PARAMETER NuGetExePath
+ The path to the nuget.exe binary to use. If not provided, nuget.exe will be downloaded into the -DownloadPath
+ directory.
+.PARAMETER PackageSource
+ The package source to use to download the verification tool. If not provided, nuget.org will be used.
+.PARAMETER DownloadPath
+ The directory path to download the verification tool and nuget.exe to. If not provided,
+ %TEMP%\NuGet.VerifyNuGetPackage will be used.
+.PARAMETER args
+ Arguments that will be passed to the verification tool.
+.EXAMPLE
+ PS> .\verify.ps1 *.nupkg
+ Verifies the metadata of all .nupkg files in the currect working directory.
+.EXAMPLE
+ PS> .\verify.ps1 --help
+ Displays the help text of the downloaded verifiction tool.
+.LINK
+ https://github.com/NuGet/NuGetGallery/blob/master/src/VerifyMicrosoftPackage/README.md
+#>
+
+# This script was copied from https://github.com/NuGet/NuGetGallery/blob/3e25ad135146676bcab0050a516939d9958bfa5d/src/VerifyMicrosoftPackage/verify.ps1
+
+[CmdletBinding(PositionalBinding = $false)]
+param(
+ [string]$NuGetExePath,
+ [string]$PackageSource = "https://api.nuget.org/v3/index.json",
+ [string]$DownloadPath,
+ [Parameter(ValueFromRemainingArguments = $true)]
+ [string[]]$args
+)
+
+# The URL to download nuget.exe.
+$nugetExeUrl = "https://dist.nuget.org/win-x86-commandline/v4.9.4/nuget.exe"
+
+# The package ID of the verification tool.
+$packageId = "NuGet.VerifyMicrosoftPackage"
+
+# The location that nuget.exe and the verification tool will be downloaded to.
+if (!$DownloadPath) {
+ $DownloadPath = (Join-Path $env:TEMP "NuGet.VerifyMicrosoftPackage")
+}
+
+$fence = New-Object -TypeName string -ArgumentList '=', 80
+
+# Create the download directory, if it doesn't already exist.
+if (!(Test-Path $DownloadPath)) {
+ New-Item -ItemType Directory $DownloadPath | Out-Null
+}
+Write-Host "Using download path: $DownloadPath"
+
+if ($NuGetExePath) {
+ $nuget = $NuGetExePath
+} else {
+ $downloadedNuGetExe = Join-Path $DownloadPath "nuget.exe"
+
+ # Download nuget.exe, if it doesn't already exist.
+ if (!(Test-Path $downloadedNuGetExe)) {
+ Write-Host "Downloading nuget.exe from $nugetExeUrl..."
+ $ProgressPreference = 'SilentlyContinue'
+ try {
+ Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe
+ $ProgressPreference = 'Continue'
+ } catch {
+ $ProgressPreference = 'Continue'
+ Write-Error $_
+ Write-Error "nuget.exe failed to download."
+ exit
+ }
+ }
+
+ $nuget = $downloadedNuGetExe
+}
+
+Write-Host "Using nuget.exe path: $nuget"
+Write-Host " "
+
+# Download the latest version of the verification tool.
+Write-Host "Downloading the latest version of $packageId from $packageSource..."
+Write-Host $fence
+& $nuget install $packageId `
+ -Prerelease `
+ -OutputDirectory $DownloadPath `
+ -Source $PackageSource
+Write-Host $fence
+Write-Host " "
+
+if ($LASTEXITCODE -ne 0) {
+ Write-Error "nuget.exe failed to fetch the verify tool."
+ exit
+}
+
+# Find the most recently downloaded tool
+Write-Host "Finding the most recently downloaded verification tool."
+$verifyProbePath = Join-Path $DownloadPath "$packageId.*"
+$verifyPath = Get-ChildItem -Path $verifyProbePath -Directory `
+ | Sort-Object -Property LastWriteTime -Descending `
+ | Select-Object -First 1
+$verify = Join-Path $verifyPath "tools\NuGet.VerifyMicrosoftPackage.exe"
+Write-Host "Using verification tool: $verify"
+Write-Host " "
+
+# Execute the verification tool.
+Write-Host "Executing the verify tool..."
+Write-Host $fence
+& $verify $args
+Write-Host $fence
+Write-Host " "
+
+# Respond to the exit code.
+if ($LASTEXITCODE -ne 0) {
+ Write-Error "The verify tool found some problems."
+} else {
+ Write-Output "The verify tool succeeded."
+}
diff --git a/eng/common/post-build/post-build-utils.ps1 b/eng/common/post-build/post-build-utils.ps1
deleted file mode 100644
index 534f6988d5b7..000000000000
--- a/eng/common/post-build/post-build-utils.ps1
+++ /dev/null
@@ -1,91 +0,0 @@
-# Most of the functions in this file require the variables `MaestroApiEndPoint`,
-# `MaestroApiVersion` and `MaestroApiAccessToken` to be globally available.
-
-$ErrorActionPreference = 'Stop'
-Set-StrictMode -Version 2.0
-
-# `tools.ps1` checks $ci to perform some actions. Since the post-build
-# scripts don't necessarily execute in the same agent that run the
-# build.ps1/sh script this variable isn't automatically set.
-$ci = $true
-$disableConfigureToolsetImport = $true
-. $PSScriptRoot\..\tools.ps1
-
-function Create-MaestroApiRequestHeaders([string]$ContentType = 'application/json') {
- Validate-MaestroVars
-
- $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
- $headers.Add('Accept', $ContentType)
- $headers.Add('Authorization',"Bearer $MaestroApiAccessToken")
- return $headers
-}
-
-function Get-MaestroChannel([int]$ChannelId) {
- Validate-MaestroVars
-
- $apiHeaders = Create-MaestroApiRequestHeaders
- $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}?api-version=$MaestroApiVersion"
-
- $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
- return $result
-}
-
-function Get-MaestroBuild([int]$BuildId) {
- Validate-MaestroVars
-
- $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
- $apiEndpoint = "$MaestroApiEndPoint/api/builds/${BuildId}?api-version=$MaestroApiVersion"
-
- $result = try { return Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
- return $result
-}
-
-function Get-MaestroSubscriptions([string]$SourceRepository, [int]$ChannelId) {
- Validate-MaestroVars
-
- $SourceRepository = [System.Web.HttpUtility]::UrlEncode($SourceRepository)
- $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
- $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions?sourceRepository=$SourceRepository&channelId=$ChannelId&api-version=$MaestroApiVersion"
-
- $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
- return $result
-}
-
-function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) {
- Validate-MaestroVars
-
- $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
- $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion"
- Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null
-}
-
-function Trigger-Subscription([string]$SubscriptionId) {
- Validate-MaestroVars
-
- $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken
- $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion"
- Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null
-}
-
-function Validate-MaestroVars {
- try {
- Get-Variable MaestroApiEndPoint | Out-Null
- Get-Variable MaestroApiVersion | Out-Null
- Get-Variable MaestroApiAccessToken | Out-Null
-
- if (!($MaestroApiEndPoint -Match '^http[s]?://maestro-(int|prod).westus2.cloudapp.azure.com$')) {
- Write-PipelineTelemetryError -Category 'MaestroVars' -Message "MaestroApiEndPoint is not a valid Maestro URL. '$MaestroApiEndPoint'"
- ExitWithExitCode 1
- }
-
- if (!($MaestroApiVersion -Match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$')) {
- Write-PipelineTelemetryError -Category 'MaestroVars' -Message "MaestroApiVersion does not match a version string in the format yyyy-MM-DD. '$MaestroApiVersion'"
- ExitWithExitCode 1
- }
- }
- catch {
- Write-PipelineTelemetryError -Category 'MaestroVars' -Message 'Error: Variables `MaestroApiEndPoint`, `MaestroApiVersion` and `MaestroApiAccessToken` are required while using this script.'
- Write-Host $_
- ExitWithExitCode 1
- }
-}
diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1
index 238945cb5ab4..90b58e32a87b 100644
--- a/eng/common/post-build/publish-using-darc.ps1
+++ b/eng/common/post-build/publish-using-darc.ps1
@@ -9,7 +9,12 @@ param(
)
try {
- . $PSScriptRoot\post-build-utils.ps1
+ # `tools.ps1` checks $ci to perform some actions. Since the post-build
+ # scripts don't necessarily execute in the same agent that run the
+ # build.ps1/sh script this variable isn't automatically set.
+ $ci = $true
+ $disableConfigureToolsetImport = $true
+ . $PSScriptRoot\..\tools.ps1
$darc = Get-Darc
@@ -37,6 +42,7 @@ try {
--azdev-pat "$AzdoToken" `
--bar-uri "$MaestroApiEndPoint" `
--ci `
+ --verbose `
@optionalParams
if ($LastExitCode -ne 0) {
diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1
new file mode 100644
index 000000000000..b7fc19591507
--- /dev/null
+++ b/eng/common/post-build/redact-logs.ps1
@@ -0,0 +1,89 @@
+[CmdletBinding(PositionalBinding=$False)]
+param(
+ [Parameter(Mandatory=$true, Position=0)][string] $InputPath,
+ [Parameter(Mandatory=$true)][string] $BinlogToolVersion,
+ [Parameter(Mandatory=$false)][string] $DotnetPath,
+ [Parameter(Mandatory=$false)][string] $PackageFeed = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json',
+ # File with strings to redact - separated by newlines.
+ # For comments start the line with '# ' - such lines are ignored
+ [Parameter(Mandatory=$false)][string] $TokensFilePath,
+ [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact
+)
+
+try {
+ $ErrorActionPreference = 'Stop'
+ Set-StrictMode -Version 2.0
+
+ # `tools.ps1` checks $ci to perform some actions. Since the post-build
+ # scripts don't necessarily execute in the same agent that run the
+ # build.ps1/sh script this variable isn't automatically set.
+ $ci = $true
+ $disableConfigureToolsetImport = $true
+ . $PSScriptRoot\..\tools.ps1
+
+ $packageName = 'binlogtool'
+
+ $dotnet = $DotnetPath
+
+ if (!$dotnet) {
+ $dotnetRoot = InitializeDotNetCli -install:$true
+ $dotnet = "$dotnetRoot\dotnet.exe"
+ }
+
+ $toolList = & "$dotnet" tool list -g
+
+ if ($toolList -like "*$packageName*") {
+ & "$dotnet" tool uninstall $packageName -g
+ }
+
+ $toolPath = "$PSScriptRoot\..\..\..\.tools"
+ $verbosity = 'minimal'
+
+ New-Item -ItemType Directory -Force -Path $toolPath
+
+ Push-Location -Path $toolPath
+
+ try {
+ Write-Host "Installing Binlog redactor CLI..."
+ Write-Host "'$dotnet' new tool-manifest"
+ & "$dotnet" new tool-manifest
+ Write-Host "'$dotnet' tool install $packageName --local --add-source '$PackageFeed' -v $verbosity --version $BinlogToolVersion"
+ & "$dotnet" tool install $packageName --local --add-source "$PackageFeed" -v $verbosity --version $BinlogToolVersion
+
+ if (Test-Path $TokensFilePath) {
+ Write-Host "Adding additional sensitive data for redaction from file: " $TokensFilePath
+ $TokensToRedact += Get-Content -Path $TokensFilePath | Foreach {$_.Trim()} | Where { $_ -notmatch "^# " }
+ }
+
+ $optionalParams = [System.Collections.ArrayList]::new()
+
+ Foreach ($p in $TokensToRedact)
+ {
+ if($p -match '^\$\(.*\)$')
+ {
+ Write-Host ("Ignoring token {0} as it is probably unexpanded AzDO variable" -f $p)
+ }
+ elseif($p)
+ {
+ $optionalParams.Add("-p:" + $p) | Out-Null
+ }
+ }
+
+ & $dotnet binlogtool redact --input:$InputPath --recurse --in-place `
+ @optionalParams
+
+ if ($LastExitCode -ne 0) {
+ Write-PipelineTelemetryError -Category 'Redactor' -Type 'warning' -Message "Problems using Redactor tool (exit code: $LastExitCode). But ignoring them now."
+ }
+ }
+ finally {
+ Pop-Location
+ }
+
+ Write-Host 'done.'
+}
+catch {
+ Write-Host $_
+ Write-PipelineTelemetryError -Category 'Redactor' -Message "There was an error while trying to redact logs. Error: $_"
+ ExitWithExitCode 1
+}
diff --git a/eng/common/post-build/sourcelink-validation.ps1 b/eng/common/post-build/sourcelink-validation.ps1
index 4011d324e739..1976ef70fb85 100644
--- a/eng/common/post-build/sourcelink-validation.ps1
+++ b/eng/common/post-build/sourcelink-validation.ps1
@@ -6,7 +6,15 @@ param(
[Parameter(Mandatory=$true)][string] $SourcelinkCliVersion # Version of SourceLink CLI to use
)
-. $PSScriptRoot\post-build-utils.ps1
+$ErrorActionPreference = 'Stop'
+Set-StrictMode -Version 2.0
+
+# `tools.ps1` checks $ci to perform some actions. Since the post-build
+# scripts don't necessarily execute in the same agent that run the
+# build.ps1/sh script this variable isn't automatically set.
+$ci = $true
+$disableConfigureToolsetImport = $true
+. $PSScriptRoot\..\tools.ps1
# Cache/HashMap (File -> Exist flag) used to consult whether a file exist
# in the repository at a specific commit point. This is populated by inserting
diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1
index cd2181bafa05..7146e593ffae 100644
--- a/eng/common/post-build/symbols-validation.ps1
+++ b/eng/common/post-build/symbols-validation.ps1
@@ -322,8 +322,6 @@ function InstallDotnetSymbol {
}
try {
- . $PSScriptRoot\post-build-utils.ps1
-
InstallDotnetSymbol
foreach ($Job in @(Get-Job)) {
diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1
deleted file mode 100644
index ac9a95778fcd..000000000000
--- a/eng/common/post-build/trigger-subscriptions.ps1
+++ /dev/null
@@ -1,64 +0,0 @@
-param(
- [Parameter(Mandatory=$true)][string] $SourceRepo,
- [Parameter(Mandatory=$true)][int] $ChannelId,
- [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken,
- [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net',
- [Parameter(Mandatory=$false)][string] $MaestroApiVersion = '2019-01-16'
-)
-
-try {
- . $PSScriptRoot\post-build-utils.ps1
-
- # Get all the $SourceRepo subscriptions
- $normalizedSourceRepo = $SourceRepo.Replace('dnceng@', '')
- $subscriptions = Get-MaestroSubscriptions -SourceRepository $normalizedSourceRepo -ChannelId $ChannelId
-
- if (!$subscriptions) {
- Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message "No subscriptions found for source repo '$normalizedSourceRepo' in channel '$ChannelId'"
- ExitWithExitCode 0
- }
-
- $subscriptionsToTrigger = New-Object System.Collections.Generic.List[string]
- $failedTriggeredSubscription = $false
-
- # Get all enabled subscriptions that need dependency flow on 'everyBuild'
- foreach ($subscription in $subscriptions) {
- if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) {
- Write-Host "Should trigger this subscription: ${$subscription.id}"
- [void]$subscriptionsToTrigger.Add($subscription.id)
- }
- }
-
- foreach ($subscriptionToTrigger in $subscriptionsToTrigger) {
- try {
- Write-Host "Triggering subscription '$subscriptionToTrigger'."
-
- Trigger-Subscription -SubscriptionId $subscriptionToTrigger
-
- Write-Host 'done.'
- }
- catch
- {
- Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'"
- Write-Host $_
- Write-Host $_.ScriptStackTrace
- $failedTriggeredSubscription = $true
- }
- }
-
- if ($subscriptionsToTrigger.Count -eq 0) {
- Write-Host "No subscription matched source repo '$normalizedSourceRepo' and channel ID '$ChannelId'."
- }
- elseif ($failedTriggeredSubscription) {
- Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message 'At least one subscription failed to be triggered...'
- ExitWithExitCode 1
- }
- else {
- Write-Host 'All subscriptions were triggered successfully!'
- }
-}
-catch {
- Write-Host $_.ScriptStackTrace
- Write-PipelineTelemetryError -Category 'TriggerSubscriptions' -Message $_
- ExitWithExitCode 1
-}
diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1
index 73828dd30d31..aab40de3fd9a 100644
--- a/eng/common/sdk-task.ps1
+++ b/eng/common/sdk-task.ps1
@@ -64,7 +64,7 @@ try {
$GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty
}
if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) {
- $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.8.1-2" -MemberType NoteProperty
+ $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty
}
if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") {
$xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true
diff --git a/eng/common/sdl/NuGet.config b/eng/common/sdl/NuGet.config
index 5bfbb02ef043..3849bdb3cf51 100644
--- a/eng/common/sdl/NuGet.config
+++ b/eng/common/sdl/NuGet.config
@@ -5,11 +5,11 @@
-
+
-
+
diff --git a/eng/common/sdl/execute-all-sdl-tools.ps1 b/eng/common/sdl/execute-all-sdl-tools.ps1
index 81ded5b7f477..4715d75e974d 100644
--- a/eng/common/sdl/execute-all-sdl-tools.ps1
+++ b/eng/common/sdl/execute-all-sdl-tools.ps1
@@ -6,6 +6,7 @@ Param(
[string] $BranchName=$env:BUILD_SOURCEBRANCH, # Optional: name of branch or version of gdn settings; defaults to master
[string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY, # Required: the directory where source files are located
[string] $ArtifactsDirectory = (Join-Path $env:BUILD_ARTIFACTSTAGINGDIRECTORY ('artifacts')), # Required: the directory where build artifacts are located
+ [string] $AzureDevOpsAccessToken, # Required: access token for dnceng; should be provided via KeyVault
# Optional: list of SDL tools to run on source code. See 'configure-sdl-tool.ps1' for tools list
# format.
@@ -74,7 +75,7 @@ try {
}
Exec-BlockVerbosely {
- & $(Join-Path $PSScriptRoot 'init-sdl.ps1') -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $workingDirectory -GuardianLoggerLevel $GuardianLoggerLevel
+ & $(Join-Path $PSScriptRoot 'init-sdl.ps1') -GuardianCliLocation $guardianCliLocation -Repository $RepoName -BranchName $BranchName -WorkingDirectory $workingDirectory -AzureDevOpsAccessToken $AzureDevOpsAccessToken -GuardianLoggerLevel $GuardianLoggerLevel
}
$gdnFolder = Join-Path $workingDirectory '.gdn'
@@ -103,6 +104,7 @@ try {
-TargetDirectory $targetDirectory `
-GdnFolder $gdnFolder `
-ToolsList $tools `
+ -AzureDevOpsAccessToken $AzureDevOpsAccessToken `
-GuardianLoggerLevel $GuardianLoggerLevel `
-CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams `
-PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams `
diff --git a/eng/common/sdl/init-sdl.ps1 b/eng/common/sdl/init-sdl.ps1
index 588ff8e22fbe..3ac1d92b3700 100644
--- a/eng/common/sdl/init-sdl.ps1
+++ b/eng/common/sdl/init-sdl.ps1
@@ -3,6 +3,7 @@ Param(
[string] $Repository,
[string] $BranchName='master',
[string] $WorkingDirectory,
+ [string] $AzureDevOpsAccessToken,
[string] $GuardianLoggerLevel='Standard'
)
@@ -20,7 +21,14 @@ $ci = $true
# Don't display the console progress UI - it's a huge perf hit
$ProgressPreference = 'SilentlyContinue'
+# Construct basic auth from AzDO access token; construct URI to the repository's gdn folder stored in that repository; construct location of zip file
+$encodedPat = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$AzureDevOpsAccessToken"))
+$escapedRepository = [Uri]::EscapeDataString("/$Repository/$BranchName/.gdn")
+$uri = "https://dev.azure.com/dnceng/internal/_apis/git/repositories/sdl-tool-cfg/Items?path=$escapedRepository&versionDescriptor[versionOptions]=0&`$format=zip&api-version=5.0"
+$zipFile = "$WorkingDirectory/gdn.zip"
+
Add-Type -AssemblyName System.IO.Compression.FileSystem
+$gdnFolder = (Join-Path $WorkingDirectory '.gdn')
try {
# if the folder does not exist, we'll do a guardian init and push it to the remote repository
diff --git a/eng/common/sdl/sdl.ps1 b/eng/common/sdl/sdl.ps1
index 7fe603fe995d..648c5068d7d6 100644
--- a/eng/common/sdl/sdl.ps1
+++ b/eng/common/sdl/sdl.ps1
@@ -4,8 +4,6 @@ function Install-Gdn {
[Parameter(Mandatory=$true)]
[string]$Path,
- [string]$Source = "https://pkgs.dev.azure.com/dnceng/_packaging/Guardian1ESPTUpstreamOrgFeed/nuget/v3/index.json",
-
# If omitted, install the latest version of Guardian, otherwise install that specific version.
[string]$Version
)
@@ -21,7 +19,7 @@ function Install-Gdn {
$ci = $true
. $PSScriptRoot\..\tools.ps1
- $argumentList = @("install", "Microsoft.Guardian.Cli.win-x64", "-Source $Source", "-OutputDirectory $Path", "-NonInteractive", "-NoCache")
+ $argumentList = @("install", "Microsoft.Guardian.Cli", "-Source https://securitytools.pkgs.visualstudio.com/_packaging/Guardian/nuget/v3/index.json", "-OutputDirectory $Path", "-NonInteractive", "-NoCache")
if ($Version) {
$argumentList += "-Version $Version"
diff --git a/eng/common/sdl/trim-assets-version.ps1 b/eng/common/sdl/trim-assets-version.ps1
index a2e004877045..0daa2a9e9462 100644
--- a/eng/common/sdl/trim-assets-version.ps1
+++ b/eng/common/sdl/trim-assets-version.ps1
@@ -72,4 +72,4 @@ catch {
Write-Host $_
Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
ExitWithExitCode 1
-}
\ No newline at end of file
+}
diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md
new file mode 100644
index 000000000000..5ef6c30ba924
--- /dev/null
+++ b/eng/common/template-guidance.md
@@ -0,0 +1,133 @@
+# Overview
+
+Arcade provides templates for public (`/templates`) and 1ES pipeline templates (`/templates-official`) scenarios. Pipelines which are required to be managed by 1ES pipeline templates should reference `/templates-offical`, all other pipelines may reference `/templates`.
+
+## How to use
+
+Basic guidance is:
+
+- 1ES Pipeline Template or 1ES Microbuild template runs should reference `eng/common/templates-official`. Any internal production-graded pipeline should use these templates.
+
+- All other runs should reference `eng/common/templates`.
+
+See [azure-pipelines.yml](../../azure-pipelines.yml) (templates-official example) or [azure-pipelines-pr.yml](../../azure-pipelines-pr.yml) (templates example) for examples.
+
+#### The `templateIs1ESManaged` parameter
+
+The `templateIs1ESManaged` is available on most templates and affects which of the variants is used for nested templates. See [Development Notes](#development-notes) below for more information on the `templateIs1ESManaged1 parameter.
+
+- For templates under `job/`, `jobs/`, `steps`, or `post-build/`, this parameter must be explicitly set.
+
+## Multiple outputs
+
+1ES pipeline templates impose a policy where every publish artifact execution results in additional security scans being injected into your pipeline. When using `templates-official/jobs/jobs.yml`, Arcade reduces the number of additional security injections by gathering all publishing outputs into the [Build.ArtifactStagingDirectory](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services), and utilizing the [outputParentDirectory](https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs#multiple-outputs) feature of 1ES pipeline templates. When implementing your pipeline, if you ensure publish artifacts are located in the `$(Build.ArtifactStagingDirectory)`, and utilize the 1ES provided template context, then you can reduce the number of security scans for your pipeline.
+
+Example:
+``` yaml
+# azure-pipelines.yml
+extends:
+ template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
+ parameters:
+ stages:
+ - stage: build
+ jobs:
+ - template: /eng/common/templates-official/jobs/jobs.yml@self
+ parameters:
+ # 1ES makes use of outputs to reduce security task injection overhead
+ templateContext:
+ outputs:
+ - output: pipelineArtifact
+ displayName: 'Publish logs from source'
+ continueOnError: true
+ condition: always()
+ targetPath: $(Build.ArtifactStagingDirectory)/artifacts/log
+ artifactName: Logs
+ jobs:
+ - job: Windows
+ steps:
+ - script: echo "friendly neighborhood" > artifacts/marvel/spiderman.txt
+ # copy build outputs to artifact staging directory for publishing
+ - task: CopyFiles@2
+ displayName: Gather build output
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel'
+ Contents: '**'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel'
+```
+
+Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`).
+
+# Development notes
+
+**Folder / file structure**
+
+``` text
+eng\common\
+ [templates || templates-official]\
+ job\
+ job.yml (shim + artifact publishing logic)
+ onelocbuild.yml (shim)
+ publish-build-assets.yml (shim)
+ source-build.yml (shim)
+ source-index-stage1.yml (shim)
+ jobs\
+ codeql-build.yml (shim)
+ jobs.yml (shim)
+ source-build.yml (shim)
+ post-build\
+ post-build.yml (shim)
+ common-variabls.yml (shim)
+ setup-maestro-vars.yml (shim)
+ steps\
+ publish-build-artifacts.yml (logic)
+ publish-pipeline-artifacts.yml (logic)
+ component-governance.yml (shim)
+ generate-sbom.yml (shim)
+ publish-logs.yml (shim)
+ retain-build.yml (shim)
+ send-to-helix.yml (shim)
+ source-build.yml (shim)
+ variables\
+ pool-providers.yml (logic + redirect) # templates/variables/pool-providers.yml will redirect to templates-official/variables/pool-providers.yml if you are running in the internal project
+ sdl-variables.yml (logic)
+ core-templates\
+ job\
+ job.yml (logic)
+ onelocbuild.yml (logic)
+ publish-build-assets.yml (logic)
+ source-build.yml (logic)
+ source-index-stage1.yml (logic)
+ jobs\
+ codeql-build.yml (logic)
+ jobs.yml (logic)
+ source-build.yml (logic)
+ post-build\
+ common-variabls.yml (logic)
+ post-build.yml (logic)
+ setup-maestro-vars.yml (logic)
+ steps\
+ component-governance.yml (logic)
+ generate-sbom.yml (logic)
+ publish-build-artifacts.yml (redirect)
+ publish-logs.yml (logic)
+ publish-pipeline-artifacts.yml (redirect)
+ retain-build.yml (logic)
+ send-to-helix.yml (logic)
+ source-build.yml (logic)
+ variables\
+ pool-providers.yml (redirect)
+```
+
+In the table above, a file is designated as "shim", "logic", or "redirect".
+
+- shim - represents a yaml file which is an intermediate step between pipeline logic and .Net Core Engineering's templates (`core-templates`) and defines the `is1ESPipeline` parameter value.
+
+- logic - represents actual base template logic.
+
+- redirect- represents a file in `core-templates` which redirects to the "logic" file in either `templates` or `templates-official`.
+
+Logic for Arcade's templates live **primarily** in the `core-templates` folder. The exceptions to the location of the logic files are around artifact publishing, which is handled differently between 1es pipeline templates and standard templates. `templates` and `templates-official` provide shim entry points which redirect to `core-templates` while also defining the `is1ESPipeline` parameter. If a shim is referenced in `templates`, then `is1ESPipeline` is set to `false`. If a shim is referenced in `templates-official`, then `is1ESPipeline` is set to `true`.
+
+Within `templates` and `templates-official`, the templates at the "stages", and "jobs" / "job" level have been replaced with shims. Templates at the "steps" and "variables" level are typically too granular to be replaced with shims and instead persist logic which is directly applicable to either scenario.
+
+Within `core-templates`, there are a handful of places where logic is dependent on which shim entry point was used. In those places, we redirect back to the respective logic file in `templates` or `templates-official`.
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index 1f035fee73f4..605692d2fb77 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -1,264 +1,80 @@
-# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
-# and some (Microbuild) should only be applied to non-PR cases for internal builds.
-
parameters:
-# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
- cancelTimeoutInMinutes: ''
- condition: ''
- container: ''
- continueOnError: false
- dependsOn: ''
- displayName: ''
- pool: ''
- steps: []
- strategy: ''
- timeoutInMinutes: ''
- variables: []
- workspace: ''
- templateContext: ''
-
-# Job base template specific parameters
- # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md
- artifacts: ''
- enableMicrobuild: false
- enablePublishBuildArtifacts: false
- enablePublishBuildAssets: false
- enablePublishTestResults: false
- enablePublishUsingPipelines: false
- enableBuildRetry: false
- disableComponentGovernance: ''
- componentGovernanceIgnoreDirectories: ''
- mergeTestResults: false
- testRunTitle: ''
- testResultsFormat: ''
- name: ''
- preSteps: []
- runAsPublic: false
# Sbom related params
enableSbom: true
- PackageVersion: 7.0.0
+ runAsPublic: false
+ PackageVersion: 9.0.0
BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
jobs:
-- job: ${{ parameters.name }}
-
- ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}:
- cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
-
- ${{ if ne(parameters.condition, '') }}:
- condition: ${{ parameters.condition }}
-
- ${{ if ne(parameters.container, '') }}:
- container: ${{ parameters.container }}
-
- ${{ if ne(parameters.continueOnError, '') }}:
- continueOnError: ${{ parameters.continueOnError }}
-
- ${{ if ne(parameters.dependsOn, '') }}:
- dependsOn: ${{ parameters.dependsOn }}
-
- ${{ if ne(parameters.displayName, '') }}:
- displayName: ${{ parameters.displayName }}
-
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
-
- ${{ if ne(parameters.strategy, '') }}:
- strategy: ${{ parameters.strategy }}
-
- ${{ if ne(parameters.timeoutInMinutes, '') }}:
- timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
-
- ${{ if ne(parameters.templateContext, '') }}:
- templateContext: ${{ parameters.templateContext }}
-
- variables:
- - ${{ if ne(parameters.enableTelemetry, 'false') }}:
- - name: DOTNET_CLI_TELEMETRY_PROFILE
- value: '$(Build.Repository.Uri)'
- - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}:
- - name: EnableRichCodeNavigation
- value: 'true'
- # Retry signature validation up to three times, waiting 2 seconds between attempts.
- # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
- - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY
- value: 3,2000
- - ${{ each variable in parameters.variables }}:
- # handle name-value variable syntax
- # example:
- # - name: [key]
- # value: [value]
- - ${{ if ne(variable.name, '') }}:
- - name: ${{ variable.name }}
- value: ${{ variable.value }}
-
- # handle variable groups
- - ${{ if ne(variable.group, '') }}:
- - group: ${{ variable.group }}
-
- # handle template variable syntax
- # example:
- # - template: path/to/template.yml
- # parameters:
- # [key]: [value]
- - ${{ if ne(variable.template, '') }}:
- - template: ${{ variable.template }}
- ${{ if ne(variable.parameters, '') }}:
- parameters: ${{ variable.parameters }}
-
- # handle key-value variable syntax.
- # example:
- # - [key]: [value]
- - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}:
- - ${{ each pair in variable }}:
- - name: ${{ pair.key }}
- value: ${{ pair.value }}
-
- # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds
- - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - group: DotNet-HelixApi-Access
-
- ${{ if ne(parameters.workspace, '') }}:
- workspace: ${{ parameters.workspace }}
-
- steps:
- - ${{ if ne(parameters.preSteps, '') }}:
- - ${{ each preStep in parameters.preSteps }}:
- - ${{ preStep }}
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- - task: MicroBuildSigningPlugin@4
- displayName: Install MicroBuild plugin
- inputs:
- signType: $(_SignType)
- zipSources: false
- feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
- env:
- TeamName: $(_TeamName)
- MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)'
- continueOnError: ${{ parameters.continueOnError }}
- condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
- - task: NuGetAuthenticate@1
-
- - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}:
- - task: DownloadPipelineArtifact@2
- inputs:
- buildType: current
- artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }}
- targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }}
- itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }}
-
- - ${{ each step in parameters.steps }}:
- - ${{ step }}
-
- - ${{ if eq(parameters.enableRichCodeNavigation, true) }}:
- - task: RichCodeNavIndexer@0
- displayName: RichCodeNav Upload
- inputs:
- languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }}
- environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }}
- richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin
- uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }}
- continueOnError: true
-
- - template: /eng/common/templates-official/steps/component-governance.yml
- parameters:
- ${{ if eq(parameters.disableComponentGovernance, '') }}:
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}:
- disableComponentGovernance: false
- ${{ else }}:
- disableComponentGovernance: true
- ${{ else }}:
- disableComponentGovernance: ${{ parameters.disableComponentGovernance }}
- componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
-
- - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: MicroBuildCleanup@1
- displayName: Execute Microbuild cleanup tasks
- condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
- continueOnError: ${{ parameters.continueOnError }}
- env:
- TeamName: $(_TeamName)
-
- - ${{ if ne(parameters.artifacts.publish, '') }}:
- - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
- - task: CopyFiles@2
- displayName: Gather binaries for publish to artifacts
- inputs:
- SourceFolder: 'artifacts/bin'
- Contents: '**'
- TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin'
- - task: CopyFiles@2
- displayName: Gather packages for publish to artifacts
- inputs:
- SourceFolder: 'artifacts/packages'
- Contents: '**'
- TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages'
- - task: 1ES.PublishBuildArtifacts@1
- displayName: Publish pipeline artifacts
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
- PublishLocation: Container
- ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
- continueOnError: true
- condition: always()
- - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
- - task: 1ES.PublishPipelineArtifact@1
- inputs:
- targetPath: 'artifacts/log'
- artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }}
- displayName: 'Publish logs'
- continueOnError: true
- condition: always()
-
- - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
- - task: 1ES.PublishBuildArtifacts@1
- displayName: Publish Logs
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)'
- PublishLocation: Container
- ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
- continueOnError: true
- condition: always()
-
- - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:
- - task: PublishTestResults@2
- displayName: Publish XUnit Test Results
- inputs:
- testResultsFormat: 'xUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
- mergeTestResults: ${{ parameters.mergeTestResults }}
- continueOnError: true
- condition: always()
- - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}:
- - task: PublishTestResults@2
- displayName: Publish TRX Test Results
- inputs:
- testResultsFormat: 'VSTest'
- testResultsFiles: '*.trx'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
- mergeTestResults: ${{ parameters.mergeTestResults }}
- continueOnError: true
- condition: always()
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
- - template: /eng/common/templates-official/steps/generate-sbom.yml
- parameters:
- PackageVersion: ${{ parameters.packageVersion}}
- BuildDropPath: ${{ parameters.buildDropPath }}
- IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
-
- - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
- - task: 1ES.PublishPipelineArtifact@1
- inputs:
- targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration'
- artifactName: 'BuildConfiguration'
- displayName: 'Publish build retry configuration'
- continueOnError: true
\ No newline at end of file
+- template: /eng/common/core-templates/job/job.yml
+ parameters:
+ is1ESPipeline: true
+
+ componentGovernanceSteps:
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
+ - template: /eng/common/templates/steps/generate-sbom.yml
+ parameters:
+ PackageVersion: ${{ parameters.packageVersion }}
+ BuildDropPath: ${{ parameters.buildDropPath }}
+ publishArtifacts: false
+
+ # publish artifacts
+ # for 1ES managed templates, use the templateContext.output to handle multiple outputs.
+ templateContext:
+ outputParentDirectory: $(Build.ArtifactStagingDirectory)
+ outputs:
+ - ${{ if ne(parameters.artifacts.publish, '') }}:
+ - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
+ - output: buildArtifacts
+ displayName: Publish pipeline artifacts
+ PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
+ ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
+ condition: always()
+ continueOnError: true
+ - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
+ - output: pipelineArtifact
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log'
+ artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)_Attempt$(System.JobAttempt)') }}
+ displayName: 'Publish logs'
+ continueOnError: true
+ condition: always()
+ sbomEnabled: false # we don't need SBOM for logs
+
+ - ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}:
+ - output: buildArtifacts
+ displayName: Publish Logs
+ PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
+ publishLocation: Container
+ ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
+ continueOnError: true
+ condition: always()
+ sbomEnabled: false # we don't need SBOM for logs
+
+ - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
+ - output: pipelineArtifact
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/eng/common/BuildConfiguration'
+ artifactName: 'BuildConfiguration'
+ displayName: 'Publish build retry configuration'
+ continueOnError: true
+ sbomEnabled: false # we don't need SBOM for BuildConfiguration
+
+ - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
+ - output: pipelineArtifact
+ displayName: Publish SBOM manifest
+ continueOnError: true
+ targetPath: $(Build.ArtifactStagingDirectory)/sbom
+ artifactName: $(ARTIFACT_NAME)
+
+ # add any outputs provided via root yaml
+ - ${{ if ne(parameters.templateContext.outputs, '') }}:
+ - ${{ each output in parameters.templateContext.outputs }}:
+ - ${{ output }}
+
+ # add any remaining templateContext properties
+ ${{ each context in parameters.templateContext }}:
+ ${{ if and(ne(context.key, 'outputParentDirectory'), ne(context.key, 'outputs')) }}:
+ ${{ context.key }}: ${{ context.value }}
+
+ ${{ each parameter in parameters }}:
+ ${{ if and(ne(parameter.key, 'templateContext'), ne(parameter.key, 'is1ESPipeline')) }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml
index 52b4d05d3f8d..0f0c514b912d 100644
--- a/eng/common/templates-official/job/onelocbuild.yml
+++ b/eng/common/templates-official/job/onelocbuild.yml
@@ -1,112 +1,7 @@
-parameters:
- # Optional: dependencies of the job
- dependsOn: ''
-
- # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
- pool: ''
-
- CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex
- GithubPat: $(BotAccount-dotnet-bot-repo-PAT)
-
- SourcesDirectory: $(Build.SourcesDirectory)
- CreatePr: true
- AutoCompletePr: false
- ReusePr: true
- UseLfLineEndings: true
- UseCheckedInLocProjectJson: false
- SkipLocProjectJsonGeneration: false
- LanguageSet: VS_Main_Languages
- LclSource: lclFilesInRepo
- LclPackageId: ''
- RepoType: gitHub
- GitHubOrg: dotnet
- MirrorRepo: ''
- MirrorBranch: main
- condition: ''
- JobNameSuffix: ''
-
jobs:
-- job: OneLocBuild${{ parameters.JobNameSuffix }}
-
- dependsOn: ${{ parameters.dependsOn }}
-
- displayName: OneLocBuild${{ parameters.JobNameSuffix }}
-
- variables:
- - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat
- - name: _GenerateLocProjectArguments
- value: -SourcesDirectory ${{ parameters.SourcesDirectory }}
- -LanguageSet "${{ parameters.LanguageSet }}"
- -CreateNeutralXlfs
- - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}:
- - name: _GenerateLocProjectArguments
- value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson
- - template: /eng/common/templates-official/variables/pool-providers.yml
-
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
- ${{ if eq(parameters.pool, '') }}:
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2022
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
- os: windows
-
- steps:
- - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:
- - task: Powershell@2
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1
- arguments: $(_GenerateLocProjectArguments)
- displayName: Generate LocProject.json
- condition: ${{ parameters.condition }}
-
- - task: OneLocBuild@2
- displayName: OneLocBuild
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- inputs:
- locProj: eng/Localize/LocProject.json
- outDir: $(Build.ArtifactStagingDirectory)
- lclSource: ${{ parameters.LclSource }}
- lclPackageId: ${{ parameters.LclPackageId }}
- isCreatePrSelected: ${{ parameters.CreatePr }}
- isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }}
- ${{ if eq(parameters.CreatePr, true) }}:
- isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }}
- ${{ if eq(parameters.RepoType, 'gitHub') }}:
- isShouldReusePrSelected: ${{ parameters.ReusePr }}
- packageSourceAuth: patAuth
- patVariable: ${{ parameters.CeapexPat }}
- ${{ if eq(parameters.RepoType, 'gitHub') }}:
- repoType: ${{ parameters.RepoType }}
- gitHubPatVariable: "${{ parameters.GithubPat }}"
- ${{ if ne(parameters.MirrorRepo, '') }}:
- isMirrorRepoSelected: true
- gitHubOrganization: ${{ parameters.GitHubOrg }}
- mirrorRepo: ${{ parameters.MirrorRepo }}
- mirrorBranch: ${{ parameters.MirrorBranch }}
- condition: ${{ parameters.condition }}
-
- - task: 1ES.PublishBuildArtifacts@1
- displayName: Publish Localization Files
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc'
- PublishLocation: Container
- ArtifactName: Loc
- condition: ${{ parameters.condition }}
+- template: /eng/common/core-templates/job/onelocbuild.yml
+ parameters:
+ is1ESPipeline: true
- - task: 1ES.PublishBuildArtifacts@1
- displayName: Publish LocProject.json
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/'
- PublishLocation: Container
- ArtifactName: Loc
- condition: ${{ parameters.condition }}
\ No newline at end of file
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml
index 0117328800c8..d667a70e8de7 100644
--- a/eng/common/templates-official/job/publish-build-assets.yml
+++ b/eng/common/templates-official/job/publish-build-assets.yml
@@ -1,160 +1,7 @@
-parameters:
- configuration: 'Debug'
-
- # Optional: condition for the job to run
- condition: ''
-
- # Optional: 'true' if future jobs should run even if this job fails
- continueOnError: false
-
- # Optional: dependencies of the job
- dependsOn: ''
-
- # Optional: Include PublishBuildArtifacts task
- enablePublishBuildArtifacts: false
-
- # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
- pool: {}
-
- # Optional: should run as a public build even in the internal project
- # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
- runAsPublic: false
-
- # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
- publishUsingPipelines: false
-
- # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
- publishAssetsImmediately: false
-
- artifactsPublishingAdditionalParameters: ''
-
- signingValidationAdditionalParameters: ''
-
jobs:
-- job: Asset_Registry_Publish
-
- dependsOn: ${{ parameters.dependsOn }}
- timeoutInMinutes: 150
-
- ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
- displayName: Publish Assets
- ${{ else }}:
- displayName: Publish to Build Asset Registry
-
- variables:
- - template: /eng/common/templates-official/variables/pool-providers.yml
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - group: Publish-Build-Assets
- - group: AzureDevOps-Artifact-Feeds-Pats
- - name: runCodesignValidationInjection
- value: false
- - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
- - template: /eng/common/templates-official/post-build/common-variables.yml
-
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2022
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Publishing-Internal
- image: windows.vs2019.amd64
- os: windows
- steps:
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download artifact
- inputs:
- artifactName: AssetManifests
- downloadPath: '$(Build.StagingDirectory)/Download'
- checkDownloadedFiles: true
- condition: ${{ parameters.condition }}
- continueOnError: ${{ parameters.continueOnError }}
-
- - task: NuGetAuthenticate@1
-
- - task: AzureCLI@2
- displayName: Publish Build Assets
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: ps
- scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
- arguments: >
- -task PublishBuildAssets -restore -msbuildEngine dotnet
- /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'
- /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com
- /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}
- /p:OfficialBuildId=$(Build.BuildNumber)
- condition: ${{ parameters.condition }}
- continueOnError: ${{ parameters.continueOnError }}
-
- - task: powershell@2
- displayName: Create ReleaseConfigs Artifact
- inputs:
- targetType: inline
- script: |
- New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force
- $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt"
- Add-Content -Path $filePath -Value $(BARBuildId)
- Add-Content -Path $filePath -Value "$(DefaultChannels)"
- Add-Content -Path $filePath -Value $(IsStableBuild)
-
- - task: 1ES.PublishBuildArtifacts@1
- displayName: Publish ReleaseConfigs Artifact
- inputs:
- PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs'
- PublishLocation: Container
- ArtifactName: ReleaseConfigs
-
- - task: powershell@2
- displayName: Check if SymbolPublishingExclusionsFile.txt exists
- inputs:
- targetType: inline
- script: |
- $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt"
- if(Test-Path -Path $symbolExclusionfile)
- {
- Write-Host "SymbolExclusionFile exists"
- Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true"
- }
- else{
- Write-Host "Symbols Exclusion file does not exists"
- Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false"
- }
-
- - task: 1ES.PublishBuildArtifacts@1
- displayName: Publish SymbolPublishingExclusionsFile Artifact
- condition: eq(variables['SymbolExclusionFile'], 'true')
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
- PublishLocation: Container
- ArtifactName: ReleaseConfigs
-
- - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
- - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: AzureCLI@2
- displayName: Publish Using Darc
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: ps
- scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
- arguments: -BuildId $(BARBuildId)
- -PublishingInfraVersion 3
- -AzdoToken '$(System.AccessToken)'
- -WaitPublishingFinish true
- -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
- -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+- template: /eng/common/core-templates/job/publish-build-assets.yml
+ parameters:
+ is1ESPipeline: true
- - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- - template: /eng/common/templates-official/steps/publish-logs.yml
- parameters:
- JobLabel: 'Publish_Artifacts_Logs'
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml
index f983033bb028..1a480034b678 100644
--- a/eng/common/templates-official/job/source-build.yml
+++ b/eng/common/templates-official/job/source-build.yml
@@ -1,75 +1,7 @@
-parameters:
- # This template adds arcade-powered source-build to CI. The template produces a server job with a
- # default ID 'Source_Build_Complete' to put in a dependency list if necessary.
-
- # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed.
- jobNamePrefix: 'Source_Build'
-
- # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for
- # managed-only repositories. This is an object with these properties:
- #
- # name: ''
- # The name of the job. This is included in the job ID.
- # targetRID: ''
- # The name of the target RID to use, instead of the one auto-detected by Arcade.
- # nonPortable: false
- # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than
- # linux-x64), and compiling against distro-provided packages rather than portable ones.
- # skipPublishValidation: false
- # Disables publishing validation. By default, a check is performed to ensure no packages are
- # published by source-build.
- # container: ''
- # A container to use. Runs in docker.
- # pool: {}
- # A pool to use. Runs directly on an agent.
- # buildScript: ''
- # Specifies the build script to invoke to perform the build in the repo. The default
- # './build.sh' should work for typical Arcade repositories, but this is customizable for
- # difficult situations.
- # jobProperties: {}
- # A list of job properties to inject at the top level, for potential extensibility beyond
- # container and pool.
- platform: {}
-
- # If set to true and running on a non-public project,
- # Internal blob storage locations will be enabled.
- # This is not enabled by default because many repositories do not need internal sources
- # and do not need to have the required service connections approved in the pipeline.
- enableInternalSources: false
-
jobs:
-- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }}
- displayName: Source-Build (${{ parameters.platform.name }})
-
- ${{ each property in parameters.platform.jobProperties }}:
- ${{ property.key }}: ${{ property.value }}
-
- ${{ if ne(parameters.platform.container, '') }}:
- container: ${{ parameters.platform.container }}
-
- ${{ if eq(parameters.platform.pool, '') }}:
- # The default VM host AzDO pool. This should be capable of running Docker containers: almost all
- # source-build builds run in Docker, including the default managed platform.
- # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic
- pool:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]
- demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open
-
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]
- image: 1es-mariner-2
- os: linux
-
- ${{ if ne(parameters.platform.pool, '') }}:
- pool: ${{ parameters.platform.pool }}
-
- workspace:
- clean: all
+- template: /eng/common/core-templates/job/source-build.yml
+ parameters:
+ is1ESPipeline: true
- steps:
- - ${{ if eq(parameters.enableInternalSources, true) }}:
- - template: /eng/common/templates-official/steps/enable-internal-runtimes.yml
- - template: /eng/common/templates-official/steps/source-build.yml
- parameters:
- platform: ${{ parameters.platform }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml
index 60dfb6b2d1c0..6d5ead316f92 100644
--- a/eng/common/templates-official/job/source-index-stage1.yml
+++ b/eng/common/templates-official/job/source-index-stage1.yml
@@ -1,83 +1,7 @@
-parameters:
- runAsPublic: false
- sourceIndexUploadPackageVersion: 2.0.0-20240502.12
- sourceIndexProcessBinlogPackageVersion: 1.0.1-20240129.2
- sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
- sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
- preSteps: []
- binlogPath: artifacts/log/Debug/Build.binlog
- condition: ''
- dependsOn: ''
- pool: ''
-
jobs:
-- job: SourceIndexStage1
- dependsOn: ${{ parameters.dependsOn }}
- condition: ${{ parameters.condition }}
- variables:
- - name: SourceIndexUploadPackageVersion
- value: ${{ parameters.sourceIndexUploadPackageVersion }}
- - name: SourceIndexProcessBinlogPackageVersion
- value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }}
- - name: SourceIndexPackageSource
- value: ${{ parameters.sourceIndexPackageSource }}
- - name: BinlogPath
- value: ${{ parameters.binlogPath }}
- - template: /eng/common/templates-official/variables/pool-providers.yml
-
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
- ${{ if eq(parameters.pool, '') }}:
- pool:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- name: $(DncEngPublicBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64.open
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- name: $(DncEngInternalBuildPool)
- image: windows.vs2022.amd64
- os: windows
-
- steps:
- - ${{ each preStep in parameters.preSteps }}:
- - ${{ preStep }}
-
- - task: UseDotNet@2
- displayName: Use .NET 8 SDK
- inputs:
- packageType: sdk
- version: 8.0.x
- installationPath: $(Agent.TempDirectory)/dotnet
- workingDirectory: $(Agent.TempDirectory)
-
- - script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
- displayName: Download Tools
- # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
- workingDirectory: $(Agent.TempDirectory)
-
- - script: ${{ parameters.sourceIndexBuildCommand }}
- displayName: Build Repository
-
- - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
- displayName: Process Binlog into indexable sln
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: AzureCLI@2
- displayName: Get stage 1 auth token
- inputs:
- azureSubscription: 'SourceDotNet Stage1 Publish'
- addSpnToEnvironment: true
- scriptType: 'ps'
- scriptLocation: 'inlineScript'
- inlineScript: |
- echo "##vso[task.setvariable variable=ARM_CLIENT_ID;issecret=true]$env:servicePrincipalId"
- echo "##vso[task.setvariable variable=ARM_ID_TOKEN;issecret=true]$env:idToken"
- echo "##vso[task.setvariable variable=ARM_TENANT_ID;issecret=true]$env:tenantId"
-
- - script: |
- az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN)
- displayName: "Login to Azure"
+- template: /eng/common/core-templates/job/source-index-stage1.yml
+ parameters:
+ is1ESPipeline: true
- - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
- displayName: Upload stage1 artifacts to source index
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml
index b68d3c2f3199..a726322ecfe0 100644
--- a/eng/common/templates-official/jobs/codeql-build.yml
+++ b/eng/common/templates-official/jobs/codeql-build.yml
@@ -1,31 +1,7 @@
-parameters:
- # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
- continueOnError: false
- # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
- jobs: []
- # Optional: if specified, restore and use this version of Guardian instead of the default.
- overrideGuardianVersion: ''
-
jobs:
-- template: /eng/common/templates-official/jobs/jobs.yml
+- template: /eng/common/core-templates/jobs/codeql-build.yml
parameters:
- enableMicrobuild: false
- enablePublishBuildArtifacts: false
- enablePublishTestResults: false
- enablePublishBuildAssets: false
- enablePublishUsingPipelines: false
- enableTelemetry: true
+ is1ESPipeline: true
- variables:
- - group: Publish-Build-Assets
- # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
- # sync with the packages.config file.
- - name: DefaultGuardianVersion
- value: 0.109.0
- - name: GuardianPackagesConfigFile
- value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
- - name: GuardianVersion
- value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
-
- jobs: ${{ parameters.jobs }}
-
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml
index 857a0f8ba43e..007deddaea0f 100644
--- a/eng/common/templates-official/jobs/jobs.yml
+++ b/eng/common/templates-official/jobs/jobs.yml
@@ -1,97 +1,7 @@
-parameters:
- # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
- continueOnError: false
-
- # Optional: Include PublishBuildArtifacts task
- enablePublishBuildArtifacts: false
-
- # Optional: Enable publishing using release pipelines
- enablePublishUsingPipelines: false
-
- # Optional: Enable running the source-build jobs to build repo from source
- enableSourceBuild: false
-
- # Optional: Parameters for source-build template.
- # See /eng/common/templates-official/jobs/source-build.yml for options
- sourceBuildParameters: []
-
- graphFileGeneration:
- # Optional: Enable generating the graph files at the end of the build
- enabled: false
- # Optional: Include toolset dependencies in the generated graph files
- includeToolset: false
-
- # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
- jobs: []
-
- # Optional: Override automatically derived dependsOn value for "publish build assets" job
- publishBuildAssetsDependsOn: ''
-
- # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage.
- publishAssetsImmediately: false
-
- # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml)
- artifactsPublishingAdditionalParameters: ''
- signingValidationAdditionalParameters: ''
-
- # Optional: should run as a public build even in the internal project
- # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
- runAsPublic: false
-
- enableSourceIndex: false
- sourceIndexParams: {}
-
-# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
-# and some (Microbuild) should only be applied to non-PR cases for internal builds.
-
jobs:
-- ${{ each job in parameters.jobs }}:
- - template: ../job/job.yml
- parameters:
- # pass along parameters
- ${{ each parameter in parameters }}:
- ${{ if ne(parameter.key, 'jobs') }}:
- ${{ parameter.key }}: ${{ parameter.value }}
-
- # pass along job properties
- ${{ each property in job }}:
- ${{ if ne(property.key, 'job') }}:
- ${{ property.key }}: ${{ property.value }}
-
- name: ${{ job.job }}
-
-- ${{ if eq(parameters.enableSourceBuild, true) }}:
- - template: /eng/common/templates-official/jobs/source-build.yml
- parameters:
- allCompletedJobId: Source_Build_Complete
- ${{ each parameter in parameters.sourceBuildParameters }}:
- ${{ parameter.key }}: ${{ parameter.value }}
-
-- ${{ if eq(parameters.enableSourceIndex, 'true') }}:
- - template: ../job/source-index-stage1.yml
- parameters:
- runAsPublic: ${{ parameters.runAsPublic }}
- ${{ each parameter in parameters.sourceIndexParams }}:
- ${{ parameter.key }}: ${{ parameter.value }}
-
-- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}:
- - template: ../job/publish-build-assets.yml
- parameters:
- continueOnError: ${{ parameters.continueOnError }}
- dependsOn:
- - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:
- - ${{ each job in parameters.publishBuildAssetsDependsOn }}:
- - ${{ job.job }}
- - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}:
- - ${{ each job in parameters.jobs }}:
- - ${{ job.job }}
- - ${{ if eq(parameters.enableSourceBuild, true) }}:
- - Source_Build_Complete
+- template: /eng/common/core-templates/jobs/jobs.yml
+ parameters:
+ is1ESPipeline: true
- runAsPublic: ${{ parameters.runAsPublic }}
- publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}
- publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }}
- enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
- artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
- signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml
index 5cf6a269c0b6..483e7b611f34 100644
--- a/eng/common/templates-official/jobs/source-build.yml
+++ b/eng/common/templates-official/jobs/source-build.yml
@@ -1,54 +1,7 @@
-parameters:
- # This template adds arcade-powered source-build to CI. A job is created for each platform, as
- # well as an optional server job that completes when all platform jobs complete.
-
- # The name of the "join" job for all source-build platforms. If set to empty string, the job is
- # not included. Existing repo pipelines can use this job depend on all source-build jobs
- # completing without maintaining a separate list of every single job ID: just depend on this one
- # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'.
- allCompletedJobId: ''
-
- # See /eng/common/templates-official/job/source-build.yml
- jobNamePrefix: 'Source_Build'
-
- # This is the default platform provided by Arcade, intended for use by a managed-only repo.
- defaultManagedPlatform:
- name: 'Managed'
- container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8'
-
- # Defines the platforms on which to run build jobs. One job is created for each platform, and the
- # object in this array is sent to the job template as 'platform'. If no platforms are specified,
- # one job runs on 'defaultManagedPlatform'.
- platforms: []
-
- # If set to true and running on a non-public project,
- # Internal nuget and blob storage locations will be enabled.
- # This is not enabled by default because many repositories do not need internal sources
- # and do not need to have the required service connections approved in the pipeline.
- enableInternalSources: false
-
jobs:
+- template: /eng/common/core-templates/jobs/source-build.yml
+ parameters:
+ is1ESPipeline: true
-- ${{ if ne(parameters.allCompletedJobId, '') }}:
- - job: ${{ parameters.allCompletedJobId }}
- displayName: Source-Build Complete
- pool: server
- dependsOn:
- - ${{ each platform in parameters.platforms }}:
- - ${{ parameters.jobNamePrefix }}_${{ platform.name }}
- - ${{ if eq(length(parameters.platforms), 0) }}:
- - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }}
-
-- ${{ each platform in parameters.platforms }}:
- - template: /eng/common/templates-official/job/source-build.yml
- parameters:
- jobNamePrefix: ${{ parameters.jobNamePrefix }}
- platform: ${{ platform }}
- enableInternalSources: ${{ parameters.enableInternalSources }}
-
-- ${{ if eq(length(parameters.platforms), 0) }}:
- - template: /eng/common/templates-official/job/source-build.yml
- parameters:
- jobNamePrefix: ${{ parameters.jobNamePrefix }}
- platform: ${{ parameters.defaultManagedPlatform }}
- enableInternalSources: ${{ parameters.enableInternalSources }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml
index c24193acfc98..c32fc49233f8 100644
--- a/eng/common/templates-official/post-build/common-variables.yml
+++ b/eng/common/templates-official/post-build/common-variables.yml
@@ -1,22 +1,8 @@
variables:
- - group: Publish-Build-Assets
+- template: /eng/common/core-templates/post-build/common-variables.yml
+ parameters:
+ # Specifies whether to use 1ES
+ is1ESPipeline: true
- # Whether the build is internal or not
- - name: IsInternalBuild
- value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
-
- # Default Maestro++ API Endpoint and API Version
- - name: MaestroApiEndPoint
- value: "https://maestro-prod.westus2.cloudapp.azure.com"
- - name: MaestroApiAccessToken
- value: $(MaestroAccessToken)
- - name: MaestroApiVersion
- value: "2020-02-20"
-
- - name: SourceLinkCLIVersion
- value: 3.0.0
- - name: SymbolToolVersion
- value: 1.0.1
-
- - name: runCodesignValidationInjection
- value: false
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml
index b81b8770b346..2364c0fd4a52 100644
--- a/eng/common/templates-official/post-build/post-build.yml
+++ b/eng/common/templates-official/post-build/post-build.yml
@@ -1,287 +1,8 @@
-parameters:
- # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.
- # Publishing V1 is no longer supported
- # Publishing V2 is no longer supported
- # Publishing V3 is the default
- - name: publishingInfraVersion
- displayName: Which version of publishing should be used to promote the build definition?
- type: number
- default: 3
- values:
- - 3
-
- - name: BARBuildId
- displayName: BAR Build Id
- type: number
- default: 0
-
- - name: PromoteToChannelIds
- displayName: Channel to promote BARBuildId to
- type: string
- default: ''
-
- - name: enableSourceLinkValidation
- displayName: Enable SourceLink validation
- type: boolean
- default: false
-
- - name: enableSigningValidation
- displayName: Enable signing validation
- type: boolean
- default: true
-
- - name: enableSymbolValidation
- displayName: Enable symbol validation
- type: boolean
- default: false
-
- - name: enableNugetValidation
- displayName: Enable NuGet validation
- type: boolean
- default: true
-
- - name: publishInstallersAndChecksums
- displayName: Publish installers and checksums
- type: boolean
- default: true
-
- - name: SDLValidationParameters
- type: object
- default:
- enable: false
- publishGdn: false
- continueOnError: false
- params: ''
- artifactNames: ''
- downloadArtifacts: true
-
- # These parameters let the user customize the call to sdk-task.ps1 for publishing
- # symbols & general artifacts as well as for signing validation
- - name: symbolPublishingAdditionalParameters
- displayName: Symbol publishing additional parameters
- type: string
- default: ''
-
- - name: artifactsPublishingAdditionalParameters
- displayName: Artifact publishing additional parameters
- type: string
- default: ''
-
- - name: signingValidationAdditionalParameters
- displayName: Signing validation additional parameters
- type: string
- default: ''
-
- # Which stages should finish execution before post-build stages start
- - name: validateDependsOn
- type: object
- default:
- - build
-
- - name: publishDependsOn
- type: object
- default:
- - Validate
-
- # Optional: Call asset publishing rather than running in a separate stage
- - name: publishAssetsImmediately
- type: boolean
- default: false
-
stages:
-- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
- - stage: Validate
- dependsOn: ${{ parameters.validateDependsOn }}
- displayName: Validate Build Assets
- variables:
- - template: common-variables.yml
- - template: /eng/common/templates-official/variables/pool-providers.yml
- jobs:
- - job:
- displayName: NuGet Validation
- condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true'))
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2022
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
- os: windows
-
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Package Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: PackageArtifacts
- checkDownloadedFiles: true
-
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1
- arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
- -ToolDestinationPath $(Agent.BuildDirectory)/Extract/
-
- - job:
- displayName: Signing Validation
- condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true'))
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2022
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
- os: windows
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Package Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: PackageArtifacts
- checkDownloadedFiles: true
- itemPattern: |
- **
- !**/Microsoft.SourceBuild.Intermediate.*.nupkg
-
- # This is necessary whenever we want to publish/restore to an AzDO private feed
- # Since sdk-task.ps1 tries to restore packages we need to do this authentication here
- # otherwise it'll complain about accessing a private feed.
- - task: NuGetAuthenticate@1
- displayName: 'Authenticate to AzDO Feeds'
-
- # Signing validation will optionally work with the buildmanifest file which is downloaded from
- # Azure DevOps above.
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: eng\common\sdk-task.ps1
- arguments: -task SigningValidation -restore -msbuildEngine vs
- /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'
- /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt'
- ${{ parameters.signingValidationAdditionalParameters }}
-
- - template: ../steps/publish-logs.yml
- parameters:
- StageLabel: 'Validation'
- JobLabel: 'Signing'
- BinlogToolVersion: $(BinlogToolVersion)
-
- - job:
- displayName: SourceLink Validation
- condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2022
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
- os: windows
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Blob Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: BlobArtifacts
- checkDownloadedFiles: true
-
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1
- arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/
- -ExtractPath $(Agent.BuildDirectory)/Extract/
- -GHRepoName $(Build.Repository.Name)
- -GHCommit $(Build.SourceVersion)
- -SourcelinkCliVersion $(SourceLinkCLIVersion)
- continueOnError: true
-
-- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}:
- - stage: publish_using_darc
- ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
- dependsOn: ${{ parameters.publishDependsOn }}
- ${{ else }}:
- dependsOn: ${{ parameters.validateDependsOn }}
- displayName: Publish using Darc
- variables:
- - template: common-variables.yml
- - template: /eng/common/templates-official/variables/pool-providers.yml
- jobs:
- - job:
- displayName: Publish Using Darc
- timeoutInMinutes: 120
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2022
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: NetCore1ESPool-Publishing-Internal
- image: windows.vs2019.amd64
- os: windows
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: NuGetAuthenticate@1
+- template: /eng/common/core-templates/post-build/post-build.yml
+ parameters:
+ # Specifies whether to use 1ES
+ is1ESPipeline: true
- - task: AzureCLI@2
- displayName: Publish Using Darc
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: ps
- scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
- arguments: -BuildId $(BARBuildId)
- -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
- -AzdoToken '$(System.AccessToken)'
- -WaitPublishingFinish true
- -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
- -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml
index 0c87f149a4ad..024397d87864 100644
--- a/eng/common/templates-official/post-build/setup-maestro-vars.yml
+++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml
@@ -1,70 +1,8 @@
-parameters:
- BARBuildId: ''
- PromoteToChannelIds: ''
-
steps:
- - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download Release Configs
- inputs:
- buildType: current
- artifactName: ReleaseConfigs
- checkDownloadedFiles: true
-
- - task: PowerShell@2
- name: setReleaseVars
- displayName: Set Release Configs Vars
- inputs:
- targetType: inline
- pwsh: true
- script: |
- try {
- if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
- $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
-
- $BarId = $Content | Select -Index 0
- $Channels = $Content | Select -Index 1
- $IsStableBuild = $Content | Select -Index 2
-
- $AzureDevOpsProject = $Env:System_TeamProject
- $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
- $AzureDevOpsBuildId = $Env:Build_BuildId
- }
- else {
- $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}"
-
- $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
- $apiHeaders.Add('Accept', 'application/json')
- $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}")
-
- $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" }
-
- $BarId = $Env:BARBuildId
- $Channels = $Env:PromoteToMaestroChannels -split ","
- $Channels = $Channels -join "]["
- $Channels = "[$Channels]"
-
- $IsStableBuild = $buildInfo.stable
- $AzureDevOpsProject = $buildInfo.azureDevOpsProject
- $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
- $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
- }
-
- Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId"
- Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels"
- Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild"
+- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ # Specifies whether to use 1ES
+ is1ESPipeline: true
- Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject"
- Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId"
- Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId"
- }
- catch {
- Write-Host $_
- Write-Host $_.Exception
- Write-Host $_.ScriptStackTrace
- exit 1
- }
- env:
- MAESTRO_API_TOKEN: $(MaestroApiAccessToken)
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/post-build/trigger-subscription.yml b/eng/common/templates-official/post-build/trigger-subscription.yml
deleted file mode 100644
index da669030daf6..000000000000
--- a/eng/common/templates-official/post-build/trigger-subscription.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-parameters:
- ChannelId: 0
-
-steps:
-- task: PowerShell@2
- displayName: Triggering subscriptions
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1
- arguments: -SourceRepo $(Build.Repository.Uri)
- -ChannelId ${{ parameters.ChannelId }}
- -MaestroApiAccessToken $(MaestroAccessToken)
- -MaestroApiEndPoint $(MaestroApiEndPoint)
- -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml
deleted file mode 100644
index f67a210d62f3..000000000000
--- a/eng/common/templates-official/steps/add-build-to-channel.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-parameters:
- ChannelId: 0
-
-steps:
-- task: PowerShell@2
- displayName: Add Build to Channel
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1
- arguments: -BuildId $(BARBuildId)
- -ChannelId ${{ parameters.ChannelId }}
- -MaestroApiAccessToken $(MaestroApiAccessToken)
- -MaestroApiEndPoint $(MaestroApiEndPoint)
- -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates-official/steps/build-reason.yml b/eng/common/templates-official/steps/build-reason.yml
deleted file mode 100644
index eba58109b52c..000000000000
--- a/eng/common/templates-official/steps/build-reason.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# build-reason.yml
-# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons
-# to include steps (',' separated).
-parameters:
- conditions: ''
- steps: []
-
-steps:
- - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}:
- - ${{ parameters.steps }}
- - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}:
- - ${{ parameters.steps }}
diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml
index cbba0596709d..30bb3985ca2b 100644
--- a/eng/common/templates-official/steps/component-governance.yml
+++ b/eng/common/templates-official/steps/component-governance.yml
@@ -1,13 +1,7 @@
-parameters:
- disableComponentGovernance: false
- componentGovernanceIgnoreDirectories: ''
-
steps:
-- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
- - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
- displayName: Set skipComponentGovernanceDetection variable
-- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
- - task: ComponentGovernanceComponentDetection@0
- continueOnError: true
- inputs:
- ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
\ No newline at end of file
+- template: /eng/common/core-templates/steps/component-governance.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/enable-internal-runtimes.yml b/eng/common/templates-official/steps/enable-internal-runtimes.yml
index 93a8394a666b..f9dd238c6cd5 100644
--- a/eng/common/templates-official/steps/enable-internal-runtimes.yml
+++ b/eng/common/templates-official/steps/enable-internal-runtimes.yml
@@ -1,28 +1,9 @@
# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
# variable with the base64-encoded SAS token, by default
-
-parameters:
-- name: federatedServiceConnection
- type: string
- default: 'dotnetbuilds-internal-read'
-- name: outputVariableName
- type: string
- default: 'dotnetbuilds-internal-container-read-token-base64'
-- name: expiryInHours
- type: number
- default: 1
-- name: base64Encode
- type: boolean
- default: true
-
steps:
-- ${{ if ne(variables['System.TeamProject'], 'public') }}:
- - template: /eng/common/templates-official/steps/get-delegation-sas.yml
- parameters:
- federatedServiceConnection: ${{ parameters.federatedServiceConnection }}
- outputVariableName: ${{ parameters.outputVariableName }}
- expiryInHours: ${{ parameters.expiryInHours }}
- base64Encode: ${{ parameters.base64Encode }}
- storageAccount: dotnetbuilds
- container: internal
- permissions: rl
+- template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/enable-internal-sources.yml b/eng/common/templates-official/steps/enable-internal-sources.yml
new file mode 100644
index 000000000000..e6d57182284d
--- /dev/null
+++ b/eng/common/templates-official/steps/enable-internal-sources.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/enable-internal-sources.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/execute-codeql.yml b/eng/common/templates-official/steps/execute-codeql.yml
deleted file mode 100644
index 9b4a5ffa30a7..000000000000
--- a/eng/common/templates-official/steps/execute-codeql.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-parameters:
- # Language that should be analyzed. Defaults to csharp
- language: csharp
- # Build Commands
- buildCommands: ''
- overrideParameters: '' # Optional: to override values for parameters.
- additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")'
- # Optional: if specified, restore and use this version of Guardian instead of the default.
- overrideGuardianVersion: ''
- # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth
- # diagnosis of problems with specific tool configurations.
- publishGuardianDirectoryToPipeline: false
- # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL
- # parameters rather than relying on YAML. It may be better to use a local script, because you can
- # reproduce results locally without piecing together a command based on the YAML.
- executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1'
- # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named
- # 'continueOnError', the parameter value is not correctly picked up.
- # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter
- # optional: determines whether to continue the build if the step errors;
- sdlContinueOnError: false
-
-steps:
-- template: /eng/common/templates-official/steps/execute-sdl.yml
- parameters:
- overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }}
- executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }}
- overrideParameters: ${{ parameters.overrideParameters }}
- additionalParameters: '${{ parameters.additionalParameters }}
- -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")'
- publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }}
- sdlContinueOnError: ${{ parameters.sdlContinueOnError }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml
deleted file mode 100644
index 301d5c591ebd..000000000000
--- a/eng/common/templates-official/steps/execute-sdl.yml
+++ /dev/null
@@ -1,86 +0,0 @@
-parameters:
- overrideGuardianVersion: ''
- executeAllSdlToolsScript: ''
- overrideParameters: ''
- additionalParameters: ''
- publishGuardianDirectoryToPipeline: false
- sdlContinueOnError: false
- condition: ''
-
-steps:
-- task: NuGetAuthenticate@1
-
-- task: NuGetToolInstaller@1
- displayName: 'Install NuGet.exe'
-
-- ${{ if ne(parameters.overrideGuardianVersion, '') }}:
- - pwsh: |
- Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl
- . .\sdl.ps1
- $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }}
- Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation"
- displayName: Install Guardian (Overridden)
-
-- ${{ if eq(parameters.overrideGuardianVersion, '') }}:
- - pwsh: |
- Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl
- . .\sdl.ps1
- $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts
- Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation"
- displayName: Install Guardian
-
-- ${{ if ne(parameters.overrideParameters, '') }}:
- - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }}
- displayName: Execute SDL (Overridden)
- continueOnError: ${{ parameters.sdlContinueOnError }}
- condition: ${{ parameters.condition }}
-
-- ${{ if eq(parameters.overrideParameters, '') }}:
- - powershell: ${{ parameters.executeAllSdlToolsScript }}
- -GuardianCliLocation $(GuardianCliLocation)
- -NugetPackageDirectory $(Build.SourcesDirectory)\.packages
- -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw)
- ${{ parameters.additionalParameters }}
- displayName: Execute SDL
- continueOnError: ${{ parameters.sdlContinueOnError }}
- condition: ${{ parameters.condition }}
-
-- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}:
- # We want to publish the Guardian results and configuration for easy diagnosis. However, the
- # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default
- # tooling files. Some of these files are large and aren't useful during an investigation, so
- # exclude them by simply deleting them before publishing. (As of writing, there is no documented
- # way to selectively exclude a dir from the pipeline artifact publish task.)
- - task: DeleteFiles@1
- displayName: Delete Guardian dependencies to avoid uploading
- inputs:
- SourceFolder: $(Agent.BuildDirectory)/.gdn
- Contents: |
- c
- i
- condition: succeededOrFailed()
-
- - publish: $(Agent.BuildDirectory)/.gdn
- artifact: GuardianConfiguration
- displayName: Publish GuardianConfiguration
- condition: succeededOrFailed()
-
- # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration
- # with the "SARIF SAST Scans Tab" Azure DevOps extension
- - task: CopyFiles@2
- displayName: Copy SARIF files
- inputs:
- flattenFolders: true
- sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/
- contents: '**/*.sarif'
- targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs
- condition: succeededOrFailed()
-
- # Use PublishBuildArtifacts because the SARIF extension only checks this case
- # see microsoft/sarif-azuredevops-extension#4
- - task: PublishBuildArtifacts@1
- displayName: Publish SARIF files to CodeAnalysisLogs container
- inputs:
- pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs
- artifactName: CodeAnalysisLogs
- condition: succeededOrFailed()
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml
index 1bf43bf807af..9a89a4706d94 100644
--- a/eng/common/templates-official/steps/generate-sbom.yml
+++ b/eng/common/templates-official/steps/generate-sbom.yml
@@ -1,48 +1,7 @@
-# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
-# PackageName - The name of the package this SBOM represents.
-# PackageVersion - The version of the package this SBOM represents.
-# ManifestDirPath - The path of the directory where the generated manifest files will be placed
-# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
-
-parameters:
- PackageVersion: 8.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
- PackageName: '.NET'
- ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
- IgnoreDirectories: ''
- sbomContinueOnError: true
-
steps:
-- task: PowerShell@2
- displayName: Prep for SBOM generation in (Non-linux)
- condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
- inputs:
- filePath: ./eng/common/generate-sbom-prep.ps1
- arguments: ${{parameters.manifestDirPath}}
-
-# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
-- script: |
- chmod +x ./eng/common/generate-sbom-prep.sh
- ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
- displayName: Prep for SBOM generation in (Linux)
- condition: eq(variables['Agent.Os'], 'Linux')
- continueOnError: ${{ parameters.sbomContinueOnError }}
-
-- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
- displayName: 'Generate SBOM manifest'
- continueOnError: ${{ parameters.sbomContinueOnError }}
- inputs:
- PackageName: ${{ parameters.packageName }}
- BuildDropPath: ${{ parameters.buildDropPath }}
- PackageVersion: ${{ parameters.packageVersion }}
- ManifestDirPath: ${{ parameters.manifestDirPath }}
- ${{ if ne(parameters.IgnoreDirectories, '') }}:
- AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
-
-- task: 1ES.PublishPipelineArtifact@1
- displayName: Publish SBOM manifest
- continueOnError: ${{parameters.sbomContinueOnError}}
- inputs:
- targetPath: '${{parameters.manifestDirPath}}'
- artifactName: $(ARTIFACT_NAME)
+- template: /eng/common/core-templates/steps/generate-sbom.yml
+ parameters:
+ is1ESPipeline: true
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/get-delegation-sas.yml b/eng/common/templates-official/steps/get-delegation-sas.yml
index c0e8f91317f0..c5a9c1f8275c 100644
--- a/eng/common/templates-official/steps/get-delegation-sas.yml
+++ b/eng/common/templates-official/steps/get-delegation-sas.yml
@@ -1,43 +1,7 @@
-parameters:
-- name: federatedServiceConnection
- type: string
-- name: outputVariableName
- type: string
-- name: expiryInHours
- type: number
- default: 1
-- name: base64Encode
- type: boolean
- default: false
-- name: storageAccount
- type: string
-- name: container
- type: string
-- name: permissions
- type: string
- default: 'rl'
-
steps:
-- task: AzureCLI@2
- displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}'
- inputs:
- azureSubscription: ${{ parameters.federatedServiceConnection }}
- scriptType: 'pscore'
- scriptLocation: 'inlineScript'
- inlineScript: |
- # Calculate the expiration of the SAS token and convert to UTC
- $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
-
- $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv
-
- if ($LASTEXITCODE -ne 0) {
- Write-Error "Failed to generate SAS token."
- exit 1
- }
-
- if ('${{ parameters.base64Encode }}' -eq 'true') {
- $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas))
- }
+- template: /eng/common/core-templates/steps/get-delegation-sas.yml
+ parameters:
+ is1ESPipeline: true
- Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
- Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas"
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/get-federated-access-token.yml b/eng/common/templates-official/steps/get-federated-access-token.yml
index 55e33bd38f71..c8dcf6b81392 100644
--- a/eng/common/templates-official/steps/get-federated-access-token.yml
+++ b/eng/common/templates-official/steps/get-federated-access-token.yml
@@ -1,40 +1,7 @@
-parameters:
-- name: federatedServiceConnection
- type: string
-- name: outputVariableName
- type: string
-- name: stepName
- type: string
- default: 'getFederatedAccessToken'
-- name: condition
- type: string
- default: ''
-# Resource to get a token for. Common values include:
-# - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps
-# - 'https://storage.azure.com/' for storage
-# Defaults to Azure DevOps
-- name: resource
- type: string
- default: '499b84ac-1321-427f-aa17-267ca6975798'
-- name: isStepOutputVariable
- type: boolean
- default: false
-
steps:
-- task: AzureCLI@2
- displayName: 'Getting federated access token for feeds'
- name: ${{ parameters.stepName }}
- ${{ if ne(parameters.condition, '') }}:
- condition: ${{ parameters.condition }}
- inputs:
- azureSubscription: ${{ parameters.federatedServiceConnection }}
- scriptType: 'pscore'
- scriptLocation: 'inlineScript'
- inlineScript: |
- $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv
- if ($LASTEXITCODE -ne 0) {
- Write-Error "Failed to get access token for resource '${{ parameters.resource }}'"
- exit 1
- }
- Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
- Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken"
\ No newline at end of file
+- template: /eng/common/core-templates/steps/get-federated-access-token.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates-official/steps/publish-build-artifacts.yml b/eng/common/templates-official/steps/publish-build-artifacts.yml
new file mode 100644
index 000000000000..100a3fc98493
--- /dev/null
+++ b/eng/common/templates-official/steps/publish-build-artifacts.yml
@@ -0,0 +1,41 @@
+parameters:
+- name: displayName
+ type: string
+ default: 'Publish to Build Artifact'
+
+- name: condition
+ type: string
+ default: succeeded()
+
+- name: artifactName
+ type: string
+
+- name: pathToPublish
+ type: string
+
+- name: continueOnError
+ type: boolean
+ default: false
+
+- name: publishLocation
+ type: string
+ default: 'Container'
+
+- name: is1ESPipeline
+ type: boolean
+ default: true
+
+steps:
+- ${{ if ne(parameters.is1ESPipeline, true) }}:
+ - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error
+- task: 1ES.PublishBuildArtifacts@1
+ displayName: ${{ parameters.displayName }}
+ condition: ${{ parameters.condition }}
+ ${{ if parameters.continueOnError }}:
+ continueOnError: ${{ parameters.continueOnError }}
+ inputs:
+ PublishLocation: ${{ parameters.publishLocation }}
+ PathtoPublish: ${{ parameters.pathToPublish }}
+ ${{ if parameters.artifactName }}:
+ ArtifactName: ${{ parameters.artifactName }}
+
diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml
index 04012fed182a..579fd531e94c 100644
--- a/eng/common/templates-official/steps/publish-logs.yml
+++ b/eng/common/templates-official/steps/publish-logs.yml
@@ -1,23 +1,7 @@
-parameters:
- StageLabel: ''
- JobLabel: ''
-
steps:
-- task: Powershell@2
- displayName: Prepare Binlogs to Upload
- inputs:
- targetType: inline
- script: |
- New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
- Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
- continueOnError: true
- condition: always()
+- template: /eng/common/core-templates/steps/publish-logs.yml
+ parameters:
+ is1ESPipeline: true
-- task: 1ES.PublishBuildArtifacts@1
- displayName: Publish Logs
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs'
- PublishLocation: Container
- ArtifactName: PostBuildLogs
- continueOnError: true
- condition: always()
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
new file mode 100644
index 000000000000..172f9f0fdc97
--- /dev/null
+++ b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
@@ -0,0 +1,28 @@
+parameters:
+- name: is1ESPipeline
+ type: boolean
+ default: true
+
+- name: args
+ type: object
+ default: {}
+
+steps:
+- ${{ if ne(parameters.is1ESPipeline, true) }}:
+ - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error
+- task: 1ES.PublishPipelineArtifact@1
+ displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }}
+ ${{ if parameters.args.condition }}:
+ condition: ${{ parameters.args.condition }}
+ ${{ else }}:
+ condition: succeeded()
+ ${{ if parameters.args.continueOnError }}:
+ continueOnError: ${{ parameters.args.continueOnError }}
+ inputs:
+ targetPath: ${{ parameters.args.targetPath }}
+ ${{ if parameters.args.artifactName }}:
+ artifactName: ${{ parameters.args.artifactName }}
+ ${{ if parameters.args.properties }}:
+ properties: ${{ parameters.args.properties }}
+ ${{ if parameters.args.sbomEnabled }}:
+ sbomEnabled: ${{ parameters.args.sbomEnabled }}
diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml
index 83d97a26a01f..5594551508a3 100644
--- a/eng/common/templates-official/steps/retain-build.yml
+++ b/eng/common/templates-official/steps/retain-build.yml
@@ -1,28 +1,7 @@
-parameters:
- # Optional azure devops PAT with build execute permissions for the build's organization,
- # only needed if the build that should be retained ran on a different organization than
- # the pipeline where this template is executing from
- Token: ''
- # Optional BuildId to retain, defaults to the current running build
- BuildId: ''
- # Azure devops Organization URI for the build in the https://dev.azure.com/ format.
- # Defaults to the organization the current pipeline is running on
- AzdoOrgUri: '$(System.CollectionUri)'
- # Azure devops project for the build. Defaults to the project the current pipeline is running on
- AzdoProject: '$(System.TeamProject)'
-
steps:
- - task: powershell@2
- inputs:
- targetType: 'filePath'
- filePath: eng/common/retain-build.ps1
- pwsh: true
- arguments: >
- -AzdoOrgUri: ${{parameters.AzdoOrgUri}}
- -AzdoProject ${{parameters.AzdoProject}}
- -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }}
- -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}}
- displayName: Enable permanent build retention
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- BUILD_ID: $(Build.BuildId)
\ No newline at end of file
+- template: /eng/common/core-templates/steps/retain-build.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml
index 3eb7e2d5f840..6500f21bf845 100644
--- a/eng/common/templates-official/steps/send-to-helix.yml
+++ b/eng/common/templates-official/steps/send-to-helix.yml
@@ -1,91 +1,7 @@
-# Please remember to update the documentation if you make changes to these parameters!
-parameters:
- HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/
- HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/'
- HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number
- HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues
- HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group
- HelixConfiguration: '' # optional -- additional property attached to a job
- HelixPreCommands: '' # optional -- commands to run before Helix work item execution
- HelixPostCommands: '' # optional -- commands to run after Helix work item execution
- WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects
- WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects
- WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects
- CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload
- XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true
- XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects
- XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects
- XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner
- XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects
- IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion
- DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
- DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
- WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget."
- IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set
- HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net )
- Creator: '' # optional -- if the build is external, use this to specify who is sending the job
- DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO
- condition: succeeded() # optional -- condition for step to execute; defaults to succeeded()
- continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false
-
steps:
- - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env: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 }}
- 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/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /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 }}
- 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 }}
+- template: /eng/common/core-templates/steps/send-to-helix.yml
+ parameters:
+ is1ESPipeline: true
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml
index 829f17c34d11..8f92c49e7b06 100644
--- a/eng/common/templates-official/steps/source-build.yml
+++ b/eng/common/templates-official/steps/source-build.yml
@@ -1,129 +1,7 @@
-parameters:
- # This template adds arcade-powered source-build to CI.
-
- # This is a 'steps' template, and is intended for advanced scenarios where the existing build
- # infra has a careful build methodology that must be followed. For example, a repo
- # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline
- # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to
- # GitHub. Using this steps template leaves room for that infra to be included.
-
- # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml'
- # for details. The entire object is described in the 'job' template for simplicity, even though
- # the usage of the properties on this object is split between the 'job' and 'steps' templates.
- platform: {}
-
steps:
-# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.)
-- script: |
- set -x
- df -h
-
- # If building on the internal project, the artifact feeds variable may be available (usually only if needed)
- # In that case, call the feed setup script to add internal feeds corresponding to public ones.
- # In addition, add an msbuild argument to copy the WIP from the repo to the target build location.
- # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those
- # changes.
- internalRestoreArgs=
- if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then
- # Temporarily work around https://github.com/dotnet/arcade/issues/7709
- chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
- $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw)
- internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'
-
- # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.
- # This only works if there is a username/email configured, which won't be the case in most CI runs.
- git config --get user.email
- if [ $? -ne 0 ]; then
- git config user.email dn-bot@microsoft.com
- git config user.name dn-bot
- fi
- fi
-
- # If building on the internal project, the internal storage variable may be available (usually only if needed)
- # In that case, add variables to allow the download of internal runtimes if the specified versions are not found
- # in the default public locations.
- internalRuntimeDownloadArgs=
- if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
- internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
- fi
-
- buildConfig=Release
- # Check if AzDO substitutes in a build config from a variable, and use it if so.
- if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then
- buildConfig='$(_BuildConfig)'
- fi
-
- officialBuildArgs=
- if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then
- officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'
- fi
-
- targetRidArgs=
- if [ '${{ parameters.platform.targetRID }}' != '' ]; then
- targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
- fi
-
- runtimeOsArgs=
- if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then
- runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'
- fi
-
- baseOsArgs=
- if [ '${{ parameters.platform.baseOS }}' != '' ]; then
- baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}'
- fi
-
- publishArgs=
- if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then
- publishArgs='--publish'
- fi
-
- assetManifestFileName=SourceBuild_RidSpecific.xml
- if [ '${{ parameters.platform.name }}' != '' ]; then
- assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml
- fi
-
- ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \
- --configuration $buildConfig \
- --restore --build --pack $publishArgs -bl \
- $officialBuildArgs \
- $internalRuntimeDownloadArgs \
- $internalRestoreArgs \
- $targetRidArgs \
- $runtimeOsArgs \
- $baseOsArgs \
- /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
- /p:ArcadeBuildFromSource=true \
- /p:AssetManifestFileName=$assetManifestFileName
- displayName: Build
-
-# Upload build logs for diagnosis.
-- task: CopyFiles@2
- displayName: Prepare BuildLogs staging directory
- inputs:
- SourceFolder: '$(Build.SourcesDirectory)'
- Contents: |
- **/*.log
- **/*.binlog
- artifacts/source-build/self/prebuilt-report/**
- TargetFolder: '$(Build.StagingDirectory)/BuildLogs'
- CleanTargetFolder: true
- continueOnError: true
- condition: succeededOrFailed()
-
-- task: 1ES.PublishPipelineArtifact@1
- displayName: Publish BuildLogs
- inputs:
- targetPath: '$(Build.StagingDirectory)/BuildLogs'
- artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
- continueOnError: true
- condition: succeededOrFailed()
+- template: /eng/common/core-templates/steps/source-build.yml
+ parameters:
+ is1ESPipeline: true
-# Manually inject component detection so that we can ignore the source build upstream cache, which contains
-# a nupkg cache of input packages (a local feed).
-# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir'
-# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets
-- task: ComponentGovernanceComponentDetection@0
- displayName: Component Detection (Exclude upstream cache)
- inputs:
- ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache'
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml
deleted file mode 100644
index 7870f93bc176..000000000000
--- a/eng/common/templates/job/execute-sdl.yml
+++ /dev/null
@@ -1,139 +0,0 @@
-parameters:
- enable: 'false' # Whether the SDL validation job should execute or not
- overrideParameters: '' # Optional: to override values for parameters.
- additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")'
- # Optional: if specified, restore and use this version of Guardian instead of the default.
- overrideGuardianVersion: ''
- # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth
- # diagnosis of problems with specific tool configurations.
- publishGuardianDirectoryToPipeline: false
- # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL
- # parameters rather than relying on YAML. It may be better to use a local script, because you can
- # reproduce results locally without piecing together a command based on the YAML.
- executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1'
- # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named
- # 'continueOnError', the parameter value is not correctly picked up.
- # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter
- sdlContinueOnError: false # optional: determines whether to continue the build if the step errors;
- # optional: determines if build artifacts should be downloaded.
- downloadArtifacts: true
- # optional: determines if this job should search the directory of downloaded artifacts for
- # 'tar.gz' and 'zip' archive files and extract them before running SDL validation tasks.
- extractArchiveArtifacts: false
- dependsOn: '' # Optional: dependencies of the job
- artifactNames: '' # Optional: patterns supplied to DownloadBuildArtifacts
- # Usage:
- # artifactNames:
- # - 'BlobArtifacts'
- # - 'Artifacts_Windows_NT_Release'
- # Optional: download a list of pipeline artifacts. 'downloadArtifacts' controls build artifacts,
- # not pipeline artifacts, so doesn't affect the use of this parameter.
- pipelineArtifactNames: []
-
-jobs:
-- job: Run_SDL
- dependsOn: ${{ parameters.dependsOn }}
- displayName: Run SDL tool
- condition: and(succeededOrFailed(), eq( ${{ parameters.enable }}, 'true'))
- variables:
- - group: DotNet-VSTS-Bot
- - name: AzDOProjectName
- value: ${{ parameters.AzDOProjectName }}
- - name: AzDOPipelineId
- value: ${{ parameters.AzDOPipelineId }}
- - name: AzDOBuildId
- value: ${{ parameters.AzDOBuildId }}
- - template: /eng/common/templates/variables/sdl-variables.yml
- - name: GuardianVersion
- value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
- - template: /eng/common/templates/variables/pool-providers.yml
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64
- steps:
- - checkout: self
- clean: true
-
- # If the template caller didn't provide an AzDO parameter, set them all up as Maestro vars.
- - ${{ if not(and(parameters.AzDOProjectName, parameters.AzDOPipelineId, parameters.AzDOBuildId)) }}:
- - template: /eng/common/templates/post-build/setup-maestro-vars.yml
-
- - ${{ if ne(parameters.downloadArtifacts, 'false')}}:
- - ${{ if ne(parameters.artifactNames, '') }}:
- - ${{ each artifactName in parameters.artifactNames }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download Build Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: ${{ artifactName }}
- downloadPath: $(Build.ArtifactStagingDirectory)\artifacts
- checkDownloadedFiles: true
- - ${{ if eq(parameters.artifactNames, '') }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download Build Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- downloadType: specific files
- itemPattern: "**"
- downloadPath: $(Build.ArtifactStagingDirectory)\artifacts
- checkDownloadedFiles: true
-
- - ${{ each artifactName in parameters.pipelineArtifactNames }}:
- - task: DownloadPipelineArtifact@2
- displayName: Download Pipeline Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: ${{ artifactName }}
- downloadPath: $(Build.ArtifactStagingDirectory)\artifacts
- checkDownloadedFiles: true
-
- - powershell: eng/common/sdl/trim-assets-version.ps1
- -InputPath $(Build.ArtifactStagingDirectory)\artifacts
- displayName: Trim the version from the NuGet packages
- continueOnError: ${{ parameters.sdlContinueOnError }}
-
- - powershell: eng/common/sdl/extract-artifact-packages.ps1
- -InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts
- -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts
- displayName: Extract Blob Artifacts
- continueOnError: ${{ parameters.sdlContinueOnError }}
-
- - powershell: eng/common/sdl/extract-artifact-packages.ps1
- -InputPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts
- -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts
- displayName: Extract Package Artifacts
- continueOnError: ${{ parameters.sdlContinueOnError }}
-
- - ${{ if ne(parameters.extractArchiveArtifacts, 'false') }}:
- - powershell: eng/common/sdl/extract-artifact-archives.ps1
- -InputPath $(Build.ArtifactStagingDirectory)\artifacts
- -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts
- displayName: Extract Archive Artifacts
- continueOnError: ${{ parameters.sdlContinueOnError }}
-
- - template: /eng/common/templates/steps/execute-sdl.yml
- parameters:
- overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }}
- executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }}
- overrideParameters: ${{ parameters.overrideParameters }}
- additionalParameters: ${{ parameters.additionalParameters }}
- publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }}
- sdlContinueOnError: ${{ parameters.sdlContinueOnError }}
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 8ec5c4f2d9f9..d1aeb92fcea5 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -1,259 +1,82 @@
-# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
-# and some (Microbuild) should only be applied to non-PR cases for internal builds.
-
-parameters:
-# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
- cancelTimeoutInMinutes: ''
- condition: ''
- container: ''
- continueOnError: false
- dependsOn: ''
- displayName: ''
- pool: ''
- steps: []
- strategy: ''
- timeoutInMinutes: ''
- variables: []
- workspace: ''
- templateContext: ''
-
-# Job base template specific parameters
- # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md
- artifacts: ''
- enableMicrobuild: false
+parameters:
enablePublishBuildArtifacts: false
- enablePublishBuildAssets: false
- enablePublishTestResults: false
- enablePublishUsingPipelines: false
- enableBuildRetry: false
disableComponentGovernance: ''
componentGovernanceIgnoreDirectories: ''
- mergeTestResults: false
- testRunTitle: ''
- testResultsFormat: ''
- name: ''
- preSteps: []
- runAsPublic: false
# Sbom related params
enableSbom: true
- PackageVersion: 7.0.0
+ runAsPublic: false
+ PackageVersion: 9.0.0
BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
jobs:
-- job: ${{ parameters.name }}
-
- ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}:
- cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }}
-
- ${{ if ne(parameters.condition, '') }}:
- condition: ${{ parameters.condition }}
-
- ${{ if ne(parameters.container, '') }}:
- container: ${{ parameters.container }}
-
- ${{ if ne(parameters.continueOnError, '') }}:
- continueOnError: ${{ parameters.continueOnError }}
-
- ${{ if ne(parameters.dependsOn, '') }}:
- dependsOn: ${{ parameters.dependsOn }}
-
- ${{ if ne(parameters.displayName, '') }}:
- displayName: ${{ parameters.displayName }}
-
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
-
- ${{ if ne(parameters.strategy, '') }}:
- strategy: ${{ parameters.strategy }}
-
- ${{ if ne(parameters.timeoutInMinutes, '') }}:
- timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
-
- ${{ if ne(parameters.templateContext, '') }}:
- templateContext: ${{ parameters.templateContext }}
-
- variables:
- - ${{ if ne(parameters.enableTelemetry, 'false') }}:
- - name: DOTNET_CLI_TELEMETRY_PROFILE
- value: '$(Build.Repository.Uri)'
- - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}:
- - name: EnableRichCodeNavigation
- value: 'true'
- # Retry signature validation up to three times, waiting 2 seconds between attempts.
- # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures
- - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY
- value: 3,2000
- - ${{ each variable in parameters.variables }}:
- # handle name-value variable syntax
- # example:
- # - name: [key]
- # value: [value]
- - ${{ if ne(variable.name, '') }}:
- - name: ${{ variable.name }}
- value: ${{ variable.value }}
-
- # handle variable groups
- - ${{ if ne(variable.group, '') }}:
- - group: ${{ variable.group }}
+- template: /eng/common/core-templates/job/job.yml
+ parameters:
+ is1ESPipeline: false
- # handle template variable syntax
- # example:
- # - template: path/to/template.yml
- # parameters:
- # [key]: [value]
- - ${{ if ne(variable.template, '') }}:
- - template: ${{ variable.template }}
- ${{ if ne(variable.parameters, '') }}:
- parameters: ${{ variable.parameters }}
+ ${{ each parameter in parameters }}:
+ ${{ if and(ne(parameter.key, 'steps'), ne(parameter.key, 'is1ESPipeline')) }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
- # handle key-value variable syntax.
- # example:
- # - [key]: [value]
- - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}:
- - ${{ each pair in variable }}:
- - name: ${{ pair.key }}
- value: ${{ pair.value }}
+ steps:
+ - ${{ each step in parameters.steps }}:
+ - ${{ step }}
- # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds
- - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - group: DotNet-HelixApi-Access
-
- ${{ if ne(parameters.workspace, '') }}:
- workspace: ${{ parameters.workspace }}
-
- steps:
- - ${{ if ne(parameters.preSteps, '') }}:
- - ${{ each preStep in parameters.preSteps }}:
- - ${{ preStep }}
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- - task: MicroBuildSigningPlugin@3
- displayName: Install MicroBuild plugin
- inputs:
- signType: $(_SignType)
- zipSources: false
- feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
- env:
- TeamName: $(_TeamName)
- continueOnError: ${{ parameters.continueOnError }}
- condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}:
- - task: NuGetAuthenticate@1
-
- - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}:
- - task: DownloadPipelineArtifact@2
- inputs:
- buildType: current
- artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }}
- targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }}
- itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }}
-
- - ${{ each step in parameters.steps }}:
- - ${{ step }}
-
- - ${{ if eq(parameters.enableRichCodeNavigation, true) }}:
- - task: RichCodeNavIndexer@0
- displayName: RichCodeNav Upload
- inputs:
- languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }}
- environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }}
- richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin
- uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }}
- continueOnError: true
-
- - template: /eng/common/templates/steps/component-governance.yml
- parameters:
- ${{ if eq(parameters.disableComponentGovernance, '') }}:
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}:
- disableComponentGovernance: false
- ${{ else }}:
- disableComponentGovernance: true
- ${{ else }}:
- disableComponentGovernance: ${{ parameters.disableComponentGovernance }}
- componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
-
- - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: MicroBuildCleanup@1
- displayName: Execute Microbuild cleanup tasks
- condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT'))
- continueOnError: ${{ parameters.continueOnError }}
- env:
- TeamName: $(_TeamName)
-
- - ${{ if ne(parameters.artifacts.publish, '') }}:
- - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
- - task: CopyFiles@2
- displayName: Gather binaries for publish to artifacts
- inputs:
- SourceFolder: 'artifacts/bin'
- Contents: '**'
- TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin'
- - task: CopyFiles@2
- displayName: Gather packages for publish to artifacts
- inputs:
- SourceFolder: 'artifacts/packages'
- Contents: '**'
- TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages'
- - task: PublishBuildArtifacts@1
- displayName: Publish pipeline artifacts
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
- PublishLocation: Container
- ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
- continueOnError: true
- condition: always()
- - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
- - publish: artifacts/log
- artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }}
- displayName: Publish logs
- continueOnError: true
- condition: always()
-
- - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
- - task: PublishBuildArtifacts@1
- displayName: Publish Logs
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)'
- PublishLocation: Container
- ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
- continueOnError: true
- condition: always()
-
- - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}:
- - task: PublishTestResults@2
- displayName: Publish XUnit Test Results
- inputs:
- testResultsFormat: 'xUnit'
- testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
- mergeTestResults: ${{ parameters.mergeTestResults }}
- continueOnError: true
- condition: always()
- - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}:
- - task: PublishTestResults@2
- displayName: Publish TRX Test Results
- inputs:
- testResultsFormat: 'VSTest'
- testResultsFiles: '*.trx'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
- testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
- mergeTestResults: ${{ parameters.mergeTestResults }}
- continueOnError: true
- condition: always()
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
- - template: /eng/common/templates/steps/generate-sbom.yml
+ componentGovernanceSteps:
+ - template: /eng/common/templates/steps/component-governance.yml
parameters:
- PackageVersion: ${{ parameters.packageVersion}}
- BuildDropPath: ${{ parameters.buildDropPath }}
- IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
-
- - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
- - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration
- artifact: BuildConfiguration
- displayName: Publish build retry configuration
- continueOnError: true
+ ${{ if eq(parameters.disableComponentGovernance, '') }}:
+ ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}:
+ disableComponentGovernance: false
+ ${{ else }}:
+ disableComponentGovernance: true
+ ${{ else }}:
+ disableComponentGovernance: ${{ parameters.disableComponentGovernance }}
+ componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
+
+ artifactPublishSteps:
+ - ${{ if ne(parameters.artifacts.publish, '') }}:
+ - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
+ - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: false
+ args:
+ displayName: Publish pipeline artifacts
+ pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
+ publishLocation: Container
+ artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
+ continueOnError: true
+ condition: always()
+ - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
+ parameters:
+ is1ESPipeline: false
+ args:
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log'
+ artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }}
+ displayName: 'Publish logs'
+ continueOnError: true
+ condition: always()
+ sbomEnabled: false # we don't need SBOM for logs
+
+ - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
+ - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ parameters:
+ is1ESPipeline: false
+ args:
+ displayName: Publish Logs
+ pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
+ publishLocation: Container
+ artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }}
+ continueOnError: true
+ condition: always()
+
+ - ${{ if eq(parameters.enableBuildRetry, 'true') }}:
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
+ parameters:
+ is1ESPipeline: false
+ args:
+ targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration'
+ artifactName: 'BuildConfiguration'
+ displayName: 'Publish build retry configuration'
+ continueOnError: true
+ sbomEnabled: false # we don't need SBOM for BuildConfiguration
diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml
index 60ab00c4de3a..ff829dc4c700 100644
--- a/eng/common/templates/job/onelocbuild.yml
+++ b/eng/common/templates/job/onelocbuild.yml
@@ -1,109 +1,7 @@
-parameters:
- # Optional: dependencies of the job
- dependsOn: ''
-
- # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
- pool: ''
-
- CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex
- GithubPat: $(BotAccount-dotnet-bot-repo-PAT)
-
- SourcesDirectory: $(Build.SourcesDirectory)
- CreatePr: true
- AutoCompletePr: false
- ReusePr: true
- UseLfLineEndings: true
- UseCheckedInLocProjectJson: false
- SkipLocProjectJsonGeneration: false
- LanguageSet: VS_Main_Languages
- LclSource: lclFilesInRepo
- LclPackageId: ''
- RepoType: gitHub
- GitHubOrg: dotnet
- MirrorRepo: ''
- MirrorBranch: main
- condition: ''
- JobNameSuffix: ''
-
jobs:
-- job: OneLocBuild${{ parameters.JobNameSuffix }}
-
- dependsOn: ${{ parameters.dependsOn }}
-
- displayName: OneLocBuild${{ parameters.JobNameSuffix }}
-
- variables:
- - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat
- - name: _GenerateLocProjectArguments
- value: -SourcesDirectory ${{ parameters.SourcesDirectory }}
- -LanguageSet "${{ parameters.LanguageSet }}"
- -CreateNeutralXlfs
- - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}:
- - name: _GenerateLocProjectArguments
- value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson
- - template: /eng/common/templates/variables/pool-providers.yml
-
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
- ${{ if eq(parameters.pool, '') }}:
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64
-
- steps:
- - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:
- - task: Powershell@2
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1
- arguments: $(_GenerateLocProjectArguments)
- displayName: Generate LocProject.json
- condition: ${{ parameters.condition }}
-
- - task: OneLocBuild@2
- displayName: OneLocBuild
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- inputs:
- locProj: eng/Localize/LocProject.json
- outDir: $(Build.ArtifactStagingDirectory)
- lclSource: ${{ parameters.LclSource }}
- lclPackageId: ${{ parameters.LclPackageId }}
- isCreatePrSelected: ${{ parameters.CreatePr }}
- isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }}
- ${{ if eq(parameters.CreatePr, true) }}:
- isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }}
- ${{ if eq(parameters.RepoType, 'gitHub') }}:
- isShouldReusePrSelected: ${{ parameters.ReusePr }}
- packageSourceAuth: patAuth
- patVariable: ${{ parameters.CeapexPat }}
- ${{ if eq(parameters.RepoType, 'gitHub') }}:
- repoType: ${{ parameters.RepoType }}
- gitHubPatVariable: "${{ parameters.GithubPat }}"
- ${{ if ne(parameters.MirrorRepo, '') }}:
- isMirrorRepoSelected: true
- gitHubOrganization: ${{ parameters.GitHubOrg }}
- mirrorRepo: ${{ parameters.MirrorRepo }}
- mirrorBranch: ${{ parameters.MirrorBranch }}
- condition: ${{ parameters.condition }}
-
- - task: PublishBuildArtifacts@1
- displayName: Publish Localization Files
- inputs:
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc'
- PublishLocation: Container
- ArtifactName: Loc
- condition: ${{ parameters.condition }}
+- template: /eng/common/core-templates/job/onelocbuild.yml
+ parameters:
+ is1ESPipeline: false
- - task: PublishBuildArtifacts@1
- displayName: Publish LocProject.json
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/'
- PublishLocation: Container
- ArtifactName: Loc
- condition: ${{ parameters.condition }}
\ No newline at end of file
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml
index cc2b346ba8ba..ab2edec2adb5 100644
--- a/eng/common/templates/job/publish-build-assets.yml
+++ b/eng/common/templates/job/publish-build-assets.yml
@@ -1,156 +1,7 @@
-parameters:
- configuration: 'Debug'
-
- # Optional: condition for the job to run
- condition: ''
-
- # Optional: 'true' if future jobs should run even if this job fails
- continueOnError: false
-
- # Optional: dependencies of the job
- dependsOn: ''
-
- # Optional: Include PublishBuildArtifacts task
- enablePublishBuildArtifacts: false
-
- # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
- pool: {}
-
- # Optional: should run as a public build even in the internal project
- # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
- runAsPublic: false
-
- # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
- publishUsingPipelines: false
-
- # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing
- publishAssetsImmediately: false
-
- artifactsPublishingAdditionalParameters: ''
-
- signingValidationAdditionalParameters: ''
-
jobs:
-- job: Asset_Registry_Publish
-
- dependsOn: ${{ parameters.dependsOn }}
- timeoutInMinutes: 150
-
- ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
- displayName: Publish Assets
- ${{ else }}:
- displayName: Publish to Build Asset Registry
-
- variables:
- - template: /eng/common/templates/variables/pool-providers.yml
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - group: Publish-Build-Assets
- - group: AzureDevOps-Artifact-Feeds-Pats
- - name: runCodesignValidationInjection
- value: false
- - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
- - template: /eng/common/templates/post-build/common-variables.yml
-
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
- name: NetCore1ESPool-Publishing-Internal
- demands: ImageOverride -equals windows.vs2019.amd64
-
- steps:
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download artifact
- inputs:
- artifactName: AssetManifests
- downloadPath: '$(Build.StagingDirectory)/Download'
- checkDownloadedFiles: true
- condition: ${{ parameters.condition }}
- continueOnError: ${{ parameters.continueOnError }}
-
- - task: NuGetAuthenticate@1
-
- - task: AzureCLI@2
- displayName: Publish Build Assets
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: ps
- scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
- arguments: >
- -task PublishBuildAssets -restore -msbuildEngine dotnet
- /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests'
- /p:MaestroApiEndpoint=https://maestro.dot.net
- /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }}
- /p:OfficialBuildId=$(Build.BuildNumber)
- condition: ${{ parameters.condition }}
- continueOnError: ${{ parameters.continueOnError }}
-
- - task: powershell@2
- displayName: Create ReleaseConfigs Artifact
- inputs:
- targetType: inline
- script: |
- Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId)
- Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)"
- Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild)
-
- - task: PublishBuildArtifacts@1
- displayName: Publish ReleaseConfigs Artifact
- inputs:
- PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt'
- PublishLocation: Container
- ArtifactName: ReleaseConfigs
-
- - task: powershell@2
- displayName: Check if SymbolPublishingExclusionsFile.txt exists
- inputs:
- targetType: inline
- script: |
- $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt"
- if(Test-Path -Path $symbolExclusionfile)
- {
- Write-Host "SymbolExclusionFile exists"
- Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true"
- }
- else{
- Write-Host "Symbols Exclusion file does not exists"
- Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false"
- }
-
- - task: PublishBuildArtifacts@1
- displayName: Publish SymbolPublishingExclusionsFile Artifact
- condition: eq(variables['SymbolExclusionFile'], 'true')
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
- PublishLocation: Container
- ArtifactName: ReleaseConfigs
-
- - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}:
- - template: /eng/common/templates/post-build/setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: AzureCLI@2
- displayName: Publish Using Darc
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: ps
- scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
- arguments: -BuildId $(BARBuildId)
- -PublishingInfraVersion 3
- -AzdoToken '$(System.AccessToken)'
- -WaitPublishingFinish true
- -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
- -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+- template: /eng/common/core-templates/job/publish-build-assets.yml
+ parameters:
+ is1ESPipeline: false
- - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- - template: /eng/common/templates/steps/publish-logs.yml
- parameters:
- JobLabel: 'Publish_Artifacts_Logs'
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/job/source-build.yml b/eng/common/templates/job/source-build.yml
index c0ff472b697b..e44d47b1d760 100644
--- a/eng/common/templates/job/source-build.yml
+++ b/eng/common/templates/job/source-build.yml
@@ -1,74 +1,7 @@
-parameters:
- # This template adds arcade-powered source-build to CI. The template produces a server job with a
- # default ID 'Source_Build_Complete' to put in a dependency list if necessary.
-
- # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed.
- jobNamePrefix: 'Source_Build'
-
- # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for
- # managed-only repositories. This is an object with these properties:
- #
- # name: ''
- # The name of the job. This is included in the job ID.
- # targetRID: ''
- # The name of the target RID to use, instead of the one auto-detected by Arcade.
- # nonPortable: false
- # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than
- # linux-x64), and compiling against distro-provided packages rather than portable ones.
- # skipPublishValidation: false
- # Disables publishing validation. By default, a check is performed to ensure no packages are
- # published by source-build.
- # container: ''
- # A container to use. Runs in docker.
- # pool: {}
- # A pool to use. Runs directly on an agent.
- # buildScript: ''
- # Specifies the build script to invoke to perform the build in the repo. The default
- # './build.sh' should work for typical Arcade repositories, but this is customizable for
- # difficult situations.
- # jobProperties: {}
- # A list of job properties to inject at the top level, for potential extensibility beyond
- # container and pool.
- platform: {}
-
- # If set to true and running on a non-public project,
- # Internal blob storage locations will be enabled.
- # This is not enabled by default because many repositories do not need internal sources
- # and do not need to have the required service connections approved in the pipeline.
- enableInternalSources: false
-
jobs:
-- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }}
- displayName: Source-Build (${{ parameters.platform.name }})
-
- ${{ each property in parameters.platform.jobProperties }}:
- ${{ property.key }}: ${{ property.value }}
-
- ${{ if ne(parameters.platform.container, '') }}:
- container: ${{ parameters.platform.container }}
-
- ${{ if eq(parameters.platform.pool, '') }}:
- # The default VM host AzDO pool. This should be capable of running Docker containers: almost all
- # source-build builds run in Docker, including the default managed platform.
- # /eng/common/templates/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic
- pool:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')]
- demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open
-
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')]
- demands: ImageOverride -equals Build.Ubuntu.1804.Amd64
-
- ${{ if ne(parameters.platform.pool, '') }}:
- pool: ${{ parameters.platform.pool }}
-
- workspace:
- clean: all
+- template: /eng/common/core-templates/job/source-build.yml
+ parameters:
+ is1ESPipeline: false
- steps:
- - ${{ if eq(parameters.enableInternalSources, true) }}:
- - template: /eng/common/templates/steps/enable-internal-runtimes.yml
- - template: /eng/common/templates/steps/source-build.yml
- parameters:
- platform: ${{ parameters.platform }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/job/source-index-stage1.yml b/eng/common/templates/job/source-index-stage1.yml
index 0b6bb89dc78a..89f3291593cb 100644
--- a/eng/common/templates/job/source-index-stage1.yml
+++ b/eng/common/templates/job/source-index-stage1.yml
@@ -1,82 +1,7 @@
-parameters:
- runAsPublic: false
- sourceIndexUploadPackageVersion: 2.0.0-20240502.12
- sourceIndexProcessBinlogPackageVersion: 1.0.1-20240129.2
- sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
- sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
- preSteps: []
- binlogPath: artifacts/log/Debug/Build.binlog
- condition: ''
- dependsOn: ''
- pool: ''
-
jobs:
-- job: SourceIndexStage1
- dependsOn: ${{ parameters.dependsOn }}
- condition: ${{ parameters.condition }}
- variables:
- - name: SourceIndexUploadPackageVersion
- value: ${{ parameters.sourceIndexUploadPackageVersion }}
- - name: SourceIndexProcessBinlogPackageVersion
- value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }}
- - name: SourceIndexPackageSource
- value: ${{ parameters.sourceIndexPackageSource }}
- - name: BinlogPath
- value: ${{ parameters.binlogPath }}
- - template: /eng/common/templates/variables/pool-providers.yml
-
- ${{ if ne(parameters.pool, '') }}:
- pool: ${{ parameters.pool }}
- ${{ if eq(parameters.pool, '') }}:
- pool:
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- name: $(DncEngPublicBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64.open
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64
-
- steps:
- - ${{ each preStep in parameters.preSteps }}:
- - ${{ preStep }}
-
- - task: UseDotNet@2
- displayName: Use .NET 8 SDK
- inputs:
- packageType: sdk
- version: 8.0.x
- installationPath: $(Agent.TempDirectory)/dotnet
- workingDirectory: $(Agent.TempDirectory)
-
- - script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
- displayName: Download Tools
- # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
- workingDirectory: $(Agent.TempDirectory)
-
- - script: ${{ parameters.sourceIndexBuildCommand }}
- displayName: Build Repository
-
- - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
- displayName: Process Binlog into indexable sln
-
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - task: AzureCLI@2
- displayName: Get stage 1 auth token
- inputs:
- azureSubscription: 'SourceDotNet Stage1 Publish'
- addSpnToEnvironment: true
- scriptType: 'ps'
- scriptLocation: 'inlineScript'
- inlineScript: |
- echo "##vso[task.setvariable variable=ARM_CLIENT_ID;issecret=true]$env:servicePrincipalId"
- echo "##vso[task.setvariable variable=ARM_ID_TOKEN;issecret=true]$env:idToken"
- echo "##vso[task.setvariable variable=ARM_TENANT_ID;issecret=true]$env:tenantId"
-
- - script: |
- az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN)
- displayName: "Login to Azure"
+- template: /eng/common/core-templates/job/source-index-stage1.yml
+ parameters:
+ is1ESPipeline: false
- - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
- displayName: Upload stage1 artifacts to source index
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/jobs/codeql-build.yml b/eng/common/templates/jobs/codeql-build.yml
index f7dc5ea4aaa6..517f24d6a52c 100644
--- a/eng/common/templates/jobs/codeql-build.yml
+++ b/eng/common/templates/jobs/codeql-build.yml
@@ -1,31 +1,7 @@
-parameters:
- # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
- continueOnError: false
- # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
- jobs: []
- # Optional: if specified, restore and use this version of Guardian instead of the default.
- overrideGuardianVersion: ''
-
jobs:
-- template: /eng/common/templates/jobs/jobs.yml
+- template: /eng/common/core-templates/jobs/codeql-build.yml
parameters:
- enableMicrobuild: false
- enablePublishBuildArtifacts: false
- enablePublishTestResults: false
- enablePublishBuildAssets: false
- enablePublishUsingPipelines: false
- enableTelemetry: true
+ is1ESPipeline: false
- variables:
- - group: Publish-Build-Assets
- # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
- # sync with the packages.config file.
- - name: DefaultGuardianVersion
- value: 0.109.0
- - name: GuardianPackagesConfigFile
- value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
- - name: GuardianVersion
- value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
-
- jobs: ${{ parameters.jobs }}
-
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml
index 289bb2396ce8..388e9037b3e6 100644
--- a/eng/common/templates/jobs/jobs.yml
+++ b/eng/common/templates/jobs/jobs.yml
@@ -1,97 +1,7 @@
-parameters:
- # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
- continueOnError: false
-
- # Optional: Include PublishBuildArtifacts task
- enablePublishBuildArtifacts: false
-
- # Optional: Enable publishing using release pipelines
- enablePublishUsingPipelines: false
-
- # Optional: Enable running the source-build jobs to build repo from source
- enableSourceBuild: false
-
- # Optional: Parameters for source-build template.
- # See /eng/common/templates/jobs/source-build.yml for options
- sourceBuildParameters: []
-
- graphFileGeneration:
- # Optional: Enable generating the graph files at the end of the build
- enabled: false
- # Optional: Include toolset dependencies in the generated graph files
- includeToolset: false
-
- # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
- jobs: []
-
- # Optional: Override automatically derived dependsOn value for "publish build assets" job
- publishBuildAssetsDependsOn: ''
-
- # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage.
- publishAssetsImmediately: false
-
- # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml)
- artifactsPublishingAdditionalParameters: ''
- signingValidationAdditionalParameters: ''
-
- # Optional: should run as a public build even in the internal project
- # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects.
- runAsPublic: false
-
- enableSourceIndex: false
- sourceIndexParams: {}
-
-# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
-# and some (Microbuild) should only be applied to non-PR cases for internal builds.
-
jobs:
-- ${{ each job in parameters.jobs }}:
- - template: ../job/job.yml
- parameters:
- # pass along parameters
- ${{ each parameter in parameters }}:
- ${{ if ne(parameter.key, 'jobs') }}:
- ${{ parameter.key }}: ${{ parameter.value }}
-
- # pass along job properties
- ${{ each property in job }}:
- ${{ if ne(property.key, 'job') }}:
- ${{ property.key }}: ${{ property.value }}
-
- name: ${{ job.job }}
-
-- ${{ if eq(parameters.enableSourceBuild, true) }}:
- - template: /eng/common/templates/jobs/source-build.yml
- parameters:
- allCompletedJobId: Source_Build_Complete
- ${{ each parameter in parameters.sourceBuildParameters }}:
- ${{ parameter.key }}: ${{ parameter.value }}
-
-- ${{ if eq(parameters.enableSourceIndex, 'true') }}:
- - template: ../job/source-index-stage1.yml
- parameters:
- runAsPublic: ${{ parameters.runAsPublic }}
- ${{ each parameter in parameters.sourceIndexParams }}:
- ${{ parameter.key }}: ${{ parameter.value }}
-
-- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}:
- - template: ../job/publish-build-assets.yml
- parameters:
- continueOnError: ${{ parameters.continueOnError }}
- dependsOn:
- - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:
- - ${{ each job in parameters.publishBuildAssetsDependsOn }}:
- - ${{ job.job }}
- - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}:
- - ${{ each job in parameters.jobs }}:
- - ${{ job.job }}
- - ${{ if eq(parameters.enableSourceBuild, true) }}:
- - Source_Build_Complete
+- template: /eng/common/core-templates/jobs/jobs.yml
+ parameters:
+ is1ESPipeline: false
- runAsPublic: ${{ parameters.runAsPublic }}
- publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }}
- publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }}
- enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
- artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
- signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/jobs/source-build.yml b/eng/common/templates/jobs/source-build.yml
index 5f46bfa895c1..818d4c326dbb 100644
--- a/eng/common/templates/jobs/source-build.yml
+++ b/eng/common/templates/jobs/source-build.yml
@@ -1,54 +1,7 @@
-parameters:
- # This template adds arcade-powered source-build to CI. A job is created for each platform, as
- # well as an optional server job that completes when all platform jobs complete.
-
- # The name of the "join" job for all source-build platforms. If set to empty string, the job is
- # not included. Existing repo pipelines can use this job depend on all source-build jobs
- # completing without maintaining a separate list of every single job ID: just depend on this one
- # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'.
- allCompletedJobId: ''
-
- # See /eng/common/templates/job/source-build.yml
- jobNamePrefix: 'Source_Build'
-
- # This is the default platform provided by Arcade, intended for use by a managed-only repo.
- defaultManagedPlatform:
- name: 'Managed'
- container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8'
-
- # Defines the platforms on which to run build jobs. One job is created for each platform, and the
- # object in this array is sent to the job template as 'platform'. If no platforms are specified,
- # one job runs on 'defaultManagedPlatform'.
- platforms: []
-
- # If set to true and running on a non-public project,
- # Internal nuget and blob storage locations will be enabled.
- # This is not enabled by default because many repositories do not need internal sources
- # and do not need to have the required service connections approved in the pipeline.
- enableInternalSources: false
-
jobs:
+- template: /eng/common/core-templates/jobs/source-build.yml
+ parameters:
+ is1ESPipeline: false
-- ${{ if ne(parameters.allCompletedJobId, '') }}:
- - job: ${{ parameters.allCompletedJobId }}
- displayName: Source-Build Complete
- pool: server
- dependsOn:
- - ${{ each platform in parameters.platforms }}:
- - ${{ parameters.jobNamePrefix }}_${{ platform.name }}
- - ${{ if eq(length(parameters.platforms), 0) }}:
- - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }}
-
-- ${{ each platform in parameters.platforms }}:
- - template: /eng/common/templates/job/source-build.yml
- parameters:
- jobNamePrefix: ${{ parameters.jobNamePrefix }}
- platform: ${{ platform }}
- enableInternalSources: ${{ parameters.enableInternalSources }}
-
-- ${{ if eq(length(parameters.platforms), 0) }}:
- - template: /eng/common/templates/job/source-build.yml
- parameters:
- jobNamePrefix: ${{ parameters.jobNamePrefix }}
- platform: ${{ parameters.defaultManagedPlatform }}
- enableInternalSources: ${{ parameters.enableInternalSources }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml
index 173914f2364a..7fa105875592 100644
--- a/eng/common/templates/post-build/common-variables.yml
+++ b/eng/common/templates/post-build/common-variables.yml
@@ -1,22 +1,8 @@
variables:
- - group: Publish-Build-Assets
+- template: /eng/common/core-templates/post-build/common-variables.yml
+ parameters:
+ # Specifies whether to use 1ES
+ is1ESPipeline: false
- # Whether the build is internal or not
- - name: IsInternalBuild
- value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
-
- # Default Maestro++ API Endpoint and API Version
- - name: MaestroApiEndPoint
- value: "https://maestro.dot.net"
- - name: MaestroApiAccessToken
- value: $(MaestroAccessToken)
- - name: MaestroApiVersion
- value: "2020-02-20"
-
- - name: SourceLinkCLIVersion
- value: 3.0.0
- - name: SymbolToolVersion
- value: 1.0.1
-
- - name: runCodesignValidationInjection
- value: false
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml
index c3b6a3012fee..53ede714bdd2 100644
--- a/eng/common/templates/post-build/post-build.yml
+++ b/eng/common/templates/post-build/post-build.yml
@@ -1,283 +1,8 @@
-parameters:
- # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST.
- # Publishing V1 is no longer supported
- # Publishing V2 is no longer supported
- # Publishing V3 is the default
- - name: publishingInfraVersion
- displayName: Which version of publishing should be used to promote the build definition?
- type: number
- default: 3
- values:
- - 3
-
- - name: BARBuildId
- displayName: BAR Build Id
- type: number
- default: 0
-
- - name: PromoteToChannelIds
- displayName: Channel to promote BARBuildId to
- type: string
- default: ''
-
- - name: enableSourceLinkValidation
- displayName: Enable SourceLink validation
- type: boolean
- default: false
-
- - name: enableSigningValidation
- displayName: Enable signing validation
- type: boolean
- default: true
-
- - name: enableSymbolValidation
- displayName: Enable symbol validation
- type: boolean
- default: false
-
- - name: enableNugetValidation
- displayName: Enable NuGet validation
- type: boolean
- default: true
-
- - name: publishInstallersAndChecksums
- displayName: Publish installers and checksums
- type: boolean
- default: true
-
- - name: SDLValidationParameters
- type: object
- default:
- enable: false
- publishGdn: false
- continueOnError: false
- params: ''
- artifactNames: ''
- downloadArtifacts: true
-
- # These parameters let the user customize the call to sdk-task.ps1 for publishing
- # symbols & general artifacts as well as for signing validation
- - name: symbolPublishingAdditionalParameters
- displayName: Symbol publishing additional parameters
- type: string
- default: ''
-
- - name: artifactsPublishingAdditionalParameters
- displayName: Artifact publishing additional parameters
- type: string
- default: ''
-
- - name: signingValidationAdditionalParameters
- displayName: Signing validation additional parameters
- type: string
- default: ''
-
- # Which stages should finish execution before post-build stages start
- - name: validateDependsOn
- type: object
- default:
- - build
-
- - name: publishDependsOn
- type: object
- default:
- - Validate
-
- # Optional: Call asset publishing rather than running in a separate stage
- - name: publishAssetsImmediately
- type: boolean
- default: false
-
stages:
-- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
- - stage: Validate
- dependsOn: ${{ parameters.validateDependsOn }}
- displayName: Validate Build Assets
- variables:
- - template: common-variables.yml
- - template: /eng/common/templates/variables/pool-providers.yml
- jobs:
- - job:
- displayName: NuGet Validation
- condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true'))
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64
-
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Package Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: PackageArtifacts
- checkDownloadedFiles: true
-
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1
- arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
- -ToolDestinationPath $(Agent.BuildDirectory)/Extract/
-
- - job:
- displayName: Signing Validation
- condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true'))
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Package Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: PackageArtifacts
- checkDownloadedFiles: true
- itemPattern: |
- **
- !**/Microsoft.SourceBuild.Intermediate.*.nupkg
-
- # This is necessary whenever we want to publish/restore to an AzDO private feed
- # Since sdk-task.ps1 tries to restore packages we need to do this authentication here
- # otherwise it'll complain about accessing a private feed.
- - task: NuGetAuthenticate@1
- displayName: 'Authenticate to AzDO Feeds'
-
- # Signing validation will optionally work with the buildmanifest file which is downloaded from
- # Azure DevOps above.
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: eng\common\sdk-task.ps1
- arguments: -task SigningValidation -restore -msbuildEngine vs
- /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'
- /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt'
- ${{ parameters.signingValidationAdditionalParameters }}
-
- - template: ../steps/publish-logs.yml
- parameters:
- StageLabel: 'Validation'
- JobLabel: 'Signing'
-
- - job:
- displayName: SourceLink Validation
- condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2019.amd64
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Blob Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: BlobArtifacts
- checkDownloadedFiles: true
-
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1
- arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/
- -ExtractPath $(Agent.BuildDirectory)/Extract/
- -GHRepoName $(Build.Repository.Name)
- -GHCommit $(Build.SourceVersion)
- -SourcelinkCliVersion $(SourceLinkCLIVersion)
- continueOnError: true
-
- - template: /eng/common/templates/job/execute-sdl.yml
- parameters:
- enable: ${{ parameters.SDLValidationParameters.enable }}
- publishGuardianDirectoryToPipeline: ${{ parameters.SDLValidationParameters.publishGdn }}
- additionalParameters: ${{ parameters.SDLValidationParameters.params }}
- continueOnError: ${{ parameters.SDLValidationParameters.continueOnError }}
- artifactNames: ${{ parameters.SDLValidationParameters.artifactNames }}
- downloadArtifacts: ${{ parameters.SDLValidationParameters.downloadArtifacts }}
-
-- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}:
- - stage: publish_using_darc
- ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}:
- dependsOn: ${{ parameters.publishDependsOn }}
- ${{ else }}:
- dependsOn: ${{ parameters.validateDependsOn }}
- displayName: Publish using Darc
- variables:
- - template: common-variables.yml
- - template: /eng/common/templates/variables/pool-providers.yml
- jobs:
- - job:
- displayName: Publish Using Darc
- timeoutInMinutes: 120
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2022-1ES
- demands: Cmd
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- name: NetCore1ESPool-Publishing-Internal
- demands: ImageOverride -equals windows.vs2019.amd64
- steps:
- - template: setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
-
- - task: NuGetAuthenticate@1
+- template: /eng/common/core-templates/post-build/post-build.yml
+ parameters:
+ # Specifies whether to use 1ES
+ is1ESPipeline: false
- - task: AzureCLI@2
- displayName: Publish Using Darc
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: ps
- scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
- arguments: -BuildId $(BARBuildId)
- -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
- -AzdoToken '$(System.AccessToken)'
- -WaitPublishingFinish true
- -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
- -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml
index 64b9abc68504..a79fab5b441e 100644
--- a/eng/common/templates/post-build/setup-maestro-vars.yml
+++ b/eng/common/templates/post-build/setup-maestro-vars.yml
@@ -1,70 +1,8 @@
-parameters:
- BARBuildId: ''
- PromoteToChannelIds: ''
-
steps:
- - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
- - task: DownloadBuildArtifacts@0
- displayName: Download Release Configs
- inputs:
- buildType: current
- artifactName: ReleaseConfigs
- checkDownloadedFiles: true
-
- - task: AzureCLI@2
- name: setReleaseVars
- displayName: Set Release Configs Vars
- inputs:
- azureSubscription: "Darc: Maestro Production"
- scriptType: pscore
- scriptLocation: inlineScript
- inlineScript: |
- try {
- if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
- $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
-
- $BarId = $Content | Select -Index 0
- $Channels = $Content | Select -Index 1
- $IsStableBuild = $Content | Select -Index 2
-
- $AzureDevOpsProject = $Env:System_TeamProject
- $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
- $AzureDevOpsBuildId = $Env:Build_BuildId
- }
- else {
- . $(Build.SourcesDirectory)\eng\common\tools.ps1
- $darc = Get-Darc
- $buildInfo = & $darc get-build `
- --id ${{ parameters.BARBuildId }} `
- --extended `
- --output-format json `
- --ci `
- | convertFrom-Json
-
- $BarId = ${{ parameters.BARBuildId }}
- $Channels = $Env:PromoteToMaestroChannels -split ","
- $Channels = $Channels -join "]["
- $Channels = "[$Channels]"
-
- $IsStableBuild = $buildInfo.stable
- $AzureDevOpsProject = $buildInfo.azureDevOpsProject
- $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
- $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
- }
-
- Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId"
- Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels"
- Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild"
+- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ # Specifies whether to use 1ES
+ is1ESPipeline: false
- Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject"
- Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId"
- Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId"
- }
- catch {
- Write-Host $_
- Write-Host $_.Exception
- Write-Host $_.ScriptStackTrace
- exit 1
- }
- env:
- PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/post-build/trigger-subscription.yml b/eng/common/templates/post-build/trigger-subscription.yml
deleted file mode 100644
index da669030daf6..000000000000
--- a/eng/common/templates/post-build/trigger-subscription.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-parameters:
- ChannelId: 0
-
-steps:
-- task: PowerShell@2
- displayName: Triggering subscriptions
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1
- arguments: -SourceRepo $(Build.Repository.Uri)
- -ChannelId ${{ parameters.ChannelId }}
- -MaestroApiAccessToken $(MaestroAccessToken)
- -MaestroApiEndPoint $(MaestroApiEndPoint)
- -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates/steps/add-build-to-channel.yml b/eng/common/templates/steps/add-build-to-channel.yml
deleted file mode 100644
index f67a210d62f3..000000000000
--- a/eng/common/templates/steps/add-build-to-channel.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-parameters:
- ChannelId: 0
-
-steps:
-- task: PowerShell@2
- displayName: Add Build to Channel
- inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1
- arguments: -BuildId $(BARBuildId)
- -ChannelId ${{ parameters.ChannelId }}
- -MaestroApiAccessToken $(MaestroApiAccessToken)
- -MaestroApiEndPoint $(MaestroApiEndPoint)
- -MaestroApiVersion $(MaestroApiVersion)
diff --git a/eng/common/templates/steps/build-reason.yml b/eng/common/templates/steps/build-reason.yml
deleted file mode 100644
index eba58109b52c..000000000000
--- a/eng/common/templates/steps/build-reason.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# build-reason.yml
-# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons
-# to include steps (',' separated).
-parameters:
- conditions: ''
- steps: []
-
-steps:
- - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}:
- - ${{ parameters.steps }}
- - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}:
- - ${{ parameters.steps }}
diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml
index cbba0596709d..c12a5f8d21d7 100644
--- a/eng/common/templates/steps/component-governance.yml
+++ b/eng/common/templates/steps/component-governance.yml
@@ -1,13 +1,7 @@
-parameters:
- disableComponentGovernance: false
- componentGovernanceIgnoreDirectories: ''
-
steps:
-- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
- - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
- displayName: Set skipComponentGovernanceDetection variable
-- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
- - task: ComponentGovernanceComponentDetection@0
- continueOnError: true
- inputs:
- ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
\ No newline at end of file
+- template: /eng/common/core-templates/steps/component-governance.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/enable-internal-runtimes.yml b/eng/common/templates/steps/enable-internal-runtimes.yml
index 54dc9416c519..b21a8038cc1c 100644
--- a/eng/common/templates/steps/enable-internal-runtimes.yml
+++ b/eng/common/templates/steps/enable-internal-runtimes.yml
@@ -1,28 +1,10 @@
# Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
# variable with the base64-encoded SAS token, by default
-parameters:
-- name: federatedServiceConnection
- type: string
- default: 'dotnetbuilds-internal-read'
-- name: outputVariableName
- type: string
- default: 'dotnetbuilds-internal-container-read-token-base64'
-- name: expiryInHours
- type: number
- default: 1
-- name: base64Encode
- type: boolean
- default: true
-
steps:
-- ${{ if ne(variables['System.TeamProject'], 'public') }}:
- - template: /eng/common/templates/steps/get-delegation-sas.yml
- parameters:
- federatedServiceConnection: ${{ parameters.federatedServiceConnection }}
- outputVariableName: ${{ parameters.outputVariableName }}
- expiryInHours: ${{ parameters.expiryInHours }}
- base64Encode: ${{ parameters.base64Encode }}
- storageAccount: dotnetbuilds
- container: internal
- permissions: rl
+- template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/enable-internal-sources.yml b/eng/common/templates/steps/enable-internal-sources.yml
new file mode 100644
index 000000000000..5f87e9abb8aa
--- /dev/null
+++ b/eng/common/templates/steps/enable-internal-sources.yml
@@ -0,0 +1,7 @@
+steps:
+- template: /eng/common/core-templates/steps/enable-internal-sources.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/execute-codeql.yml b/eng/common/templates/steps/execute-codeql.yml
deleted file mode 100644
index 3930b1630214..000000000000
--- a/eng/common/templates/steps/execute-codeql.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-parameters:
- # Language that should be analyzed. Defaults to csharp
- language: csharp
- # Build Commands
- buildCommands: ''
- overrideParameters: '' # Optional: to override values for parameters.
- additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")'
- # Optional: if specified, restore and use this version of Guardian instead of the default.
- overrideGuardianVersion: ''
- # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth
- # diagnosis of problems with specific tool configurations.
- publishGuardianDirectoryToPipeline: false
- # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL
- # parameters rather than relying on YAML. It may be better to use a local script, because you can
- # reproduce results locally without piecing together a command based on the YAML.
- executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1'
- # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named
- # 'continueOnError', the parameter value is not correctly picked up.
- # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter
- # optional: determines whether to continue the build if the step errors;
- sdlContinueOnError: false
-
-steps:
-- template: /eng/common/templates/steps/execute-sdl.yml
- parameters:
- overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }}
- executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }}
- overrideParameters: ${{ parameters.overrideParameters }}
- additionalParameters: '${{ parameters.additionalParameters }}
- -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")'
- publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }}
- sdlContinueOnError: ${{ parameters.sdlContinueOnError }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/execute-sdl.yml b/eng/common/templates/steps/execute-sdl.yml
deleted file mode 100644
index fe0ebf8c904e..000000000000
--- a/eng/common/templates/steps/execute-sdl.yml
+++ /dev/null
@@ -1,89 +0,0 @@
-parameters:
- overrideGuardianVersion: ''
- executeAllSdlToolsScript: ''
- overrideParameters: ''
- additionalParameters: ''
- publishGuardianDirectoryToPipeline: false
- sdlContinueOnError: false
- condition: ''
-
-steps:
-- task: NuGetAuthenticate@1
-
-- task: NuGetToolInstaller@1
- displayName: 'Install NuGet.exe'
-
-- ${{ if ne(parameters.overrideGuardianVersion, '') }}:
- - pwsh: |
- Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl
- . .\sdl.ps1
- $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }}
- Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation"
- displayName: Install Guardian (Overridden)
-
-- ${{ if eq(parameters.overrideGuardianVersion, '') }}:
- - pwsh: |
- Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl
- . .\sdl.ps1
- $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts
- Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation"
- displayName: Install Guardian
-
-- ${{ if ne(parameters.overrideParameters, '') }}:
- - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }}
- displayName: Execute SDL (Overridden)
- continueOnError: ${{ parameters.sdlContinueOnError }}
- condition: ${{ parameters.condition }}
- env:
- GUARDIAN_DEFAULT_PACKAGE_SOURCE_SECRET: $(System.AccessToken)
-
-- ${{ if eq(parameters.overrideParameters, '') }}:
- - powershell: ${{ parameters.executeAllSdlToolsScript }}
- -GuardianCliLocation $(GuardianCliLocation)
- -NugetPackageDirectory $(Build.SourcesDirectory)\.packages
- ${{ parameters.additionalParameters }}
- displayName: Execute SDL
- continueOnError: ${{ parameters.sdlContinueOnError }}
- condition: ${{ parameters.condition }}
- env:
- GUARDIAN_DEFAULT_PACKAGE_SOURCE_SECRET: $(System.AccessToken)
-
-- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}:
- # We want to publish the Guardian results and configuration for easy diagnosis. However, the
- # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default
- # tooling files. Some of these files are large and aren't useful during an investigation, so
- # exclude them by simply deleting them before publishing. (As of writing, there is no documented
- # way to selectively exclude a dir from the pipeline artifact publish task.)
- - task: DeleteFiles@1
- displayName: Delete Guardian dependencies to avoid uploading
- inputs:
- SourceFolder: $(Agent.BuildDirectory)/.gdn
- Contents: |
- c
- i
- condition: succeededOrFailed()
-
- - publish: $(Agent.BuildDirectory)/.gdn
- artifact: GuardianConfiguration
- displayName: Publish GuardianConfiguration
- condition: succeededOrFailed()
-
- # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration
- # with the "SARIF SAST Scans Tab" Azure DevOps extension
- - task: CopyFiles@2
- displayName: Copy SARIF files
- inputs:
- flattenFolders: true
- sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/
- contents: '**/*.sarif'
- targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs
- condition: succeededOrFailed()
-
- # Use PublishBuildArtifacts because the SARIF extension only checks this case
- # see microsoft/sarif-azuredevops-extension#4
- - task: PublishBuildArtifacts@1
- displayName: Publish SARIF files to CodeAnalysisLogs container
- inputs:
- pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs
- artifactName: CodeAnalysisLogs
- condition: succeededOrFailed()
\ No newline at end of file
diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml
index 2b21eae42732..26dc00a2e0f3 100644
--- a/eng/common/templates/steps/generate-sbom.yml
+++ b/eng/common/templates/steps/generate-sbom.yml
@@ -1,48 +1,7 @@
-# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
-# PackageName - The name of the package this SBOM represents.
-# PackageVersion - The version of the package this SBOM represents.
-# ManifestDirPath - The path of the directory where the generated manifest files will be placed
-# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
-
-parameters:
- PackageVersion: 8.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
- PackageName: '.NET'
- ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
- IgnoreDirectories: ''
- sbomContinueOnError: true
-
steps:
-- task: PowerShell@2
- displayName: Prep for SBOM generation in (Non-linux)
- condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
- inputs:
- filePath: ./eng/common/generate-sbom-prep.ps1
- arguments: ${{parameters.manifestDirPath}}
-
-# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
-- script: |
- chmod +x ./eng/common/generate-sbom-prep.sh
- ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
- displayName: Prep for SBOM generation in (Linux)
- condition: eq(variables['Agent.Os'], 'Linux')
- continueOnError: ${{ parameters.sbomContinueOnError }}
-
-- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
- displayName: 'Generate SBOM manifest'
- continueOnError: ${{ parameters.sbomContinueOnError }}
- inputs:
- PackageName: ${{ parameters.packageName }}
- BuildDropPath: ${{ parameters.buildDropPath }}
- PackageVersion: ${{ parameters.packageVersion }}
- ManifestDirPath: ${{ parameters.manifestDirPath }}
- ${{ if ne(parameters.IgnoreDirectories, '') }}:
- AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
-
-- task: PublishPipelineArtifact@1
- displayName: Publish SBOM manifest
- continueOnError: ${{parameters.sbomContinueOnError}}
- inputs:
- targetPath: '${{parameters.manifestDirPath}}'
- artifactName: $(ARTIFACT_NAME)
+- template: /eng/common/core-templates/steps/generate-sbom.yml
+ parameters:
+ is1ESPipeline: false
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/get-delegation-sas.yml b/eng/common/templates/steps/get-delegation-sas.yml
index c0e8f91317f0..83760c9798e3 100644
--- a/eng/common/templates/steps/get-delegation-sas.yml
+++ b/eng/common/templates/steps/get-delegation-sas.yml
@@ -1,43 +1,7 @@
-parameters:
-- name: federatedServiceConnection
- type: string
-- name: outputVariableName
- type: string
-- name: expiryInHours
- type: number
- default: 1
-- name: base64Encode
- type: boolean
- default: false
-- name: storageAccount
- type: string
-- name: container
- type: string
-- name: permissions
- type: string
- default: 'rl'
-
steps:
-- task: AzureCLI@2
- displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}'
- inputs:
- azureSubscription: ${{ parameters.federatedServiceConnection }}
- scriptType: 'pscore'
- scriptLocation: 'inlineScript'
- inlineScript: |
- # Calculate the expiration of the SAS token and convert to UTC
- $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
-
- $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv
-
- if ($LASTEXITCODE -ne 0) {
- Write-Error "Failed to generate SAS token."
- exit 1
- }
-
- if ('${{ parameters.base64Encode }}' -eq 'true') {
- $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas))
- }
+- template: /eng/common/core-templates/steps/get-delegation-sas.yml
+ parameters:
+ is1ESPipeline: false
- Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
- Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas"
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/get-federated-access-token.yml b/eng/common/templates/steps/get-federated-access-token.yml
index 55e33bd38f71..31e151d9d9e7 100644
--- a/eng/common/templates/steps/get-federated-access-token.yml
+++ b/eng/common/templates/steps/get-federated-access-token.yml
@@ -1,40 +1,7 @@
-parameters:
-- name: federatedServiceConnection
- type: string
-- name: outputVariableName
- type: string
-- name: stepName
- type: string
- default: 'getFederatedAccessToken'
-- name: condition
- type: string
- default: ''
-# Resource to get a token for. Common values include:
-# - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps
-# - 'https://storage.azure.com/' for storage
-# Defaults to Azure DevOps
-- name: resource
- type: string
- default: '499b84ac-1321-427f-aa17-267ca6975798'
-- name: isStepOutputVariable
- type: boolean
- default: false
-
steps:
-- task: AzureCLI@2
- displayName: 'Getting federated access token for feeds'
- name: ${{ parameters.stepName }}
- ${{ if ne(parameters.condition, '') }}:
- condition: ${{ parameters.condition }}
- inputs:
- azureSubscription: ${{ parameters.federatedServiceConnection }}
- scriptType: 'pscore'
- scriptLocation: 'inlineScript'
- inlineScript: |
- $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv
- if ($LASTEXITCODE -ne 0) {
- Write-Error "Failed to get access token for resource '${{ parameters.resource }}'"
- exit 1
- }
- Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
- Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken"
\ No newline at end of file
+- template: /eng/common/core-templates/steps/get-federated-access-token.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/publish-build-artifacts.yml b/eng/common/templates/steps/publish-build-artifacts.yml
new file mode 100644
index 000000000000..6428a98dfef6
--- /dev/null
+++ b/eng/common/templates/steps/publish-build-artifacts.yml
@@ -0,0 +1,40 @@
+parameters:
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+- name: displayName
+ type: string
+ default: 'Publish to Build Artifact'
+
+- name: condition
+ type: string
+ default: succeeded()
+
+- name: artifactName
+ type: string
+
+- name: pathToPublish
+ type: string
+
+- name: continueOnError
+ type: boolean
+ default: false
+
+- name: publishLocation
+ type: string
+ default: 'Container'
+
+steps:
+- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ - 'eng/common/templates cannot be referenced from a 1ES managed template': error
+- task: PublishBuildArtifacts@1
+ displayName: ${{ parameters.displayName }}
+ condition: ${{ parameters.condition }}
+ ${{ if parameters.continueOnError }}:
+ continueOnError: ${{ parameters.continueOnError }}
+ inputs:
+ PublishLocation: ${{ parameters.publishLocation }}
+ PathtoPublish: ${{ parameters.pathToPublish }}
+ ${{ if parameters.artifactName }}:
+ ArtifactName: ${{ parameters.artifactName }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/publish-logs.yml b/eng/common/templates/steps/publish-logs.yml
index 88f238f36bfd..4ea86bd88235 100644
--- a/eng/common/templates/steps/publish-logs.yml
+++ b/eng/common/templates/steps/publish-logs.yml
@@ -1,23 +1,7 @@
-parameters:
- StageLabel: ''
- JobLabel: ''
-
steps:
-- task: Powershell@2
- displayName: Prepare Binlogs to Upload
- inputs:
- targetType: inline
- script: |
- New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
- Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
- continueOnError: true
- condition: always()
+- template: /eng/common/core-templates/steps/publish-logs.yml
+ parameters:
+ is1ESPipeline: false
-- task: PublishBuildArtifacts@1
- displayName: Publish Logs
- inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs'
- PublishLocation: Container
- ArtifactName: PostBuildLogs
- continueOnError: true
- condition: always()
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/publish-pipeline-artifacts.yml b/eng/common/templates/steps/publish-pipeline-artifacts.yml
new file mode 100644
index 000000000000..5dd698b212fc
--- /dev/null
+++ b/eng/common/templates/steps/publish-pipeline-artifacts.yml
@@ -0,0 +1,34 @@
+parameters:
+- name: is1ESPipeline
+ type: boolean
+ default: false
+
+- name: args
+ type: object
+ default: {}
+
+steps:
+- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ - 'eng/common/templates cannot be referenced from a 1ES managed template': error
+- task: PublishPipelineArtifact@1
+ displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }}
+ ${{ if parameters.args.condition }}:
+ condition: ${{ parameters.args.condition }}
+ ${{ else }}:
+ condition: succeeded()
+ ${{ if parameters.args.continueOnError }}:
+ continueOnError: ${{ parameters.args.continueOnError }}
+ inputs:
+ targetPath: ${{ parameters.args.targetPath }}
+ ${{ if parameters.args.artifactName }}:
+ artifactName: ${{ parameters.args.artifactName }}
+ ${{ if parameters.args.publishLocation }}:
+ publishLocation: ${{ parameters.args.publishLocation }}
+ ${{ if parameters.args.fileSharePath }}:
+ fileSharePath: ${{ parameters.args.fileSharePath }}
+ ${{ if parameters.args.Parallel }}:
+ parallel: ${{ parameters.args.Parallel }}
+ ${{ if parameters.args.parallelCount }}:
+ parallelCount: ${{ parameters.args.parallelCount }}
+ ${{ if parameters.args.properties }}:
+ properties: ${{ parameters.args.properties }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/retain-build.yml b/eng/common/templates/steps/retain-build.yml
index 83d97a26a01f..8e841ace3d29 100644
--- a/eng/common/templates/steps/retain-build.yml
+++ b/eng/common/templates/steps/retain-build.yml
@@ -1,28 +1,7 @@
-parameters:
- # Optional azure devops PAT with build execute permissions for the build's organization,
- # only needed if the build that should be retained ran on a different organization than
- # the pipeline where this template is executing from
- Token: ''
- # Optional BuildId to retain, defaults to the current running build
- BuildId: ''
- # Azure devops Organization URI for the build in the https://dev.azure.com/ format.
- # Defaults to the organization the current pipeline is running on
- AzdoOrgUri: '$(System.CollectionUri)'
- # Azure devops project for the build. Defaults to the project the current pipeline is running on
- AzdoProject: '$(System.TeamProject)'
-
steps:
- - task: powershell@2
- inputs:
- targetType: 'filePath'
- filePath: eng/common/retain-build.ps1
- pwsh: true
- arguments: >
- -AzdoOrgUri: ${{parameters.AzdoOrgUri}}
- -AzdoProject ${{parameters.AzdoProject}}
- -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }}
- -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}}
- displayName: Enable permanent build retention
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- BUILD_ID: $(Build.BuildId)
\ No newline at end of file
+- template: /eng/common/core-templates/steps/retain-build.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/run-on-unix.yml b/eng/common/templates/steps/run-on-unix.yml
deleted file mode 100644
index e1733814f65d..000000000000
--- a/eng/common/templates/steps/run-on-unix.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-parameters:
- agentOs: ''
- steps: []
-
-steps:
-- ${{ if ne(parameters.agentOs, 'Windows_NT') }}:
- - ${{ parameters.steps }}
diff --git a/eng/common/templates/steps/run-on-windows.yml b/eng/common/templates/steps/run-on-windows.yml
deleted file mode 100644
index 73e7e9c275a1..000000000000
--- a/eng/common/templates/steps/run-on-windows.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-parameters:
- agentOs: ''
- steps: []
-
-steps:
-- ${{ if eq(parameters.agentOs, 'Windows_NT') }}:
- - ${{ parameters.steps }}
diff --git a/eng/common/templates/steps/run-script-ifequalelse.yml b/eng/common/templates/steps/run-script-ifequalelse.yml
deleted file mode 100644
index 3d1242f5587c..000000000000
--- a/eng/common/templates/steps/run-script-ifequalelse.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-parameters:
- # if parameter1 equals parameter 2, run 'ifScript' command, else run 'elsescript' command
- parameter1: ''
- parameter2: ''
- ifScript: ''
- elseScript: ''
-
- # name of script step
- name: Script
-
- # display name of script step
- displayName: If-Equal-Else Script
-
- # environment
- env: {}
-
- # conditional expression for step execution
- condition: ''
-
-steps:
-- ${{ if and(ne(parameters.ifScript, ''), eq(parameters.parameter1, parameters.parameter2)) }}:
- - script: ${{ parameters.ifScript }}
- name: ${{ parameters.name }}
- displayName: ${{ parameters.displayName }}
- env: ${{ parameters.env }}
- condition: ${{ parameters.condition }}
-
-- ${{ if and(ne(parameters.elseScript, ''), ne(parameters.parameter1, parameters.parameter2)) }}:
- - script: ${{ parameters.elseScript }}
- name: ${{ parameters.name }}
- displayName: ${{ parameters.displayName }}
- env: ${{ parameters.env }}
- condition: ${{ parameters.condition }}
\ No newline at end of file
diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml
index 3eb7e2d5f840..39f99fc2762d 100644
--- a/eng/common/templates/steps/send-to-helix.yml
+++ b/eng/common/templates/steps/send-to-helix.yml
@@ -1,91 +1,7 @@
-# Please remember to update the documentation if you make changes to these parameters!
-parameters:
- HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/
- HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/'
- HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number
- HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues
- HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group
- HelixConfiguration: '' # optional -- additional property attached to a job
- HelixPreCommands: '' # optional -- commands to run before Helix work item execution
- HelixPostCommands: '' # optional -- commands to run after Helix work item execution
- WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects
- WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects
- WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects
- CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload
- XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true
- XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects
- XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects
- XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner
- XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects
- IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion
- DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
- DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
- WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget."
- IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set
- HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net )
- Creator: '' # optional -- if the build is external, use this to specify who is sending the job
- DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO
- condition: succeeded() # optional -- condition for step to execute; defaults to succeeded()
- continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false
-
steps:
- - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env: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 }}
- 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/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /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 }}
- 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 }}
+- template: /eng/common/core-templates/steps/send-to-helix.yml
+ parameters:
+ is1ESPipeline: false
+
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml
index 41bbb915736a..23c1d6f4e9f8 100644
--- a/eng/common/templates/steps/source-build.yml
+++ b/eng/common/templates/steps/source-build.yml
@@ -1,129 +1,7 @@
-parameters:
- # This template adds arcade-powered source-build to CI.
-
- # This is a 'steps' template, and is intended for advanced scenarios where the existing build
- # infra has a careful build methodology that must be followed. For example, a repo
- # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline
- # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to
- # GitHub. Using this steps template leaves room for that infra to be included.
-
- # Defines the platform on which to run the steps. See 'eng/common/templates/job/source-build.yml'
- # for details. The entire object is described in the 'job' template for simplicity, even though
- # the usage of the properties on this object is split between the 'job' and 'steps' templates.
- platform: {}
-
steps:
-# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.)
-- script: |
- set -x
- df -h
-
- # If building on the internal project, the artifact feeds variable may be available (usually only if needed)
- # In that case, call the feed setup script to add internal feeds corresponding to public ones.
- # In addition, add an msbuild argument to copy the WIP from the repo to the target build location.
- # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those
- # changes.
- internalRestoreArgs=
- if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then
- # Temporarily work around https://github.com/dotnet/arcade/issues/7709
- chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
- $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw)
- internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true'
-
- # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo.
- # This only works if there is a username/email configured, which won't be the case in most CI runs.
- git config --get user.email
- if [ $? -ne 0 ]; then
- git config user.email dn-bot@microsoft.com
- git config user.name dn-bot
- fi
- fi
-
- # If building on the internal project, the internal storage variable may be available (usually only if needed)
- # In that case, add variables to allow the download of internal runtimes if the specified versions are not found
- # in the default public locations.
- internalRuntimeDownloadArgs=
- if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
- internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)'
- fi
-
- buildConfig=Release
- # Check if AzDO substitutes in a build config from a variable, and use it if so.
- if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then
- buildConfig='$(_BuildConfig)'
- fi
-
- officialBuildArgs=
- if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then
- officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)'
- fi
-
- targetRidArgs=
- if [ '${{ parameters.platform.targetRID }}' != '' ]; then
- targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
- fi
-
- runtimeOsArgs=
- if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then
- runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}'
- fi
-
- baseOsArgs=
- if [ '${{ parameters.platform.baseOS }}' != '' ]; then
- baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}'
- fi
-
- publishArgs=
- if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then
- publishArgs='--publish'
- fi
-
- assetManifestFileName=SourceBuild_RidSpecific.xml
- if [ '${{ parameters.platform.name }}' != '' ]; then
- assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml
- fi
-
- ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \
- --configuration $buildConfig \
- --restore --build --pack $publishArgs -bl \
- $officialBuildArgs \
- $internalRuntimeDownloadArgs \
- $internalRestoreArgs \
- $targetRidArgs \
- $runtimeOsArgs \
- $baseOsArgs \
- /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \
- /p:ArcadeBuildFromSource=true \
- /p:AssetManifestFileName=$assetManifestFileName
- displayName: Build
-
-# Upload build logs for diagnosis.
-- task: CopyFiles@2
- displayName: Prepare BuildLogs staging directory
- inputs:
- SourceFolder: '$(Build.SourcesDirectory)'
- Contents: |
- **/*.log
- **/*.binlog
- artifacts/source-build/self/prebuilt-report/**
- TargetFolder: '$(Build.StagingDirectory)/BuildLogs'
- CleanTargetFolder: true
- continueOnError: true
- condition: succeededOrFailed()
-
-- task: PublishPipelineArtifact@1
- displayName: Publish BuildLogs
- inputs:
- targetPath: '$(Build.StagingDirectory)/BuildLogs'
- artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
- continueOnError: true
- condition: succeededOrFailed()
+- template: /eng/common/core-templates/steps/source-build.yml
+ parameters:
+ is1ESPipeline: false
-# Manually inject component detection so that we can ignore the source build upstream cache, which contains
-# a nupkg cache of input packages (a local feed).
-# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir'
-# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets
-- task: ComponentGovernanceComponentDetection@0
- displayName: Component Detection (Exclude upstream cache)
- inputs:
- ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache'
+ ${{ each parameter in parameters }}:
+ ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates/steps/telemetry-end.yml b/eng/common/templates/steps/telemetry-end.yml
deleted file mode 100644
index fadc04ca1b9a..000000000000
--- a/eng/common/templates/steps/telemetry-end.yml
+++ /dev/null
@@ -1,102 +0,0 @@
-parameters:
- maxRetries: 5
- retryDelay: 10 # in seconds
-
-steps:
-- bash: |
- if [ "$AGENT_JOBSTATUS" = "Succeeded" ] || [ "$AGENT_JOBSTATUS" = "PartiallySucceeded" ]; then
- errorCount=0
- else
- errorCount=1
- fi
- warningCount=0
-
- curlStatus=1
- retryCount=0
- # retry loop to harden against spotty telemetry connections
- # we don't retry successes and 4xx client errors
- until [[ $curlStatus -eq 0 || ( $curlStatus -ge 400 && $curlStatus -le 499 ) || $retryCount -ge $MaxRetries ]]
- do
- if [ $retryCount -gt 0 ]; then
- echo "Failed to send telemetry to Helix; waiting $RetryDelay seconds before retrying..."
- sleep $RetryDelay
- fi
-
- # create a temporary file for curl output
- res=`mktemp`
-
- curlResult=`
- curl --verbose --output $res --write-out "%{http_code}"\
- -H 'Content-Type: application/json' \
- -H "X-Helix-Job-Token: $Helix_JobToken" \
- -H 'Content-Length: 0' \
- -X POST -G "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$Helix_WorkItemId/finish" \
- --data-urlencode "errorCount=$errorCount" \
- --data-urlencode "warningCount=$warningCount"`
- curlStatus=$?
-
- if [ $curlStatus -eq 0 ]; then
- if [ $curlResult -gt 299 ] || [ $curlResult -lt 200 ]; then
- curlStatus=$curlResult
- fi
- fi
-
- let retryCount++
- done
-
- if [ $curlStatus -ne 0 ]; then
- echo "Failed to Send Build Finish information after $retryCount retries"
- vstsLogOutput="vso[task.logissue type=error;sourcepath=templates/steps/telemetry-end.yml;code=1;]Failed to Send Build Finish information: $curlStatus"
- echo "##$vstsLogOutput"
- exit 1
- fi
- displayName: Send Unix Build End Telemetry
- env:
- # defined via VSTS variables in start-job.sh
- Helix_JobToken: $(Helix_JobToken)
- Helix_WorkItemId: $(Helix_WorkItemId)
- MaxRetries: ${{ parameters.maxRetries }}
- RetryDelay: ${{ parameters.retryDelay }}
- condition: and(always(), ne(variables['Agent.Os'], 'Windows_NT'))
-- powershell: |
- if (($env:Agent_JobStatus -eq 'Succeeded') -or ($env:Agent_JobStatus -eq 'PartiallySucceeded')) {
- $ErrorCount = 0
- } else {
- $ErrorCount = 1
- }
- $WarningCount = 0
-
- # Basic retry loop to harden against server flakiness
- $retryCount = 0
- while ($retryCount -lt $env:MaxRetries) {
- try {
- Invoke-RestMethod -Uri "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$env:Helix_WorkItemId/finish?errorCount=$ErrorCount&warningCount=$WarningCount" -Method Post -ContentType "application/json" -Body "" `
- -Headers @{ 'X-Helix-Job-Token'=$env:Helix_JobToken }
- break
- }
- catch {
- $statusCode = $_.Exception.Response.StatusCode.value__
- if ($statusCode -ge 400 -and $statusCode -le 499) {
- Write-Host "##vso[task.logissue]error Failed to send telemetry to Helix (status code $statusCode); not retrying (4xx client error)"
- Write-Host "##vso[task.logissue]error ", $_.Exception.GetType().FullName, $_.Exception.Message
- exit 1
- }
- Write-Host "Failed to send telemetry to Helix (status code $statusCode); waiting $env:RetryDelay seconds before retrying..."
- $retryCount++
- sleep $env:RetryDelay
- continue
- }
- }
-
- if ($retryCount -ge $env:MaxRetries) {
- Write-Host "##vso[task.logissue]error Failed to send telemetry to Helix after $retryCount retries."
- exit 1
- }
- displayName: Send Windows Build End Telemetry
- env:
- # defined via VSTS variables in start-job.ps1
- Helix_JobToken: $(Helix_JobToken)
- Helix_WorkItemId: $(Helix_WorkItemId)
- MaxRetries: ${{ parameters.maxRetries }}
- RetryDelay: ${{ parameters.retryDelay }}
- condition: and(always(),eq(variables['Agent.Os'], 'Windows_NT'))
diff --git a/eng/common/templates/steps/telemetry-start.yml b/eng/common/templates/steps/telemetry-start.yml
deleted file mode 100644
index 32c01ef0b553..000000000000
--- a/eng/common/templates/steps/telemetry-start.yml
+++ /dev/null
@@ -1,241 +0,0 @@
-parameters:
- helixSource: 'undefined_defaulted_in_telemetry.yml'
- helixType: 'undefined_defaulted_in_telemetry.yml'
- buildConfig: ''
- runAsPublic: false
- maxRetries: 5
- retryDelay: 10 # in seconds
-
-steps:
-- ${{ if and(eq(parameters.runAsPublic, 'false'), not(eq(variables['System.TeamProject'], 'public'))) }}:
- - task: AzureKeyVault@1
- inputs:
- azureSubscription: 'HelixProd_KeyVault'
- KeyVaultName: HelixProdKV
- SecretsFilter: 'HelixApiAccessToken'
- condition: always()
-- bash: |
- # create a temporary file
- jobInfo=`mktemp`
-
- # write job info content to temporary file
- cat > $jobInfo < /dev/null; then
echo "Curl failed; dumping some information about dotnet.microsoft.com for later investigation"
- echo | openssl s_client -showcerts -servername dotnet.microsoft.com -connect dotnet.microsoft.com:443
+ echo | openssl s_client -showcerts -servername dotnet.microsoft.com -connect dotnet.microsoft.com:443 || true
fi
echo "Will now retry the same URL with verbose logging."
with_retries curl "$install_script_url" -sSL --verbose --retry 10 --create-dirs -o "$install_script" || {
@@ -343,20 +341,20 @@ function InitializeBuildTool {
_InitializeBuildToolCommand="msbuild"
# use override if it exists - commonly set by source-build
if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then
- _InitializeBuildToolFramework="net8.0"
+ _InitializeBuildToolFramework="net9.0"
else
_InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}"
fi
}
-# Set RestoreNoCache as a workaround for https://github.com/NuGet/Home/issues/3116
+# Set RestoreNoHttpCache as a workaround for https://github.com/NuGet/Home/issues/3116
function GetNuGetPackageCachePath {
if [[ -z ${NUGET_PACKAGES:-} ]]; then
if [[ "$use_global_nuget_cache" == true ]]; then
- export NUGET_PACKAGES="$HOME/.nuget/packages"
+ export NUGET_PACKAGES="$HOME/.nuget/packages/"
else
- export NUGET_PACKAGES="$repo_root/.packages"
- export RESTORENOCACHE=true
+ export NUGET_PACKAGES="$repo_root/.packages/"
+ export RESTORENOHTTPCACHE=true
fi
fi
@@ -440,7 +438,7 @@ function StopProcesses {
}
function MSBuild {
- local args=$@
+ local args=( "$@" )
if [[ "$pipelines_log" == true ]]; then
InitializeBuildTool
InitializeToolset
@@ -458,12 +456,10 @@ function MSBuild {
local possiblePaths=()
possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.ArcadeLogging.dll" )
possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" )
- possiblePaths+=( "$toolset_dir/netcoreapp2.1/Microsoft.DotNet.ArcadeLogging.dll" )
- possiblePaths+=( "$toolset_dir/netcoreapp2.1/Microsoft.DotNet.Arcade.Sdk.dll" )
- possiblePaths+=( "$toolset_dir/netcoreapp3.1/Microsoft.DotNet.ArcadeLogging.dll" )
- possiblePaths+=( "$toolset_dir/netcoreapp3.1/Microsoft.DotNet.Arcade.Sdk.dll" )
possiblePaths+=( "$toolset_dir/net7.0/Microsoft.DotNet.ArcadeLogging.dll" )
possiblePaths+=( "$toolset_dir/net7.0/Microsoft.DotNet.Arcade.Sdk.dll" )
+ possiblePaths+=( "$toolset_dir/net8.0/Microsoft.DotNet.ArcadeLogging.dll" )
+ possiblePaths+=( "$toolset_dir/net8.0/Microsoft.DotNet.Arcade.Sdk.dll" )
for path in "${possiblePaths[@]}"; do
if [[ -f $path ]]; then
selectedPath=$path
@@ -477,7 +473,7 @@ function MSBuild {
args+=( "-logger:$selectedPath" )
fi
- MSBuild-Core ${args[@]}
+ MSBuild-Core "${args[@]}"
}
function MSBuild-Core {
@@ -510,7 +506,8 @@ function MSBuild-Core {
echo "Build failed with exit code $exit_code. Check errors above."
# When running on Azure Pipelines, override the returned exit code to avoid double logging.
- if [[ "$ci" == "true" && -n ${SYSTEM_TEAMPROJECT:-} ]]; then
+ # Skip this when the build is a child of the VMR orchestrator build.
+ if [[ "$ci" == true && -n ${SYSTEM_TEAMPROJECT:-} && "$product_build" != true && "$properties" != *"DotNetBuildRepo=true"* ]]; then
Write-PipelineSetResult -result "Failed" -message "msbuild execution failed."
# Exiting with an exit code causes the azure pipelines task to log yet another "noise" error
# The above Write-PipelineSetResult will cause the task to be marked as failure without adding yet another error
diff --git a/eng/devices/android.cake b/eng/devices/android.cake
index 8d27db4d6b6b..2fcbadd7ad10 100644
--- a/eng/devices/android.cake
+++ b/eng/devices/android.cake
@@ -47,6 +47,7 @@ Information("Android SDK Root: {0}", androidSdkRoot);
Information("Project File: {0}", projectPath);
Information("Build Binary Log (binlog): {0}", binlogDirectory);
Information("Build Configuration: {0}", configuration);
+Information("Build Target Framework: {0}", targetFramework);
var avdSettings = new AndroidAvdManagerToolSettings { SdkRoot = androidSdkRoot };
var adbSettings = new AdbToolSettings { SdkRoot = androidSdkRoot };
@@ -250,6 +251,11 @@ void ExecuteTests(string project, string device, string appPath, string appPacka
}
finally
{
+ if (testsFailed)
+ {
+ // uncomment if you want to copy the test app to the results directory for any reason
+ // CopyFile(testApp, new DirectoryPath(resultsDir).CombineWithFilePath(new FilePath(testApp).GetFilename()));
+ }
HandleTestResults(resultsDir, testsFailed, false);
}
diff --git a/eng/devices/catalyst.cake b/eng/devices/catalyst.cake
index 734a13eb2547..0cec737d21d1 100644
--- a/eng/devices/catalyst.cake
+++ b/eng/devices/catalyst.cake
@@ -171,7 +171,6 @@ void ExecuteBuildUITestApp(string appProject, string binDir, string config, stri
Framework = tfm,
ToolPath = toolPath,
ArgumentCustomization = args => args
- .Append("/t:Restore;Build")
.Append($"/bl:{binlog}")
});
diff --git a/eng/devices/devices-shared.cake b/eng/devices/devices-shared.cake
index 42c61bffd3ba..1be3ebf34d1a 100644
--- a/eng/devices/devices-shared.cake
+++ b/eng/devices/devices-shared.cake
@@ -1,6 +1,6 @@
//This assumes that this is always running from a mac with global workloads
const string DotnetToolPathDefault = "/usr/local/share/dotnet/dotnet";
-const string DotnetVersion = "net8.0";
+string DotnetVersion = Argument("targetFrameworkVersion", EnvironmentVariable("TARGET_FRAMEWORK_VERSION") ?? "net9.0");
const string TestFramework = "net472";
// Map project types to specific subdirectories under artifacts
@@ -208,11 +208,11 @@ string GetDotnetToolPath()
if(IsRunningOnWindows())
{
- toolPath = isLocalDotnet ? $"{MakeAbsolute(Directory("../../bin/dotnet/")).ToString()}/dotnet" : null;
+ toolPath = isLocalDotnet ? $"{MakeAbsolute(Directory("../../.dotnet/")).ToString()}/dotnet.exe" : null;
}
else
{
- toolPath = isLocalDotnet ? $"{MakeAbsolute(Directory("../../bin/dotnet/")).ToString()}/dotnet" : DotnetToolPathDefault;
+ toolPath = isLocalDotnet ? $"{MakeAbsolute(Directory("../../.dotnet/")).ToString()}/dotnet" : DotnetToolPathDefault;
}
Information(isLocalDotnet ? "Using local dotnet" : "Using system dotnet");
diff --git a/eng/devices/ios.cake b/eng/devices/ios.cake
index 089017b5089f..c4b2eba3098b 100644
--- a/eng/devices/ios.cake
+++ b/eng/devices/ios.cake
@@ -1,7 +1,7 @@
#addin nuget:?package=Cake.AppleSimulator&version=0.2.0
#load "./uitests-shared.cake"
-const string DefaultVersion = "17.2";
+const string DefaultVersion = "18.0";
const string DefaultTestDevice = $"ios-simulator-64_{DefaultVersion}";
// Required arguments
@@ -37,6 +37,7 @@ Information($"Build Runtime Identifier: {runtimeIdentifier}");
Information($"Build Target Framework: {targetFramework}");
Information($"Test Device: {testDevice}");
Information($"Test Results Path: {testResultsPath}");
+Information("Runtime Variant: {0}", RUNTIME_VARIANT);
var dotnetToolPath = GetDotnetToolPath();
@@ -139,13 +140,10 @@ void ExecuteBuild(string project, string device, string binDir, string config, s
{
args
.Append("/p:BuildIpa=true")
+ .Append($"/p:RuntimeIdentifier={rid}")
.Append("/bl:" + binlog)
.Append("/tl");
- if (device.ToLower().Contains("device"))
- {
- args.Append("/p:RuntimeIdentifier=ios-arm64");
- }
return args;
}
});
@@ -212,12 +210,14 @@ void ExecuteTests(string project, string device, string resultsDir, string confi
void ExecutePrepareUITests(string project, string app, string device, string resultsDir, string binDir, string config, string tfm, string rid, string ver, string toolPath)
{
Information("Preparing UI Tests...");
- var testApp = GetTestApplications(app, device, config, tfm, rid).FirstOrDefault();
-
Information($"Testing Device: {device}");
Information($"Testing App Project: {app}");
- Information($"Testing App: {testApp}");
+ Information($"USE_NATIVE_AOT: {USE_NATIVE_AOT}");
+
+ var testApp = GetTestApplications(app, device, config, tfm, rid).FirstOrDefault();
+ Information($"Testing App found: {testApp}");
+
if (string.IsNullOrEmpty(testApp))
{
throw new Exception("UI Test application path not specified.");
@@ -243,6 +243,7 @@ void ExecuteUITests(string project, string app, string device, string resultsDir
ToolPath = toolPath,
ArgumentCustomization = args => args
.Append("/p:ExtraDefineConstants=IOSUITEST")
+ .Append($"/p:_UseNativeAot={USE_NATIVE_AOT}")
.Append("/bl:" + binlog)
});
@@ -256,9 +257,19 @@ void ExecuteUITests(string project, string app, string device, string resultsDir
void ExecuteBuildUITestApp(string appProject, string device, string binDir, string config, string tfm, string rid, string toolPath)
{
Information($"Building UI Test app: {appProject}");
+ Information($"USE_NATIVE_AOT: {USE_NATIVE_AOT}");
+
var projectName = System.IO.Path.GetFileNameWithoutExtension(appProject);
var binlog = $"{binDir}/{projectName}-{config}-ios.binlog";
+ if (USE_NATIVE_AOT && config.Equals("Debug", StringComparison.OrdinalIgnoreCase))
+ {
+ var errMsg = $"Error: Running UI tests with NativeAOT is only supported in Release configuration";
+ Error(errMsg);
+ throw new Exception(errMsg);
+ }
+
+
DotNetBuild(appProject, new DotNetBuildSettings
{
Configuration = config,
@@ -268,15 +279,11 @@ void ExecuteBuildUITestApp(string appProject, string device, string binDir, stri
{
args
.Append("/p:BuildIpa=true")
+ .Append($"/p:_UseNativeAot={USE_NATIVE_AOT}")
+ .Append($"/p:RuntimeIdentifier={rid}")
.Append("/bl:" + binlog)
.Append("/tl");
- // if we building for a device
- if (device.ToLower().Contains("device"))
- {
- args.Append("/p:RuntimeIdentifier=ios-arm64");
- }
-
return args;
}
});
@@ -291,7 +298,7 @@ void ExecuteCGLegacyUITests(string project, string appProject, string device, st
CleanDirectories(resultsDir);
Information("Starting Compatibility Gallery UI Tests...");
-
+
var testApp = GetTestApplications(appProject, device, config, tfm, rid).FirstOrDefault();
Information($"Testing Device: {device}");
@@ -321,7 +328,7 @@ void ExecuteCGLegacyUITests(string project, string appProject, string device, st
//set env var for the app path for Xamarin.UITest setup
SetEnvironmentVariable("iOS_APP", $"{testApp}");
- var resultName = $"{System.IO.Path.GetFileNameWithoutExtension(project)}-{config}-{DateTime.UtcNow.ToFileTimeUtc()}";
+ var resultName = $"{System.IO.Path.GetFileNameWithoutExtension(project)}-{config}-{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}";
Information("Run UITests project {0}", resultName);
RunTestWithLocalDotNet(
project,
@@ -344,6 +351,7 @@ void PerformCleanupIfNeeded(bool cleanupEnabled, bool createDeviceLogs)
var sims = ListAppleSimulators().Where(s => s.Name.Contains("XHarness")).ToArray();
foreach (var sim in sims)
{
+ var timestamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
if(createDeviceLogs)
{
try
@@ -353,7 +361,7 @@ void PerformCleanupIfNeeded(bool cleanupEnabled, bool createDeviceLogs)
StartProcess("zip", new ProcessSettings {
Arguments = new ProcessArgumentBuilder()
.Append("-9r")
- .AppendQuoted($"{logDirectory}/DiagnosticReports_{sim.UDID}.zip")
+ .AppendQuoted($"{logDirectory}/DiagnosticReports_{sim.UDID}_{timestamp}.zip")
.AppendQuoted($"{homeDirectory}/Library/Logs/DiagnosticReports/"),
RedirectStandardOutput = false
});
@@ -362,28 +370,28 @@ void PerformCleanupIfNeeded(bool cleanupEnabled, bool createDeviceLogs)
StartProcess("zip", new ProcessSettings {
Arguments = new ProcessArgumentBuilder()
.Append("-9r")
- .AppendQuoted($"{logDirectory}/CoreSimulator_{sim.UDID}.zip")
+ .AppendQuoted($"{logDirectory}/CoreSimulator_{sim.UDID}_{timestamp}.zip")
.AppendQuoted($"{homeDirectory}/Library/Logs/CoreSimulator/{sim.UDID}"),
RedirectStandardOutput = false
});
- StartProcess("xcrun", $"simctl spawn {sim.UDID} log collect --output {homeDirectory}/{sim.UDID}_log.logarchive");
+ StartProcess("xcrun", $"simctl spawn {sim.UDID} log collect --output {homeDirectory}/{sim.UDID}_{timestamp}_log.logarchive");
StartProcess("zip", new ProcessSettings {
Arguments = new ProcessArgumentBuilder()
.Append("-9r")
- .AppendQuoted($"{logDirectory}/{sim.UDID}_log.logarchive.zip")
- .AppendQuoted($"{homeDirectory}/{sim.UDID}_log.logarchive"),
+ .AppendQuoted($"{logDirectory}/{sim.UDID}_{timestamp}_log.logarchive.zip")
+ .AppendQuoted($"{homeDirectory}/{sim.UDID}_{timestamp}_log.logarchive"),
RedirectStandardOutput = false
});
- var screenshotPath = $"{testResultsPath}/{sim.UDID}_screenshot.png";
+ var screenshotPath = $"{testResultsPath}/{sim.UDID}_{timestamp}_screenshot.png";
StartProcess("xcrun", $"simctl io {sim.UDID} screenshot {screenshotPath}");
}
catch(Exception ex)
{
Information($"Failed to collect logs for simulator {sim.Name} ({sim.UDID}): {ex.Message}");
- Information($"Command Executed: simctl spawn {sim.UDID} log collect --output {logDirectory}/{sim.UDID}_log.logarchive");
+ Information($"Command Executed: simctl spawn {sim.UDID} log collect --output {logDirectory}/{sim.UDID}_{timestamp}_log.logarchive");
}
}
diff --git a/eng/devices/windows.cake b/eng/devices/windows.cake
index 558b4db01e4a..93b000281274 100644
--- a/eng/devices/windows.cake
+++ b/eng/devices/windows.cake
@@ -4,7 +4,6 @@ using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
const string defaultVersion = "10.0.19041.0";
-const string dotnetVersion = "net8.0";
// required
string DEFAULT_WINDOWS_PROJECT = "../../src/Controls/tests/TestCases.WinUI.Tests/Controls.TestCases.WinUI.Tests.csproj";
@@ -17,7 +16,7 @@ var PACKAGEID = Argument("packageid", EnvironmentVariable("WINDOWS_TEST_PACKAGE_
// optional
var DOTNET_PATH = Argument("dotnet-path", EnvironmentVariable("DOTNET_PATH"));
var DOTNET_ROOT = Argument("dotnet-root", EnvironmentVariable("DOTNET_ROOT"));
-var TARGET_FRAMEWORK = Argument("tfm", EnvironmentVariable("TARGET_FRAMEWORK") ?? $"{dotnetVersion}-windows{defaultVersion}");
+var TARGET_FRAMEWORK = Argument("tfm", EnvironmentVariable("TARGET_FRAMEWORK") ?? $"{DotnetVersion}-windows{defaultVersion}");
var BINLOG_ARG = Argument("binlog", EnvironmentVariable("WINDOWS_TEST_BINLOG") ?? "");
DirectoryPath BINLOG_DIR = string.IsNullOrEmpty(BINLOG_ARG) && !string.IsNullOrEmpty(PROJECT.FullPath) ? PROJECT.GetDirectory() : BINLOG_ARG;
var TEST_APP = Argument("app", EnvironmentVariable("WINDOWS_TEST_APP") ?? "");
@@ -29,6 +28,8 @@ string CONFIGURATION = Argument("configuration", "Debug");
var windowsVersion = Argument("apiversion", EnvironmentVariable("WINDOWS_PLATFORM_VERSION") ?? defaultVersion);
+var dotnetToolPath = GetDotnetToolPath();
+
// other
string PLATFORM = "windows";
string DOTNET_PLATFORM = $"win10-x64";
@@ -55,6 +56,7 @@ Information("Build Binary Log (binlog): {0}", BINLOG_DIR);
Information("Build Platform: {0}", PLATFORM);
Information("Build Configuration: {0}", CONFIGURATION);
+Information("Target Framework: {0}", TARGET_FRAMEWORK);
Information("Windows version: {0}", windowsVersion);
Setup(context =>
@@ -139,23 +141,19 @@ Task("Build")
var name = System.IO.Path.GetFileNameWithoutExtension(PROJECT.FullPath);
var binlog = $"{BINLOG_DIR}/{name}-{CONFIGURATION}-windows.binlog";
- var localDotnetRoot = MakeAbsolute(Directory("../../bin/dotnet/"));
+ var localDotnetRoot = MakeAbsolute(Directory("../../.dotnet/"));
Information("new dotnet root: {0}", localDotnetRoot);
-
DOTNET_ROOT = localDotnetRoot.ToString();
-
SetDotNetEnvironmentVariables(DOTNET_ROOT);
-
- var toolPath = $"{localDotnetRoot}/dotnet.exe";
-
- Information("toolPath: {0}", toolPath);
+
+ Information("toolPath: {0}", dotnetToolPath);
Information("Building and publishing device test app");
// Build the app in publish mode
// Using the certificate thumbprint for the cert we just created
var s = new DotNetPublishSettings();
- s.ToolPath = toolPath;
+ s.ToolPath = dotnetToolPath;
s.Configuration = CONFIGURATION;
s.Framework = TARGET_FRAMEWORK;
s.MSBuildSettings = new DotNetMSBuildSettings();
@@ -203,7 +201,7 @@ Task("Test")
.IsDependentOn("SetupTestPaths")
.Does(() =>
{
- var waitForResultTimeoutInSeconds = 120;
+ var waitForResultTimeoutInSeconds = 240;
CleanDirectories(TEST_RESULTS);
@@ -437,7 +435,7 @@ Task("SetupTestPaths")
throw new Exception("If no app was specified, an app must be provided.");
}
- var winVersion = $"{dotnetVersion}-windows{windowsVersion}";
+ var winVersion = $"{DotnetVersion}-windows{windowsVersion}";
var binDir = TEST_APP_PROJECT.GetDirectory().Combine("Controls.TestCases.HostApp").Combine(CONFIGURATION + "/" + winVersion).Combine(DOTNET_PLATFORM);
Information("BinDir: {0}", binDir);
var apps = GetFiles(binDir + "/*.exe").Where(c => !c.FullPath.EndsWith("createdump.exe"));
@@ -523,26 +521,34 @@ Task("uitest")
Information("old dotnet root: {0}", DOTNET_ROOT);
Information("old dotnet path: {0}", DOTNET_PATH);
- var localDotnetRoot = MakeAbsolute(Directory("../../bin/dotnet/"));
- Information("new dotnet root: {0}", localDotnetRoot);
-
- DOTNET_ROOT = localDotnetRoot.ToString();
-
- var localToolPath = $"{localDotnetRoot}/dotnet.exe";
-
- Information("new dotnet toolPath: {0}", localToolPath);
-
- SetDotNetEnvironmentVariables(DOTNET_ROOT);
-
- DotNetBuild(PROJECT.FullPath, new DotNetBuildSettings {
+ var buildSettings = new DotNetBuildSettings {
Configuration = CONFIGURATION,
- ToolPath = localToolPath,
ArgumentCustomization = args => args
.Append("/p:ExtraDefineConstants=WINTEST")
.Append("/bl:" + binlog)
.Append("/maxcpucount:1")
//.Append("/tl")
- });
+ };
+
+ string? localToolPath = null;
+
+ if (localDotnet)
+ {
+ var localDotnetRoot = MakeAbsolute(Directory("../../.dotnet/"));
+ Information("new dotnet root: {0}", localDotnetRoot);
+
+ DOTNET_ROOT = localDotnetRoot.ToString();
+
+ localToolPath = $"{localDotnetRoot}/dotnet.exe";
+
+ Information("new dotnet toolPath: {0}", localToolPath);
+
+ SetDotNetEnvironmentVariables(DOTNET_ROOT);
+
+ buildSettings.ToolPath = localToolPath;
+ }
+
+ DotNetBuild(PROJECT.FullPath, buildSettings);
SetEnvironmentVariable("WINDOWS_APP_PATH", TEST_APP);
SetEnvironmentVariable("APPIUM_LOG_FILE", $"{BINLOG_DIR}/appium_windows.log");
diff --git a/eng/pipelines/azure-pipelines-public.yml b/eng/pipelines/azure-pipelines-public.yml
new file mode 100644
index 000000000000..1dca4a6753ec
--- /dev/null
+++ b/eng/pipelines/azure-pipelines-public.yml
@@ -0,0 +1,170 @@
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ - release/*
+ paths:
+ include:
+ - '*'
+ exclude:
+ - '**.md'
+ - eng/Version.Details.xml
+ - .github/*
+ - docs/*
+ - LICENSE.TXT
+ - PATENTS.TXT
+ - THIRD-PARTY-NOTICES.TXT
+
+pr:
+ branches:
+ include:
+ - main
+ - release/*
+ - feature/*
+ paths:
+ include:
+ - '*'
+ exclude:
+ - '**.md'
+ - eng/Version.Details.xml
+ - .github/*
+ - docs/*
+ - LICENSE.TXT
+ - PATENTS.TXT
+ - THIRD-PARTY-NOTICES.TXT
+
+variables:
+ - template: /eng/common/templates/variables/pool-providers.yml
+
+ - name: _BuildConfig
+ value: Release
+ - name: Build.Arcade.ArtifactsPath
+ value: $(Build.SourcesDirectory)/artifacts/
+ - name: Build.Arcade.LogsPath
+ value: $(Build.Arcade.ArtifactsPath)log/$(_BuildConfig)/
+ - name: Build.Arcade.TestResultsPath
+ value: $(Build.Arcade.ArtifactsPath)TestResults/$(_BuildConfig)/
+
+ # needed for darc (dependency flow) publishing
+ - name: _PublishArgs
+ value: ''
+ - name: _OfficialBuildIdArgs
+ value: ''
+ # needed for signing
+ - name: _SignType
+ value: test
+ - name: _SignArgs
+ value: ''
+ - name: _Sign
+ value: false
+ - name: HelixApiAccessToken
+ value: ''
+ - name: _InternalBuildArgs
+ value: ''
+
+
+stages:
+
+# ----------------------------------------------------------------
+# This stage performs build, test, packaging
+# ----------------------------------------------------------------
+- stage: build
+ displayName: Build
+ jobs:
+ - template: /eng/common/templates/jobs/jobs.yml
+ parameters:
+ artifacts:
+ publish:
+ artifacts: false
+ logs:
+ name: 'Logs_Build_$(Agent.JobName)_$(_BuildConfig)'
+ manifests: true
+ enableMicrobuild: true
+ enablePublishUsingPipelines: true
+ publishAssetsImmediately: true
+ enablePublishTestResults: true
+ enableSourceBuild: true
+ testResultsFormat: vstest
+ enableSourceIndex: false
+ workspace:
+ clean: all
+
+ jobs:
+
+ - ${{ each testVariant in split(',_helix_tests', ',') }}:
+ - job: Windows${{ testVariant }}
+
+ # timeout accounts for wait times for helix agents up to 30mins
+ timeoutInMinutes: 90
+
+ pool:
+ name: $(DncEngPublicBuildPool)
+ demands: ImageOverride -equals windows.vs2022preview.amd64.open
+
+ variables:
+ - name: _buildScript
+ value: $(Build.SourcesDirectory)/build.cmd -ci
+
+ preSteps:
+ - checkout: self
+ fetchDepth: 1
+ clean: true
+
+ steps:
+ - template: /eng/pipelines/common/build-test-pack.yml
+ parameters:
+ runAsPublic: true
+ dotnetScript: $(Build.SourcesDirectory)/dotnet.cmd
+ buildScript: $(_buildScript)
+ buildConfig: $(_BuildConfig)
+ repoArtifactsPath: $(Build.Arcade.ArtifactsPath)
+ repoLogPath: $(Build.Arcade.LogsPath)
+ repoTestResultsPath: $(Build.Arcade.TestResultsPath)
+ isWindows: true
+ runHelixTests: ${{ contains(testVariant, 'helix') }}
+
+# ----------------------------------------------------------------
+# This stage performs quality gates checks
+# ----------------------------------------------------------------
+- stage: codecoverage
+ displayName: CodeCoverage
+ dependsOn:
+ - build
+ condition: succeeded('build')
+ variables:
+ - template: /eng/common/templates/variables/pool-providers.yml
+ jobs:
+ - template: /eng/common/templates/jobs/jobs.yml
+ parameters:
+ enableMicrobuild: true
+ enableTelemetry: true
+ runAsPublic: false
+ workspace:
+ clean: all
+
+ # ----------------------------------------------------------------
+ # This stage downloads the code coverage reports from the build jobs,
+ # merges those and validates the combined test coverage.
+ # ----------------------------------------------------------------
+ jobs:
+ - job: CodeCoverageReport
+ timeoutInMinutes: 10
+
+ pool:
+ name: $(DncEngPublicBuildPool)
+ demands: ImageOverride -equals build.ubuntu.2004.amd64.open
+
+ preSteps:
+ - checkout: self
+ fetchDepth: 1
+ clean: true
+
+ steps:
+ - script: $(Build.SourcesDirectory)/build.sh --ci --restore
+ displayName: Init toolset
+
+ - template: /eng/pipelines/templates/VerifyCoverageReport.yml
+ parameters:
+ # matches what is used in the conditions for the build/test jobs
+ testVariants: ',_helix_tests'
diff --git a/eng/pipelines/common/build-test-pack.yml b/eng/pipelines/common/build-test-pack.yml
new file mode 100644
index 000000000000..60d27cf760e3
--- /dev/null
+++ b/eng/pipelines/common/build-test-pack.yml
@@ -0,0 +1,158 @@
+
+parameters:
+ - name: runAsPublic
+ type: boolean
+ default: false
+ - name: buildScript
+ type: string
+ - name: buildConfig
+ type: string
+ - name: repoArtifactsPath
+ type: string
+ - name: repoLogPath
+ type: string
+ - name: repoTestResultsPath
+ type: string
+ - name: isWindows
+ type: string
+ default: false
+ - name: dotnetScript
+ type: string
+ - name: runHelixTests
+ type: boolean
+ default: false
+
+steps:
+
+ # - task: UseDotNet@2
+ # inputs:
+ # useGlobalJson: true
+
+ - pwsh: |
+ if ($env:JAVA_HOME_17_X64) {
+ $env:JAVA_HOME = $env:JAVA_HOME_17_X64
+ } else {
+ $path = (Get-ChildItem $env:ProgramFiles\Microsoft\jdk-17.*\bin\java.exe) | Select-Object -First 1
+ if ($path -and (Test-Path $path)) {
+ $env:JAVA_HOME = $path.Directory.Parent.FullName
+ }
+ }
+ if ($env:JAVA_HOME) {
+ echo "##vso[task.setvariable variable=JAVA_HOME]$env:JAVA_HOME"
+ echo "JAVA_HOME set to '$env:JAVA_HOME'"
+ } else {
+ echo "Unable to set JAVA_HOME"
+ }
+ displayName: Set JAVA_HOME
+
+
+ - ${{ if ne(parameters.isWindows, 'true') }}:
+ - script: ${{ parameters.buildScript }}
+ -restore -build
+ -configuration ${{ parameters.buildConfig }}
+ /p:ArchiveTests=true
+ /bl:${{ parameters.repoLogPath }}build.binlog
+ $(_OfficialBuildIdArgs)
+ -p:Platform=`uname -m`
+ displayName: 🛠️ Build
+
+ - ${{ if eq(parameters.isWindows, 'true') }}:
+ - script: ${{ parameters.buildScript }}
+ -restore -build
+ -configuration ${{ parameters.buildConfig }}
+ /p:ArchiveTests=true
+ /p:TreatWarningsAsErrors=false
+ /bl:${{ parameters.repoLogPath }}build.binlog
+ $(_OfficialBuildIdArgs)
+ displayName: 🛠️ Build
+
+ # - ${{ if or(ne(parameters.runAsPublic, 'true'), ne(parameters.runHelixTests, 'true')) }}:
+ # - ${{ if ne(parameters.isWindows, 'true') }}:
+ # - script: mkdir ${{ parameters.repoArtifactsPath }}/devcert-scripts &&
+ # cd ${{ parameters.repoArtifactsPath }}/devcert-scripts &&
+ # wget https://raw.githubusercontent.com/BorisWilhelms/create-dotnet-devcert/main/scripts/ubuntu-create-dotnet-devcert.sh &&
+ # wget https://raw.githubusercontent.com/BorisWilhelms/create-dotnet-devcert/main/scripts/common.sh &&
+ # chmod +x ubuntu-create-dotnet-devcert.sh &&
+ # ./ubuntu-create-dotnet-devcert.sh
+ # displayName: Install devcerts
+
+ # - ${{ if eq(parameters.isWindows, 'true') }}:
+ # - script: dotnet dev-certs https
+ # displayName: Install dev-certs
+
+ # - ${{ if ne(parameters.isWindows, 'true') }}:
+ # - script: ${{ parameters.dotnetScript }} dotnet-coverage collect
+ # --settings $(Build.SourcesDirectory)/eng/CodeCoverage.config
+ # --output ${{ parameters.repoTestResultsPath }}/NonHelix.cobertura.xml
+ # "${{ parameters.buildScript }} -testnobuild -test -configuration ${{ parameters.buildConfig }} /bl:${{ parameters.repoLogPath }}tests.binlog $(_OfficialBuildIdArgs) -p:Platform=`uname -m`"
+ # displayName: Run non-helix tests
+
+ # - ${{ if eq(parameters.runHelixTests, 'true') }}:
+ # - task: CopyFiles@2
+ # inputs:
+ # Contents: '${{ parameters.repoArtifactsPath }}/helixresults/**/*.trx'
+ # TargetFolder: '${{ parameters.repoArtifactsPath }}/log/$(_BuildConfig)/TestResults'
+ # flattenFolders: true
+ # OverWrite: true
+ # displayName: Gather helix trx files
+ # continueOnError: true
+ # condition: always()
+
+ # - task: CopyFiles@2
+ # inputs:
+ # Contents: '${{ parameters.repoArtifactsPath }}/**/*.cobertura.xml'
+ # TargetFolder: '${{ parameters.repoArtifactsPath }}/CodeCoverage'
+ # flattenFolders: true
+ # displayName: Gather code coverage results
+
+ # - ${{ if eq(parameters.runAsPublic, 'true') }}:
+ # - task: PublishPipelineArtifact@1
+ # displayName: Publish coverage results (cobertura.xml)
+ # inputs:
+ # targetPath: '${{ parameters.repoArtifactsPath }}/CodeCoverage'
+ # artifactName: '$(Agent.JobName)_CodeCoverageResults'
+ # publishLocation: 'pipeline'
+
+ # - ${{ if ne(parameters.runAsPublic, 'true') }}:
+ # - task: 1ES.PublishPipelineArtifact@1
+ # displayName: Publish code coverage results
+ # inputs:
+ # targetPath: '${{ parameters.repoArtifactsPath }}/CodeCoverage'
+ # artifactName: '$(Agent.JobName)_CodeCoverageResults'
+
+ # Run on windows, for internal pipeline, or public+non-helix-tests job
+ - ${{ if and(eq(parameters.isWindows, 'true'), or(ne(parameters.runAsPublic, 'true'), ne(parameters.runHelixTests, 'true'))) }}:
+
+ - script: ${{ parameters.buildScript }}
+ -pack
+ -sign $(_SignArgs)
+ -publish $(_PublishArgs)
+ -configuration $(_BuildConfig)
+ /bl:${{ parameters.repoLogPath }}/pack.binlog
+ $(_OfficialBuildIdArgs)
+ displayName: Pack, Sign & Publish
+
+ # - script: ${{ parameters.buildScript }}
+ # -restore -build
+ # -sign $(_SignArgs)
+ # -publish $(_PublishArgs)
+ # -configuration $(_BuildConfig)
+ # /bl:${{ parameters.repoLogPath }}/build-workloads.binlog
+ # -projects src/Workload/workloads.csproj
+ # $(_OfficialBuildIdArgs)
+ # displayName: Build Workloads
+
+ # - ${{ if eq(parameters.runAsPublic, 'true') }}:
+ # - task: PublishPipelineArtifact@1
+ # displayName: Publish VSDrop MSIs
+ # inputs:
+ # targetPath: '$(Build.SourcesDirectory)/artifacts/VSSetup/$(_BuildConfig)'
+ # artifactName: VSDropInsertion
+ # publishLocation: 'pipeline'
+
+ # - ${{ if ne(parameters.runAsPublic, 'true') }}:
+ # - task: 1ES.PublishPipelineArtifact@1
+ # displayName: Publish VSDrop MSIs
+ # inputs:
+ # targetPath: '$(Build.SourcesDirectory)/artifacts/VSSetup/$(_BuildConfig)'
+ # artifactName: VSDropInsertion
\ No newline at end of file
diff --git a/eng/pipelines/common/device-tests-steps.yml b/eng/pipelines/common/device-tests-steps.yml
index a9ac50cdeecb..854a1e67c078 100644
--- a/eng/pipelines/common/device-tests-steps.yml
+++ b/eng/pipelines/common/device-tests-steps.yml
@@ -4,6 +4,7 @@ parameters:
device: '' # the xharness device to use
apiversion: '' # the iOS device api version to use
cakeArgs: '' # additional cake args
+ androidConfiguration: '' # Indicates the configuration to use for Android. We're slowly enabling this for all projects
provisionatorChannel: 'latest'
agentPoolAccessToken: ''
artifactName: 'nuget'
@@ -30,8 +31,9 @@ steps:
platform: macos
skipXcode: ${{ or(eq(parameters.platform, 'android'), eq(parameters.platform, 'windows')) }}
skipProvisioning: ${{ eq(parameters.platform, 'windows') }}
- skipAndroidImages : ${{ eq(parameters.platform, 'ios') }}
- skipAndroidSdks: ${{ eq(parameters.platform, 'ios') }}
+ skipAndroidImages : ${{ or(eq(parameters.platform, 'ios'), eq(parameters.platform, 'catalyst')) }}
+ skipAndroidSdks: ${{ or(eq(parameters.platform, 'ios'), eq(parameters.platform, 'catalyst')) }}
+ installDefaultAndroidApi: ${{ or(eq(parameters.platform, 'ios'), eq(parameters.platform, 'catalyst')) }}
provisionatorChannel: ${{ parameters.provisionatorChannel }}
- pwsh: ./build.ps1 --target=dotnet --configuration="Release" --verbosity=diagnostic
@@ -88,20 +90,41 @@ steps:
continueOnError: true
timeoutInMinutes: 5
- - pwsh: |
- ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --project="${{ parameters.path }}" --device=${{ parameters.device }} --apiversion=${{ parameters.apiversion }} --packageid=${{ parameters.windowsPackageId }} --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }}
- displayName: $(Agent.JobName)
- workingDirectory: ${{ parameters.checkoutDirectory }}
- condition: and(succeeded(), ne(variables['Platform.Name'], 'Mac'))
- retryCountOnTaskFailure: 1
-
- - bash: |
- # Execute the powershell script from a bash shell on Mac to avoid interference between powershell processes that lead to this error: The STDIO streams did not close within 10 seconds of the exit event from process '/usr/local/bin/pwsh'. This may indicate a child process inherited the STDIO streams and has not yet exited.
- pwsh ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --project="${{ parameters.path }}" --device=${{ parameters.device }} --apiversion=${{ parameters.apiversion }} --packageid=${{ parameters.windowsPackageId }} --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }}
- displayName: $(Agent.JobName)
- workingDirectory: ${{ parameters.checkoutDirectory }}
- condition: and(succeeded(), eq(variables['Platform.Name'], 'Mac'))
- retryCountOnTaskFailure: 1
+ # Everything should be release but doing android for now to work around an xharness issue
+ - ${{ if eq(parameters.platform, 'android')}}:
+ - pwsh: |
+ ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --project="${{ parameters.path }}" --device=${{ parameters.device }} --apiversion=${{ parameters.apiversion }} --packageid=${{ parameters.windowsPackageId }} --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }} --configuration=${{ parameters.androidConfiguration }}
+ displayName: $(Agent.JobName)
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+ condition: and(succeeded(), ne(variables['Platform.Name'], 'Mac'))
+ retryCountOnTaskFailure: 1
+
+ - ${{ if eq(parameters.platform, 'android')}}:
+ - bash: |
+ # Execute the powershell script from a bash shell on Mac to avoid interference between powershell processes that lead to this error: The STDIO streams did not close within 10 seconds of the exit event from process '/usr/local/bin/pwsh'. This may indicate a child process inherited the STDIO streams and has not yet exited.
+ pwsh ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --project="${{ parameters.path }}" --device=${{ parameters.device }} --apiversion=${{ parameters.apiversion }} --packageid=${{ parameters.windowsPackageId }} --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }} --configuration=${{ parameters.androidConfiguration }}
+ displayName: $(Agent.JobName)
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+ condition: and(succeeded(), eq(variables['Platform.Name'], 'Mac'))
+ retryCountOnTaskFailure: 1
+
+ - ${{ if ne(parameters.platform, 'android')}}:
+ - pwsh: |
+ ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --project="${{ parameters.path }}" --device=${{ parameters.device }} --apiversion=${{ parameters.apiversion }} --packageid=${{ parameters.windowsPackageId }} --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }}
+ displayName: $(Agent.JobName)
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+ condition: and(succeeded(), ne(variables['Platform.Name'], 'Mac'))
+ retryCountOnTaskFailure: 1
+
+ - ${{ if ne(parameters.platform, 'android')}}:
+ - bash: |
+ # Execute the powershell script from a bash shell on Mac to avoid interference between powershell processes that lead to this error: The STDIO streams did not close within 10 seconds of the exit event from process '/usr/local/bin/pwsh'. This may indicate a child process inherited the STDIO streams and has not yet exited.
+ pwsh ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --project="${{ parameters.path }}" --device=${{ parameters.device }} --apiversion=${{ parameters.apiversion }} --packageid=${{ parameters.windowsPackageId }} --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }}
+ displayName: $(Agent.JobName)
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+ condition: and(succeeded(), eq(variables['Platform.Name'], 'Mac'))
+ retryCountOnTaskFailure: 1
+ # Everything should be release but doing android for now to work around an xharness issue
- ${{ if eq(parameters.platform, 'ios')}}:
- bash: |
diff --git a/eng/pipelines/common/device-tests.yml b/eng/pipelines/common/device-tests.yml
index 04e3edf5210f..1bac43fff791 100644
--- a/eng/pipelines/common/device-tests.yml
+++ b/eng/pipelines/common/device-tests.yml
@@ -12,7 +12,11 @@ parameters:
artifactName: 'nuget'
artifactItemPattern: '**/*.nupkg'
checkoutDirectory: $(System.DefaultWorkingDirectory)
+ androidConfiguration: 'debug' # Indicates the configuration to use for Android. We're slowly enabling this for all projects
useArtifacts: false
+ targetFrameworkVersion:
+ - tfm: ''
+ dependsOn: ''
projects:
- name: name
desc: Human Description
@@ -21,14 +25,18 @@ parameters:
catalyst: /optional/path/to/catalyst.csproj
stages:
- - stage: android_device_tests
- displayName: Android Device Tests
- dependsOn: []
+ - stage: android_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
+ displayName: ${{ parameters.targetFrameworkVersion.tfm }} Android Device Tests
+ ${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
+ dependsOn:
+ - android_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
+ ${{ else }}:
+ dependsOn: []
jobs:
- - job: android_device_tests
+ - job: android_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
- displayName: "Android emulator tests"
+ displayName: "Android"
pool: ${{ parameters.androidPool }}
timeoutInMinutes: 60
strategy:
@@ -41,6 +49,8 @@ stages:
${{ replace(coalesce(project.desc, project.name), ' ', '_') }}_API_${{ api }}:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
PROJECT_PATH: ${{ project.android }}
+ ANDROID_CONFIGURATION: ${{ project.androidConfiguration }}
+ TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
${{ if eq(api, 27) }}:
DEVICE: android-emulator-32_${{ api }}
APIVERSION: ${{ api }}
@@ -62,15 +72,20 @@ stages:
checkoutDirectory: ${{ parameters.checkoutDirectory }}
useArtifacts: ${{ parameters.useArtifacts }}
poolName: ${{ parameters.androidPool.name }}
+ androidConfiguration: $(ANDROID_CONFIGURATION)
- - stage: ios_device_tests
- displayName: iOS Device Tests
- dependsOn: []
+ - stage: ios_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
+ displayName: ${{ parameters.targetFrameworkVersion.tfm }} iOS Device Tests
+ ${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
+ dependsOn:
+ - ios_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
+ ${{ else }}:
+ dependsOn: []
jobs:
- - job: ios_device_tests
+ - job: ios_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
- displayName: "iOS tests"
+ displayName: "iOS"
pool: ${{ parameters.iosPool }}
timeoutInMinutes: 120
strategy:
@@ -83,6 +98,7 @@ stages:
${{ replace(coalesce(project.desc, project.name), ' ', '_') }}_V_${{ version }}:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
PROJECT_PATH: ${{ project.ios }}
+ TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
${{ if contains(version, 'device') }}:
DEVICE: ios-device
APIVERSION: ${{ replace(version, 'device-', '') }}
@@ -105,14 +121,18 @@ stages:
useArtifacts: ${{ parameters.useArtifacts }}
poolName: 'Azure Pipelines'
- - stage: catalyst_device_tests
- displayName: macOS Device Tests
- dependsOn: []
+ - stage: catalyst_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
+ displayName: ${{ parameters.targetFrameworkVersion.tfm }} macOS Device Tests
+ ${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
+ dependsOn:
+ - catalyst_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
+ ${{ else }}:
+ dependsOn: []
jobs:
- - job: catalyst_device_tests
+ - job: catalyst_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
- displayName: "macOS tests"
+ displayName: "macOS"
pool: ${{ parameters.catalystPool }}
timeoutInMinutes: 240
strategy:
@@ -125,6 +145,7 @@ stages:
${{ replace(coalesce(project.desc, project.name), ' ', '_') }}_V_${{ version }}:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
PROJECT_PATH: ${{ project.catalyst }}
+ TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
${{ if eq(version, 'latest') }}:
DEVICE: maccatalyst
${{ else }}:
@@ -146,14 +167,18 @@ stages:
poolName: 'Azure Pipelines'
- - stage: windows_device_tests
- displayName: Windows Device Tests
- dependsOn: []
+ - stage: windows_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
+ displayName: ${{ parameters.targetFrameworkVersion.tfm }} Windows Device Tests
+ ${{ if ne(parameters.targetFrameworkVersion.dependsOn, '') }}:
+ dependsOn:
+ - windows_device_tests_${{ replace(parameters.targetFrameworkVersion.dependsOn, '.', '') }}
+ ${{ else }}:
+ dependsOn: []
jobs:
- - job: windows_device_tests
+ - job: windows_device_tests_${{ replace(parameters.targetFrameworkVersion.tfm, '.', '') }}
workspace:
clean: all
- displayName: "Windows device tests"
+ displayName: "Windows"
pool: ${{ parameters.windowsPool }}
timeoutInMinutes: 240 # how long to run the job before automatically cancelling
strategy:
@@ -166,6 +191,7 @@ stages:
PROJECT_PATH: ${{ project.windows }}
PACKAGE_ID: ${{ project.windowsPackageId }}
DEVICE: ${{ version }}
+ TARGET_FRAMEWORK_VERSION: ${{ parameters.targetFrameworkVersion.tfm }}
steps:
- template: device-tests-steps.yml
parameters:
diff --git a/eng/pipelines/common/maui-templates.yml b/eng/pipelines/common/maui-templates.yml
index e026e70a8afd..6bc2fe51e4f5 100644
--- a/eng/pipelines/common/maui-templates.yml
+++ b/eng/pipelines/common/maui-templates.yml
@@ -20,109 +20,119 @@ parameters:
- name: BuildPlatforms
type: object
+
+ - name: BuildCategories
+ type: object
default:
- - name: Windows
- poolName: $(windowsVmPool)
- vmImage: $(windowsVmImage)
- artifact: templates-windows
- - name: macOS
- poolName: $(macOSXVmPool)
- vmImage: $(macOSXVmImage)
- artifact: templates-macos
+ - WindowsTemplates
+ - macOSTemplates
+ - Build
+ - Blazor
+ - MultiProject
+ - AOT
- name: RunPlatforms
type: object
- default:
- - name: $(androidTestsVmPool)
- vmImage: $(androidTestsVmImage)
- demands:
- - macOS.Name -equals Sonoma
- - macOS.Architecture -equals x64
- testName: RunOnAndroid
- artifact: templates-run-android
- - name: $(iosTestsVmPool)
- vmImage: $(iosTestsVmImage)
- demands:
- - macOS.Name -equals Sonoma
- - macOS.Architecture -equals x64
- testName: RunOniOS
- artifact: templates-run-ios
- name: prepareSteps
type: stepList
default: []
jobs:
-- job: build_maui_templates
- workspace:
- clean: all
- displayName: 'Build platform:'
- timeoutInMinutes: 240
- condition: ${{ parameters.condition}}
- strategy:
- matrix:
- ${{ each BuildPlatform in parameters.BuildPlatforms }}:
- ${{ BuildPlatform.name }}:
- POOL_NAME: ${{ BuildPlatform.poolName }}
- POOL_VIMAGE: ${{ BuildPlatform.vmImage }}
- PLATFORM_NAME: ${{ lower(BuildPlatform.name) }}
-
- pool:
- name: $(POOL_NAME)
- vmImage: $(POOL_VIMAGE)
- demands:
- - macOS.Name -equals Sonoma
- - macOS.Architecture -equals x64
- steps:
-
- - ${{ each step in parameters.prepareSteps }}:
- - ${{ each pair in step }}:
- ${{ pair.key }}: ${{ pair.value }}
-
- - template: provision.yml
- parameters:
- checkoutDirectory: ${{ parameters.checkoutDirectory }}
-
- - task: DownloadBuildArtifacts@0
- displayName: 'Download Packages'
- inputs:
- artifactName: ${{ parameters.artifactName }}
- itemPattern: ${{ parameters.artifactItemPattern }}
- downloadPath: $(System.DefaultWorkingDirectory)/artifacts
-
- - pwsh: Move-Item -Path artifacts\${{ parameters.artifactName }}\*.nupkg -Destination artifacts -Force
- displayName: Move the downloaded artifacts
-
- - pwsh: ./build.ps1 --target=dotnet-local-workloads --verbosity=diagnostic
- displayName: 'Install .NET (Local Workloads)'
- retryCountOnTaskFailure: 3
- workingDirectory: ${{ parameters.checkoutDirectory }}
- env:
- DOTNET_TOKEN: $(dotnetbuilds-internal-container-read-token)
- PRIVATE_BUILD: $(PrivateBuild)
-
- - pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
- displayName: Build Microsoft.Maui.IntegrationTests
- workingDirectory: ${{ parameters.checkoutDirectory }}
-
- - pwsh: ./build.ps1 --target=dotnet-integration-test --filter="FullyQualifiedName=Microsoft.Maui.IntegrationTests.TemplateTests" --resultsfilename="integration-tests" --verbosity=diagnostic
- displayName: Run $(PLATFORM_NAME) templates build tests
- workingDirectory: ${{ parameters.checkoutDirectory }}
-
- - task: PublishTestResults@2
- displayName: Publish the $(PLATFORM_NAME) templates build tests
- condition: always()
- inputs:
- testRunner: VSTest
- testResultsFiles: '$(build.artifactstagingdirectory)/**/*.trx'
- testRunTitle: $(PLATFORM_NAME) templates build tests
-
- - pwsh: |
- Write-Host "Current job status is: $env:AGENT_JOBSTATUS"
- if ($env:AGENT_JOBSTATUS -eq "SucceededWithIssues") {
- Write-Host "##vso[task.complete result=Failed;]DONE"
- }
- displayName: Fail if any issues occurred
+- ${{ each category in parameters.BuildCategories }}:
+ - job: build_maui_templates_${{ category }}
+ workspace:
+ clean: all
+ displayName: 'Build ${{ category }}: '
+ timeoutInMinutes: 240
+ condition: ${{ parameters.condition}}
+ strategy:
+ matrix:
+ ${{ each BuildPlatform in parameters.BuildPlatforms }}:
+ ${{ BuildPlatform.name }}:
+ POOL_NAME: ${{ BuildPlatform.poolName }}
+ POOL_VIMAGE: ${{ BuildPlatform.vmImage }}
+ PLATFORM_NAME: ${{ lower(BuildPlatform.name) }}
+
+ pool:
+ name: $(POOL_NAME)
+ vmImage: $(POOL_VIMAGE)
+ demands:
+ - macOS.Name -equals Sonoma
+ - macOS.Architecture -equals x64
+ steps:
+
+ - ${{ each step in parameters.prepareSteps }}:
+ - ${{ each pair in step }}:
+ ${{ pair.key }}: ${{ pair.value }}
+
+ - template: provision.yml
+ parameters:
+ checkoutDirectory: ${{ parameters.checkoutDirectory }}
+
+ - task: DownloadBuildArtifacts@0
+ displayName: 'Download Packages'
+ inputs:
+ artifactName: ${{ parameters.artifactName }}
+ itemPattern: ${{ parameters.artifactItemPattern }}
+ downloadPath: $(System.DefaultWorkingDirectory)/artifacts
+
+ - pwsh: Move-Item -Path artifacts\${{ parameters.artifactName }}\*.nupkg -Destination artifacts -Force
+ displayName: Move the downloaded artifacts
+
+ - pwsh: |
+ Get-ChildItem artifacts -Filter 'Microsoft.Maui.Controls.*.nupkg' | Where-Object { $_.Name -match '^Microsoft\.Maui\.Controls\.([\d\.]+.*)\.nupkg$' }
+ $version = $Matches.1
+ if (!$version) {
+ Write-Error "Failed to extract the version from the nupkgs"
+ exit 1
+ }
+ Write-Host "Found .NET MAUI version (MAUI_PACKAGE_VERSION): $version"
+ Write-Host "##vso[task.setvariable variable=MAUI_PACKAGE_VERSION]$version"
+ displayName: Read the .NET MAUI version from the nugets
+
+ - pwsh: ./build.ps1 --target=dotnet-local-workloads --verbosity=diagnostic
+ displayName: 'Install .NET (Local Workloads)'
+ retryCountOnTaskFailure: 3
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+ env:
+ DOTNET_TOKEN: $(dotnetbuilds-internal-container-read-token)
+ PRIVATE_BUILD: $(PrivateBuild)
+
+ - pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
+ displayName: Build Microsoft.Maui.IntegrationTests
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+
+ - pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Category=${{ category }}" --resultsfilename="integration-tests" --verbosity=diagnostic
+ displayName: Run $(PLATFORM_NAME) templates build tests
+ workingDirectory: ${{ parameters.checkoutDirectory }}
+
+ - task: CopyFiles@2
+ displayName: Copy binlogs
+ inputs:
+ SourceFolder: '$(Build.SourcesDirectory)'
+ Contents: |
+ **/*.binlog
+ ../**/*.binlog
+ ../../**/*.binlog
+ TargetFolder: '$(Build.StagingDirectory)/IntegrationTestsBuildLogs'
+ continueOnError: true
+ condition: succeededOrFailed()
+
+ - task: PublishTestResults@2
+ displayName: Publish the $(PLATFORM_NAME) templates build tests
+ condition: always()
+ inputs:
+ testRunner: VSTest
+ testResultsFiles: '$(build.artifactstagingdirectory)/**/*.trx'
+ testRunTitle: $(PLATFORM_NAME) templates build tests
+
+ - pwsh: |
+ Write-Host "Current job status is: $env:AGENT_JOBSTATUS"
+ if ($env:AGENT_JOBSTATUS -eq "SucceededWithIssues") {
+ Write-Host "##vso[task.complete result=Failed;]DONE"
+ }
+ displayName: Fail if any issues occurred
- ${{ each RunPlatform in parameters.RunPlatforms }}:
- job: run_${{ RunPlatform.testName }}
@@ -150,6 +160,7 @@ jobs:
- template: provision.yml
parameters:
skipXcode: ${{ eq(RunPlatform.testName, 'RunOnAndroid') }}
+ skipAndroidImages: ${{ ne(RunPlatform.testName, 'RunOnAndroid') }}
checkoutDirectory: ${{ parameters.checkoutDirectory }}
- task: DownloadBuildArtifacts@0
@@ -162,6 +173,17 @@ jobs:
- pwsh: Move-Item -Path artifacts\${{ parameters.artifactName }}\*.nupkg -Destination artifacts -Force
displayName: Move the downloaded artifacts
+ - pwsh: |
+ Get-ChildItem artifacts -Filter 'Microsoft.Maui.Controls.*.nupkg' | Where-Object { $_.Name -match '^Microsoft\.Maui\.Controls\.([\d\.]+.*)\.nupkg$' }
+ $version = $Matches.1
+ if (!$version) {
+ Write-Error "Failed to extract the version from the nupkgs"
+ exit 1
+ }
+ Write-Host "Found .NET MAUI version (MAUI_PACKAGE_VERSION): $version"
+ Write-Host "##vso[task.setvariable variable=MAUI_PACKAGE_VERSION]$version"
+ displayName: Read the .NET MAUI version from the nugets
+
- pwsh: ./build.ps1 --target=dotnet-local-workloads --verbosity=diagnostic
displayName: 'Install .NET (Local Workloads)'
retryCountOnTaskFailure: 3
@@ -183,7 +205,7 @@ jobs:
- pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
displayName: Build Microsoft.Maui.IntegrationTests
- - pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Name=${{ RunPlatform.testName }}" --resultsfilename="integration-run-${{ RunPlatform.testName }}" --verbosity=diagnostic
+ - pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Category=${{ RunPlatform.testName }}" --resultsfilename="integration-run-${{ RunPlatform.testName }}" --verbosity=diagnostic
displayName: Run $(PLATFORM_NAME) templates run tests
continueOnError: true
# TODO: pass properly device type/version from top-level yml
diff --git a/eng/pipelines/common/pack.yml b/eng/pipelines/common/pack.yml
index c82597446880..eb3cb7da5aad 100644
--- a/eng/pipelines/common/pack.yml
+++ b/eng/pipelines/common/pack.yml
@@ -150,7 +150,7 @@ steps:
condition: succeeded()
inputs:
Contents: |
- ${{ parameters.checkoutDirectory }}/artifacts/bin/Controls.Nuget/${{ parameters.buildConfiguration }}/**/*.dll
+ ${{ parameters.checkoutDirectory }}/artifacts/bin/Controls.Nuget/${{ parameters.buildConfiguration }}/**/Microsoft.Maui*.dll
TargetFolder: ${{ parameters.checkoutDirectory }}/artifacts/binaries
flattenFolders: false
diff --git a/eng/pipelines/common/provision.yml b/eng/pipelines/common/provision.yml
index 6b3cdd86b498..13302d8e0025 100644
--- a/eng/pipelines/common/provision.yml
+++ b/eng/pipelines/common/provision.yml
@@ -5,6 +5,7 @@ parameters:
skipProvisioning: $(skipProvisionator)
skipAndroidSdks: false
skipAndroidImages: false
+ installDefaultAndroidApi: false
checkoutDirectory: $(System.DefaultWorkingDirectory)
provisionatorPath: $(provisionator.path)
provisionatorXCodePath: $(provisionator.xcode)
@@ -12,6 +13,10 @@ parameters:
provisionatorExtraArguments: $(provisionator.extraArguments)
gitHubToken: $(github--pat--vs-mobiletools-engineering-service2)
certPass: $(pass--components-mac-ios-certificate-p12)
+ federatedServiceConnection: 'dotnetbuilds-internal-read'
+ outputVariableName: 'dotnetbuilds-internal-container-read-token'
+ expiryInHours: 1
+ base64Encode: false
steps:
# Prepare macOS
@@ -54,23 +59,26 @@ steps:
SKIP_ANDROID_API_SDKS: 'true'
${{ if eq(parameters.skipAndroidImages, true) }}:
SKIP_ANDROID_API_IMAGES: 'true'
+ ${{ if eq(parameters.installDefaultAndroidApi, true) }}:
+ INSTALL_DEFAULT_ANDROID_API: 'true'
# Setup JDK Paths (gradle needs it)
- bash: |
- echo "##vso[task.setvariable variable=JI_JAVA_HOME]$(JAVA_HOME_11_X64)"
- echo "##vso[task.setvariable variable=JAVA_HOME]$(JAVA_HOME_11_X64)"
+ echo "##vso[task.setvariable variable=JI_JAVA_HOME]$(JAVA_HOME_17_X64)"
+ echo "##vso[task.setvariable variable=JAVA_HOME]$(JAVA_HOME_17_X64)"
+ # brew install --cask microsoft-openjdk@17
displayName: 'Setup JDK Paths'
condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
# Configure VS Mac for Xcode
# This seems to be needed or else it will pick other xcode for example on xharness
- - bash: |
- set -x
- mkdir -p ~/Library/Preferences/Xamarin
- rm -f ~/Library/Preferences/Xamarin/Settings.plist
- /usr/libexec/PlistBuddy -c "add :AppleSdkRoot string $(dirname $(dirname $(xcode-select -p)))" ~/Library/Preferences/Xamarin/Settings.plist || true
- cat ~/Library/Preferences/Xamarin/Settings.plist || true
- displayName: 'Configure Visual Studio'
- condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
+ # - bash: |
+ # set -x
+ # mkdir -p ~/Library/Preferences/Xamarin
+ # rm -f ~/Library/Preferences/Xamarin/Settings.plist
+ # /usr/libexec/PlistBuddy -c "add :AppleSdkRoot string $(dirname $(dirname $(xcode-select -p)))" ~/Library/Preferences/Xamarin/Settings.plist || true
+ # cat ~/Library/Preferences/Xamarin/Settings.plist || true
+ # displayName: 'Configure Visual Studio'
+ # condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
# Prepare Windows
# Provision Additional Software
@@ -88,12 +96,14 @@ steps:
SKIP_ANDROID_API_SDKS: 'true'
${{ if eq(parameters.skipAndroidImages, true) }}:
SKIP_ANDROID_API_IMAGES: 'true'
+ ${{ if eq(parameters.installDefaultAndroidApi, true) }}:
+ INSTALL_DEFAULT_ANDROID_API: 'true'
- pwsh: |
- if ($env:JAVA_HOME_11_X64) {
- $env:JAVA_HOME = $env:JAVA_HOME_11_X64
+ if ($env:JAVA_HOME_17_X64) {
+ $env:JAVA_HOME = $env:JAVA_HOME_17_X64
} else {
- $path = (Get-ChildItem $env:ProgramFiles\Microsoft\jdk-11.*\bin\java.exe) | Select-Object -First 1
+ $path = (Get-ChildItem $env:ProgramFiles\Microsoft\jdk-17.*\bin\java.exe) | Select-Object -First 1
if ($path -and (Test-Path $path)) {
$env:JAVA_HOME = $path.Directory.Parent.FullName
}
@@ -130,6 +140,7 @@ steps:
inputs:
packageType: sdk
version: $(DOTNET_VERSION)
+ includePreviewVersions: true
- pwsh: |
dotnet --version
@@ -141,11 +152,11 @@ steps:
displayName: 'Clear all NuGet caches'
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
- - task: PowerShell@2
- condition: eq(variables['PrivateBuild'], 'true')
- displayName: Setup Private Feeds Credentials
- inputs:
- filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
- arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token
- env:
- Token: $(dn-bot-dnceng-artifact-feeds-rw)
\ No newline at end of file
+ - template: ../../common/templates-official/steps/enable-internal-sources.yml
+
+ - template: ../../common/templates-official/steps/enable-internal-runtimes.yml
+ parameters:
+ federatedServiceConnection: ${{ parameters.federatedServiceConnection }}
+ outputVariableName: ${{ parameters.outputVariableName }}
+ expiryInHours: ${{ parameters.expiryInHours }}
+ base64Encode: ${{ parameters.base64Encode }}
diff --git a/eng/pipelines/common/sdk-insertion.yml b/eng/pipelines/common/sdk-insertion.yml
index 70b21ec58fa6..fea5695cc9ef 100644
--- a/eng/pipelines/common/sdk-insertion.yml
+++ b/eng/pipelines/common/sdk-insertion.yml
@@ -57,10 +57,11 @@ jobs:
buildNumber: $(ReleaseDropPrefix)/nugets
destinationPath: ${{ parameters.nugetArtifactPath }}
- - task: UseDotNet@2
- displayName: Install .NET 9.x
+ - task: UseDotNet@2 # https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/tool/dotnet-core-tool-installer?view=azure-devops
+ displayName: 'Use .NET SDK $(DOTNET_VERSION)'
inputs:
- version: 9.x
+ packageType: sdk
+ version: $(DOTNET_VERSION)
includePreviewVersions: true
- task: AzureCLI@2
@@ -70,13 +71,11 @@ jobs:
scriptType: ps
scriptLocation: inlineScript
inlineScript: >-
- & dotnet build $(Build.SourcesDirectory)\src\Workload\Microsoft.Maui.Sdk\Microsoft.Maui.Sdk.csproj
+ dotnet build $(Build.SourcesDirectory)\src\Workload\Microsoft.Maui.Sdk\Microsoft.Maui.Sdk.csproj
-t:PushManifestToBuildAssetRegistry
-p:OfficialBuildId=$(_BuildOfficalId)
-p:OutputPath=${{ parameters.nugetArtifactPath }}
-v:n -bl:$(Build.StagingDirectory)\binlogs\push-bar-manifest.binlog
- # Execute outside of the source directory to avoid any conflicting global.json file
- workingDirectory: $(Build.SourcesDirectory)\..
condition: and(succeeded(), eq('${{ parameters.pushMauiPackagesToMaestro }}', 'true'))
- task: AzureCLI@2
@@ -90,7 +89,5 @@ jobs:
$arcadeServicesSource = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
& dotnet tool update microsoft.dotnet.darc --version "$darcVersion" --add-source "$arcadeServicesSource" --tool-path $(Agent.ToolsDirectory)\darc -v n
& $(Agent.ToolsDirectory)\darc\darc add-build-to-channel --default-channels --id $(BARBuildId) --ci --publishing-infra-version 3 --azdev-pat $(System.AccessToken)
- # Execute outside of the source directory to avoid any conflicting global.json file
- workingDirectory: $(Build.SourcesDirectory)\..
displayName: Add build to default darc channel
condition: and(succeeded(), eq('${{ parameters.pushMauiPackagesToMaestro }}', 'true'))
diff --git a/eng/pipelines/common/ui-tests-build-sample.yml b/eng/pipelines/common/ui-tests-build-sample.yml
index 9d359ee2f87e..c133355d3e32 100644
--- a/eng/pipelines/common/ui-tests-build-sample.yml
+++ b/eng/pipelines/common/ui-tests-build-sample.yml
@@ -9,6 +9,7 @@ parameters:
agentPoolAccessToken: ''
configuration : "Release"
testFilter: ''
+ runtimeVariant: 'Mono'
steps:
- ${{ if eq(parameters.platform, 'ios')}}:
@@ -22,7 +23,8 @@ steps:
- template: provision.yml
parameters:
skipProvisioning: ${{ eq(parameters.platform, 'windows') }}
- skipAndroidSdks: ${{ ne(parameters.platform, 'android') }}
+ # FIXME: 'Build the MSBuild Tasks' step fails for net9.0-android35 without API 35
+ skipAndroidSdks: false
skipXcode: ${{ or(eq(parameters.platform, 'android'), eq(parameters.platform, 'windows')) }}
provisionatorChannel: ${{ parameters.provisionatorChannel }}
@@ -47,7 +49,7 @@ steps:
- pwsh: echo "##vso[task.prependpath]$(DotNet.Dir)"
displayName: 'Add .NET to PATH'
- - pwsh: ./build.ps1 --target=uitests-apphost --configuration="${{ parameters.configuration }}" --${{ parameters.platform }} --verbosity=diagnostic --usenuget=false
+ - pwsh: ./build.ps1 --target=uitests-apphost --configuration="${{ parameters.configuration }}" --${{ parameters.platform }} --verbosity=diagnostic --usenuget=false --runtimevariant="${{ parameters.runtimeVariant }}"
displayName: 'Build the samples'
- bash: |
@@ -58,17 +60,31 @@ steps:
continueOnError: true
- publish: $(System.DefaultWorkingDirectory)/artifacts/bin
- condition: and(ne('${{ parameters.platform }}' , 'windows'), succeeded())
+ condition: and(ne('${{ parameters.platform }}' , 'windows'), ne('${{ parameters.runtimeVariant }}' , 'NativeAOT'), succeeded())
artifact: ui-tests-samples
+
+ - publish: $(System.DefaultWorkingDirectory)/artifacts/bin
+ condition: and(ne('${{ parameters.platform }}' , 'windows'), eq('${{ parameters.runtimeVariant }}' , 'NativeAOT'), succeeded())
+ artifact: ui-tests-samples-nativeaot
- publish: $(System.DefaultWorkingDirectory)/artifacts/bin
condition: and(eq('${{ parameters.platform }}' , 'windows'), succeeded())
artifact: ui-tests-samples-windows
- publish: $(System.DefaultWorkingDirectory)/artifacts/bin
- condition: and(ne('${{ parameters.platform }}' , 'windows'), failed())
+ condition: and(ne('${{ parameters.platform }}' , 'windows'), ne('${{ parameters.runtimeVariant }}' , 'NativeAOT'), failed())
artifact: ui-tests-samples_failed_$(System.JobAttempt)
+ - publish: $(System.DefaultWorkingDirectory)/artifacts/bin
+ condition: and(ne('${{ parameters.platform }}' , 'windows'), eq('${{ parameters.runtimeVariant }}' , 'NativeAOT'), failed())
+ artifact: ui-tests-samples-nativeaot_failed_$(System.JobAttempt)
+
- publish: $(System.DefaultWorkingDirectory)/artifacts/bin
condition: and(eq('${{ parameters.platform }}' , 'windows'), failed())
- artifact: ui-tests-samples-windows_failed_$(System.JobAttempt)
\ No newline at end of file
+ artifact: ui-tests-samples-windows_failed_$(System.JobAttempt)
+
+ - task: PublishBuildArtifacts@1
+ displayName: Publish Artifacts
+ condition: always()
+ inputs:
+ artifactName: '$(Agent.JobName) (attempt $(System.JobAttempt))'
diff --git a/eng/pipelines/common/ui-tests-steps.yml b/eng/pipelines/common/ui-tests-steps.yml
index 86ab2bd5c7c3..095103432667 100644
--- a/eng/pipelines/common/ui-tests-steps.yml
+++ b/eng/pipelines/common/ui-tests-steps.yml
@@ -8,13 +8,19 @@ parameters:
provisionatorChannel: 'latest'
agentPoolAccessToken: ''
configuration : "Release"
+ runtimeVariant : "Mono"
testFilter: ''
steps:
- task: DownloadPipelineArtifact@2
- condition: ne('${{ parameters.platform }}' , 'windows')
+ condition: and(ne('${{ parameters.platform }}' , 'windows'), eq('${{ parameters.runtimeVariant }}' , 'Mono'))
inputs:
artifact: ui-tests-samples
+
+ - task: DownloadPipelineArtifact@2
+ condition: and(ne('${{ parameters.platform }}' , 'windows'), eq('${{ parameters.runtimeVariant }}' , 'NativeAOT'))
+ inputs:
+ artifact: ui-tests-samples-nativeaot
- task: DownloadPipelineArtifact@2
condition: eq('${{ parameters.platform }}' , 'windows')
@@ -84,6 +90,7 @@ steps:
- pwsh: |
$command = "./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --target=uitest --project=""${{ parameters.path }}"""
$command += " --appproject=""${{ parameters.app }}"" --device=""${{ parameters.device }}"" --apiversion=""${{ parameters.version }}"" --configuration=""${{ parameters.configuration }}"""
+ $command += " --runtimevariant=""${{ parameters.runtimeVariant }}"""
$command += " --results=""$(TestResultsDirectory)"" --binlog=""$(LogDirectory)"" ${{ parameters.cakeArgs }} --verbosity=diagnostic"
$testFilter = ""
@@ -128,4 +135,4 @@ steps:
# This must always be placed as the last step in the job
- template: agent-rebooter/mac.v1.yml@yaml-templates
parameters:
- AgentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
+ AgentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
\ No newline at end of file
diff --git a/eng/pipelines/common/ui-tests.yml b/eng/pipelines/common/ui-tests.yml
index 2cc19a42d6ac..16d1ab574bfc 100644
--- a/eng/pipelines/common/ui-tests.yml
+++ b/eng/pipelines/common/ui-tests.yml
@@ -53,6 +53,24 @@ stages:
APPIUM_HOME: $(System.DefaultWorkingDirectory)/.appium/
steps:
- template: ui-tests-build-sample.yml
+ parameters:
+ runtimeVariant: "Mono"
+
+ - stage: build_ui_tests_nativeaot
+ displayName: Build UITests Sample App NativeAOT
+ dependsOn: []
+ jobs:
+ - job: build_ui_tests
+ displayName: Build Sample App
+ pool: ${{ parameters.androidPool }}
+ variables:
+ REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
+ APPIUM_HOME: $(System.DefaultWorkingDirectory)/.appium/
+ steps:
+ - template: ui-tests-build-sample.yml
+ parameters:
+ runtimeVariant: "NativeAOT"
+ platform: ios
- stage: build_ui_tests_windows
displayName: Build UITests Windows Sample App
@@ -106,15 +124,15 @@ stages:
agentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
testFilter: $(CATEGORYGROUP)
- - stage: ios_ui_tests
- displayName: iOS UITests
+ - stage: ios_ui_tests_mono
+ displayName: iOS UITests Mono
dependsOn: build_ui_tests
jobs:
- ${{ each project in parameters.projects }}:
- ${{ if ne(project.ios, '') }}:
- ${{ each version in parameters.iosVersions }}:
- ${{ if not(containsValue(project.iosVersionsExclude, version)) }}:
- - job: ios_ui_tests_${{ project.name }}_${{ replace(version, '.', '_') }}
+ - job: ios_ui_tests_mono_${{ project.name }}_${{ replace(version, '.', '_') }}
strategy:
matrix:
${{ each categoryGroup in parameters.categoryGroupsToTest }}:
@@ -144,6 +162,49 @@ stages:
device: ios-simulator-64_${{ version }}
provisionatorChannel: ${{ parameters.provisionatorChannel }}
agentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
+ runtimeVariant : "Mono"
+ testFilter: $(CATEGORYGROUP)
+
+
+ - stage: ios_ui_tests_nativeaot
+ displayName: iOS UITests NativeAOT
+ dependsOn: build_ui_tests_nativeaot
+ jobs:
+ - ${{ each project in parameters.projects }}:
+ - ${{ if ne(project.ios, '') }}:
+ - ${{ each version in parameters.iosVersions }}:
+ - ${{ if not(containsValue(project.iosVersionsExclude, version)) }}:
+ - job: ios_ui_tests_nativeaot_${{ project.name }}_${{ replace(version, '.', '_') }}
+ strategy:
+ matrix:
+ ${{ each categoryGroup in parameters.categoryGroupsToTest }}:
+ ${{ categoryGroup }}:
+ CATEGORYGROUP: ${{ categoryGroup }}
+ timeoutInMinutes: 240 # how long to run the job before automatically cancelling
+ workspace:
+ clean: all
+ displayName: ${{ coalesce(project.desc, project.name) }} (v${{ version }})
+ pool: ${{ parameters.iosPool }}
+ variables:
+ REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
+ APPIUM_HOME: $(System.DefaultWorkingDirectory)/.appium/
+ steps:
+ - template: ui-tests-steps.yml
+ parameters:
+ platform: ios
+ ${{ if eq(version, 'latest') }}:
+ version: 17.2
+ ${{ if ne(version, 'latest') }}:
+ version: ${{ version }}
+ path: ${{ project.ios }}
+ app: ${{ project.app }}
+ ${{ if eq(version, 'latest') }}:
+ device: ios-simulator-64
+ ${{ if ne(version, 'latest') }}:
+ device: ios-simulator-64_${{ version }}
+ provisionatorChannel: ${{ parameters.provisionatorChannel }}
+ agentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
+ runtimeVariant : "NativeAOT"
testFilter: $(CATEGORYGROUP)
- stage: winui_ui_tests
diff --git a/eng/pipelines/common/variables.yml b/eng/pipelines/common/variables.yml
index 663378cf41fd..1f29c6c8278d 100644
--- a/eng/pipelines/common/variables.yml
+++ b/eng/pipelines/common/variables.yml
@@ -8,11 +8,11 @@ variables:
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: true
- name: DOTNET_VERSION
- value: 8.0.300
+ value: 9.0.100-preview.4.24267.66
- name: REQUIRED_XCODE
- value: 15.4.0
+ value: 16.0.0
- name: DEVICETESTS_REQUIRED_XCODE
- value: 15.4.0
+ value: 16.0.0
- name: LocBranchPrefix
value: 'loc-hb'
- name: isMainBranch
@@ -48,9 +48,9 @@ variables:
- name: provisionator.extraArguments
value: '-vvvv'
- name: DotNet.Dir
- value: $(System.DefaultWorkingDirectory)/bin/dotnet
+ value: $(System.DefaultWorkingDirectory)/.dotnet
- name: DotNet.Path
- value: $(System.DefaultWorkingDirectory)/bin/dotnet/dotnet
+ value: $(System.DefaultWorkingDirectory)/.dotnet/dotnet
- name: TeamName
value: Maui
- name: POWERSHELL_VERSION
@@ -58,11 +58,33 @@ variables:
- name: Codeql.Enabled
value: false
- group: Xamarin-Secrets
+
# Variable groups required for private builds
-# - ${{ if or(eq(variables['System.TeamProject'], 'DevDiv'), eq(variables['Build.DefinitionName'], 'dotnet-maui')) }}:
-# - name: PrivateBuild
-# value: true
-# # For eng/common/SetupNugetSources.ps1
-# - group: DotNetBuilds storage account read tokens
-# - group: AzureDevOps-Artifact-Feeds-Pats
+- ${{ if or(eq(variables['System.TeamProject'], 'DevDiv'), eq(variables['Build.DefinitionName'], 'dotnet-maui')) }}:
+ - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
+ - name: PrivateBuild
+ value: false
+ - name: _RunAsPublic
+ value: False
+ - name: _RunAsInternal
+ value: True
+ - name: _SignType
+ value: real
+ # - name: PostBuildSign
+ # value: true
+ # For eng/common/SetupNugetSources.ps1
+ - group: DotNetBuilds storage account read tokens
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - name: _InternalBuildArgs
+ value: /p:DotNetSignType=$(_SignType)
+ /p:TeamName=$(_TeamName)
+ /p:DotNetPublishUsingPipelines=true
+ /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
+- ${{ if eq(variables['Build.DefinitionName'], 'dotnet-maui') }}:
+ - ${{ if notin(variables['Build.Reason'], 'PullRequest') }}:
+ # Publish-Build-Assets provides: MaestroAccessToken, BotAccount-dotnet-maestro-bot-PAT
+ # DotNet-HelixApi-Access provides: HelixApiAccessToken
+ - group: Publish-Build-Assets
+ - group: DotNet-HelixApi-Access
+ - group: SDL_Settings
\ No newline at end of file
diff --git a/eng/pipelines/device-tests.yml b/eng/pipelines/device-tests.yml
index 3ecf40a1ff71..f863a35c56e8 100644
--- a/eng/pipelines/device-tests.yml
+++ b/eng/pipelines/device-tests.yml
@@ -72,17 +72,17 @@ parameters:
- name: iosPool
type: object
default:
- name: $(iosTestsVmPool)
- vmImage: $(iosTestsVmImage)
+ name: $(iosDeviceTestsVmPool)
+ vmImage: $(iosDeviceTestsVmImage)
demands:
- - macOS.Name -equals Sonoma
- - macOS.Architecture -equals x64
-
+ - Agent.OSVersion -equals 14.5
+ - Agent.OSArchitecture -equals ARM64
+
- name: catalystPool
type: object
default:
- name: $(iosTestsVmPool)
- vmImage: $(iosTestsVmImage)
+ name: $(androidTestsVmPool)
+ vmImage: $(androidTestsVmImage)
demands:
- macOS.Name -equals Sonoma
- macOS.Architecture -equals x64
@@ -93,6 +93,11 @@ parameters:
name: $(windowsTestsVmPool)
vmImage: $(windowsTestsVmImage)
+ - name: targetFrameworkVersions
+ type: object
+ default:
+ - tfm: net9.0
+
resources:
repositories:
- repository: yaml-templates
@@ -102,7 +107,7 @@ resources:
ref: refs/heads/main
stages:
-
+- ${{ each targetFrameworkVersion in parameters.targetFrameworkVersions }}:
- template: common/device-tests.yml
parameters:
androidPool: ${{ parameters.androidPool }}
@@ -110,15 +115,16 @@ stages:
catalystPool: ${{ parameters.catalystPool }}
windowsPool: ${{ parameters.windowsPool }}
agentPoolAccessToken: $(AgentPoolAccessToken)
+ targetFrameworkVersion: ${{ targetFrameworkVersion }}
${{ if or(parameters.BuildEverything, and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['System.TeamProject'], 'devdiv'))) }}:
androidApiLevels: [ 33, 30, 29, 28, 27, 26, 25, 24, 23 ]
- iosVersions: [ 'simulator-17.2']
+ iosVersions: [ 'simulator-18.0']
catalystVersions: [ 'latest' ]
windowsVersions: ['packaged', 'unpackaged']
provisionatorChannel: ${{ parameters.provisionatorChannel }}
- ${{ if not(or(parameters.BuildEverything, and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['System.TeamProject'], 'devdiv')))) }}:
+ ${{ else }}:
androidApiLevels: [ 33, 23 ]
- iosVersions: [ 'simulator-17.2' ]
+ iosVersions: [ 'simulator-18.0' ]
catalystVersions: [ 'latest' ]
windowsVersions: ['packaged', 'unpackaged']
provisionatorChannel: ${{ parameters.provisionatorChannel }}
@@ -126,6 +132,7 @@ stages:
- name: essentials
desc: Essentials
androidApiLevelsExclude: [25] # Ignore for now API25 since the runs's are not stable
+ androidConfiguration: 'Release'
windowsPackageId: 'com.microsoft.maui.essentials.devicetests'
android: $(System.DefaultWorkingDirectory)/src/Essentials/test/DeviceTests/Essentials.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/Essentials/test/DeviceTests/Essentials.DeviceTests.csproj
@@ -134,6 +141,7 @@ stages:
- name: graphics
desc: Graphics
androidApiLevelsExclude: [25] # Ignore for now API25 since the runs's are not stable
+ androidConfiguration: 'Release'
windowsPackageId: 'com.microsoft.maui.graphics.devicetests'
android: $(System.DefaultWorkingDirectory)/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/Graphics/tests/DeviceTests/Graphics.DeviceTests.csproj
@@ -142,6 +150,7 @@ stages:
- name: core
desc: Core
androidApiLevelsExclude: [25] # Ignore for now API25 since the runs's are not stable
+ androidConfiguration: 'Release'
windowsPackageId: 'com.microsoft.maui.core.devicetests'
android: $(System.DefaultWorkingDirectory)/src/Core/tests/DeviceTests/Core.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/Core/tests/DeviceTests/Core.DeviceTests.csproj
@@ -150,6 +159,7 @@ stages:
- name: controls
desc: Controls
androidApiLevelsExclude: [27, 25] # Ignore for now API25 since the runs's are not stable
+ androidConfiguration: 'Debug'
windowsPackageId: 'com.microsoft.maui.controls.devicetests'
android: $(System.DefaultWorkingDirectory)/src/Controls/tests/DeviceTests/Controls.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/Controls/tests/DeviceTests/Controls.DeviceTests.csproj
@@ -157,7 +167,8 @@ stages:
windows: $(System.DefaultWorkingDirectory)/src/Controls/tests/DeviceTests/Controls.DeviceTests.csproj
- name: blazorwebview
desc: BlazorWebView
- androidApiLevelsExclude: [ 27, 26, 25, 24, 23, 22, 21 ] # BlazorWebView requires a recent version of Chrome
+ androidApiLevelsExclude: [ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21 ] # BlazorWebView requires a recent version of Chrome
+ androidConfiguration: 'Release'
windowsPackageId: 'Microsoft.Maui.MauiBlazorWebView.DeviceTests'
android: $(System.DefaultWorkingDirectory)/src/BlazorWebView/tests/MauiDeviceTests/MauiBlazorWebView.DeviceTests.csproj
ios: $(System.DefaultWorkingDirectory)/src/BlazorWebView/tests/MauiDeviceTests/MauiBlazorWebView.DeviceTests.csproj
diff --git a/eng/pipelines/handlers.yml b/eng/pipelines/handlers.yml
index 6a804080dedf..ad1740cba0e3 100644
--- a/eng/pipelines/handlers.yml
+++ b/eng/pipelines/handlers.yml
@@ -29,6 +29,7 @@ pr:
- release/*
- net9.0
- net8.0
+ - net9.0
paths:
include:
- '*'
@@ -87,7 +88,7 @@ parameters:
vmImage: $(macOSXVmImage)
artifact: nuget-macos
- - name: BuilTemplatePlatforms
+ - name: BuildTemplatePlatforms
type: object
default:
- name: Windows
@@ -122,8 +123,8 @@ parameters:
default:
- name: default
tfm: default
- - name: net8
- tfm: net8.0
+ - name: net9
+ tfm: net9.0
resources:
repositories:
@@ -166,6 +167,9 @@ stages:
parameters:
poolName: ${{ BuildPlatform.poolName }}
gitHubToken: $(github--pat--vs-mobiletools-engineering-service2)
+ skipAndroidSdks: true
+ skipAndroidImages: true
+ installDefaultAndroidApi: false
- pwsh: ./build.ps1 --target=dotnet --configuration="${{ BuildConfiguration }}" --verbosity=diagnostic
displayName: 'Install .NET'
retryCountOnTaskFailure: 3
@@ -233,7 +237,9 @@ stages:
checkoutDirectory: '$(System.DefaultWorkingDirectory)'
provisionatorChannel: ${{ parameters.provisionatorChannel }}
gitHubToken: $(github--pat--vs-mobiletools-engineering-service2)
+ skipAndroidSdks: true
skipAndroidImages: true
+ installDefaultAndroidApi: true
- stage: samples_net
displayName: Test .NET MAUI Samples
@@ -255,6 +261,9 @@ stages:
- template: common/provision.yml
parameters:
poolName: ${{ BuildPlatform.poolName }}
+ skipAndroidSdks: true
+ skipAndroidImages: true
+ installDefaultAndroidApi: true
- task: DownloadBuildArtifacts@0
displayName: 'Download Packages'
@@ -272,7 +281,7 @@ stages:
PRIVATE_BUILD: $(PrivateBuild)
- pwsh: ./build.ps1 --target=dotnet-integration-build --verbosity=diagnostic
displayName: Build Microsoft.Maui.IntegrationTests
- - pwsh: ./build.ps1 --target=dotnet-integration-test --filter="FullyQualifiedName=Microsoft.Maui.IntegrationTests.SampleTests" --resultsfilename="integration-samples" --verbosity=diagnostic
+ - pwsh: ./build.ps1 --target=dotnet-integration-test --filter="Category=Samples" --resultsfilename="integration-samples" --verbosity=diagnostic
displayName: Run ${{ BuildPlatform.name }} sample build tests
- task: PublishTestResults@2
displayName: Publish the ${{ BuildPlatform.name }} sample build tests
@@ -281,6 +290,11 @@ stages:
testRunner: VSTest
testResultsFiles: '$(build.artifactstagingdirectory)/**/*.trx'
testRunTitle: ${{ BuildPlatform.name }} sample build tests
+ - task: PublishBuildArtifacts@1
+ condition: always()
+ displayName: publish artifacts
+ inputs:
+ ArtifactName: build_net_${{ BuildPlatform.name }}_samples
- stage: templates_net
displayName: Test Templates
@@ -289,7 +303,7 @@ stages:
- template: common/maui-templates.yml
parameters:
RunPlatforms: ${{ parameters.RunTemplatePlatforms }}
- BuildPlatforms: ${{ parameters.BuilTemplatePlatforms }}
+ BuildPlatforms: ${{ parameters.BuildTemplatePlatforms }}
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
- template: common/localization-handoff.yml # Process outgoing strings [Localization Handoff]
diff --git a/eng/pipelines/maui-release-internal.yml b/eng/pipelines/maui-release-internal.yml
index 0c4dd4e3883b..246a45c62ecb 100644
--- a/eng/pipelines/maui-release-internal.yml
+++ b/eng/pipelines/maui-release-internal.yml
@@ -2,6 +2,7 @@ trigger:
branches:
include:
- main
+ - net9.0
- release/*
tags:
include:
@@ -30,11 +31,11 @@ schedules:
variables:
- template: /eng/pipelines/common/variables.yml@self
+ - template: /eng/common/templates-official/variables/pool-providers.yml@self
+
- group: DotNetBuilds storage account read tokens
- group: AzureDevOps-Artifact-Feeds-Pats
- - name: _InternalRuntimeDownloadArgs
- value: /p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal
- /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64)
+
# needed for darc (dependency flow) publishing
- name: _BuildConfig
value: Release
@@ -44,18 +45,38 @@ variables:
value: $(Build.Arcade.ArtifactsPath)log/$(_BuildConfig)/
- name: Build.Arcade.TestResultsPath
value: $(Build.Arcade.ArtifactsPath)TestResults/$(_BuildConfig)/
- - name: _PublishArgs
- value: >-
- /p:DotNetPublishUsingPipelines=true
- - name: _OfficialBuildIdArgs
- value: /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
- # needed for signing
- - name: _SignType
- value: real
- - name: _SignArgs
- value: /p:DotNetSignType=$(_SignType) /p:TeamName=$(_TeamName) /p:Sign=$(_Sign)
- - name: _Sign
- value: true
+
+ # Produce test-signed build for PR and Public builds
+ - ${{ if or(eq(variables['_RunAsPublic'], 'true'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ # needed for darc (dependency flow) publishing
+ - name: _PublishArgs
+ value: ''
+ - name: _OfficialBuildIdArgs
+ value: ''
+ # needed for signing
+ - name: _SignType
+ value: test
+ - name: _SignArgs
+ value: ''
+ - name: _Sign
+ value: false
+
+ # Set up non-PR build from internal project
+ - ${{ if and(ne(variables['_RunAsPublic'], 'true'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ # needed for darc (dependency flow) publishing
+ - name: _PublishArgs
+ value: >-
+ /p:DotNetPublishUsingPipelines=true
+ # - name: _OfficialBuildIdArgs
+ # value: /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
+ # needed for signing
+ - name: _SignType
+ value: real
+ - name: _SignArgs
+ value: /p:DotNetSignType=$(_SignType) /p:TeamName=$(TeamName) /p:Sign=$(_Sign) /p:DotNetPublishUsingPipelines=true
+ - name: _Sign
+ value: true
+
parameters:
- name: pushMauiPackagesToMaestro
@@ -116,115 +137,98 @@ extends:
suppression:
suppressionFile: $(Build.SourcesDirectory)\eng\automation\guardian\source.gdnsuppress
stages:
- - stage: pack_net
+ - stage: Pack
displayName: Pack .NET MAUI
dependsOn: []
jobs:
- template: /eng/common/templates-official/jobs/jobs.yml@self
parameters:
+ enableMicrobuild: true
helixRepo: dotnet/maui
pool: ${{ parameters.VM_IMAGE_HOST }}
enablePublishUsingPipelines: true
enablePublishBuildAssets: true
enableTelemetry: true
+ enableSourceBuild: false
enableSourceIndex: false
- # Publish build logs
+ publishAssetsImmediately: true
+ # Publish build logs
enablePublishBuildArtifacts: true
# Publish test logs
- enablePublishTestResults: false
+ enablePublishTestResults: true
workspace:
clean: all
jobs:
- job: pack_net_${{ parameters.PackPlatform.name }}
displayName: ${{ parameters.PackPlatform.name }}
+
timeoutInMinutes: 240
- templateContext:
- outputs:
- - output: pipelineArtifact
- displayName: 'Publish the ${{ parameters.PackPlatform.artifact }} artifacts'
- artifactName: ${{ parameters.PackPlatform.artifact }}
- targetPath: '${{ parameters.PackPlatform.artifactsPath }}/nuget'
+ # templateContext:
+ # outputs:
+ # - output: pipelineArtifact
+ # displayName: 'Publish the ${{ parameters.PackPlatform.artifact }} artifacts'
+ # artifactName: ${{ parameters.PackPlatform.artifact }}
+ # targetPath: '${{ parameters.PackPlatform.artifactsPath }}/nuget'
- - output: pipelineArtifact
- displayName: 'Publish the ${{ parameters.PackPlatform.binariesArtifact }} artifacts'
- artifactName: ${{ parameters.PackPlatform.binariesArtifact }}
- targetPath: '$(System.DefaultWorkingDirectory)/artifacts/binaries'
-
- - output: pipelineArtifact
- displayName: 'Publish the ${{ parameters.PackPlatform.docsArtifact }} artifacts'
- artifactName: ${{ parameters.PackPlatform.docsArtifact }}
- targetPath: '$(System.DefaultWorkingDirectory)/artifacts/docs-packs'
-
- - output: pipelineArtifact
- displayName: 'Publish the ${{ parameters.PackPlatform.metadataArtifact }} artifacts'
- artifactName: ${{ parameters.PackPlatform.metadataArtifact }}
- targetPath: '${{ parameters.PackPlatform.artifactsPath }}/metadata'
-
- - output: pipelineArtifact
- displayName: 'Publish the ${{ parameters.PackPlatform.logsArtifact }} artifacts'
- artifactName: ${{ parameters.PackPlatform.logsArtifact }}
- targetPath: '${{ parameters.PackPlatform.artifactsPath }}/logs'
+ # - output: pipelineArtifact
+ # displayName: 'Publish the ${{ parameters.PackPlatform.binariesArtifact }} artifacts'
+ # artifactName: ${{ parameters.PackPlatform.binariesArtifact }}
+ # targetPath: '$(System.DefaultWorkingDirectory)/artifacts/binaries'
+
+ # - output: pipelineArtifact
+ # displayName: 'Publish the ${{ parameters.PackPlatform.docsArtifact }} artifacts'
+ # artifactName: ${{ parameters.PackPlatform.docsArtifact }}
+ # targetPath: '$(System.DefaultWorkingDirectory)/artifacts/docs-packs'
+
+ # - output: pipelineArtifact
+ # displayName: 'Publish the ${{ parameters.PackPlatform.metadataArtifact }} artifacts'
+ # artifactName: ${{ parameters.PackPlatform.metadataArtifact }}
+ # targetPath: '${{ parameters.PackPlatform.artifactsPath }}/metadata'
+
+ # - output: pipelineArtifact
+ # displayName: 'Publish the ${{ parameters.PackPlatform.logsArtifact }} artifacts'
+ # artifactName: ${{ parameters.PackPlatform.logsArtifact }}
+ # targetPath: '${{ parameters.PackPlatform.artifactsPath }}/logs'
variables:
- name: _buildScript
value: $(Build.SourcesDirectory)/build.cmd -ci
- - name: _BuildConfig
- value: Release
- name: _BuildOfficalId
value: $[ format('{0}.{1}', format('{0:yyyyMMdd}', pipeline.startTime), counter(format('{0:yyyyMMdd}', pipeline.startTime), 1) )]
-
+ - name: TreatWarningsAsErrors
+ value: false
+ - name: _OfficialBuildIdArgs
+ value: /p:OfficialBuildId=$(_BuildOfficalId) /p:_SkipUpdateBuildNumber=true
+
preSteps:
- checkout: self
fetchDepth: 1
clean: true
steps:
- - template: /eng/pipelines/common/pack.yml@self
+ - template: /eng/pipelines/common/build-test-pack.yml@self
parameters:
- publishArtifacts: false
- platform: ${{ parameters.PackPlatform.name }}
- provisionatorChannel: ${{ parameters.provisionatorChannel }}
- artifact: ${{ parameters.PackPlatform.artifact }}
- artifactBinaries: ${{ parameters.PackPlatform.binariesArtifact }}
- artifactsPath: ${{ parameters.PackPlatform.artifactsPath }}
- buildConfiguration: $(_BuildConfig)
dotnetScript: $(Build.SourcesDirectory)/dotnet.cmd
buildScript: $(_buildScript)
+ buildConfig: $(_BuildConfig)
repoArtifactsPath: $(Build.Arcade.ArtifactsPath)
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
- officialBuildId: $(_BuildOfficalId)
- # prepareSteps:
- # - template: /eng/pipelines/common/provision.yml@self
- # parameters:
- # checkoutDirectory: '$(System.DefaultWorkingDirectory)'
- # provisionatorChannel: ${{ parameters.provisionatorChannel }}
- # gitHubToken: $(github--pat--vs-mobiletools-engineering-service2)
- # skipAndroidImages: true
-
- # - task: DotNetCoreCLI@2
- # displayName: Generate and publish BAR manifest
- # inputs:
- # projects: $(Build.SourcesDirectory)\src\Workload\Microsoft.Maui.Sdk\Microsoft.Maui.Sdk.csproj
- # arguments: >-
- # -t:PushManifestToBuildAssetRegistry
- # -p:BuildAssetRegistryToken=$(MaestroAccessToken)
- # -p:OutputPath=$(Build.StagingDirectory)\nuget\
- # -v:n -bl:$(Build.StagingDirectory)\binlogs\push-bar-manifest.binlog
- # condition: and(succeeded(), eq('${{ parameters.pushMauiPackagesToMaestro }}', 'true'))
-
- # - powershell: |
- # $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16'
- # $darcVersion = $(Invoke-WebRequest -Uri $versionEndpoint -UseBasicParsing).Content
- # $arcadeServicesSource = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
- # & dotnet tool update microsoft.dotnet.darc --version "$darcVersion" --add-source "$arcadeServicesSource" --tool-path $(Agent.ToolsDirectory)\darc -v n
- # & $(Agent.ToolsDirectory)\darc\darc add-build-to-channel --default-channels --id $(BARBuildId) --publishing-infra-version 3 --skip-assets-publishing --password $(MaestroAccessToken) --azdev-pat $(publishing-dnceng-devdiv-code-r-build-re)
+ isWindows: true
# Publish and validation steps. Only run in official builds
- template: /eng/common/templates-official/post-build/post-build.yml@self
parameters:
publishingInfraVersion: 3
+ enableSymbolValidation: true
+ enableSigningValidation: true
+ # Disable for now as we test the new signing process
+ enableSourceLinkValidation: false
validateDependsOn:
- - pack_net
- enableSourceLinkValidation: true
\ No newline at end of file
+ - Pack
+ publishDependsOn:
+ - Validate
+ # This is to enable SDL runs part of Post-Build Validation Stage
+ SDLValidationParameters:
+ enable: false
\ No newline at end of file
diff --git a/eng/pipelines/maui-release.yml b/eng/pipelines/maui-release.yml
index 962a9ce682f6..c25664848a36 100644
--- a/eng/pipelines/maui-release.yml
+++ b/eng/pipelines/maui-release.yml
@@ -2,6 +2,7 @@ trigger:
branches:
include:
- main
+ - net9.0
- release/*
tags:
include:
@@ -26,7 +27,6 @@ schedules:
branches:
include:
- main
- - net9.0
variables:
- template: /eng/pipelines/common/variables.yml@self
@@ -171,6 +171,8 @@ extends:
provisionatorChannel: ${{ parameters.provisionatorChannel }}
gitHubToken: $(github--pat--vs-mobiletools-engineering-service2)
skipAndroidImages: true
+ skipAndroidSdks: true
+ installDefaultAndroidApi: true
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}: # Sign only using the private server
- template: /eng/pipelines/common/sign.yml@self
@@ -199,6 +201,7 @@ extends:
tsaUploadEnabled: true
tsaConfigFile: '$(Build.SourcesDirectory)\eng\automation\guardian\tsaoptions-v2.json'
scanArtifacts: ['${{ parameters.PackPlatform.binariesArtifact }}']
+ softwareVersion: 9.0
- ${{ if eq(variables['Build.Reason'], 'Schedule') }}:
- template: /eng/pipelines/common/push-nightly.yml@self
diff --git a/eng/pipelines/ui-tests.yml b/eng/pipelines/ui-tests.yml
index d6ea2bd6b565..d6d44bc4be41 100644
--- a/eng/pipelines/ui-tests.yml
+++ b/eng/pipelines/ui-tests.yml
@@ -130,11 +130,11 @@ stages:
agentPoolAccessToken: $(AgentPoolAccessToken)
${{ if or(parameters.BuildEverything, and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['System.TeamProject'], 'devdiv'))) }}:
androidApiLevels: [ 30 ]
- iosVersions: [ '17.2' ]
+ iosVersions: [ '18.0' ]
provisionatorChannel: ${{ parameters.provisionatorChannel }}
${{ if not(or(parameters.BuildEverything, and(ne(variables['Build.Reason'], 'PullRequest'), eq(variables['System.TeamProject'], 'devdiv')))) }}:
androidApiLevels: [ 30 ]
- iosVersions: [ '17.2' ]
+ iosVersions: [ '18.0' ]
provisionatorChannel: ${{ parameters.provisionatorChannel }}
${{ if parameters.CompatibilityTests }}:
runCompatibilityTests: true
diff --git a/eng/provisioning/provisioning.csx b/eng/provisioning/provisioning.csx
index 1e753b9fb5aa..565ecc5adfda 100644
--- a/eng/provisioning/provisioning.csx
+++ b/eng/provisioning/provisioning.csx
@@ -1,7 +1,7 @@
if (IsMac)
{
ForceJavaCleanup();
- MicrosoftOpenJdk ("11.0.13.8.1");
+ MicrosoftOpenJdk ("17.0.12");
//this is needed for tools on macos like for nuget pack additional target and for classic xamarin projects
Item("https://download.mono-project.com/archive/6.12.0/macos-10-universal/MonoFramework-MDK-6.12.0.206.macos10.xamarin.universal.pkg");
@@ -15,11 +15,15 @@ string ANDROID_API_SDKS = Environment.GetEnvironmentVariable ("ANDROID_API_SDKS"
string SKIP_ANDROID_API_SDKS = Environment.GetEnvironmentVariable ("SKIP_ANDROID_API_SDKS");
string SKIP_ANDROID_API_IMAGES = Environment.GetEnvironmentVariable ("SKIP_ANDROID_API_IMAGES");
+string INSTALL_DEFAULT_ANDROID_API = Environment.GetEnvironmentVariable ("INSTALL_DEFAULT_ANDROID_API");
+
Console.WriteLine($"LOGGING:");
Console.WriteLine($"ANDROID_API_SDKS: {ANDROID_API_SDKS}");
Console.WriteLine($"SKIP_ANDROID_API_SDKS: {SKIP_ANDROID_API_SDKS}");
Console.WriteLine($"SKIP_ANDROID_API_IMAGES: {SKIP_ANDROID_API_IMAGES}");
+Console.WriteLine($"INSTALL_DEFAULT_ANDROID_API: {INSTALL_DEFAULT_ANDROID_API}");
+
if(String.IsNullOrWhiteSpace(ANDROID_API_SDKS) && String.IsNullOrWhiteSpace(SKIP_ANDROID_API_SDKS))
{
AndroidSdk()
@@ -34,7 +38,8 @@ if(String.IsNullOrWhiteSpace(ANDROID_API_SDKS) && String.IsNullOrWhiteSpace(SKIP
.ApiLevel((AndroidApiLevel)31)
.ApiLevel((AndroidApiLevel)32)
.ApiLevel((AndroidApiLevel)33)
- .ApiLevel((AndroidApiLevel)34);
+ .ApiLevel((AndroidApiLevel)34)
+ .ApiLevel((AndroidApiLevel)35);
if(string.IsNullOrWhiteSpace(SKIP_ANDROID_API_IMAGES))
{
@@ -70,9 +75,15 @@ if(String.IsNullOrWhiteSpace(ANDROID_API_SDKS) && String.IsNullOrWhiteSpace(SKIP
}
}
- AndroidSdk().SdkManagerPackage ("build-tools;33.0.0");
+ AndroidSdk().SdkManagerPackage ("build-tools;35.0.0");
}
+if(!string.IsNullOrEmpty(INSTALL_DEFAULT_ANDROID_API))
+{
+ AndroidSdk()
+ .ApiLevel((AndroidApiLevel)35)
+ .SdkManagerPackage ("build-tools;35.0.0");;
+}
else if(!String.IsNullOrWhiteSpace(ANDROID_API_SDKS))
{
diff --git a/global.json b/global.json
index 0efe559da047..d34c468d1c5c 100644
--- a/global.json
+++ b/global.json
@@ -1,13 +1,13 @@
{
"tools": {
- "dotnet": "9.0.100-rc.1.24452.12"
+ "dotnet": "9.0.100-rtm.24509.30"
},
"msbuild-sdks": {
"MSBuild.Sdk.Extras": "3.0.44",
"Microsoft.Build.NoTargets": "3.7.0",
- "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24310.5"
+ "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24509.3"
},
"sdk": {
- "allowPrerelease": false
+ "allowPrerelease": true
}
}
diff --git a/loc/cs/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/cs/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index bdebe13a998c..6a114998aa44 100644
--- a/loc/cs/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/cs/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..1cd08b96a732
--- /dev/null
+++ b/loc/cs/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 40cd7f5cdfcf..52919557f7dd 100644
--- a/loc/cs/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/cs/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index d62e1a505960..41b6001d9711 100644
--- a/loc/cs/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/cs/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index b6d4b054371e..647557da0809 100644
--- a/loc/cs/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/cs/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 23f8084b6d9b..e914f0a3d39a 100644
--- a/loc/cs/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/cs/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index 485babe793ef..63cfed2949ca 100644
--- a/loc/cs/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/cs/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/cs/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/cs/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 4f9c2ef2e9e0..284f7350c8c3 100644
--- a/loc/cs/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/cs/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/de/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 07eea9a3b04f..4787624f9cd8 100644
--- a/loc/de/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/de/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..19bf555da0af
--- /dev/null
+++ b/loc/de/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 5200b2f0f369..252ed6beaf91 100644
--- a/loc/de/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/de/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index 0aa0223dfdf6..d548188adec8 100644
--- a/loc/de/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/de/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 9be2a38c2299..49fefad5c302 100644
--- a/loc/de/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/de/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 6aceca0438fd..79e83f024cb3 100644
--- a/loc/de/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/de/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index fe3e9a63c188..c23b879bc81e 100644
--- a/loc/de/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/de/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/de/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/de/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 5dce31ee71af..15a0adff77bb 100644
--- a/loc/de/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/de/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/es/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 135ce54205f4..8e73ce83c34c 100644
--- a/loc/es/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/es/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..c135e88c9053
--- /dev/null
+++ b/loc/es/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 764caada0c10..705baad630f6 100644
--- a/loc/es/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/es/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index 038de6667f66..3962504cd2d4 100644
--- a/loc/es/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/es/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index bbb5192bc452..b4f5b0f19e11 100644
--- a/loc/es/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/es/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index e127029487ee..c7a6ce1cacb3 100644
--- a/loc/es/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/es/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index ae519da60cee..fd271d55e732 100644
--- a/loc/es/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/es/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/es/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/es/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index dc4d705a21bd..bcfd468122ad 100644
--- a/loc/es/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/es/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/fr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 31c104308722..eff229f027e2 100644
--- a/loc/fr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/fr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..0fdb710c89f1
--- /dev/null
+++ b/loc/fr/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 110f09be1048..60d3c8022fd0 100644
--- a/loc/fr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/fr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index dcbc49f9c9ec..d061d7c14e6c 100644
--- a/loc/fr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/fr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 65799104c4c1..222690913be4 100644
--- a/loc/fr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/fr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 6b66d110aee4..623f306c07f9 100644
--- a/loc/fr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/fr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index 0a0ffd9328a3..865c351301bf 100644
--- a/loc/fr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/fr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/fr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/fr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 70e012b7e204..d38fdcdd76fa 100644
--- a/loc/fr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/fr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/it/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 7d72c6e44055..947e21de8d3f 100644
--- a/loc/it/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/it/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..59c0f4b8e879
--- /dev/null
+++ b/loc/it/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index d82b060bb47e..a128ca1e9c82 100644
--- a/loc/it/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/it/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index 5cce1c0fde9a..42a07611305a 100644
--- a/loc/it/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/it/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index d9352d930cc3..b74297518109 100644
--- a/loc/it/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/it/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 34a1958cdfd7..c2726aa87482 100644
--- a/loc/it/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/it/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index ec2c9a7b6062..62211c454683 100644
--- a/loc/it/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/it/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/it/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/it/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 23a5abee2211..96765feb7107 100644
--- a/loc/it/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/it/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/ja/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index c1640efeb062..770f5d074bb3 100644
--- a/loc/ja/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/ja/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..2d0c2fd3bab4
--- /dev/null
+++ b/loc/ja/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index b65f1948b812..bac7c9ba1ef1 100644
--- a/loc/ja/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ja/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index fbf9ea4950bd..722a8c60bd06 100644
--- a/loc/ja/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ja/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index bc3676551184..14ba90da4f0d 100644
--- a/loc/ja/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ja/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index a5c7feccc40e..45834fc2e375 100644
--- a/loc/ja/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ja/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index fca976483332..a6268920de11 100644
--- a/loc/ja/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ja/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ja/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ja/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 48898616cdb0..2f4d47f4df23 100644
--- a/loc/ja/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ja/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/ko/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 4f54a09f93d0..e5d394953b40 100644
--- a/loc/ko/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/ko/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..560c40fcf479
--- /dev/null
+++ b/loc/ko/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 8c411dbb172f..4335403e253b 100644
--- a/loc/ko/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ko/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index efba932b4303..5f902a15ee09 100644
--- a/loc/ko/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ko/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 7c7a35823ca8..5943236f24b2 100644
--- a/loc/ko/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ko/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index afb4963b6ccc..c84020523a9c 100644
--- a/loc/ko/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ko/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index 1a7a6c107675..004bb236b257 100644
--- a/loc/ko/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ko/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ko/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ko/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 7d231b46ad21..46dd790f0734 100644
--- a/loc/ko/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ko/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/pl/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 18afd8e3d256..a9f23a58d559 100644
--- a/loc/pl/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/pl/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..57e4c0b6e874
--- /dev/null
+++ b/loc/pl/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index d675020bbac0..2f74fd8ff85e 100644
--- a/loc/pl/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pl/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index 327a1b2ca3e9..1e8cea1699aa 100644
--- a/loc/pl/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pl/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 4436126cfe78..12a0ec119096 100644
--- a/loc/pl/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pl/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index ede86bb1aa56..e7ea2425de49 100644
--- a/loc/pl/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pl/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index 424b525ab4e6..d9ed37741d52 100644
--- a/loc/pl/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pl/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pl/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/pl/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index eec8e6be5426..b80ac3d150ac 100644
--- a/loc/pl/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pl/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/pt-BR/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 32fb63bd50dd..51c9c3af62fc 100644
--- a/loc/pt-BR/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/pt-BR/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..36cbe32fd8b8
--- /dev/null
+++ b/loc/pt-BR/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 1ec51eef7064..a32b18fac49e 100644
--- a/loc/pt-BR/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pt-BR/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index ce9dfb988e5e..5743d86778b3 100644
--- a/loc/pt-BR/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pt-BR/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index a28e9a35aa97..19784cf53ced 100644
--- a/loc/pt-BR/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pt-BR/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index b2ca63417ccf..df254f39564b 100644
--- a/loc/pt-BR/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pt-BR/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index d236b4dfde0f..dd42e797c2c2 100644
--- a/loc/pt-BR/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pt-BR/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/pt-BR/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/pt-BR/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index b6bbfea39457..a754c54dc818 100644
--- a/loc/pt-BR/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/pt-BR/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/ru/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 5bb8a14f7d64..b2dd6de69de7 100644
--- a/loc/ru/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/ru/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..f5111c4dd1d9
--- /dev/null
+++ b/loc/ru/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index fd7bad8481ff..815c5a2427f0 100644
--- a/loc/ru/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ru/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index ac15532d4be2..0c2b4564f8aa 100644
--- a/loc/ru/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ru/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 266a1954a0f9..33ca41b977e1 100644
--- a/loc/ru/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ru/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 010d6db6af34..e4da66d29b84 100644
--- a/loc/ru/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ru/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index ac63f835ea5a..c57ba5b20c83 100644
--- a/loc/ru/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ru/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/ru/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/ru/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 367e78213968..2dab8e53a81a 100644
--- a/loc/ru/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/ru/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/tr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index d9bc6f8f571b..7bd53d150d2a 100644
--- a/loc/tr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/tr/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..a98c54738ebb
--- /dev/null
+++ b/loc/tr/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 8f11d9d4f358..741c02a6d1c2 100644
--- a/loc/tr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/tr/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index ae67d7f7b6ea..4a0cc21752a4 100644
--- a/loc/tr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/tr/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index d69ed7b0278e..7ce7ac08cc9e 100644
--- a/loc/tr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/tr/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index a866a55bbf12..a526c255b556 100644
--- a/loc/tr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/tr/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index ca2588dda0e0..b67e6a661bfb 100644
--- a/loc/tr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/tr/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/tr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/tr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 7c19b2c10ebc..14051446db74 100644
--- a/loc/tr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/tr/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/zh-Hans/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index 653eb1fc9f94..f85976cc2b3d 100644
--- a/loc/zh-Hans/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/zh-Hans/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..76bc2ce76ee2
--- /dev/null
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index 13b5e4a95521..189c780f0768 100644
--- a/loc/zh-Hans/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index 89996008e9ff..a340bbefbf31 100644
--- a/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 60dd7679e3e9..021759e14756 100644
--- a/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 90a70c856472..4eaabf6d2bba 100644
--- a/loc/zh-Hans/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index 0ba83fb61eb4..1cec5f796252 100644
--- a/loc/zh-Hans/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hans/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hans/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index 8537756b6ce0..36b6ad6ea62a 100644
--- a/loc/zh-Hans/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hans/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl b/loc/zh-Hant/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
index d89acaef8944..08fa1e0ebb32 100644
--- a/loc/zh-Hant/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
+++ b/loc/zh-Hant/src/Controls/src/Build.Tasks/ErrorMessages.resx.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,288 +13,375 @@
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+ true in your project file and make sure the correct x:DataType is specified for this binding. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.]]>
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
-
-
-
+
+
+
-
+
+
+
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
new file mode 100644
index 000000000000..887fd539200e
--- /dev/null
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-blazor-solution/.template.config/localize/templatestrings.json.lcl
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+ -
+
+
-
+
+
-
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
index eab593fc9b8c..ace76b3d1fcf 100644
--- a/loc/zh-Hant/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-blazor/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,45 +13,93 @@
-
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
index e5f68cb3a2f5..d514a55c5fa2 100644
--- a/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
index 7de66552db80..9068f5fe88b1 100644
--- a/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-contentpage-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
index 7743f8b99bad..53a5ff662536 100644
--- a/loc/zh-Hant/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-contentview-csharp/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
index 691c70ef4199..c6df3dfcea7b 100644
--- a/loc/zh-Hant/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-contentview-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/loc/zh-Hant/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl b/loc/zh-Hant/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
index b915e679c454..422c76195516 100644
--- a/loc/zh-Hant/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
+++ b/loc/zh-Hant/src/Templates/src/templates/maui-resourcedictionary-xaml/.template.config/localize/templatestrings.json.lcl
@@ -1,10 +1,11 @@
-
+
+
-
-
@@ -12,27 +13,48 @@
-
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/maui.code-workspace b/maui.code-workspace
index 876a1499c09d..bccea6924a3c 100644
--- a/maui.code-workspace
+++ b/maui.code-workspace
@@ -4,5 +4,9 @@
"path": "."
}
],
- "settings": {}
+ "settings": {
+ "files.associations": {
+ "*.yaml": "home-assistant"
+ }
+ }
}
\ No newline at end of file
diff --git a/src/BlazorWebView/samples/BlazorWinFormsApp/Form1.cs b/src/BlazorWebView/samples/BlazorWinFormsApp/Form1.cs
index 3f41c849e7d0..ccb8ef4bd0c2 100644
--- a/src/BlazorWebView/samples/BlazorWinFormsApp/Form1.cs
+++ b/src/BlazorWebView/samples/BlazorWinFormsApp/Form1.cs
@@ -60,10 +60,10 @@ public Form1()
private void button1_Click(object sender, EventArgs e)
{
- MessageBox.Show(
- owner: this,
- text: $"Current counter value is: {_appState.Counter}",
- caption: "Counter");
+ //MessageBox.Show(
+ // owner: this,
+ // text: $"Current counter value is: {_appState.Counter}",
+ // caption: "Counter");
}
private void _webViewActionButton_Click(object sender, EventArgs e)
@@ -100,7 +100,7 @@ private async void _useServicesButton_Click(object sender, EventArgs e)
if (!called)
{
- MessageBox.Show(this, "Couldn't call TryDispatchAsync!");
+ //s MessageBox.Show(this, "Couldn't call TryDispatchAsync!");
}
}
}
diff --git a/src/BlazorWebView/samples/MauiRazorClassLibrarySample/MauiRazorClassLibrarySample.csproj b/src/BlazorWebView/samples/MauiRazorClassLibrarySample/MauiRazorClassLibrarySample.csproj
index 24648effda0e..4f6d21573020 100644
--- a/src/BlazorWebView/samples/MauiRazorClassLibrarySample/MauiRazorClassLibrarySample.csproj
+++ b/src/BlazorWebView/samples/MauiRazorClassLibrarySample/MauiRazorClassLibrarySample.csproj
@@ -1,7 +1,8 @@
- $(_MauiDotNetTfm)
+ $(_MauiDotNetTfm)
+ $(TargetFrameworks);$(_MauiPreviousDotNetTfm)
false
diff --git a/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj b/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj
index 060a2c43cb4e..5a530b48d967 100644
--- a/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj
+++ b/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj
@@ -2,11 +2,18 @@
$(_MauiDotNetTfm);$(MauiPlatforms)
+ $(TargetFrameworks);$(_MauiPreviousDotNetTfm);$(MauiPreviousPlatforms)
enable
$(DefineConstants);WEBVIEW2_MAUI
true
+
+ true
+ true
+ true
+
+
true
diff --git a/src/BlazorWebView/src/Maui/iOS/IOSWebViewManager.cs b/src/BlazorWebView/src/Maui/iOS/IOSWebViewManager.cs
index 8576dff08f0b..527e58c2d714 100644
--- a/src/BlazorWebView/src/Maui/iOS/IOSWebViewManager.cs
+++ b/src/BlazorWebView/src/Maui/iOS/IOSWebViewManager.cs
@@ -40,8 +40,8 @@ internal class IOSWebViewManager : WebViewManager
public IOSWebViewManager(BlazorWebViewHandler blazorMauiWebViewHandler, WKWebView webview, IServiceProvider provider, Dispatcher dispatcher, IFileProvider fileProvider, JSComponentConfigurationStore jsComponents, string contentRootRelativeToAppRoot, string hostPageRelativePath, ILogger logger)
: base(provider, dispatcher, BlazorWebViewHandler.AppOriginUri, fileProvider, jsComponents, hostPageRelativePath)
{
- ArgumentNullException.ThrowIfNull(nameof(blazorMauiWebViewHandler));
- ArgumentNullException.ThrowIfNull(nameof(webview));
+ ArgumentNullException.ThrowIfNull(blazorMauiWebViewHandler);
+ ArgumentNullException.ThrowIfNull(webview);
if (provider.GetService() is null)
{
diff --git a/src/BlazorWebView/src/WindowsForms/BlazorWebView.cs b/src/BlazorWebView/src/WindowsForms/BlazorWebView.cs
index 5a54464ce022..061e96cd3857 100644
--- a/src/BlazorWebView/src/WindowsForms/BlazorWebView.cs
+++ b/src/BlazorWebView/src/WindowsForms/BlazorWebView.cs
@@ -71,6 +71,7 @@ protected override void OnCreateControl()
/// This property must be set to a valid value for the Razor components to start.
///
[Category("Behavior")]
+ [DefaultValue(null)]
[Description(@"Path to the host page within the application's static files. Example: wwwroot\index.html.")]
public string? HostPage
{
@@ -86,6 +87,7 @@ public string? HostPage
/// Path for initial Blazor navigation when the Blazor component is finished loading.
///
[Category("Behavior")]
+ [DefaultValue("/")]
[Description(@"Path for initial Blazor navigation when the Blazor component is finished loading.")]
public string StartPath { get; set; } = "/";
@@ -170,7 +172,9 @@ private void StartWebViewCoreIfPossible()
// We assume the host page is always in the root of the content directory, because it's
// unclear there's any other use case. We can add more options later if so.
string appRootDir;
+#pragma warning disable IL3000 // 'System.Reflection.Assembly.Location.get' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
var entryAssemblyLocation = Assembly.GetEntryAssembly()?.Location;
+#pragma warning restore IL3000
if (!string.IsNullOrEmpty(entryAssemblyLocation))
{
appRootDir = Path.GetDirectoryName(entryAssemblyLocation)!;
diff --git a/src/BlazorWebView/src/WindowsForms/Microsoft.AspNetCore.Components.WebView.WindowsForms.csproj b/src/BlazorWebView/src/WindowsForms/Microsoft.AspNetCore.Components.WebView.WindowsForms.csproj
index 0e8d16a7f252..3877c5eaa307 100644
--- a/src/BlazorWebView/src/WindowsForms/Microsoft.AspNetCore.Components.WebView.WindowsForms.csproj
+++ b/src/BlazorWebView/src/WindowsForms/Microsoft.AspNetCore.Components.WebView.WindowsForms.csproj
@@ -12,6 +12,12 @@
true
+
+ true
+ true
+ true
+
+
true
diff --git a/src/BlazorWebView/src/Wpf/BlazorWebView.cs b/src/BlazorWebView/src/Wpf/BlazorWebView.cs
index af673607a2de..bebcc9ce6ff5 100644
--- a/src/BlazorWebView/src/Wpf/BlazorWebView.cs
+++ b/src/BlazorWebView/src/Wpf/BlazorWebView.cs
@@ -255,7 +255,9 @@ private void StartWebViewCoreIfPossible()
// We assume the host page is always in the root of the content directory, because it's
// unclear there's any other use case. We can add more options later if so.
string appRootDir;
+#pragma warning disable IL3000 // 'System.Reflection.Assembly.Location.get' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
var entryAssemblyLocation = Assembly.GetEntryAssembly()?.Location;
+#pragma warning restore IL3000
if (!string.IsNullOrEmpty(entryAssemblyLocation))
{
appRootDir = Path.GetDirectoryName(entryAssemblyLocation)!;
diff --git a/src/BlazorWebView/src/Wpf/Microsoft.AspNetCore.Components.WebView.Wpf.csproj b/src/BlazorWebView/src/Wpf/Microsoft.AspNetCore.Components.WebView.Wpf.csproj
index 15efc75f0653..85901e18a68f 100644
--- a/src/BlazorWebView/src/Wpf/Microsoft.AspNetCore.Components.WebView.Wpf.csproj
+++ b/src/BlazorWebView/src/Wpf/Microsoft.AspNetCore.Components.WebView.Wpf.csproj
@@ -12,6 +12,12 @@
true
+
+ true
+ true
+ true
+
+
true
diff --git a/src/BlazorWebView/tests/MauiDeviceTests/MauiAppNewWindowStub.Windows.cs b/src/BlazorWebView/tests/MauiDeviceTests/MauiAppNewWindowStub.Windows.cs
index f0fb73bf4516..34ed68addcd1 100644
--- a/src/BlazorWebView/tests/MauiDeviceTests/MauiAppNewWindowStub.Windows.cs
+++ b/src/BlazorWebView/tests/MauiDeviceTests/MauiAppNewWindowStub.Windows.cs
@@ -106,6 +106,11 @@ public void OpenWindow(IWindow window)
throw new NotImplementedException();
}
+ public void ActivateWindow(IWindow window)
+ {
+ throw new NotImplementedException();
+ }
+
public void ThemeChanged()
{
throw new NotImplementedException();
diff --git a/src/Compatibility/Android.AppLinks/src/Compatibility.Android.AppLinks.csproj b/src/Compatibility/Android.AppLinks/src/Compatibility.Android.AppLinks.csproj
index 6291f18b2528..80335f991d0a 100644
--- a/src/Compatibility/Android.AppLinks/src/Compatibility.Android.AppLinks.csproj
+++ b/src/Compatibility/Android.AppLinks/src/Compatibility.Android.AppLinks.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/src/Compatibility/ControlGallery/src/Android/Compatibility.ControlGallery.Android.csproj b/src/Compatibility/ControlGallery/src/Android/Compatibility.ControlGallery.Android.csproj
index 90c11c47e82d..f4cd1dabf33c 100644
--- a/src/Compatibility/ControlGallery/src/Android/Compatibility.ControlGallery.Android.csproj
+++ b/src/Compatibility/ControlGallery/src/Android/Compatibility.ControlGallery.Android.csproj
@@ -9,7 +9,7 @@
false
disable
- IL2036;0618;0612
+ IL2036;0618;0612;CS0672;CS0618
- 0612
+ 0612;CS0672;CS0618
diff --git a/src/Compatibility/ControlGallery/src/WinUI/BrokenNativeControl.cs b/src/Compatibility/ControlGallery/src/WinUI/BrokenNativeControl.cs
index 24c4c3d50b3b..2a14186edb76 100644
--- a/src/Compatibility/ControlGallery/src/WinUI/BrokenNativeControl.cs
+++ b/src/Compatibility/ControlGallery/src/WinUI/BrokenNativeControl.cs
@@ -27,7 +27,7 @@ public BrokenNativeControl()
Background =
new Microsoft.UI.Xaml.Media.LinearGradientBrush(
- new Microsoft.UI.Xaml.Media.GradientStopCollection { new Microsoft.UI.Xaml.Media.GradientStop { Color = Colors.Green, Offset = 0.5 }, new Microsoft.UI.Xaml.Media.GradientStop { Color = Colors.Blue, Offset = 1 } }, 0);
+ new Microsoft.UI.Xaml.Media.GradientStopCollection { new Microsoft.UI.Xaml.Media.GradientStop { Color = global::Microsoft.UI.Colors.Green, Offset = 0.5 }, new Microsoft.UI.Xaml.Media.GradientStop { Color = global::Microsoft.UI.Colors.Blue, Offset = 1 } }, 0);
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
@@ -66,4 +66,4 @@ public string Text
return new global::Windows.Foundation.Size(size.Width, _textBlock.DesiredSize.Height);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Compatibility/ControlGallery/src/WinUI/Compatibility.ControlGallery.WinUI.csproj b/src/Compatibility/ControlGallery/src/WinUI/Compatibility.ControlGallery.WinUI.csproj
index 75c82319dc84..242f283cf36e 100644
--- a/src/Compatibility/ControlGallery/src/WinUI/Compatibility.ControlGallery.WinUI.csproj
+++ b/src/Compatibility/ControlGallery/src/WinUI/Compatibility.ControlGallery.WinUI.csproj
@@ -4,19 +4,23 @@
WinExe
- $(_MauiDotNetTfm)-windows10.0.19041.0
+ $(_MauiDotNetTfm)-windows$(WindowsTargetFrameworkVersion)
10.0.17134.0
Microsoft.Maui.Controls.Compatibility.ControlGallery.WinUI
app.manifest
- 1701;1702;CS8305;8305;CA1416;0612
+ 1701;1702;CS8305;8305;CA1416;0612;CS0672;CS0618
true
false
-
+ false
true
MSIX
win10-x64
+
+
+
+
@@ -32,6 +36,10 @@
+
+
+
+
@@ -103,7 +111,7 @@
-
+
diff --git a/src/Compatibility/ControlGallery/src/iOS/AppDelegate.cs b/src/Compatibility/ControlGallery/src/iOS/AppDelegate.cs
index 5a4d415ac351..f5de87919a98 100644
--- a/src/Compatibility/ControlGallery/src/iOS/AppDelegate.cs
+++ b/src/Compatibility/ControlGallery/src/iOS/AppDelegate.cs
@@ -162,7 +162,7 @@ public void StartPressed40911()
button.TouchUpInside += (sender, e) =>
{
- Maui.Controls.Application.Current.MainPage = new ContentPage { Content = new Label { Text = "40911 Success" } };
+ Maui.Controls.Application.Current.Windows[0].Page = new ContentPage { Content = new Label { Text = "40911 Success" } };
loginViewController.DismissViewController(true, null);
};
diff --git a/src/Compatibility/ControlGallery/src/iOS/Compatibility.ControlGallery.iOS.csproj b/src/Compatibility/ControlGallery/src/iOS/Compatibility.ControlGallery.iOS.csproj
index 802f11b97c5a..0e61c3c61132 100644
--- a/src/Compatibility/ControlGallery/src/iOS/Compatibility.ControlGallery.iOS.csproj
+++ b/src/Compatibility/ControlGallery/src/iOS/Compatibility.ControlGallery.iOS.csproj
@@ -9,9 +9,9 @@
disable
- 0612
- 11.0
- 11.0
+ 0612;CS0672;CS0618
+ 15.0
+ 15.0
@@ -56,4 +56,3 @@
-
diff --git a/src/Compatibility/ControlGallery/test/Android.UITests/Compatibility.ControlGallery.Android.UITests.csproj b/src/Compatibility/ControlGallery/test/Android.UITests/Compatibility.ControlGallery.Android.UITests.csproj
index 12e89688c362..509b95814821 100644
--- a/src/Compatibility/ControlGallery/test/Android.UITests/Compatibility.ControlGallery.Android.UITests.csproj
+++ b/src/Compatibility/ControlGallery/test/Android.UITests/Compatibility.ControlGallery.Android.UITests.csproj
@@ -1,4 +1,4 @@
-
+
net472
@@ -7,7 +7,7 @@
false
disable
$(DefineConstants);__ANDROID__;UITEST;__SHELL__;ANDROID
- 1701;1702;0618;0612;CA1307;CA1309
+ 1701;1702;0618;0612;CA1307;CA1309;CS0672;CS0618
true
@@ -17,6 +17,7 @@
+
diff --git a/src/Compatibility/ControlGallery/test/WinUI.UITests/WinUI.UITests.csproj b/src/Compatibility/ControlGallery/test/WinUI.UITests/WinUI.UITests.csproj
index d3f92c002a91..ec9e195bb301 100644
--- a/src/Compatibility/ControlGallery/test/WinUI.UITests/WinUI.UITests.csproj
+++ b/src/Compatibility/ControlGallery/test/WinUI.UITests/WinUI.UITests.csproj
@@ -7,7 +7,7 @@
false
disable
$(DefineConstants);WINDOWS;UITEST
- 0114;0108;4014;0649;0169;0168;0219;0618;0612;CA1307;CA1309
+ 0114;0108;4014;0649;0169;0168;0219;0618;0612;CA1307;CA1309;CS0672;CS0618
diff --git a/src/Compatibility/ControlGallery/test/iOS.UITests/Compatibility.ControlGallery.iOS.UITests.csproj b/src/Compatibility/ControlGallery/test/iOS.UITests/Compatibility.ControlGallery.iOS.UITests.csproj
index b76a900ce507..8db27a53d51c 100644
--- a/src/Compatibility/ControlGallery/test/iOS.UITests/Compatibility.ControlGallery.iOS.UITests.csproj
+++ b/src/Compatibility/ControlGallery/test/iOS.UITests/Compatibility.ControlGallery.iOS.UITests.csproj
@@ -7,7 +7,7 @@
false
disable
$(DefineConstants);__IOS__;UITEST;__SHELL__;IOS;iOS
- 1701;1702;0618;0612;CA1307;CA1309
+ 1701;1702;0618;0612;CA1307;CA1309;CS0672;CS0618
true
diff --git a/src/Compatibility/Core/src/Android/AppCompat/FormsAppCompatActivity.cs b/src/Compatibility/Core/src/Android/AppCompat/FormsAppCompatActivity.cs
index 030490cae7a5..05317f6d23de 100644
--- a/src/Compatibility/Core/src/Android/AppCompat/FormsAppCompatActivity.cs
+++ b/src/Compatibility/Core/src/Android/AppCompat/FormsAppCompatActivity.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Android.App;
@@ -101,10 +102,12 @@ public override bool OnOptionsItemSelected(IMenuItem item)
public void SetStatusBarColor(AColor color)
{
+#pragma warning disable CA1422 // Obsolete in API 35 https://developer.android.com/reference/android/view/Window#setStatusBarColor(int)
Window.SetStatusBarColor(color);
+#pragma warning restore CA1422 // Obsolete in API 35
}
- static void RegisterHandler(Type target, Type handler, Type filter)
+ static void RegisterHandler(Type target, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type handler, Type filter)
{
Profile.FrameBegin();
@@ -459,7 +462,7 @@ void OnStateChanged()
}
// This is currently being used by the previewer please do not change or remove this
- void RegisterHandlerForDefaultRenderer(Type target, Type handler, Type filter)
+ void RegisterHandlerForDefaultRenderer(Type target, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type handler, Type filter)
{
RegisterHandler(target, handler, filter);
}
diff --git a/src/Compatibility/Core/src/Android/AppCompat/FormsFragmentPagerAdapter.cs b/src/Compatibility/Core/src/Android/AppCompat/FormsFragmentPagerAdapter.cs
index 992b18c70a8c..3d94df67b881 100644
--- a/src/Compatibility/Core/src/Android/AppCompat/FormsFragmentPagerAdapter.cs
+++ b/src/Compatibility/Core/src/Android/AppCompat/FormsFragmentPagerAdapter.cs
@@ -12,7 +12,11 @@
namespace Microsoft.Maui.Controls.Compatibility.Platform.Android.AppCompat
{
[System.Obsolete]
- internal class FormsFragmentPagerAdapter<[DynamicallyAccessedMembers(BindableProperty.DeclaringTypeMembers)] T> : FragmentPagerAdapter where T : Page
+ internal class FormsFragmentPagerAdapter<[DynamicallyAccessedMembers(BindableProperty.DeclaringTypeMembers
+ #if NET8_0 // IL2091
+ | BindableProperty.ReturnTypeMembers
+ #endif
+ )] T> : FragmentPagerAdapter where T : Page
{
MultiPage _page;
FragmentManager _fragmentManager;
diff --git a/src/Compatibility/Core/src/Android/AppCompat/Platform.cs b/src/Compatibility/Core/src/Android/AppCompat/Platform.cs
index 9705ebbf6a47..d738a737eee4 100644
--- a/src/Compatibility/Core/src/Android/AppCompat/Platform.cs
+++ b/src/Compatibility/Core/src/Android/AppCompat/Platform.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Android.Content;
@@ -16,6 +17,7 @@
namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
{
[Obsolete]
+ [TypeConverter(typeof(PlatformTypeConverter))]
public class Platform : BindableObject, IPlatformLayout, INavigation
{
readonly Context _context;
@@ -720,6 +722,20 @@ public static implicit operator ViewGroup(Platform canvas)
#endregion
+ private sealed class PlatformTypeConverter : TypeConverter
+ {
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) => destinationType == typeof(ViewGroup);
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ => value switch
+ {
+ Platform platformValue when destinationType == typeof(ViewGroup) => (ViewGroup)platformValue,
+ _ => throw new NotSupportedException(),
+ };
+
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) => false;
+ public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) => throw new NotSupportedException();
+ }
+
#pragma warning disable CS0618 // Type or member is obsolete
internal class DefaultRenderer : VisualElementRenderer, ILayoutChanges
#pragma warning restore CS0618 // Type or member is obsolete
diff --git a/src/Compatibility/Core/src/Android/ButtonLayoutManager.cs b/src/Compatibility/Core/src/Android/ButtonLayoutManager.cs
index 48871171dcea..caeefa454d2a 100644
--- a/src/Compatibility/Core/src/Android/ButtonLayoutManager.cs
+++ b/src/Compatibility/Core/src/Android/ButtonLayoutManager.cs
@@ -154,12 +154,16 @@ public void OnLayout(bool changed, int left, int top, int right, int bottom)
var measuredTextWidth = view.Paint.MeasureText(buttonText, 0, buttonText.Length());
var textWidth = Math.Min((int)measuredTextWidth, view.Layout.Width);
+#pragma warning disable CS0618 // Obsolete
var contentsWidth = ViewCompat.GetPaddingStart(view) + iconWidth + view.CompoundDrawablePadding + textWidth + ViewCompat.GetPaddingEnd(view);
+#pragma warning restore CS0618 // Obsolete
var newLeft = (view.MeasuredWidth - contentsWidth) / 2;
if (_element.ContentLayout.Position == Button.ButtonContentLayout.ImagePosition.Right)
newLeft = -newLeft;
+#pragma warning disable CS0618 // Obsolete
if (ViewCompat.GetLayoutDirection(view) == ViewCompat.LayoutDirectionRtl)
+#pragma warning restore CS0618 // Obsolete
newLeft = -newLeft;
_drawableBounds.Set(newLeft, _drawableBounds.Top, newLeft + iconWidth, _drawableBounds.Bottom);
diff --git a/src/Compatibility/Core/src/Android/Extensions/NativeBindingExtensions.cs b/src/Compatibility/Core/src/Android/Extensions/NativeBindingExtensions.cs
index 1cce4eff3e42..54dca7b49c2f 100644
--- a/src/Compatibility/Core/src/Android/Extensions/NativeBindingExtensions.cs
+++ b/src/Compatibility/Core/src/Android/Extensions/NativeBindingExtensions.cs
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Microsoft.Maui.Controls.Internals;
namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
{
public static class NativeBindingExtensions
{
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public static void SetBinding(this global::Android.Views.View view, string propertyName, BindingBase binding, string updateSourceEventName = null)
{
PlatformBindingHelpers.SetBinding(view, propertyName, binding, updateSourceEventName);
diff --git a/src/Compatibility/Core/src/Android/FastRenderers/ImageElementManager.cs b/src/Compatibility/Core/src/Android/FastRenderers/ImageElementManager.cs
index fc77f7c38a40..15ae12b64739 100644
--- a/src/Compatibility/Core/src/Android/FastRenderers/ImageElementManager.cs
+++ b/src/Compatibility/Core/src/Android/FastRenderers/ImageElementManager.cs
@@ -25,7 +25,10 @@ public static void Init(IVisualElementRenderer renderer)
static void OnLayoutChange(object sender, global::Android.Views.View.LayoutChangeEventArgs e)
{
if (sender is IVisualElementRenderer renderer && renderer.View is ImageView imageView)
+#pragma warning disable CS0618 // Obsolete
AViewCompat.SetClipBounds(imageView, imageView.GetScaleType() == AScaleType.CenterCrop ? new ARect(0, 0, e.Right - e.Left, e.Bottom - e.Top) : null);
+#pragma warning restore CS0618 // Obsolete
+
}
public static void Dispose(IVisualElementRenderer renderer)
diff --git a/src/Compatibility/Core/src/Android/HandlerToRendererShim.cs b/src/Compatibility/Core/src/Android/HandlerToRendererShim.cs
index ef0285104148..8914227dc165 100644
--- a/src/Compatibility/Core/src/Android/HandlerToRendererShim.cs
+++ b/src/Compatibility/Core/src/Android/HandlerToRendererShim.cs
@@ -82,10 +82,14 @@ public void SetLabelFor(int? id)
{
if (_defaultLabelFor == null)
{
+#pragma warning disable CS0618 // Obsolete
_defaultLabelFor = ViewCompat.GetLabelFor(View);
+#pragma warning restore CS0618 // Obsolete
}
+#pragma warning disable CS0618 // Obsolete
ViewCompat.SetLabelFor(View, (int)(id ?? _defaultLabelFor));
+#pragma warning restore CS0618 // Obsolete
}
public void UpdateLayout()
diff --git a/src/Compatibility/Core/src/Android/NativeBindingservice.cs b/src/Compatibility/Core/src/Android/NativeBindingservice.cs
index 5b7b9fad8b10..5fa34009a928 100644
--- a/src/Compatibility/Core/src/Android/NativeBindingservice.cs
+++ b/src/Compatibility/Core/src/Android/NativeBindingservice.cs
@@ -9,7 +9,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Android
{
class NativeBindingService : INativeBindingService
{
- [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = TrimmerConstants.NativeBindingService)]
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public bool TrySetBinding(object target, string propertyName, BindingBase binding)
{
var view = target as AView;
diff --git a/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs b/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs
index 738b7da01ee7..8336909f2134 100644
--- a/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs
+++ b/src/Compatibility/Core/src/Android/Renderers/ListViewAdapter.cs
@@ -736,7 +736,9 @@ Cell GetNewGroupHeaderCell(ITemplatedItemsList group)
else
{
groupHeaderCell = new TextCell();
- groupHeaderCell.SetBinding(TextCell.TextProperty, nameof(group.Name));
+ groupHeaderCell.SetBinding(
+ TextCell.TextProperty,
+ static (ITemplatedItemsList g) => g.Name);
groupHeaderCell.BindingContext = group;
}
diff --git a/src/Compatibility/Core/src/Android/Shapes/ShapeRenderer.cs b/src/Compatibility/Core/src/Android/Shapes/ShapeRenderer.cs
index 22e26a639359..5bff243e9df8 100644
--- a/src/Compatibility/Core/src/Android/Shapes/ShapeRenderer.cs
+++ b/src/Compatibility/Core/src/Android/Shapes/ShapeRenderer.cs
@@ -423,7 +423,9 @@ protected void UpdatePathShape()
_drawable.Paint.StrokeWidth = 0.01f;
_drawable.Paint.SetStyle(Paint.Style.Stroke);
_drawable.Paint.GetFillPath(_path, fillPath);
+#pragma warning disable CA1422 // Obsolete in API 35 https://developer.android.com/reference/android/graphics/Path#computeBounds(android.graphics.RectF,%20boolean)
fillPath.ComputeBounds(_pathFillBounds, false);
+#pragma warning restore CA1422
_drawable.Paint.StrokeWidth = _strokeWidth;
}
}
@@ -480,7 +482,9 @@ void UpdatePathStrokeBounds()
{
_drawable.Paint.SetStyle(Paint.Style.Stroke);
_drawable.Paint.GetFillPath(_path, strokePath);
+#pragma warning disable CA1422 // Obsolete in API 35 https://developer.android.com/reference/android/graphics/Path#computeBounds(android.graphics.RectF,%20boolean)
strokePath.ComputeBounds(_pathStrokeBounds, false);
+#pragma warning restore CA1422 // Obsolete in API 35
}
}
else
diff --git a/src/Compatibility/Core/src/Compatibility.csproj b/src/Compatibility/Core/src/Compatibility.csproj
index bdec21c355e0..87c2bf3b13fb 100644
--- a/src/Compatibility/Core/src/Compatibility.csproj
+++ b/src/Compatibility/Core/src/Compatibility.csproj
@@ -1,6 +1,7 @@
netstandard2.1;netstandard2.0;$(_MauiDotNetTfm);$(MauiPlatforms)
+ $(TargetFrameworks);$(_MauiPreviousDotNetTfm);$(MauiPreviousPlatforms)
Microsoft.Maui.Controls.Compatibility
Microsoft.Maui.Controls.Compatibility
disable
@@ -8,15 +9,15 @@
iOS\
Windows\
Tizen\
- true
+ true
true
true
- $(NoWarn);CS1591
+ $(NoWarn);CS1591;CS0672;CS0618
$(DefineConstants);COMPATIBILITY
- $(NoWarn);CA1416;CS8305
+ $(NoWarn);CA1416;CS8305;IL2059
$(DefineConstants);WINDOWS
@@ -49,7 +50,16 @@
Windows\BootstrapHelper.cs
-
+
+ $(InterceptorsPreviewNamespaces);Microsoft.Maui.Controls.Generated
+
+ $(CompilerResponseFile);WorkaroundXamlPreCompilePreviewFeatures.rsp
+
+
+
diff --git a/src/Compatibility/Core/src/ExportRendererAttribute.cs b/src/Compatibility/Core/src/ExportRendererAttribute.cs
index 212130be8af0..acb5f89d160d 100644
--- a/src/Compatibility/Core/src/ExportRendererAttribute.cs
+++ b/src/Compatibility/Core/src/ExportRendererAttribute.cs
@@ -1,15 +1,16 @@
using System;
+using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Maui.Controls.Compatibility
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportRendererAttribute : HandlerAttribute
{
- public ExportRendererAttribute(Type handler, Type target) : this(handler, target, null)
+ public ExportRendererAttribute(Type handler, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type target) : this(handler, target, null)
{
}
- public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals)
+ public ExportRendererAttribute(Type handler, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals)
{
}
}
@@ -17,7 +18,7 @@ public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisual
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportCellAttribute : HandlerAttribute
{
- public ExportCellAttribute(Type handler, Type target) : base(handler, target)
+ public ExportCellAttribute(Type handler, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type target) : base(handler, target)
{
}
}
@@ -25,7 +26,7 @@ public ExportCellAttribute(Type handler, Type target) : base(handler, target)
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ExportImageSourceHandlerAttribute : HandlerAttribute
{
- public ExportImageSourceHandlerAttribute(Type handler, Type target) : base(handler, target)
+ public ExportImageSourceHandlerAttribute(Type handler, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type target) : base(handler, target)
{
}
}
diff --git a/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs b/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs
index df004cad2fc7..507321e6c571 100644
--- a/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs
+++ b/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using Microsoft.Maui.Controls.Hosting;
using Microsoft.Maui.Hosting;
@@ -6,7 +7,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Hosting
{
public static class MauiHandlersCollectionExtensions
{
- public static IMauiHandlersCollection TryAddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection, Type controlType, Type rendererType)
+ public static IMauiHandlersCollection TryAddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection, Type controlType, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type rendererType)
{
Internals.Registrar.CheckIfRendererIsCompatibilityRenderer(rendererType);
Hosting.MauiAppBuilderExtensions.CheckForCompatibility();
@@ -21,7 +22,7 @@ public static IMauiHandlersCollection TryAddCompatibilityRenderer(this IMauiHand
return handlersCollection;
}
- public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection, Type controlType, Type rendererType)
+ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection, Type controlType, [DynamicallyAccessedMembers(Internals.HandlerType.TargetMembers)] Type rendererType)
{
Internals.Registrar.CheckIfRendererIsCompatibilityRenderer(rendererType);
Hosting.MauiAppBuilderExtensions.CheckForCompatibility();
@@ -36,7 +37,7 @@ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandler
return handlersCollection;
}
- public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection)
+ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection)
where TMauiType : IView
{
Internals.Registrar.CheckIfRendererIsCompatibilityRenderer(typeof(TRenderer));
@@ -51,7 +52,7 @@ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection)
+ public static IMauiHandlersCollection AddCompatibilityRenderer(this IMauiHandlersCollection handlersCollection)
where TControlType : IView
{
Internals.Registrar.CheckIfRendererIsCompatibilityRenderer(typeof(TRenderer));
diff --git a/src/Compatibility/Core/src/Properties/AssemblyInfo.cs b/src/Compatibility/Core/src/Properties/AssemblyInfo.cs
index 8ee7328de170..34a0a0078b89 100644
--- a/src/Compatibility/Core/src/Properties/AssemblyInfo.cs
+++ b/src/Compatibility/Core/src/Properties/AssemblyInfo.cs
@@ -2,6 +2,7 @@
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Internals;
using Microsoft.Maui.Controls.StyleSheets;
+#pragma warning disable CS0618 // Type or member is obsolete
using CFlexLayout = Microsoft.Maui.Controls.Compatibility.FlexLayout;
using CGrid = Microsoft.Maui.Controls.Compatibility.Grid;
using CStackLayout = Microsoft.Maui.Controls.Compatibility.StackLayout;
@@ -29,4 +30,5 @@
//xf specific
[assembly: StyleProperty("-maui-spacing", typeof(CStackLayout), nameof(CStackLayout.SpacingProperty))]
-[assembly: StyleProperty("-maui-orientation", typeof(CStackLayout), nameof(CStackLayout.OrientationProperty))]
\ No newline at end of file
+[assembly: StyleProperty("-maui-orientation", typeof(CStackLayout), nameof(CStackLayout.OrientationProperty))]
+#pragma warning restore CS0618 // Type or member is obsolete
\ No newline at end of file
diff --git a/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs
index 5cbb35f62b12..0286d6911cf6 100644
--- a/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs
+++ b/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Microsoft.Maui.Controls.Internals;
using NView = Tizen.NUI.BaseComponents.View;
@@ -7,6 +8,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen
{
public static class NativeBindingExtensions
{
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public static void SetBinding(this NView view, string propertyName, BindingBase binding, string updateSourceEventName = null)
{
PlatformBindingHelpers.SetBinding(view, propertyName, binding, updateSourceEventName);
diff --git a/src/Compatibility/Core/src/Tizen/NativeBindingService.cs b/src/Compatibility/Core/src/Tizen/NativeBindingService.cs
index d575dbf30615..e377576f703e 100644
--- a/src/Compatibility/Core/src/Tizen/NativeBindingService.cs
+++ b/src/Compatibility/Core/src/Tizen/NativeBindingService.cs
@@ -7,7 +7,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen
{
class NativeBindingService : INativeBindingService
{
- [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = TrimmerConstants.NativeBindingService)]
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public bool TrySetBinding(object target, string propertyName, BindingBase binding)
{
Hosting.MauiAppBuilderExtensions.CheckForCompatibility();
diff --git a/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs
index 21b7d6d6eb30..f590927fc7d0 100644
--- a/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs
+++ b/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs
@@ -260,7 +260,7 @@ protected virtual void Dispose(bool disposing)
{
// This is the reason why I call SendDisappearing() here.
// When OnChildRemove is called first like how it is called in Navigation.PopToRootAsync(),
- // you can not controll using SendDisappearing() on the lower class.
+ // you cannot control using SendDisappearing() on the lower class.
(Element as IPageController)?.SendDisappearing();
if (Element != null)
diff --git a/src/Compatibility/Core/src/Tizen/ResourcePath.cs b/src/Compatibility/Core/src/Tizen/ResourcePath.cs
index 47671abfd080..b1fee46baf59 100644
--- a/src/Compatibility/Core/src/Tizen/ResourcePath.cs
+++ b/src/Compatibility/Core/src/Tizen/ResourcePath.cs
@@ -14,7 +14,7 @@ public static string GetPath(string res)
return res;
}
- foreach (AppFW.ResourceManager.Category category in Enum.GetValues(typeof(AppFW.ResourceManager.Category)))
+ foreach (AppFW.ResourceManager.Category category in Enum.GetValues())
{
var path = AppFW.ResourceManager.TryGetPath(category, res);
diff --git a/src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/Verify.cs b/src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/Verify.cs
index 18e64534505a..19a1440a40c1 100644
--- a/src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/Verify.cs
+++ b/src/Compatibility/Core/src/WPF/Microsoft.Windows.Shell/Standard/Verify.cs
@@ -55,7 +55,7 @@ public static void IsNeitherNullNorEmpty(string value, string name)
Assert.IsNeitherNullNorEmpty(name);
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
- const string errorMessage = "The parameter can not be either null or empty.";
+ const string errorMessage = "The parameter cannot be either null or empty.";
if (null == value)
{
Assert.Fail();
@@ -82,7 +82,7 @@ public static void IsNeitherNullNorWhitespace(string value, string name)
Assert.IsNeitherNullNorEmpty(name);
// Notice that ArgumentNullException and ArgumentException take the parameters in opposite order :P
- const string errorMessage = "The parameter can not be either null or empty or consist only of white space characters.";
+ const string errorMessage = "The parameter cannot be either null or empty or consist only of white space characters.";
if (null == value)
{
Assert.Fail();
diff --git a/src/Compatibility/Core/src/Windows/FrameworkElementExtensions.cs b/src/Compatibility/Core/src/Windows/FrameworkElementExtensions.cs
index 8a49258a0241..a3b41d1bf9d6 100644
--- a/src/Compatibility/Core/src/Windows/FrameworkElementExtensions.cs
+++ b/src/Compatibility/Core/src/Windows/FrameworkElementExtensions.cs
@@ -82,7 +82,9 @@ static DependencyProperty GetForegroundProperty(FrameworkElement element)
DependencyProperty foregroundProperty;
if (!ForegroundProperties.Value.TryGetValue(type, out foregroundProperty))
{
- FieldInfo field = ReflectionExtensions.GetFields(type).FirstOrDefault(f => f.Name == "ForegroundProperty");
+#pragma warning disable IL2075 // The Compatibility assembly is not trimmable
+ FieldInfo field = type.GetField("ForegroundProperty", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
+#pragma warning restore IL2075
if (field == null)
throw new ArgumentException("type is not a Foregroundable type");
diff --git a/src/Compatibility/Core/src/Windows/NativeBindingExtensions.cs b/src/Compatibility/Core/src/Windows/NativeBindingExtensions.cs
index 00de36ce7264..938df2a83e75 100644
--- a/src/Compatibility/Core/src/Windows/NativeBindingExtensions.cs
+++ b/src/Compatibility/Core/src/Windows/NativeBindingExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using Microsoft.Maui.Controls.Internals;
using Microsoft.UI.Xaml;
using static System.String;
@@ -9,6 +10,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.UWP
{
public static class NativeBindingExtensions
{
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public static void SetBinding(this FrameworkElement view, string propertyName, BindingBase bindingBase, string updateSourceEventName = null)
{
var binding = bindingBase as Binding;
diff --git a/src/Compatibility/Core/src/Windows/NativeBindingService.cs b/src/Compatibility/Core/src/Windows/NativeBindingService.cs
index 794e91db2e33..53cf9aa35b27 100644
--- a/src/Compatibility/Core/src/Windows/NativeBindingService.cs
+++ b/src/Compatibility/Core/src/Windows/NativeBindingService.cs
@@ -9,7 +9,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.UWP
{
public class NativeBindingService : INativeBindingService
{
- [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = TrimmerConstants.NativeBindingService)]
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public bool TrySetBinding(object target, string propertyName, BindingBase binding)
{
var view = target as FrameworkElement;
diff --git a/src/Compatibility/Core/src/Windows/NativeEventWrapper.cs b/src/Compatibility/Core/src/Windows/NativeEventWrapper.cs
index 8c49cd00da43..82a157455077 100644
--- a/src/Compatibility/Core/src/Windows/NativeEventWrapper.cs
+++ b/src/Compatibility/Core/src/Windows/NativeEventWrapper.cs
@@ -1,5 +1,6 @@
using System;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices.WindowsRuntime;
@@ -20,7 +21,10 @@ public NativeEventWrapper(object target, string targetProperty, string updateSou
TargetProperty = targetProperty;
try
{
+
+#pragma warning disable IL2072 // Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.
var updateSourceEvent = target.GetType().GetRuntimeEvent(updateSourceEventName);
+#pragma warning restore IL2072 // Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.
MethodInfo addMethod = updateSourceEvent.AddMethod;
MethodInfo removeMethod = updateSourceEvent.RemoveMethod;
ParameterInfo[] addParameters = addMethod.GetParameters();
@@ -34,7 +38,7 @@ public NativeEventWrapper(object target, string targetProperty, string updateSou
}
catch (Exception)
{
- Application.Current?.FindMauiContext()?.CreateLogger()?.LogWarning("Can not attach NativeEventWrapper.");
+ Application.Current?.FindMauiContext()?.CreateLogger()?.LogWarning("Cannot attach NativeEventWrapper.");
}
}
diff --git a/src/Compatibility/Core/src/WorkaroundXamlPreCompilePreviewFeatures.rsp b/src/Compatibility/Core/src/WorkaroundXamlPreCompilePreviewFeatures.rsp
new file mode 100644
index 000000000000..e60a129bbc68
--- /dev/null
+++ b/src/Compatibility/Core/src/WorkaroundXamlPreCompilePreviewFeatures.rsp
@@ -0,0 +1 @@
+/features:"InterceptorsPreviewNamespaces=Microsoft.Maui.Controls.Generated"
\ No newline at end of file
diff --git a/src/Compatibility/Core/src/iOS/NativeBindingService.cs b/src/Compatibility/Core/src/iOS/NativeBindingService.cs
index 0fd914b78845..6fe5fb746c07 100644
--- a/src/Compatibility/Core/src/iOS/NativeBindingService.cs
+++ b/src/Compatibility/Core/src/iOS/NativeBindingService.cs
@@ -8,10 +8,9 @@
namespace Microsoft.Maui.Controls.Compatibility.Platform.iOS
{
- [Preserve(AllMembers = true)]
class NativeBindingService : INativeBindingService
{
- [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = TrimmerConstants.NativeBindingService)]
+ [RequiresUnreferencedCode(TrimmerConstants.StringPathBindingWarning, Url = TrimmerConstants.ExpressionBasedBindingsDocsUrl)]
public bool TrySetBinding(object target, string propertyName, BindingBase binding)
{
Hosting.MauiAppBuilderExtensions.CheckForCompatibility();
diff --git a/src/Compatibility/Core/src/iOS/Renderers/SwipeViewRenderer.cs b/src/Compatibility/Core/src/iOS/Renderers/SwipeViewRenderer.cs
index 78dcfabec40c..9ee778516ba9 100644
--- a/src/Compatibility/Core/src/iOS/Renderers/SwipeViewRenderer.cs
+++ b/src/Compatibility/Core/src/iOS/Renderers/SwipeViewRenderer.cs
@@ -706,7 +706,7 @@ async void UpdateSwipeItemIconImage(UIButton swipeButton, SwipeItem swipeItem)
catch (Exception)
{
// UIImage ctor throws on file not found if MonoTouch.ObjCRuntime.Class.ThrowOnInitFailure is true;
- Forms.MauiContext?.CreateLogger()?.LogWarning("Can not load SwipeItem Icon");
+ Forms.MauiContext?.CreateLogger()?.LogWarning("Cannot load SwipeItem Icon");
}
}
}
diff --git a/src/Compatibility/Core/tests/Compatibility.UnitTests/ApplicationStub.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/ApplicationStub.cs
index ed89efcc164e..112bfec84381 100644
--- a/src/Compatibility/Core/tests/Compatibility.UnitTests/ApplicationStub.cs
+++ b/src/Compatibility/Core/tests/Compatibility.UnitTests/ApplicationStub.cs
@@ -32,6 +32,8 @@ public void CloseWindow(IWindow window)
_windows.Remove(window);
}
+ public void ActivateWindow(IWindow window) { }
+
public void ThemeChanged() { }
}
}
\ No newline at end of file
diff --git a/src/Compatibility/Core/tests/Compatibility.UnitTests/BaseTestFixture.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/BaseTestFixture.cs
new file mode 100644
index 000000000000..6df23fa7410e
--- /dev/null
+++ b/src/Compatibility/Core/tests/Compatibility.UnitTests/BaseTestFixture.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Globalization;
+using System.Threading;
+using Microsoft.Maui.ApplicationModel;
+using Microsoft.Maui.Controls.Internals;
+using Microsoft.Maui.Devices;
+using Microsoft.Maui.Dispatching;
+using Microsoft.Maui.UnitTests;
+using Xunit;
+
+// By default, xUnit will run test collections (the tests in each class) in parallel
+// with other test collections. Unfortunately, a _ton_ of the Controls legacy tests
+// interact with properties on static classes (e.g., Application.Current), and if we
+// let them run in parallel they'll step on one another. So we tell xUnit to consider
+// the whole assembly as a single collection for now, so all the tests run in sequence.
+// (Hopefully in the future we can untangle some of the singletons and run these in parallel,
+// because it'll be a lot faster.)
+[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]
+
+namespace Microsoft.Maui.Controls.Core.UnitTests
+{
+ public class BaseTestFixture : IDisposable
+ {
+ CultureInfo _defaultCulture;
+ CultureInfo _defaultUICulture;
+
+ public BaseTestFixture()
+ {
+ Microsoft.Maui.Controls.Hosting.CompatibilityCheck.UseCompatibility();
+ _defaultCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
+ _defaultUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
+ DispatcherProvider.SetCurrent(new DispatcherProviderStub());
+ DeviceDisplay.SetCurrent(null);
+ DeviceInfo.SetCurrent(null);
+ AppInfo.SetCurrent(null);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ bool _disposed;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ AppInfo.SetCurrent(null);
+ DeviceDisplay.SetCurrent(null);
+ DeviceInfo.SetCurrent(null);
+ System.Threading.Thread.CurrentThread.CurrentCulture = _defaultCulture;
+ System.Threading.Thread.CurrentThread.CurrentUICulture = _defaultUICulture;
+ DispatcherProvider.SetCurrent(null);
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/src/Controls/tests/Core.UnitTests/FlexLayoutAlignContentTests.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignContentTests.cs
similarity index 74%
rename from src/Controls/tests/Core.UnitTests/FlexLayoutAlignContentTests.cs
rename to src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignContentTests.cs
index 66aa292d46b4..556ae6265fbb 100644
--- a/src/Controls/tests/Core.UnitTests/FlexLayoutAlignContentTests.cs
+++ b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignContentTests.cs
@@ -13,7 +13,7 @@ public class FlexLayoutAlignContentTests : BaseTestFixture
[Fact]
public void TestAlignContentFlexStart()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(50, 10));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(50, 10));
var layout = new FlexLayout
{
@@ -27,19 +27,19 @@ public void TestAlignContentFlexStart()
Wrap = FlexWrap.Wrap,
};
- var view0 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 130, 100));
@@ -55,7 +55,7 @@ public void TestAlignContentFlexStart()
[Fact]
public void TestAlignContentFlexStartWithoutHeightOnChildren()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(50, 10));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(50, 10));
var layout = new FlexLayout
{
@@ -67,19 +67,19 @@ public void TestAlignContentFlexStartWithoutHeightOnChildren()
Direction = FlexDirection.Column,
Wrap = FlexWrap.Wrap,
};
- var view0 = new View { IsPlatformEnabled = true, WidthRequest = 50, };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50);
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50, };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 100, 100));
@@ -94,7 +94,7 @@ public void TestAlignContentFlexStartWithoutHeightOnChildren()
[Fact]
public void TestAlignContentFlexStartWithFlex()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(0, 0));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(0, 0));
var layout = new FlexLayout
{
@@ -107,31 +107,31 @@ public void TestAlignContentFlexStartWithFlex()
AlignItems = FlexAlignItems.Start,
};
- var view0 = new View { IsPlatformEnabled = true };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize);
FlexLayout.SetGrow(view0, 1);
FlexLayout.SetBasis(view0, 0);
view0.WidthRequest = 50;
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize);
FlexLayout.SetGrow(view1, 1);
FlexLayout.SetBasis(view1, 0);
view1.WidthRequest = 50;
view1.HeightRequest = 10;
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize);
view2.WidthRequest = 50;
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize);
FlexLayout.SetGrow(view3, 1);
FlexLayout.SetShrink(view3, 1);
FlexLayout.SetBasis(view3, 0);
view3.WidthRequest = 50;
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize);
view4.WidthRequest = 50;
layout.Children.Add(view4);
@@ -148,7 +148,7 @@ public void TestAlignContentFlexStartWithFlex()
[Fact]
public void TestAlignContentFlexEnd()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(50, 10));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(50, 10));
var layout = new FlexLayout
{
@@ -162,12 +162,7 @@ public void TestAlignContentFlexEnd()
Wrap = FlexWrap.Wrap,
};
- Func createView = () => new View
- {
- IsPlatformEnabled = true,
- WidthRequest = 50,
- HeightRequest = 10,
- };
+ Func createView = () => MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
var view0 = createView();
layout.Children.Add(view0);
@@ -198,7 +193,7 @@ public void TestAlignContentFlexEnd()
[Fact]
public void TestAlignContentStretch()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(0, 0));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(0, 0));
var layout = new FlexLayout
{
@@ -210,23 +205,23 @@ public void TestAlignContentStretch()
WidthRequest = 150,
HeightRequest = 100
};
- var view0 = new View { IsPlatformEnabled = true };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize);
view0.WidthRequest = 50;
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize);
view1.WidthRequest = 50;
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize);
view2.WidthRequest = 50;
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize);
view3.WidthRequest = 50;
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize);
view4.WidthRequest = 50;
layout.Children.Add(view4);
@@ -266,7 +261,7 @@ public void TestAlignContentStretch()
[Fact]
public void TestAlignContentSpaceBetween()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(50, 10));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(50, 10));
var layout = new FlexLayout
{
@@ -279,19 +274,19 @@ public void TestAlignContentSpaceBetween()
Wrap = FlexWrap.Wrap,
};
- var view0 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10 };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10 };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10 };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10 };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10 };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 130, 100));
@@ -307,7 +302,7 @@ public void TestAlignContentSpaceBetween()
[Fact]
public void TestAlignContentSpaceAround()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(50, 10));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(50, 10));
var layout = new FlexLayout
{
@@ -319,19 +314,19 @@ public void TestAlignContentSpaceAround()
AlignContent = FlexAlignContent.SpaceAround,
Wrap = FlexWrap.Wrap,
};
- var view0 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50, HeightRequest = 10, };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize, width: 50, height: 10);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 140, 120));
@@ -357,23 +352,23 @@ public void TestAlignContentStretchRow()
WidthRequest = 150,
HeightRequest = 100
};
- var view0 = new View { IsPlatformEnabled = true };
+ var view0 = MockPlatformSizeService.Sub();
view0.WidthRequest = 50;
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true };
+ var view1 = MockPlatformSizeService.Sub();
view1.WidthRequest = 50;
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true };
+ var view2 = MockPlatformSizeService.Sub();
view2.WidthRequest = 50;
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true };
+ var view3 = MockPlatformSizeService.Sub();
view3.WidthRequest = 50;
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true };
+ var view4 = MockPlatformSizeService.Sub();
view4.WidthRequest = 50;
layout.Children.Add(view4);
@@ -426,22 +421,22 @@ public void TestAlignContentStretchRowWithChildren()
var view0 = new FlexLayout { IsPlatformEnabled = true, WidthRequest = 50, };
layout.Children.Add(view0);
- //var view0_child0 = new View { IsPlatformEnabled = true };
+ //var view0_child0 = MockPlatformSizeService.Sub();
//FlexLayout.SetGrow(view0_child0, 1);
//FlexLayout.SetShrink(view0_child0, 1);
//FlexLayout.SetBasis(view0_child0, 0);
//view0.Children.Add(view0_child0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50, };
+ var view1 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50, };
+ var view2 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50, };
+ var view3 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50, };
+ var view4 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 150, 100));
@@ -490,25 +485,25 @@ public void TestAlignContentStretchRowWithFlex()
Direction = FlexDirection.Row,
Wrap = FlexWrap.Wrap,
};
- var view0 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view0 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view1 = MockPlatformSizeService.Sub(width: 50);
FlexLayout.SetGrow(view1, 1);
FlexLayout.SetShrink(view1, 1);
FlexLayout.SetBasis(view1, 0);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view2 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view3 = MockPlatformSizeService.Sub(width: 50);
FlexLayout.SetGrow(view3, 1);
FlexLayout.SetShrink(view3, 1);
FlexLayout.SetBasis(view3, 0);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view4 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 150, 100));
@@ -533,24 +528,24 @@ public void TestAlignContentStretchRowWithFlexNoShrink()
WidthRequest = 150,
HeightRequest = 100
};
- var view0 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view0 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view1 = MockPlatformSizeService.Sub(width: 50);
FlexLayout.SetGrow(view1, 1);
FlexLayout.SetShrink(view1, 1);
FlexLayout.SetBasis(view1, 0);
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view2 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view3 = MockPlatformSizeService.Sub(width: 50);
FlexLayout.SetGrow(view3, 1);
FlexLayout.SetBasis(view3, 0);
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true, WidthRequest = 50 };
+ var view4 = MockPlatformSizeService.Sub(width: 50);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 150, 100));
@@ -608,38 +603,16 @@ public void TestAlignContentStretchRowWithMargin()
layout.Children.Add(view0);
- var view1 = new View
- {
- IsPlatformEnabled = true,
- Margin = 10,
- WidthRequest = 50,
- HeightRequest = 20,
- };
+ var view1 = MockPlatformSizeService.Sub(width: 50, height: 20, margin: 10);
layout.Children.Add(view1);
- var view2 = new View
- {
- IsPlatformEnabled = true,
- WidthRequest = 50,
- HeightRequest = 20,
- };
+ var view2 = MockPlatformSizeService.Sub(width: 50, height: 20);
layout.Children.Add(view2);
- var view3 = new View
- {
- IsPlatformEnabled = true,
- Margin = new Thickness(10),
- WidthRequest = 50,
- HeightRequest = 20,
- };
+ var view3 = MockPlatformSizeService.Sub(width: 50, height: 20, margin: 10);
layout.Children.Add(view3);
- var view4 = new View
- {
- IsPlatformEnabled = true,
- WidthRequest = 50,
- HeightRequest = 20,
- };
+ var view4 = MockPlatformSizeService.Sub(width: 50, height: 20);
layout.Children.Add(view4);
layout.Layout(new Rect(0, 0, 150, 100));
@@ -664,11 +637,11 @@ public void TestAlignContentStretchRowWithSingleRow()
WidthRequest = 150,
HeightRequest = 100
};
- var view0 = new View { IsPlatformEnabled = true };
+ var view0 = MockPlatformSizeService.Sub();
view0.WidthRequest = 50;
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true };
+ var view1 = MockPlatformSizeService.Sub();
view1.WidthRequest = 50;
layout.Children.Add(view1);
@@ -693,7 +666,7 @@ public void TestAlignContentStretchRowWithSingleRow()
[Fact]
public void TestAlignContentStretchRowWithFixedHeight()
{
- MockPlatformSizeService.Current.GetPlatformSizeFunc = (visual, width, height) => new SizeRequest(new Size(0, 0));
+ static SizeRequest GetPlatformSize(VisualElement v, double w, double h) => new(new Size(0, 0));
var layout = new FlexLayout
{
@@ -705,24 +678,24 @@ public void TestAlignContentStretchRowWithFixedHeight()
WidthRequest = 150,
HeightRequest = 100
};
- var view0 = new View { IsPlatformEnabled = true };
+ var view0 = MockPlatformSizeService.Sub(GetPlatformSize);
view0.WidthRequest = 50;
layout.Children.Add(view0);
- var view1 = new View { IsPlatformEnabled = true };
+ var view1 = MockPlatformSizeService.Sub(GetPlatformSize);
view1.WidthRequest = 50;
view1.HeightRequest = 60;
layout.Children.Add(view1);
- var view2 = new View { IsPlatformEnabled = true };
+ var view2 = MockPlatformSizeService.Sub(GetPlatformSize);
view2.WidthRequest = 50;
layout.Children.Add(view2);
- var view3 = new View { IsPlatformEnabled = true };
+ var view3 = MockPlatformSizeService.Sub(GetPlatformSize);
view3.WidthRequest = 50;
layout.Children.Add(view3);
- var view4 = new View { IsPlatformEnabled = true };
+ var view4 = MockPlatformSizeService.Sub(GetPlatformSize);
view4.WidthRequest = 50;
layout.Children.Add(view4);
diff --git a/src/Controls/tests/Core.UnitTests/FlexLayoutAlignItemsTests.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignItemsTests.cs
similarity index 100%
rename from src/Controls/tests/Core.UnitTests/FlexLayoutAlignItemsTests.cs
rename to src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignItemsTests.cs
diff --git a/src/Controls/tests/Core.UnitTests/FlexLayoutAlignSelfTests.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignSelfTests.cs
similarity index 100%
rename from src/Controls/tests/Core.UnitTests/FlexLayoutAlignSelfTests.cs
rename to src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutAlignSelfTests.cs
diff --git a/src/Controls/tests/Core.UnitTests/FlexLayoutFlexDirectionTests.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutFlexDirectionTests.cs
similarity index 97%
rename from src/Controls/tests/Core.UnitTests/FlexLayoutFlexDirectionTests.cs
rename to src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutFlexDirectionTests.cs
index 4fd0c39e2341..83ca15f64c88 100644
--- a/src/Controls/tests/Core.UnitTests/FlexLayoutFlexDirectionTests.cs
+++ b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutFlexDirectionTests.cs
@@ -29,7 +29,7 @@ public void TestFlexDirectionColumnWithoutHeight()
Direction = FlexDirection.Column,
};
- var sizeRequest = layout.Measure(100, double.PositiveInfinity);
+ var sizeRequest = layout.Measure(100, double.PositiveInfinity, MeasureFlags.None);
layout.Layout(new Rect(0, 0, sizeRequest.Request.Width, sizeRequest.Request.Height));
Assert.Equal(layout.Bounds, new Rect(0, 0, 100, 30));
Assert.Equal(view0.Bounds, new Rect(0, 0, 100, 10));
@@ -56,7 +56,7 @@ public void TestFlexDirectionRowNoWidth()
};
- var measure = layout.Measure(double.PositiveInfinity, 100);
+ var measure = layout.Measure(double.PositiveInfinity, 100, MeasureFlags.None);
layout.Layout(new Rect(0, 0, measure.Request.Width, measure.Request.Height));
Assert.Equal(layout.Bounds, new Rect(0, 0, 30, 100));
Assert.Equal(view0.Bounds, new Rect(0, 0, 10, 100));
diff --git a/src/Controls/tests/Core.UnitTests/FlexLayoutTests.cs b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutTests.cs
similarity index 80%
rename from src/Controls/tests/Core.UnitTests/FlexLayoutTests.cs
rename to src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutTests.cs
index be2584e2750f..9b7710112043 100644
--- a/src/Controls/tests/Core.UnitTests/FlexLayoutTests.cs
+++ b/src/Compatibility/Core/tests/Compatibility.UnitTests/FlexLayoutTests.cs
@@ -16,8 +16,8 @@ public class FlexLayoutTests : BaseTestFixture
[Fact]
public void TestBasicLayout()
{
- var label1 = new Label { IsPlatformEnabled = true };
- var label2 = new Label { IsPlatformEnabled = true };
+ var label1 = MockPlatformSizeService.Sub | |