diff --git a/.azuredevops/dependabot.yml b/.azuredevops/dependabot.yml
new file mode 100644
index 000000000000..f18e60565a42
--- /dev/null
+++ b/.azuredevops/dependabot.yml
@@ -0,0 +1,5 @@
+version: 2
+
+# Disabling dependabot on Azure DevOps as this is a mirrored repo. Updates should go through github.
+enable-campaigned-updates: false
+enable-security-updates: false
diff --git a/.config/1espt/PipelineAutobaseliningConfig.yml b/.config/1espt/PipelineAutobaseliningConfig.yml
index ff5dcdf1e37b..528461221ba3 100644
--- a/.config/1espt/PipelineAutobaseliningConfig.yml
+++ b/.config/1espt/PipelineAutobaseliningConfig.yml
@@ -1,23 +1,146 @@
-## DO NOT MODIFY THIS FILE MANUALLY. This is part of auto-baselining from 1ES Pipeline Templates. Go to [https://aka.ms/1espt-autobaselining] for more details.
-
-pipelines:
- 1330:
- retail:
- source:
- credscan:
- lastModifiedDate: 2024-03-25
- eslint:
- lastModifiedDate: 2024-03-25
- psscriptanalyzer:
- lastModifiedDate: 2024-03-25
- armory:
- lastModifiedDate: 2024-03-25
- policheck:
- lastModifiedDate: 2025-03-27
- binary:
- credscan:
- lastModifiedDate: 2024-03-25
- binskim:
- lastModifiedDate: 2025-01-23
- spotbugs:
- lastModifiedDate: 2024-03-25
+## DO NOT MODIFY THIS FILE MANUALLY. This is part of auto-baselining from 1ES Pipeline Templates. Go to [https://aka.ms/1espt-autobaselining] for more details.
+
+pipelines:
+ 1330:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2024-03-25
+ eslint:
+ lastModifiedDate: 2024-03-25
+ psscriptanalyzer:
+ lastModifiedDate: 2024-03-25
+ armory:
+ lastModifiedDate: 2024-03-25
+ policheck:
+ lastModifiedDate: 2025-03-27
+ binary:
+ credscan:
+ lastModifiedDate: 2024-03-25
+ binskim:
+ lastModifiedDate: 2025-10-03
+ spotbugs:
+ lastModifiedDate: 2024-03-25
+ usedBinskimScanAllExtensions: true
+ 1299:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2024-04-02
+ eslint:
+ lastModifiedDate: 2024-04-02
+ psscriptanalyzer:
+ lastModifiedDate: 2024-04-02
+ armory:
+ lastModifiedDate: 2024-04-02
+ policheck:
+ lastModifiedDate: 2025-03-26
+ binary:
+ credscan:
+ lastModifiedDate: 2024-12-20
+ binskim:
+ lastModifiedDate: 2025-01-09
+ 1219:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2024-04-02
+ eslint:
+ lastModifiedDate: 2024-04-02
+ psscriptanalyzer:
+ lastModifiedDate: 2024-04-02
+ armory:
+ lastModifiedDate: 2024-04-02
+ policheck:
+ lastModifiedDate: 2025-03-27
+ binary:
+ credscan:
+ lastModifiedDate: 2024-12-23
+ binskim:
+ lastModifiedDate: 2025-01-09
+ 1231:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2024-10-17
+ eslint:
+ lastModifiedDate: 2024-10-17
+ psscriptanalyzer:
+ lastModifiedDate: 2024-10-17
+ armory:
+ lastModifiedDate: 2024-10-17
+ policheck:
+ lastModifiedDate: 2025-03-26
+ binary:
+ credscan:
+ lastModifiedDate: 2024-10-17
+ binskim:
+ lastModifiedDate: 2025-01-10
+ spotbugs:
+ lastModifiedDate: 2024-10-17
+ 1301:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2024-10-24
+ eslint:
+ lastModifiedDate: 2024-10-24
+ psscriptanalyzer:
+ lastModifiedDate: 2024-10-24
+ armory:
+ lastModifiedDate: 2024-10-24
+ policheck:
+ lastModifiedDate: 2025-04-01
+ binary:
+ credscan:
+ lastModifiedDate: 2024-10-24
+ binskim:
+ lastModifiedDate: 2025-01-13
+ spotbugs:
+ lastModifiedDate: 2024-10-24
+ 1447:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2025-05-09
+ policheck:
+ lastModifiedDate: 2025-05-09
+ eslint:
+ lastModifiedDate: 2025-05-09
+ psscriptanalyzer:
+ lastModifiedDate: 2025-05-09
+ armory:
+ lastModifiedDate: 2025-05-09
+ binary:
+ credscan:
+ lastModifiedDate: 2025-05-09
+ binskim:
+ lastModifiedDate: 2025-05-09
+ spotbugs:
+ lastModifiedDate: 2025-05-09
+ 1484:
+ retail:
+ source:
+ eslint:
+ lastModifiedDate: 2025-08-06
+ armory:
+ lastModifiedDate: 2025-08-06
+ binary:
+ binskim:
+ lastModifiedDate: 2025-08-06
+ 1525:
+ retail:
+ source:
+ credscan:
+ lastModifiedDate: 2025-09-19
+ eslint:
+ lastModifiedDate: 2025-09-19
+ psscriptanalyzer:
+ lastModifiedDate: 2025-09-19
+ armory:
+ lastModifiedDate: 2025-09-19
+ binary:
+ credscan:
+ lastModifiedDate: 2025-09-19
+ binskim:
+ lastModifiedDate: 2025-09-19
diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json
index ccd35fe83c71..79d6b4056224 100644
--- a/.config/CredScanSuppressions.json
+++ b/.config/CredScanSuppressions.json
@@ -265,14 +265,7 @@
"/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyPemTests.cs",
"/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyPemTests.cs",
"/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
- "/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/TestData.cs",
- "/src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/gRPC/grpc-dotnet/testassets/Certs/InteropTests/server1.key"
- ]
- },
- {
- "_justification": "Suppression approved. Private key for testing purpose.",
- "file": [
- "/src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/gRPC/grpc-dotnet/testassets/Certs/InteropTests/server1.pfx"
+ "/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/TestData.cs"
]
},
{
@@ -289,6 +282,25 @@
"/src/source-build-reference-packages/src/externalPackages/src/humanizer/src/Humanizer.Tests.Uwp.Runner/Humanizer.Tests.Uwp.Runner_TemporaryKey.pfx",
"/src/source-build-reference-packages/src/externalPackages/src/xunit/appveyor.yml"
]
+ },
+ {
+ "_justification": "Files contain private keys used by test code.",
+ "file": [
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned1024_SHA1.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned1024_SHA256.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA256.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA256_2.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA384.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA512.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/humanizer/src/Humanizer.Tests.Uwp.Runner/Humanizer.Tests.Uwp.Runner_TemporaryKey.pfx",
+ "/src/source-build-reference-packages/src/externalPackages/src/humanizer/src/Humanizer.Tests.Uwp/Humanizer.Tests.Uwp_TemporaryKey.pfx"
+ ]
+ },
+ {
+ "_justification": "File uses a test-only credential.",
+ "file": [
+ "/src/source-build-reference-packages/src/externalPackages/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs"
+ ]
}
]
}
\ No newline at end of file
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index ab9278bf1531..2b07d7d4face 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"microsoft.dotnet.darc": {
- "version": "1.1.0-beta.25412.1",
+ "version": "1.1.0-beta.25619.4",
"commands": [
"darc"
]
diff --git a/.config/guardian/.gdnbaselines b/.config/guardian/.gdnbaselines
new file mode 100644
index 000000000000..78f0f5f72ca5
--- /dev/null
+++ b/.config/guardian/.gdnbaselines
@@ -0,0 +1,2602 @@
+{
+ "properties": {
+ "helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/baselines"
+ },
+ "version": "1.0.0",
+ "baselines": {
+ "default": {
+ "name": "default",
+ "createdDate": "2024-03-25 18:56:33Z",
+ "lastUpdatedDate": "2024-03-25 18:56:33Z"
+ }
+ },
+ "results": {
+ "5f3b52e23f96eb01bcfd73ead3cbaa2e1430de0006e5103109dd39bf9f292165": {
+ "signature": "5f3b52e23f96eb01bcfd73ead3cbaa2e1430de0006e5103109dd39bf9f292165",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/docs/cross-platform-debugging.md",
+ "line": 66,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "72b28f655eadc78b21ab36a7f572708315d8d909d1b460162511e37086288e30": {
+ "signature": "72b28f655eadc78b21ab36a7f572708315d8d909d1b460162511e37086288e30",
+ "alternativeSignatures": [
+ "60efb04c6e0431e477e792a96d32b30b3a309b4ee19fad084a015e2946985459"
+ ],
+ "target": "src/roslyn/eng/build.ps1",
+ "line": 339,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingConvertToSecureStringWithPlainText",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "e0aafe4de4d762a800edeca36ed2144ed173a138d126423863b1710425b90b33": {
+ "signature": "e0aafe4de4d762a800edeca36ed2144ed173a138d126423863b1710425b90b33",
+ "alternativeSignatures": [],
+ "target": "src/aspire/tests/Aspire.Npgsql.EntityFrameworkCore.PostgreSQL.Tests/ConformanceTests.cs",
+ "line": 20,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0030",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "a5142e7bafbf664fdcb2d4d7071ca8427c7da0c8ba66cc7706c9c07b816f1201": {
+ "signature": "a5142e7bafbf664fdcb2d4d7071ca8427c7da0c8ba66cc7706c9c07b816f1201",
+ "alternativeSignatures": [],
+ "target": "src/aspire/tests/Aspire.Npgsql.Tests/ConformanceTests.cs",
+ "line": 17,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0030",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "b6aecc1d8697beab291f9925633b5ec3e37a088033efc7e93928fd9cac96cda4": {
+ "signature": "b6aecc1d8697beab291f9925633b5ec3e37a088033efc7e93928fd9cac96cda4",
+ "alternativeSignatures": [
+ "985838b2d1518f507c85ae0f635951bad92dde58eb24c252d7e56fb6ccda6191"
+ ],
+ "target": "src/aspnetcore/src/DataProtection/CreateTestCert.ps1",
+ "line": 11,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingConvertToSecureStringWithPlainText",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "5c349e8f183364d99cde545c6da7549c9d6227957c820fcde8e8beb2b40de39c": {
+ "signature": "5c349e8f183364d99cde545c6da7549c9d6227957c820fcde8e8beb2b40de39c",
+ "alternativeSignatures": [
+ "8546393d391f4010c04ed43788c36626f870b02028937cf390014c660f657f7b"
+ ],
+ "target": "src/command-line-api/eng/common/SetupNugetSources.ps1",
+ "line": 38,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-01 22:10:09Z",
+ "expirationDate": "2024-09-19 00:45:33Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 00:45:33Z"
+ },
+ "a9e7b46f71cc21fd96e3bbb1c30a7beb36470f0a4c857794b4444856e54ffc2b": {
+ "signature": "a9e7b46f71cc21fd96e3bbb1c30a7beb36470f0a4c857794b4444856e54ffc2b",
+ "alternativeSignatures": [
+ "34597b8dc5d2e482d7178a50440f3b8815c44e510906dd92a4d31d434c87053b"
+ ],
+ "target": "src/command-line-api/eng/common/SetupNugetSources.ps1",
+ "line": 56,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-01 22:10:09Z",
+ "expirationDate": "2024-09-19 00:45:33Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 00:45:33Z"
+ },
+ "3df69ea15defeb820ba0823dc80513e75a79b049dee023b51dee4419cd1d2276": {
+ "signature": "3df69ea15defeb820ba0823dc80513e75a79b049dee023b51dee4419cd1d2276",
+ "alternativeSignatures": [
+ "deb5cfe250ae8f9c1bbcdf230c425dc071067ee26cc7b3d41b9fc078782febfc"
+ ],
+ "target": "src/command-line-api/eng/common/SetupNugetSources.ps1",
+ "line": 88,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-01 22:10:09Z",
+ "expirationDate": "2024-09-19 00:45:33Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 00:45:33Z"
+ },
+ "32eb952e8561b331092ec83b626102388202071d192f9eb22c233b06ea90d2a1": {
+ "signature": "32eb952e8561b331092ec83b626102388202071d192f9eb22c233b06ea90d2a1",
+ "alternativeSignatures": [
+ "cce04b0a7c54b775c1464a32d85804de7d1777ac2a6d21da8b080c29ac46162c"
+ ],
+ "target": "src/diagnostics/eng/common/SetupNugetSources.ps1",
+ "line": 38,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "7d3c27b6bd42f58e624890a1669c188c6afee080e6330673942d364641876d52": {
+ "signature": "7d3c27b6bd42f58e624890a1669c188c6afee080e6330673942d364641876d52",
+ "alternativeSignatures": [
+ "29d9fec9e2b10d721512bb68a68759baa33b6bbc0683a2d3d5cdcb74894917ee"
+ ],
+ "target": "src/diagnostics/eng/common/SetupNugetSources.ps1",
+ "line": 56,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "42c9ee2033a50a53e2fcc83cb08b3a8c38a5c9e2230414ae0590d3c8f45a9a8d": {
+ "signature": "42c9ee2033a50a53e2fcc83cb08b3a8c38a5c9e2230414ae0590d3c8f45a9a8d",
+ "alternativeSignatures": [
+ "44e2cd3b2773d63b155f2093202415744b74f8b5c47612ad92f2ffee3939cb2f"
+ ],
+ "target": "src/diagnostics/eng/common/SetupNugetSources.ps1",
+ "line": 88,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "11d1ee60346a9d183bdfead22ccfd12efe5b121e24d50ea479e6ed51c5b284f8": {
+ "signature": "11d1ee60346a9d183bdfead22ccfd12efe5b121e24d50ea479e6ed51c5b284f8",
+ "alternativeSignatures": [
+ "f1095a63813963bb218b2e2a11bcfdf33c712ac8e182a37903ac05aa27618431"
+ ],
+ "target": "src/scenario-tests/eng/common/SetupNugetSources.ps1",
+ "line": 38,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "df1e4e250d2fec7e1df1b811d11ee5fde3f74ad34a4cfbb3c347fa0fa1f5f021": {
+ "signature": "df1e4e250d2fec7e1df1b811d11ee5fde3f74ad34a4cfbb3c347fa0fa1f5f021",
+ "alternativeSignatures": [
+ "5721e98504beccf9da5a70c8ea673f82adfa53a36883886e1c81097e7d2dc3a8"
+ ],
+ "target": "src/scenario-tests/eng/common/SetupNugetSources.ps1",
+ "line": 56,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "697b46955be8c055972365abf2b21287b19595c0204245465e3d05869bdf3b2b": {
+ "signature": "697b46955be8c055972365abf2b21287b19595c0204245465e3d05869bdf3b2b",
+ "alternativeSignatures": [
+ "fcef36ad5176c97ff601e5636a327fb6a2d7e89b0767b2a3c515f6f10b21ed4a"
+ ],
+ "target": "src/scenario-tests/eng/common/SetupNugetSources.ps1",
+ "line": 88,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "148a534bb099170811f8dcc0d51c1caa399488739a5ee98fb12bee51c7a9244d": {
+ "signature": "148a534bb099170811f8dcc0d51c1caa399488739a5ee98fb12bee51c7a9244d",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/xunit/appveyor.yml",
+ "line": 7,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0130",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "2960b8fc6b1f6665b5988544f1d44a05dfe83b9b39a14efef5e042d7a78e4e19": {
+ "signature": "2960b8fc6b1f6665b5988544f1d44a05dfe83b9b39a14efef5e042d7a78e4e19",
+ "alternativeSignatures": [
+ "b4177488d7a45f4a54472adf8bb97026f0799e61e10f580ea52fbbd74cf08f10"
+ ],
+ "target": "src/symreader/eng/common/SetupNugetSources.ps1",
+ "line": 38,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-03-25 18:56:33Z",
+ "expirationDate": "2024-09-11 20:34:12Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-03-25 20:34:12Z"
+ },
+ "c1c411bf7b80d684d2c444ed611f333f08f1073fbaaf4c6bd0238c16ffccbe4d": {
+ "signature": "c1c411bf7b80d684d2c444ed611f333f08f1073fbaaf4c6bd0238c16ffccbe4d",
+ "alternativeSignatures": [
+ "8ca9e6612eb3802d5c1fd93ce0f1de61c2559512966fc97dcbeb017d1942c0fe"
+ ],
+ "target": "src/symreader/eng/common/SetupNugetSources.ps1",
+ "line": 56,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-03-25 18:56:33Z",
+ "expirationDate": "2024-09-11 20:34:12Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-03-25 20:34:12Z"
+ },
+ "a0437af80b26a79fc6c7e101114a0a455bd0bc7a4e9ccea1fa3b355aaac07390": {
+ "signature": "a0437af80b26a79fc6c7e101114a0a455bd0bc7a4e9ccea1fa3b355aaac07390",
+ "alternativeSignatures": [
+ "495012003aa9faede4c4ad115a12784f6a8f549e1ebe976537b021d6e5296da9"
+ ],
+ "target": "src/symreader/eng/common/SetupNugetSources.ps1",
+ "line": 88,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingUsernameAndPasswordParams",
+ "createdDate": "2024-03-25 18:56:33Z",
+ "expirationDate": "2024-09-11 20:34:12Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-03-25 20:34:12Z"
+ },
+ "d43d77b6bd95a33891a3f76e3b20bf3001f300e0fe05b477faa4b74a35735740": {
+ "signature": "d43d77b6bd95a33891a3f76e3b20bf3001f300e0fe05b477faa4b74a35735740",
+ "alternativeSignatures": [],
+ "target": "src/aspire/tests/Shared/TestCertificates/testCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "3c494c3cdc3d2ab897a96f5b498fbf1731ba2c6dcc73e49399083635bc084e8a": {
+ "signature": "3c494c3cdc3d2ab897a96f5b498fbf1731ba2c6dcc73e49399083635bc084e8a",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/aspnetdevcert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "8bb20ad2a210dc906e39ceb48b0a6a39b240878688ad6854161240ae3a597c87": {
+ "signature": "8bb20ad2a210dc906e39ceb48b0a6a39b240878688ad6854161240ae3a597c87",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/eku.client.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "486f45a6c6f00cc927a87f4b7b122829bee893d6f523fed279e7e2deda450aff": {
+ "signature": "486f45a6c6f00cc927a87f4b7b122829bee893d6f523fed279e7e2deda450aff",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/eku.code_signing.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "643ded93447723ad1faad1de45b19108d986db08e488174a5422f3f1f7f0f7a3": {
+ "signature": "643ded93447723ad1faad1de45b19108d986db08e488174a5422f3f1f7f0f7a3",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/eku.multiple_usages.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "51d877cdee6cab498e1a0fd4c4dd2702b3e5da9eb308e0a631d2104e2d3d2a8c": {
+ "signature": "51d877cdee6cab498e1a0fd4c4dd2702b3e5da9eb308e0a631d2104e2d3d2a8c",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/eku.server.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "849b1bea0ba2f8d1c24a58896b9d230ca317e8cff7e9540f73d578dd1aba12cb": {
+ "signature": "849b1bea0ba2f8d1c24a58896b9d230ca317e8cff7e9540f73d578dd1aba12cb",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-aspnet.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "c535332f090c89ae22a79aac4b9d344333c5479b891b79d72d252611c9364450": {
+ "signature": "c535332f090c89ae22a79aac4b9d344333c5479b891b79d72d252611c9364450",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-dsa-protected.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "bc8ce9f1fd92dd123db1b6f8c33d15123bc8f3c4cb4fd42c54b4a2c5210bb158": {
+ "signature": "bc8ce9f1fd92dd123db1b6f8c33d15123bc8f3c4cb4fd42c54b4a2c5210bb158",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-dsa.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "9507f913c4445bebb9bdd471960011afa198c1e42d19c45d44aea58af61a137d": {
+ "signature": "9507f913c4445bebb9bdd471960011afa198c1e42d19c45d44aea58af61a137d",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-ecdsa-protected.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "9ac9e0a5efc7c0d1e6d89422ca8e70e913eaba647ef42650f0bbc50da080a556": {
+ "signature": "9ac9e0a5efc7c0d1e6d89422ca8e70e913eaba647ef42650f0bbc50da080a556",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-ecdsa.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "5d49433b67f4a2f1b6b323c498722d16aeda2d8781dafe9fcb9faaf9db4ee3e1": {
+ "signature": "5d49433b67f4a2f1b6b323c498722d16aeda2d8781dafe9fcb9faaf9db4ee3e1",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-ecdsa.key",
+ "line": 4,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "71ee57f56c77339e4a0cb3f5bdfd05d15191136fc8ad887cef26fe1488522529": {
+ "signature": "71ee57f56c77339e4a0cb3f5bdfd05d15191136fc8ad887cef26fe1488522529",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-rsa-protected.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "74b8ab85959da39f4da6710c6375080c44c8929d6b68f59a06dede355aeffacc": {
+ "signature": "74b8ab85959da39f4da6710c6375080c44c8929d6b68f59a06dede355aeffacc",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/https-rsa.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "ca37e6fb6eb26bdec92893b3f6b08f8f41e6241f573a1b8e14d4e4d4ff1d2c7a": {
+ "signature": "ca37e6fb6eb26bdec92893b3f6b08f8f41e6241f573a1b8e14d4e4d4ff1d2c7a",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/intermediate2_ca.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "d7657bb2e0603e7b353f7b1e1d884306fe44f116c7665192fd6b33003333ef7a": {
+ "signature": "d7657bb2e0603e7b353f7b1e1d884306fe44f116c7665192fd6b33003333ef7a",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/intermediate_ca.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "90b7e7a132c8df4864a9ee49670cbaec9cbc5f5c53bf009eba5a583e0934a24f": {
+ "signature": "90b7e7a132c8df4864a9ee49670cbaec9cbc5f5c53bf009eba5a583e0934a24f",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/leaf.com.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "8a5003e2db05146eaba3a7fc7aba715f51a5506b741a6ac2662e47e39c6165aa": {
+ "signature": "8a5003e2db05146eaba3a7fc7aba715f51a5506b741a6ac2662e47e39c6165aa",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/no_extensions.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "02590eb0efbb241f09bae58f60907c6dee5b33507519a4be87e168a458c2b9cb": {
+ "signature": "02590eb0efbb241f09bae58f60907c6dee5b33507519a4be87e168a458c2b9cb",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/root_ca.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "df250772236d85876a9d789cca90b48e5eb79ad6cb13782465c8c88366c5d845": {
+ "signature": "df250772236d85876a9d789cca90b48e5eb79ad6cb13782465c8c88366c5d845",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Shared/TestCertificates/testCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "0d9b21b17336fcaa4d1e6360b228eef8db6a2afe199d9db14a245eba8e59f9f7": {
+ "signature": "0d9b21b17336fcaa4d1e6360b228eef8db6a2afe199d9db14a245eba8e59f9f7",
+ "alternativeSignatures": [],
+ "target": "src/msbuild/src/Tasks.UnitTests/TestResources/mycert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "3cd8e3eb9b94b01c93591c685406ea91d9d31b16aace0f109734e4bacb3838f2": {
+ "signature": "3cd8e3eb9b94b01c93591c685406ea91d9d31b16aace0f109734e4bacb3838f2",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DefaultBuilder/test/Microsoft.AspNetCore.FunctionalTests/testCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "e91e45a96bf36327f551eadf27d9598b3d058fc051b0f9f0f1da9420410dc79a": {
+ "signature": "e91e45a96bf36327f551eadf27d9598b3d058fc051b0f9f0f1da9420410dc79a",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Servers/IIS/tools/TestCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "1c8a3d52bb83c1fbd1208b94663769b6452e73988540113dff20bfb4df4ca010": {
+ "signature": "1c8a3d52bb83c1fbd1208b94663769b6452e73988540113dff20bfb4df4ca010",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/SignalR/common/Shared/testCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "8839c1c5ab6e962faf123ad7b79a584170d6491855f69555664986a425984a36": {
+ "signature": "8839c1c5ab6e962faf123ad7b79a584170d6491855f69555664986a425984a36",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/SignalR/common/Shared/testCertECC.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "d2df996be35f179b45a3bdc28fcd9d5254a924ab52d2ca14b068bfea35e65284": {
+ "signature": "d2df996be35f179b45a3bdc28fcd9d5254a924ab52d2ca14b068bfea35e65284",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned1024_SHA1.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "7a20b01096651f581c51904be7cd1281150c40efc61352b70aabbca3c40ea177": {
+ "signature": "7a20b01096651f581c51904be7cd1281150c40efc61352b70aabbca3c40ea177",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned1024_SHA256.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "ef394eaa05e6eb5af1f5e523fd01f4e970f36cb2c7eacb3d363b47c9f70b0fec": {
+ "signature": "ef394eaa05e6eb5af1f5e523fd01f4e970f36cb2c7eacb3d363b47c9f70b0fec",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA256.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "cb83a69b59f2de3fa1d049750ddeb855030d5662c43a1c5fea6b95f01e21547f": {
+ "signature": "cb83a69b59f2de3fa1d049750ddeb855030d5662c43a1c5fea6b95f01e21547f",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA256_2.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "d08376cdfec80b5c0884a8b85f18c8b34ffee19f1395d12aef1ffc2821120f03": {
+ "signature": "d08376cdfec80b5c0884a8b85f18c8b34ffee19f1395d12aef1ffc2821120f03",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA384.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "ef471993ee9839701feba16b5b56a926545a165bf95224130d6c8a2bdafdd451": {
+ "signature": "ef471993ee9839701feba16b5b56a926545a165bf95224130d6c8a2bdafdd451",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Certs/SelfSigned2048_SHA512.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "d742600df5b4b6b71f65cf0079b09ec36a5d58bb4b8b07923b13ab8458f68a15": {
+ "signature": "d742600df5b4b6b71f65cf0079b09ec36a5d58bb4b8b07923b13ab8458f68a15",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 31,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "fd9536ec348269dbb12b813270403b7410fc13575d1cbb7770604dcf54ee776b": {
+ "signature": "fd9536ec348269dbb12b813270403b7410fc13575d1cbb7770604dcf54ee776b",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 40,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "1614f1f0821f8900c7c8d2cb3a784272518ef6b86fb82070bda88b4bac9dbda8": {
+ "signature": "1614f1f0821f8900c7c8d2cb3a784272518ef6b86fb82070bda88b4bac9dbda8",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 50,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "3479973e9ab00c84264e70c5d7290a5bfda506aafdb08c3277cb1df5db688ab9": {
+ "signature": "3479973e9ab00c84264e70c5d7290a5bfda506aafdb08c3277cb1df5db688ab9",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 56,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "e5bd231f55be121ed2579da9651c4ec0e661a386991ef8463facf3588c306a06": {
+ "signature": "e5bd231f55be121ed2579da9651c4ec0e661a386991ef8463facf3588c306a06",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 65,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "19661fe89c5e1f59089cdec06cbdf6bdda2439b52731dfd630b50ff5885d6223": {
+ "signature": "19661fe89c5e1f59089cdec06cbdf6bdda2439b52731dfd630b50ff5885d6223",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 75,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "3bf81d57b0872ef6c8ac7878513cb8f58044e07238883f71f24b09542a8d1a07": {
+ "signature": "3bf81d57b0872ef6c8ac7878513cb8f58044e07238883f71f24b09542a8d1a07",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 80,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "2e07fdf491a04fc8a6cc50ae299f8345a81798499bda961a118e974970bb71a8": {
+ "signature": "2e07fdf491a04fc8a6cc50ae299f8345a81798499bda961a118e974970bb71a8",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 86,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "560fdab2979120fa3cfd2d9865d1ce2c0ba164982cc086cdc871b7e16fd12466": {
+ "signature": "560fdab2979120fa3cfd2d9865d1ce2c0ba164982cc086cdc871b7e16fd12466",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 92,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "489c5d92c47b3c961db0d5c32426a4d5fb48311e46ae49791be0f6ef03ddfc6e": {
+ "signature": "489c5d92c47b3c961db0d5c32426a4d5fb48311e46ae49791be0f6ef03ddfc6e",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 101,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "5890ec8b0f533c8186a824f1b46b2d99c2d54e7ed09917e5fedcdaea19b34706": {
+ "signature": "5890ec8b0f533c8186a824f1b46b2d99c2d54e7ed09917e5fedcdaea19b34706",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/azure-activedirectory-identitymodel-extensions-for-dotnet/test/Microsoft.IdentityModel.TestUtils/KeyingMaterial.cs",
+ "line": 230,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0140",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "70a8cd9f176fa02a78470ae78c285f56b617060ec339f0c8dfda095a5b0fc6c9": {
+ "signature": "70a8cd9f176fa02a78470ae78c285f56b617060ec339f0c8dfda095a5b0fc6c9",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/humanizer/src/Humanizer.Tests.Uwp/Humanizer.Tests.Uwp_TemporaryKey.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "7afd296a74705d2e561497c0ab8c3750179c1eff425f496297d3b877ff718526": {
+ "signature": "7afd296a74705d2e561497c0ab8c3750179c1eff425f496297d3b877ff718526",
+ "alternativeSignatures": [],
+ "target": "src/source-build-externals/src/humanizer/src/Humanizer.Tests.Uwp.Runner/Humanizer.Tests.Uwp.Runner_TemporaryKey.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "6ffd69e0724ed3b57e926224932b0aeeed7a834ee5dc1ad24c3262deb49172d7": {
+ "signature": "6ffd69e0724ed3b57e926224932b0aeeed7a834ee5dc1ad24c3262deb49172d7",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/Extensions/test/TestFiles/TestCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "ca298b6b96ebfae8f14e29993264310b89fd738b365c2e7ca04e7af1a5cd67b7": {
+ "signature": "ca298b6b96ebfae8f14e29993264310b89fd738b365c2e7ca04e7af1a5cd67b7",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/Extensions/test/TestFiles/TestCert2.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "8764975fced41745e1a9c844144b2aacd30d3fcd77a8c4b1067adc5f2cd8b990": {
+ "signature": "8764975fced41745e1a9c844144b2aacd30d3fcd77a8c4b1067adc5f2cd8b990",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/Extensions/test/TestFiles/TestCert3.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "7cc3b3782554547d94e0f2e8817dbf823a84de8a95b6b358bdd29067bcff64c3": {
+ "signature": "7cc3b3782554547d94e0f2e8817dbf823a84de8a95b6b358bdd29067bcff64c3",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/Extensions/test/TestFiles/TestCert3WithoutPrivateKey.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "db15b8200219494e427c3943404a81e931bf17af175823bc51da9b85b63a6831": {
+ "signature": "db15b8200219494e427c3943404a81e931bf17af175823bc51da9b85b63a6831",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/Extensions/test/TestFiles/TestCertWithoutPrivateKey.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "979582e68b87ec6e4cd7d90df4e05f01a6f9150ed07a0abc205112a241f0c16f": {
+ "signature": "979582e68b87ec6e4cd7d90df4e05f01a6f9150ed07a0abc205112a241f0c16f",
+ "alternativeSignatures": [],
+ "target": "src/diagnostics/src/SOS/SOS.UnitTests/Debuggees/WebApp3/testCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "56b251ecea166720fac682142922d79e01699a8cc576683b6d8944dfd3158de2": {
+ "signature": "56b251ecea166720fac682142922d79e01699a8cc576683b6d8944dfd3158de2",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 72,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "cbcd76cbd2a6b0a8028fd6c3d1d11ee2e211519af2420396399c3c111a4da667": {
+ "signature": "cbcd76cbd2a6b0a8028fd6c3d1d11ee2e211519af2420396399c3c111a4da667",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 73,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "8060e90601237ded928ae57570ef982dd3a57e7bffbec010fcd37e0bda518f10": {
+ "signature": "8060e90601237ded928ae57570ef982dd3a57e7bffbec010fcd37e0bda518f10",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 90,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "bc4b0a2231b13e5472e1548250ef4d7174d130daf559bca81f5d3c2c0c169690": {
+ "signature": "bc4b0a2231b13e5472e1548250ef4d7174d130daf559bca81f5d3c2c0c169690",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 91,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "91f0752674a19d0db604c50e23950746ff4d231cc76e40a7fa0f53dd5e855f4d": {
+ "signature": "91f0752674a19d0db604c50e23950746ff4d231cc76e40a7fa0f53dd5e855f4d",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 109,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "889e33f8e52ecb1d2b98d28772c572c2a10f0dc0c22fcc03b1da03df008d5f91": {
+ "signature": "889e33f8e52ecb1d2b98d28772c572c2a10f0dc0c22fcc03b1da03df008d5f91",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 110,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "6969ae787ed7e1caef670545de569929814479666e60a227abcb36395c3d3f60": {
+ "signature": "6969ae787ed7e1caef670545de569929814479666e60a227abcb36395c3d3f60",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 111,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "81adfccafd8eb134b75b59de6d4d0d8198c4639a3972d8072b61c67c9e1a104d": {
+ "signature": "81adfccafd8eb134b75b59de6d4d0d8198c4639a3972d8072b61c67c9e1a104d",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/GetCredentialsResponseTests.cs",
+ "line": 112,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "cf0223227addcd8b17bc89e4e5f0ee9174bca83c9ffc5b5493ef74940b33b58c": {
+ "signature": "cf0223227addcd8b17bc89e4e5f0ee9174bca83c9ffc5b5493ef74940b33b58c",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/SetCredentialsRequestTests.cs",
+ "line": 49,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "fc000248c70e613f381ee770fb96dfd28e26766fa9627d28e5b9eb5fb314a3c8": {
+ "signature": "fc000248c70e613f381ee770fb96dfd28e26766fa9627d28e5b9eb5fb314a3c8",
+ "alternativeSignatures": [],
+ "target": "src/nuget-client/test/NuGet.Core.Tests/NuGet.Protocol.Tests/Plugins/Messages/SetCredentialsRequestTests.cs",
+ "line": 72,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "b93b213c68cbbde7c5d0f64b48ad5289efccfcb18e202930a256ac7dbdd2264a": {
+ "signature": "b93b213c68cbbde7c5d0f64b48ad5289efccfcb18e202930a256ac7dbdd2264a",
+ "alternativeSignatures": [],
+ "target": "src/roslyn/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_BasicTests.cs",
+ "line": 4207,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "5ac1e0f1847cf476ae1c810ac0a74ee5993d05873feca939c0df1ac691a1527c": {
+ "signature": "5ac1e0f1847cf476ae1c810ac0a74ee5993d05873feca939c0df1ac691a1527c",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs",
+ "line": 3441,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0060",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "2987ea627ea4f2effb417244c4aac8f554bf42136d6ebe0fef1df440410be09c": {
+ "signature": "2987ea627ea4f2effb417244c4aac8f554bf42136d6ebe0fef1df440410be09c",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs",
+ "line": 2743,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "4c2880cbace8da677942b80be039a982e356c18c827ebeddab265175c9640427": {
+ "signature": "4c2880cbace8da677942b80be039a982e356c18c827ebeddab265175c9640427",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs",
+ "line": 2879,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "849ea2c1bdff1b36df8848a7f8898f11e981c3ba8f9b033abd9d1e8b1a03c8ca": {
+ "signature": "849ea2c1bdff1b36df8848a7f8898f11e981c3ba8f9b033abd9d1e8b1a03c8ca",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/System.Security.Cryptography/tests/X509Certificates/TestData.cs",
+ "line": 2962,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "1706aea6ec9bfbbe540cfab3713db9b1a9ebc7f475b49f2348860e3ee6d8e682": {
+ "signature": "1706aea6ec9bfbbe540cfab3713db9b1a9ebc7f475b49f2348860e3ee6d8e682",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert1.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "8369054f43a96d4f463976b23773b2d22f8081d95f715161f019ceb58296d64a": {
+ "signature": "8369054f43a96d4f463976b23773b2d22f8081d95f715161f019ceb58296d64a",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/DataProtection/DataProtection/test/Microsoft.AspNetCore.DataProtection.Tests/TestFiles/TestCert2.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "4ab520e2ed77b36c88f9eeeb5473205fd7f8f0a761eacee4cbbff389368dad8f": {
+ "signature": "4ab520e2ed77b36c88f9eeeb5473205fd7f8f0a761eacee4cbbff389368dad8f",
+ "alternativeSignatures": [
+ "7ad51ffeb7d5438f15781162de5183c58d5db2d195f96e8c3527451adeb4e02c"
+ ],
+ "target": "src/aspnetcore/src/Hosting/Server.IntegrationTesting/src/Deployers/RemoteWindowsDeployer/RemotePSSessionHelper.ps1",
+ "line": 40,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingConvertToSecureStringWithPlainText",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "96ab8bbaf30065be77880d679174d028a151c0fc888fca38a79038d341710563": {
+ "signature": "96ab8bbaf30065be77880d679174d028a151c0fc888fca38a79038d341710563",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Security/Authentication/Negotiate/samples/NegotiateAuthSample/Startup.cs",
+ "line": 30,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-MSFT0090",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "7bda7ae4037698bbdf188b4d3fb8a82e99063a8df2dcfe5f66ef747e3bd3f1a0": {
+ "signature": "7bda7ae4037698bbdf188b4d3fb8a82e99063a8df2dcfe5f66ef747e3bd3f1a0",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Security/Authentication/Negotiate/test/Negotiate.FunctionalTest/negotiateAuthCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "a2dcb4a5d7e266049f9f865b27e69af19447e94f63ec9de8290763ddf901c756": {
+ "signature": "a2dcb4a5d7e266049f9f865b27e69af19447e94f63ec9de8290763ddf901c756",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Security/Authentication/Negotiate/test/Negotiate.Test/LdapSettingsValidationTests.cs",
+ "line": 25,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-MSFT0090",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "3aaf66a9a1f5bfba3b78eb7964ce8bf4dcabf7132465a31e219c6961f53dec56": {
+ "signature": "3aaf66a9a1f5bfba3b78eb7964ce8bf4dcabf7132465a31e219c6961f53dec56",
+ "alternativeSignatures": [],
+ "target": "src/aspnetcore/src/Middleware/WebSockets/test/ConformanceTests/AutobahnTestApp/TestResources/testCert.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "c6ed8bf76382b72621892d895d0659eb8ed66ef400f5d38506a3b62129b0f60e": {
+ "signature": "c6ed8bf76382b72621892d895d0659eb8ed66ef400f5d38506a3b62129b0f60e",
+ "alternativeSignatures": [
+ "07873a6bbdd04caf121ed279cd4c24e55fb79ae3e86083c413b839d8d5e81cba"
+ ],
+ "target": "src/runtime/src/libraries/Common/tests/System/Net/Prerequisites/Deployment/setup_activedirectory_domaincontroller.ps1",
+ "line": 36,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingConvertToSecureStringWithPlainText",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "c511a0f0c15b79748a62ee0198689e7a0c8c2af102730c337823f6cd52b3ec66": {
+ "signature": "c511a0f0c15b79748a62ee0198689e7a0c8c2af102730c337823f6cd52b3ec66",
+ "alternativeSignatures": [
+ "7142b2e2126a0c0e5bf2ad08e9e56d405620fbb9f12dfcd3f90a9dfcc30f8bf5"
+ ],
+ "target": "src/runtime/src/libraries/Common/tests/System/Net/Prerequisites/Deployment/setup_iisserver.ps1",
+ "line": 82,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "psscriptanalyzer",
+ "ruleId": "PSAvoidUsingConvertToSecureStringWithPlainText",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "bfe258b52e19062b9009a68549bff3b2c99a6105f493cbf14332b3366691d446": {
+ "signature": "bfe258b52e19062b9009a68549bff3b2c99a6105f493cbf14332b3366691d446",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyPemTests.cs",
+ "line": 54,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "52364f6839cf4bc824f1c82a31f3c7ee1cfb228383b3bee476ef7442526c0de8": {
+ "signature": "52364f6839cf4bc824f1c82a31f3c7ee1cfb228383b3bee476ef7442526c0de8",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyPemTests.cs",
+ "line": 358,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "cef12040ed2c91d3bd7eba717e6c4bff8e547cb6d2b40363f1d859b02c873276": {
+ "signature": "cef12040ed2c91d3bd7eba717e6c4bff8e547cb6d2b40363f1d859b02c873276",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyPemTests.cs",
+ "line": 61,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "ab290d190fa6582f2826c9b8524a4013ea67380f65328bc39c31dbcba59ec63c": {
+ "signature": "ab290d190fa6582f2826c9b8524a4013ea67380f65328bc39c31dbcba59ec63c",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyPemTests.cs",
+ "line": 168,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "710963884a4d1e73d1ff4da0db7e1c8e1eeae25fe4a9e3c1de8b5019bb5d9d74": {
+ "signature": "710963884a4d1e73d1ff4da0db7e1c8e1eeae25fe4a9e3c1de8b5019bb5d9d74",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyPemTests.cs",
+ "line": 412,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "db276fb1ea2a8e74e7ab80522362b8f402d361652ca823d7cab59465d038eb82": {
+ "signature": "db276fb1ea2a8e74e7ab80522362b8f402d361652ca823d7cab59465d038eb82",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
+ "line": 229,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "807277ed6647bcdc3eab2e24d8fbcaca0a6506d2ed455248b0497ceb42831e30": {
+ "signature": "807277ed6647bcdc3eab2e24d8fbcaca0a6506d2ed455248b0497ceb42831e30",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
+ "line": 328,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "685288ad132baddbcdf7a2201960f6d48805151f1aef2e094c4dbc16841b3e54": {
+ "signature": "685288ad132baddbcdf7a2201960f6d48805151f1aef2e094c4dbc16841b3e54",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyPemTests.cs",
+ "line": 489,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "e972eb97ea7ea4a9524820036a42557f13a48240b6083c7baa0d465c00adfdee": {
+ "signature": "e972eb97ea7ea4a9524820036a42557f13a48240b6083c7baa0d465c00adfdee",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/gRPC/grpc-dotnet/testassets/Certs/InteropTests/server1.key",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "1b2c907630acaff5b6e62eb4895043c82e93d885331f1f46296812634fd30abe": {
+ "signature": "1b2c907630acaff5b6e62eb4895043c82e93d885331f1f46296812634fd30abe",
+ "alternativeSignatures": [],
+ "target": "src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/gRPC/grpc-dotnet/testassets/Certs/InteropTests/server1.pfx",
+ "line": 1,
+ "memberOf": [
+ "default"
+ ],
+ "tool": "credscan",
+ "ruleId": "CSCAN-GENERAL0020",
+ "createdDate": "2024-04-02 08:30:33Z",
+ "expirationDate": "2024-09-19 11:21:54Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2024-04-02 11:21:54Z"
+ },
+ "b1a4e35c6f6e2d47dbcac13c715893653c3bb2c754a5a7fe6399f5ff21e74038": {
+ "signature": "b1a4e35c6f6e2d47dbcac13c715893653c3bb2c754a5a7fe6399f5ff21e74038",
+ "alternativeSignatures": [
+ "89a6120a7a327b4237773410934c46acfe5519839e770df5cb3e1468e65cb71d"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-x86.zip/shared/Microsoft.NETCore.App/10.0.0-rc.1.25502.108/pgort140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:27:46Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "13e53e10c92cc5effa6cfa9ee9a12076f3013ff2bb350387077b141c6497169f": {
+ "signature": "13e53e10c92cc5effa6cfa9ee9a12076f3013ff2bb350387077b141c6497169f",
+ "alternativeSignatures": [
+ "52ed7325288709348459996965423183afecf0fafdb0c6e2f32de37fa7b8020f"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-x86.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:27:46Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "faf0f1cf576e3ae00c738698fb086b2edb23118e441aec3a44501073bfbd57d1": {
+ "signature": "faf0f1cf576e3ae00c738698fb086b2edb23118e441aec3a44501073bfbd57d1",
+ "alternativeSignatures": [
+ "72577e042c4deb1859f569d414ea39b44bf3301330a78242e0d459e1d57dce73"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-x86.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:27:46Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "f0641e291fd7b4c041d2f5a1c788a6f4bdc540f825c0b2d9a42d2fc5e5d42cf8": {
+ "signature": "f0641e291fd7b4c041d2f5a1c788a6f4bdc540f825c0b2d9a42d2fc5e5d42cf8",
+ "alternativeSignatures": [
+ "968ab4f609cb8418bd48e95e0528daa2cfa64d30f15f3b23b1716d27559f3721"
+ ],
+ "target": "artifacts/packages/Release/NonShipping/arcade/gdn-Microsoft.DotNet.SignCheck.11.0.0-beta.25502.108.nupkg/tools/winterop.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "67713a5842aee81d885c418ad955663ca50804a3406ffa54210c5b4f802d235e": {
+ "signature": "67713a5842aee81d885c418ad955663ca50804a3406ffa54210c5b4f802d235e",
+ "alternativeSignatures": [
+ "5be43d512e86d10c1f195fe42e38a2a31b27a2a22a2598df92e79b603b93d02e"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/python.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "0fee4802d05838bc2ac1693c62c2d06eded190d02af69e1592f8c466991a8784": {
+ "signature": "0fee4802d05838bc2ac1693c62c2d06eded190d02af69e1592f8c466991a8784",
+ "alternativeSignatures": [
+ "967b8e9808f44938a1eafa10c4df03f1f4728cb7c622c05556d2495929a0732b"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/python311.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "3c95e62450aba7299a724597b109084e0b16152feed00033115c1fdf2f364db0": {
+ "signature": "3c95e62450aba7299a724597b109084e0b16152feed00033115c1fdf2f364db0",
+ "alternativeSignatures": [
+ "9fd3a1add81af22778a6794ec31ce343319c9b9fb2a36a5b7d11ae57f3300b5f"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/pythonw.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "9f7b8c414f7aefbca8ceafe605b486bb1835cfcaafb3013137718e0f916688a8": {
+ "signature": "9f7b8c414f7aefbca8ceafe605b486bb1835cfcaafb3013137718e0f916688a8",
+ "alternativeSignatures": [
+ "f166031a8e2a689be432e308af8548ba7d1586c48123c051d1be9c6123c227f6"
+ ],
+ "target": "artifacts/packages/Release/NonShipping/arcade/gdn-Microsoft.DotNet.SignCheckTask.11.0.0-beta.25502.108.nupkg/lib/net/winterop.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "05189863b82096832a660f1e01ec735359f58e9c6693ed5f1125055d86f9169d": {
+ "signature": "05189863b82096832a660f1e01ec735359f58e9c6693ed5f1125055d86f9169d",
+ "alternativeSignatures": [
+ "d68bd067927adf3129aefd09ad6a350f00eeb570daedcf30a6546840c084d81f"
+ ],
+ "target": "artifacts/packages/Release/NonShipping/arcade/gdn-Microsoft.DotNet.SignCheckTask.11.0.0-beta.25502.108.nupkg/lib/netframework/winterop.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "6cfc27271fe2d31d5d4f21f80e54a1a610637b5d8f7359995f939322ce3f916b": {
+ "signature": "6cfc27271fe2d31d5d4f21f80e54a1a610637b5d8f7359995f939322ce3f916b",
+ "alternativeSignatures": [
+ "acb7542d2d43f6851c3e77b9eb72527779838bb133adf6db891a5631a35f6620"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Node.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/node.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "02d4643dee81896d22745590731ee2367603cdaca456790429ce81e6031ddca8": {
+ "signature": "02d4643dee81896d22745590731ee2367603cdaca456790429ce81e6031ddca8",
+ "alternativeSignatures": [
+ "03fca0aa1b32cecac33dd9e65703b3bd03ccc12b1b2bdbf72729bad511227a71"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/libcrypto-1_1.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "7bfd851dd05c872084901d1191fac7a460a6b2aa44d15ea4d09d9206c8135efb": {
+ "signature": "7bfd851dd05c872084901d1191fac7a460a6b2aa44d15ea4d09d9206c8135efb",
+ "alternativeSignatures": [
+ "8c5739b132bdd4dc841dff1f920859f8a1f72633b0247e12f3dcdb1ed119118c"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/libffi-8.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "0e3871e0517f179825f08c32840c37cd8127fbbfbdc28f05461317cdcbdf7ce8": {
+ "signature": "0e3871e0517f179825f08c32840c37cd8127fbbfbdc28f05461317cdcbdf7ce8",
+ "alternativeSignatures": [
+ "62c9390883ffade1edcbbaa81b42faafb0ef623876afd25eed91a09d28da4b30"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/libssl-1_1.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "b2483930fe85bb60fd8ccfc009c24017a008fa917a12f2db595309dd98af813b": {
+ "signature": "b2483930fe85bb60fd8ccfc009c24017a008fa917a12f2db595309dd98af813b",
+ "alternativeSignatures": [
+ "b3ef03cd0f2d65f68e7dd260944954af496f2f09b9259765c53355f33a09b1b3"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/sqlite3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "1dbd981155b4350d707c97d60d13439782c804155e0f713d553da4bdcf0cf745": {
+ "signature": "1dbd981155b4350d707c97d60d13439782c804155e0f713d553da4bdcf0cf745",
+ "alternativeSignatures": [
+ "db8eada4fa32f729ae94d3ea31adf0f7b378bbd42b78868c13f9d2f14dba743a"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-as.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "cbb656150acc03a17364565046449f56afc76408ced114a655a0dcb05f31ed91": {
+ "signature": "cbb656150acc03a17364565046449f56afc76408ced114a655a0dcb05f31ed91",
+ "alternativeSignatures": [
+ "9373981f810bce595d6f8a43c75c0b2bce7d2f52deab202ce02b41eee9ee8ff9"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-ctor-eval.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "ec41a8a87efa39dbd9d17926a95fadc5630aba170c9e054a1ae42078ece2a377": {
+ "signature": "ec41a8a87efa39dbd9d17926a95fadc5630aba170c9e054a1ae42078ece2a377",
+ "alternativeSignatures": [
+ "a488a332ce32157923f7c87987e2eaf87e16d7769f8dc4caaa6498440227405f"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-dis.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "76f59cc377c3ea7a99b2e2447e43781a2bf3be48a33d6ace9c1c54cbd1691b7e": {
+ "signature": "76f59cc377c3ea7a99b2e2447e43781a2bf3be48a33d6ace9c1c54cbd1691b7e",
+ "alternativeSignatures": [
+ "705d36060ccb25ac33c988f1421e2178b02bcc92634275de56b117d8ec0b7f96"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-emscripten-finalize.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "024fa5301f3575390086ae804602ab4af21b2141dd73916ff86dc443361f52aa": {
+ "signature": "024fa5301f3575390086ae804602ab4af21b2141dd73916ff86dc443361f52aa",
+ "alternativeSignatures": [
+ "3a45c46312cc741895275bbeca3379649406a380b5975410cbca3e4ef1650db6"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-fuzz-lattices.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "8f04767dfd27efcda4fdfbec9f04315400a9730b396c8e4ff5cb67c1c4e77e72": {
+ "signature": "8f04767dfd27efcda4fdfbec9f04315400a9730b396c8e4ff5cb67c1c4e77e72",
+ "alternativeSignatures": [
+ "c7d9993738cb57b61ccd7dd628ff036bd373ea927bf39aaea469dbe3e77ff5d2"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-fuzz-types.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "d40e6851155762cfc6a8ff8b0dcdfe550c17a55d5d5cfc405e350f5b1c29d144": {
+ "signature": "d40e6851155762cfc6a8ff8b0dcdfe550c17a55d5d5cfc405e350f5b1c29d144",
+ "alternativeSignatures": [
+ "8c3028867026eeba81df7ea7b82758af6c74fb793374e542760c0f7965592965"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-merge.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "781ded98de7ac07f9cf926252ceeb0c4cd9f8569de11cd55d88701608530b5a9": {
+ "signature": "781ded98de7ac07f9cf926252ceeb0c4cd9f8569de11cd55d88701608530b5a9",
+ "alternativeSignatures": [
+ "8c1167dad9ce205146a7618bbbc7c0fc9da3fb7d072396acefbc72078f30bc74"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-metadce.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "9fbf6e887d56593bef399aa3c9b9395db73822bbcfb81c8a6ea78fd183a0d00e": {
+ "signature": "9fbf6e887d56593bef399aa3c9b9395db73822bbcfb81c8a6ea78fd183a0d00e",
+ "alternativeSignatures": [
+ "eab53ad84490648fd035541e728d9a554e35a10c07f66a384a3ffebb5b0e87e6"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-opt.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "8f90fbd9eee9fec759935fb4d02c1392946a22533412a61cfdb91eb4501e68cf": {
+ "signature": "8f90fbd9eee9fec759935fb4d02c1392946a22533412a61cfdb91eb4501e68cf",
+ "alternativeSignatures": [
+ "000f79bdb952139fe4ef8510783559c9966ef197c578b5389b6569e237963e14"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-reduce.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "de0defd9b26cc2046d60827b3102c2b178415ece5076480b9744a3701efbbf38": {
+ "signature": "de0defd9b26cc2046d60827b3102c2b178415ece5076480b9744a3701efbbf38",
+ "alternativeSignatures": [
+ "70f004bde6290488c2f023a1e1dfd0b35d66e1a2bccc11034daae0f1f5f95f0d"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-shell.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "a81975b343c5313cab035a5d322c81181e4f7ebd10e3399a78df1234579bb7e7": {
+ "signature": "a81975b343c5313cab035a5d322c81181e4f7ebd10e3399a78df1234579bb7e7",
+ "alternativeSignatures": [
+ "12cb40097fd2ef1a6635e96297a0aad21327059c8aaef2d172dbda81ab32ae1b"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-split.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "e5a2edd2e2dcc3edfcceca7cd1a604b7851a67100e89286bd200c1c2772a8044": {
+ "signature": "e5a2edd2e2dcc3edfcceca7cd1a604b7851a67100e89286bd200c1c2772a8044",
+ "alternativeSignatures": [
+ "308c6aae6e167c90312ad5eea661937440456fa2586c2013d38812f3d831e024"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-x64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm2js.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "df1aa6cc2afc109c2cf28c097fab07badd9bba1a6ae033271b3f6235e3291d7a": {
+ "signature": "df1aa6cc2afc109c2cf28c097fab07badd9bba1a6ae033271b3f6235e3291d7a",
+ "alternativeSignatures": [
+ "c357dfb740203d92abd503e3d69a1d948af9091442deccce970462d86aeb5f5e"
+ ],
+ "target": "artifacts/packages/Release/NonShipping/wpf/gdn-runtime.win-x64.Microsoft.DotNet.Wpf.GitHub.10.0.0-rc.1.25502.108.nupkg/runtimes/win-x64/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "c1be0f6fb53b6ea4050ea7424603669f0982a551138ac02245bbd64227326a5d": {
+ "signature": "c1be0f6fb53b6ea4050ea7424603669f0982a551138ac02245bbd64227326a5d",
+ "alternativeSignatures": [
+ "3932ecc7c7cdfdac506abc1e52e0256592b24cbf150f62a051958ac2a0ca6e3d"
+ ],
+ "target": "artifacts/packages/Release/Shipping/vstest/gdn-Microsoft.TestPlatform.TestHost.18.0.0-preview-25502-108.nupkg/lib/net8.0/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "5cdbef1911a7a7c21e9fb5cacbf8b8677c9971092ab64a7f04d68065f50fe92f": {
+ "signature": "5cdbef1911a7a7c21e9fb5cacbf8b8677c9971092ab64a7f04d68065f50fe92f",
+ "alternativeSignatures": [
+ "9bcf8577915ccab267862ce1a00373abed5e4d928663bd5b49f10ff2e9fd7965"
+ ],
+ "target": "artifacts/packages/Release/Shipping/vstest/gdn-Microsoft.TestPlatform.TestHost.18.0.0-preview-25502-108.nupkg/lib/net8.0/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "d5a52ebd5c210820734e5d7f05dcab401bfd9ece76811cba7cfd175891ef73d3": {
+ "signature": "d5a52ebd5c210820734e5d7f05dcab401bfd9ece76811cba7cfd175891ef73d3",
+ "alternativeSignatures": [
+ "2425b2e7ecf48101e65a899c03380a895655b58c6231af3a1d44061f7322163f"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-10.0.100-rc.2.25502.108-win-x64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "fb2231919574d47b4b621dce6ffabc4a8587f3a401dbc2d93cba3989101c0991": {
+ "signature": "fb2231919574d47b4b621dce6ffabc4a8587f3a401dbc2d93cba3989101c0991",
+ "alternativeSignatures": [
+ "b32f25f713894911af41e646e9566c92b94d3911ac7e45a673c0455c8a240e89"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-10.0.100-rc.2.25502.108-win-x64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "ca6c4c6ed2f6d813f89ac02d3dffe6474131e87377b74dbd2e0d2b1160000047": {
+ "signature": "ca6c4c6ed2f6d813f89ac02d3dffe6474131e87377b74dbd2e0d2b1160000047",
+ "alternativeSignatures": [
+ "ec078fc50ce8b43ea2a65d035af9fc8306a3655e683523eda5c60f7a399e3d3c"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.TestPlatform.TestHost.18.0.0-preview-25502-108.symbols.nupkg/lib/net8.0/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "3442a8439d57ca8a0379c5e41bbdd10f52c74f0ade7409a08403d7a6338d5094": {
+ "signature": "3442a8439d57ca8a0379c5e41bbdd10f52c74f0ade7409a08403d7a6338d5094",
+ "alternativeSignatures": [
+ "12906435fa67e59f08c2f92ae5669bccccba39a307e31e767c26f7ec5e0c668e"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.TestPlatform.TestHost.18.0.0-preview-25502-108.symbols.nupkg/lib/net8.0/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "c2380a81994190aef6609573ff05a793aa1c13fe3b0ff8ab3e7472207c90bb0f": {
+ "signature": "c2380a81994190aef6609573ff05a793aa1c13fe3b0ff8ab3e7472207c90bb0f",
+ "alternativeSignatures": [
+ "5b70d443252104a129c66d974d671df6b13674d114c0714c62f3685742b69e8c"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.WindowsDesktop.App.Runtime.win-x64.10.0.0-rc.1.25502.108.symbols.nupkg/runtimes/win-x64/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "aaccf2efeeb282e6b1a2959af9303390439ccd2776e31af5b51664dad32a9aa6": {
+ "signature": "aaccf2efeeb282e6b1a2959af9303390439ccd2776e31af5b51664dad32a9aa6",
+ "alternativeSignatures": [
+ "6c8747ce0c0af3335d012feb7e7b13c7cef449db978d20521fe51ace1d82fe5a"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-runtime.win-x64.Microsoft.DotNet.Wpf.GitHub.10.0.0-rc.1.25502.108.symbols.nupkg/runtimes/win-x64/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "ef571cdd3dded762c12349c914f6e061b2a58104527396926500a425c0f28fe9": {
+ "signature": "ef571cdd3dded762c12349c914f6e061b2a58104527396926500a425c0f28fe9",
+ "alternativeSignatures": [
+ "17d3df0e6fe15fffd13ce3c9971210822b13e58687bd0046a7e0d2a208763708"
+ ],
+ "target": "artifacts/packages/Release/Shipping/vstest/gdn-Microsoft.TestPlatform.CLI.18.0.0-preview-25502-108.nupkg/contentFiles/any/net9.0/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "edf2ab0c86c89aed232c27937c192e4a035cb89809ba0d5b89dae8e5176165c5": {
+ "signature": "edf2ab0c86c89aed232c27937c192e4a035cb89809ba0d5b89dae8e5176165c5",
+ "alternativeSignatures": [
+ "0a4a24a5b055631d0d7045fc2b368eca3a00648cc8bb9c9f49e1c4fc3a03765a"
+ ],
+ "target": "artifacts/packages/Release/Shipping/vstest/gdn-Microsoft.TestPlatform.CLI.18.0.0-preview-25502-108.nupkg/contentFiles/any/net9.0/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "2033877cf8794a81127de497c63057f338d090083649de819baf086429c7fea5": {
+ "signature": "2033877cf8794a81127de497c63057f338d090083649de819baf086429c7fea5",
+ "alternativeSignatures": [
+ "4f92264f1ee7f5da6487cf5a5c52e54f3312636090f0a6d160d9b6a92d8c10df"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.TestPlatform.CLI.18.0.0-preview-25502-108.symbols.nupkg/contentFiles/any/net9.0/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "ccb5151bf7ff40b005a8b6a657310c8a398c50253dcd803ef19ee6f9c3631677": {
+ "signature": "ccb5151bf7ff40b005a8b6a657310c8a398c50253dcd803ef19ee6f9c3631677",
+ "alternativeSignatures": [
+ "ec9e9e897bf291eef6b4346aa7d8cb37a86dfb5decdb5260db0fc0f8a77ad712"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.TestPlatform.CLI.18.0.0-preview-25502-108.symbols.nupkg/contentFiles/any/net9.0/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:01:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "ea3f5bded86323088d7076ed6f743874f3464abedb2809ada060b093e20e26b1": {
+ "signature": "ea3f5bded86323088d7076ed6f743874f3464abedb2809ada060b093e20e26b1",
+ "alternativeSignatures": [
+ "f7c0707362b152fc8ce120cd4c23d53cee7d7066219b4f4a33bfb5dcce318d88"
+ ],
+ "target": "artifacts/packages/Release/NonShipping/wpf/gdn-runtime.win-x86.Microsoft.DotNet.Wpf.GitHub.10.0.0-rc.1.25502.108.nupkg/runtimes/win-x86/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 21:30:12Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "b70ac6417c02105848419028ade16fcc44972d631b9fbd7e5ec3130ebfdb18c3": {
+ "signature": "b70ac6417c02105848419028ade16fcc44972d631b9fbd7e5ec3130ebfdb18c3",
+ "alternativeSignatures": [
+ "b68f35127803d50fbc42cda951e529f57b0b2aa8bfb2a4a9e06fea3cbe7c507d"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-10.0.100-rc.2.25502.108-win-x86.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:30:12Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "0e77e5c8a4fc1fc39f17e58230601665e9a5cce134bc463306e5edf69113b4a3": {
+ "signature": "0e77e5c8a4fc1fc39f17e58230601665e9a5cce134bc463306e5edf69113b4a3",
+ "alternativeSignatures": [
+ "df24689d7c5c9e01eb0bc5f1e252c5b288f71f593ad9597520f9596a6b07b9c5"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-10.0.100-rc.2.25502.108-win-x86.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:30:12Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "2c4082f5972891f8ee540d8b9aac9dcc86d58fb0562833491731fa358e3d0b19": {
+ "signature": "2c4082f5972891f8ee540d8b9aac9dcc86d58fb0562833491731fa358e3d0b19",
+ "alternativeSignatures": [
+ "5de4b311481c71137f4af527fbf8f0b84bb7c731b7f7d65c6da1fd62e4a2b469"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.WindowsDesktop.App.Runtime.win-x86.10.0.0-rc.1.25502.108.symbols.nupkg/runtimes/win-x86/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 21:30:12Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "86072ada24477bf451b98d951ad8bc10c930c4e3a291f29837d1b2138b02969f": {
+ "signature": "86072ada24477bf451b98d951ad8bc10c930c4e3a291f29837d1b2138b02969f",
+ "alternativeSignatures": [
+ "c65128ca8c8a7c533a0f16a68e8d8216f06636d9a921da9e6d9f817d83a121bc"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-runtime.win-x86.Microsoft.DotNet.Wpf.GitHub.10.0.0-rc.1.25502.108.symbols.nupkg/runtimes/win-x86/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 21:30:12Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "1ba08945e0c66c73328584ad4884def99c0008fdc7edd415a7c5d6b529bf8bde": {
+ "signature": "1ba08945e0c66c73328584ad4884def99c0008fdc7edd415a7c5d6b529bf8bde",
+ "alternativeSignatures": [
+ "ca05e5cf0615f7ad08756f9e7da2c7fe0dee4a82a0bd6754160f92734dbb0a6c"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/python.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "0b449732366978c1acaa71aea325a05df77daafed5c7e196196294daf6edb244": {
+ "signature": "0b449732366978c1acaa71aea325a05df77daafed5c7e196196294daf6edb244",
+ "alternativeSignatures": [
+ "b988b00755ae4051d64263c6b9fe62ccc5365c0920168db4352cc775595a59a1"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/python311.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "35720572ff89bc08fec585f0e196e8e71e77701b1a69a2c5f61babb9d5e1018d": {
+ "signature": "35720572ff89bc08fec585f0e196e8e71e77701b1a69a2c5f61babb9d5e1018d",
+ "alternativeSignatures": [
+ "a62e810f9d2405c546e9b072b614030caf7a510758eedf005a1e4640aca69e0d"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/pythonw.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "40d640724c84e5e1ba3f3e634cbe103c7d99d6cff6a7971f774ea17741c7eb28": {
+ "signature": "40d640724c84e5e1ba3f3e634cbe103c7d99d6cff6a7971f774ea17741c7eb28",
+ "alternativeSignatures": [
+ "1d746633d2ba961237adf2f4f5fdc5c1ad18a8f70f7f1023d5ed2314f9056f6d"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Node.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/node.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "1f7c3f3d8efcdd183753099acb13d4c62e8fbdde72bfa01813822c4f434085f9": {
+ "signature": "1f7c3f3d8efcdd183753099acb13d4c62e8fbdde72bfa01813822c4f434085f9",
+ "alternativeSignatures": [
+ "013f212b819eda0c7ef336486fc08b322d9b489e48af62a84979fef2f1888b7a"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/libcrypto-1_1-arm64.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "b5e56198a2166716f8d1180717469eec17817e302af806c3ca1095bda1299149": {
+ "signature": "b5e56198a2166716f8d1180717469eec17817e302af806c3ca1095bda1299149",
+ "alternativeSignatures": [
+ "17fc098435410868788691b1e8ebc6f1c51c53a5e4b41d3b6a86b281f62847a5"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/libffi-8.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "5fcd00b6f7a0e4897dc8f2c267fce3bdeca2961fc269bbf093f98fa0abc905d7": {
+ "signature": "5fcd00b6f7a0e4897dc8f2c267fce3bdeca2961fc269bbf093f98fa0abc905d7",
+ "alternativeSignatures": [
+ "aab83bcf0f7d509903dcefc262b11fad3a96bd79d1285adc88aad294861affb1"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/libssl-1_1-arm64.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "ed6e5d4963ea3a4d978d6c543366aa9452c890e9f1a7c0f1247325e29bcea782": {
+ "signature": "ed6e5d4963ea3a4d978d6c543366aa9452c890e9f1a7c0f1247325e29bcea782",
+ "alternativeSignatures": [
+ "0beff131e1fb8419072f461a2c5f24df9efac487782eac1afb7c9ba898c4c855"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Python.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/DLLs/sqlite3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "14f8f9189ed31b84a0ad36698646c7cff58d6167124ff9375e37b7ffbffa849b": {
+ "signature": "14f8f9189ed31b84a0ad36698646c7cff58d6167124ff9375e37b7ffbffa849b",
+ "alternativeSignatures": [
+ "c47610878022fa177a28f6eab8301663750817f694deeba90df796938ebfa5b2"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-as.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "63386d2b07d75fe2db413cfc2fd99810b1885d3c9960cac67c26c7129f21e71a": {
+ "signature": "63386d2b07d75fe2db413cfc2fd99810b1885d3c9960cac67c26c7129f21e71a",
+ "alternativeSignatures": [
+ "c8ba98ce42b285c391708713bee9e144c31597902b9a00b8ccc6b7dfa9d2cd32"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-ctor-eval.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "4234798402cdb18c0f1181f054147a87abd16c016ed68279c499933dead8f18f": {
+ "signature": "4234798402cdb18c0f1181f054147a87abd16c016ed68279c499933dead8f18f",
+ "alternativeSignatures": [
+ "3de42dc30777140eeaa5a9bfc793c8733c06e2654a4856ca79a0f7c0718d3489"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-dis.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "c3deb33ac73aacb03e45c81f7b0c87158c253557eb1f4afdf0c9d21a5a5de242": {
+ "signature": "c3deb33ac73aacb03e45c81f7b0c87158c253557eb1f4afdf0c9d21a5a5de242",
+ "alternativeSignatures": [
+ "ec5fe5158ea4b571b38e02ba42f905cab55d2ab23e9cf05ac4e3c0de83f68a13"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-emscripten-finalize.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "e05ab16f68102cf7c299e4686d55cbe075d72a1f18957b98d350640653a22131": {
+ "signature": "e05ab16f68102cf7c299e4686d55cbe075d72a1f18957b98d350640653a22131",
+ "alternativeSignatures": [
+ "b976d229fe6cf84bfb8f4cc130a0fc8cb857732422d986b522e5c00ef4402acf"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-fuzz-lattices.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "e86426235304d266a679b898b747b4ce36515f3d80a437d21c91dafc0e72f469": {
+ "signature": "e86426235304d266a679b898b747b4ce36515f3d80a437d21c91dafc0e72f469",
+ "alternativeSignatures": [
+ "d17fd3b360e9c2f6183c25e815d3340c3351d9345112e437ae92d0f327d5328e"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-fuzz-types.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "4168f212ef0117b3095a51061f0c69b4c106d1b8b67819a292dff159f2ce93c4": {
+ "signature": "4168f212ef0117b3095a51061f0c69b4c106d1b8b67819a292dff159f2ce93c4",
+ "alternativeSignatures": [
+ "57c374509d926289985697614003ee9a0495cfec23c023445a84b713b26d4bff"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-merge.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "aa3a79ba341ea50fd4b8b647183729d027f81a82ee6bcd175f8b45b817f625cf": {
+ "signature": "aa3a79ba341ea50fd4b8b647183729d027f81a82ee6bcd175f8b45b817f625cf",
+ "alternativeSignatures": [
+ "af0fde3afeaa1130d35daafe3413c1e324135385d686dcc576809bdb25326609"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-metadce.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "f7d19d83158eac73990cc59e1ee44fcca2e451058e5ac5c99a9c875b9c941099": {
+ "signature": "f7d19d83158eac73990cc59e1ee44fcca2e451058e5ac5c99a9c875b9c941099",
+ "alternativeSignatures": [
+ "36094b8e3b70d6f1f94dc8a7f8c870f6c569d2e876c6c16db1a12cf24cc53478"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-opt.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "3624c6ca4296839fc1110446e9e8a310f15f1b2d3412b98404152441c11fa77f": {
+ "signature": "3624c6ca4296839fc1110446e9e8a310f15f1b2d3412b98404152441c11fa77f",
+ "alternativeSignatures": [
+ "d38f36b0f1b23122ea94b58ca5f9f8797e0eaa02caeda293bfe4722404b3cceb"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-reduce.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "04f8f5404ddd74178f02f47cd3a50261f9587fe01273f0dc39d9fa72410af77e": {
+ "signature": "04f8f5404ddd74178f02f47cd3a50261f9587fe01273f0dc39d9fa72410af77e",
+ "alternativeSignatures": [
+ "dad2707f29c9acbea3eda1305da9f096b5f42add7500104fdd0d0778178e77ff"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-shell.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "e90ac9380e7420e98535cca35dfcbe1693491bbe6c6304d3b29c1f7739a61339": {
+ "signature": "e90ac9380e7420e98535cca35dfcbe1693491bbe6c6304d3b29c1f7739a61339",
+ "alternativeSignatures": [
+ "a106ee5a986aa4eb4af594c7c149846058e5807af2fd02549cad3fc60e5b82a5"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm-split.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "2d8d2dc6bed5dcad23eb78e05d88b037b9e7599cc0d15e1022614757dce9d867": {
+ "signature": "2d8d2dc6bed5dcad23eb78e05d88b037b9e7599cc0d15e1022614757dce9d867",
+ "alternativeSignatures": [
+ "b0b22882021bda24b1a4e748223dd6da166d09711782bdadae1c5b56270dbcbf"
+ ],
+ "target": "artifacts/packages/Release/Shipping/emsdk/gdn-Microsoft.NET.Runtime.Emscripten.3.1.56.Sdk.win-arm64.10.0.0-rc.1.25502.108.nupkg/tools/bin/wasm2js.exe",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "6259412a4e5276951d2cdf13c684bea47102fd44b010189a60bb94dc52fc7139": {
+ "signature": "6259412a4e5276951d2cdf13c684bea47102fd44b010189a60bb94dc52fc7139",
+ "alternativeSignatures": [
+ "3e2ce2f85fe2d39e1910328c5f150da1819ac4174906ce77aaa1c7911dbe8532"
+ ],
+ "target": "artifacts/packages/Release/NonShipping/wpf/gdn-runtime.win-arm64.Microsoft.DotNet.Wpf.GitHub.10.0.0-rc.1.25502.108.nupkg/runtimes/win-arm64/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "b1570a73fa466fca46dd44ef8708889b7a30cc7d7ee6baa3039fa8c6f6a00a30": {
+ "signature": "b1570a73fa466fca46dd44ef8708889b7a30cc7d7ee6baa3039fa8c6f6a00a30",
+ "alternativeSignatures": [
+ "28e3bdb04b186359d73f970e872f1e0b44577c23d55d754348f64e84bd2adf53"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-10.0.100-rc.2.25502.108-win-arm64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "da9d9479c9c0b83810d01a5b96c7683036556a738c7802132af6de96ddf0be7d": {
+ "signature": "da9d9479c9c0b83810d01a5b96c7683036556a738c7802132af6de96ddf0be7d",
+ "alternativeSignatures": [
+ "706689d7bd92d8fb0103027d72a74ec4a852fce529c8d9aba53882e9f9813b35"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-10.0.100-rc.2.25502.108-win-arm64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "11ece6129bfdcc0fd8b77ae979b71fe2437e37217a74a407b66366c3af4cd7a7": {
+ "signature": "11ece6129bfdcc0fd8b77ae979b71fe2437e37217a74a407b66366c3af4cd7a7",
+ "alternativeSignatures": [
+ "8d4825ad2e8e89b2eb1e80497ab858287ed270c024c794571a65e121a2d75b4b"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-Microsoft.WindowsDesktop.App.Runtime.win-arm64.10.0.0-rc.1.25502.108.symbols.nupkg/runtimes/win-arm64/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "179ad8f8c976b5f59750a91911ad43810a56a8f7dc9cffe62d80be9e49a91bc0": {
+ "signature": "179ad8f8c976b5f59750a91911ad43810a56a8f7dc9cffe62d80be9e49a91bc0",
+ "alternativeSignatures": [
+ "31dfd79e271d36f0d104313ebe6b56e30e4736c4666259b465eb0020778c93fb"
+ ],
+ "target": "artifacts/assets/Release/assets/symbols/dotnet-dotnet/20251002.8/gdn-runtime.win-arm64.Microsoft.DotNet.Wpf.GitHub.10.0.0-rc.1.25502.108.symbols.nupkg/runtimes/win-arm64/native/PresentationNative_cor3.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2007",
+ "createdDate": "2025-10-02 21:50:29Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "29c68f5f4fa12fac1bce05d79696e6920a12255e5cfb92f8462c36e7adce0ebf": {
+ "signature": "29c68f5f4fa12fac1bce05d79696e6920a12255e5cfb92f8462c36e7adce0ebf",
+ "alternativeSignatures": [
+ "5b3215012d46284ab33aafdf007458a49c10f389af74c8debe5ec33b57c178cf"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-x64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:42:43Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "fb815f05aca12b80acbbb7c4f200e4657660fe3d6ee1af6419dd312f81d98a06": {
+ "signature": "fb815f05aca12b80acbbb7c4f200e4657660fe3d6ee1af6419dd312f81d98a06",
+ "alternativeSignatures": [
+ "fe169538efbb430a89a48a1fb75d5e51de9376f5060530ef5eee622e0988bcd5"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-x64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 22:42:43Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "bd462cd1515b7f004badbcf510229dff9fabbe5dae3486faa119d7f8d5a2bd98": {
+ "signature": "bd462cd1515b7f004badbcf510229dff9fabbe5dae3486faa119d7f8d5a2bd98",
+ "alternativeSignatures": [
+ "926e6f98a4124e10b1186470517addaed0909f0dfcaf86c7525abd470a7ec1c5"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-arm64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x64/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:43:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ },
+ "d905ffe10b6aa3c41965a455ab64944ac1c1dca94a554cf7e49c213a4b9f2369": {
+ "signature": "d905ffe10b6aa3c41965a455ab64944ac1c1dca94a554cf7e49c213a4b9f2369",
+ "alternativeSignatures": [
+ "f926d889635beb5cc9e8134e09b81383c7a0303556c34d2da8f7ed1e25f5040b"
+ ],
+ "target": "artifacts/assets/Release/Sdk/10.0.100-rc.2.25502.108/gdn-dotnet-sdk-pgo-10.0.100-rc.2.25502.108-win-arm64.zip/sdk/10.0.100-rc.2.25502.108/TestHostNetFramework/x86/msdia140.dll",
+ "memberOf": [
+ "default"
+ ],
+ "tool": "binskim",
+ "ruleId": "BA2008",
+ "createdDate": "2025-10-02 21:43:50Z",
+ "expirationDate": "2026-03-22 00:14:24Z",
+ "justification": "This error is baselined with an expiration date of 180 days from 2025-10-03 00:14:24Z"
+ }
+ }
+}
\ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 77c6d68c2bd2..597d3891c030 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -20,6 +20,8 @@
},
"remoteEnv": {
"PATH": "${containerWorkspaceFolder}/.dotnet:${containerEnv:PATH}",
+ // Enable SHA1. Required for compilers to strong name assemblies.
+ "OPENSSL_ENABLE_SHA1_SIGNATURES":"1",
},
"onCreateCommand": ".devcontainer/init.sh"
}
diff --git a/.github/ISSUE_TEMPLATE/unified-build-operational-issue.yml b/.github/ISSUE_TEMPLATE/unified-build-operational-issue.yml
new file mode 100644
index 000000000000..0b909aea51e2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/unified-build-operational-issue.yml
@@ -0,0 +1,57 @@
+name: Unified Build Operational Issue
+description: Report operational issues related to unified build infrastructure
+title: "[Operational Issue]: "
+labels: ["area-unified-build-OperationalIssue"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Use this template to report operational issues with the unified build infrastructure.
+
+ - type: textarea
+ id: error
+ attributes:
+ label: Error
+ description: Provide the error message or description of the operational issue
+ placeholder: |
+ Include stack traces, error messages, or detailed descriptions of the problem.
+ validations:
+ required: true
+
+ - type: textarea
+ id: links
+ attributes:
+ label: Links
+ description: Provide relevant links (build logs, pipeline runs, etc.)
+ placeholder: |
+ - https://dev.azure.com/...
+ - https://github.com/...
+ validations:
+ required: false
+
+ - type: input
+ id: root-cause
+ attributes:
+ label: Root Cause
+ description: Current understanding of the root cause
+ value: unknown
+ validations:
+ required: false
+
+ - type: checkboxes
+ id: blocking
+ attributes:
+ label: Blocking
+ description: Is this issue blocking any releases or critical workflows?
+ options:
+ - label: This issue is blocking
+
+ - type: checkboxes
+ id: affected-releases
+ attributes:
+ label: Affected Releases
+ description: Select the releases affected by this operational issue
+ options:
+ - label: .NET 10
+ - label: .NET 10 (SDK band build)
+ - label: .NET 11
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000000..87ca1035f54a
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,9 @@
+version: 2
+updates:
+ - package-ecosystem: "nuget"
+ directory: "/eng/dependabot"
+ open-pull-requests-limit: 5
+ schedule:
+ interval: "weekly"
+ labels:
+ - "dependencies"
diff --git a/.github/policies/assign_ownership.yml b/.github/policies/assign_ownership.yml
index 5abc3fd72525..8598f02c8d1e 100644
--- a/.github/policies/assign_ownership.yml
+++ b/.github/policies/assign_ownership.yml
@@ -9,7 +9,215 @@ configuration:
if:
- payloadType: Pull_Request
- filesMatchPattern:
- pattern: src/arcade/.*
+ pattern: 'src/arcade/.*'
+ matchAny: true
then:
- requestReview:
teamReviewer: dnceng
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/aspnetcore/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: aspnet-build
+ # - description:
+ # if:
+ # - payloadType: Pull_Request
+ # - filesMatchPattern:
+ # pattern: 'src/cecil/.*'
+ # matchAny: true
+ # then:
+ # - requestReview:
+ # teamReviewer: PLACEHOLDER
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/command-line-api/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: system-commandline
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/deployment-tools/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: deployment-tools-admins
+ # - description:
+ # if:
+ # - payloadType: Pull_Request
+ # - filesMatchPattern:
+ # pattern: 'src/diagnostics/.*'
+ # matchAny: true
+ # then:
+ # - requestReview:
+ # teamReviewer: PLACEHOLDER
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/efcore/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: efteam
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/emsdk/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: dnr-codeflow
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/fsharp/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: fsharp
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/msbuild/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: msbuild
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/nuget-client/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: nuget-team
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/razor/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: roslyn-infrastructure-current-swat
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/roslyn/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: roslyn-infrastructure-current-swat
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/runtime/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: dnr-codeflow
+ # - description:
+ # if:
+ # - payloadType: Pull_Request
+ # - filesMatchPattern:
+ # pattern: 'src/scenario-tests/.*'
+ # matchAny: true
+ # then:
+ # - requestReview:
+ # teamReviewer: PLACEHOLDER
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/sdk/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: dotnet-cli
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/source-build-reference-packages/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: source-build
+ # - description:
+ # if:
+ # - payloadType: Pull_Request
+ # - filesMatchPattern:
+ # pattern: 'src/sourcelink/.*'
+ # matchAny: true
+ # then:
+ # - requestReview:
+ # teamReviewer: PLACEHOLDER
+ # - description:
+ # if:
+ # - payloadType: Pull_Request
+ # - filesMatchPattern:
+ # pattern: 'src/symreader/.*'
+ # matchAny: true
+ # then:
+ # - requestReview:
+ # teamReviewer: PLACEHOLDER
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/templating/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: templating-engine-maintainers
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/vstest/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: testing-admin
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/windowsdesktop/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: wpf-developers
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/winforms/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: dotnet-winforms-admin
+ - description:
+ if:
+ - payloadType: Pull_Request
+ - filesMatchPattern:
+ pattern: 'src/wpf/.*'
+ matchAny: true
+ then:
+ - requestReview:
+ teamReviewer: wpf-developers
diff --git a/.github/workflows/protected-files-validation.yml b/.github/workflows/protected-files-validation.yml
deleted file mode 100644
index 2e7c8e3c1271..000000000000
--- a/.github/workflows/protected-files-validation.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: 'Check Protected Files for Changes'
-
-on:
- pull_request:
- # Update the error message when changing these paths
- paths:
- - eng/common/**/*
- - eng/Version.Details.xml
- - eng/Versions.props
-
-permissions:
- pull-requests: read
-
-jobs:
- check-protect-files:
- runs-on: ubuntu-22.04
- if: ${{ github.event.pull_request.user.login != 'dotnet-sb-bot' && github.event.pull_request.user.login != 'dotnet-maestro[bot]' }}
- steps:
- - name: Protected File has Changes
- run: |
- echo "${{ github.event.pull_request.user.login }} cannot make changes to 'eng/Version.Details.xml', 'eng/Versions.props', and 'eng/common/'."
- exit 1
diff --git a/.gitignore b/.gitignore
index 1f77e38b1215..c5f20d339622 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
/prereqs/packages
/src/nuget-client/NuGet.config
*.binlog
+
+# Visual Studio
+.vs/
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
index c7200938e920..749f68c6f687 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -61,8 +61,11 @@
true
true
-
+
+
true
+ true
+
latest
false
diff --git a/Directory.Build.targets b/Directory.Build.targets
index a2cc483d74e0..4d65de75c2a6 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,6 +1,7 @@
+
@@ -37,72 +38,19 @@
-
- dotnet-runtime-
-
+
+
+
-
+
-
-
-
-
- %(RuntimeArchiveItem.Filename)%(RuntimeArchiveItem.Extension)
- %(RuntimeArchiveItem.Identity)
- $(RuntimeFilename.Replace('$(RuntimeFilenamePrefix)','').Replace('-$(TargetRid)$(ArchiveExtension)',''))
+ $([System.IO.Path]::GetFileName($([System.IO.Path]::GetDirectoryName('%(RuntimeVersionFile.Identity)'))))
-
-
-
- <_PreviouslySourceBuiltSharedComponentAssetManifests>$(SharedComponentsArtifactsPath)VerticalManifest.xml
- ;@(SharedRepositoryReference);
-
- false
-
-
-
-
-
-
-
-
-
- <_ItemsToRemove Include="@(_SharedComponentFilteredPackages)"
- Condition="!$(SharedRepositoryReferenceString.Contains(';%(RepoOrigin);')) or $([System.String]::new(';$(BootstrapArcadeRepos);').Contains(';%(RepoOrigin);'))" />
-
-
-
-
- <_ItemsToRemove Include="@(_SharedComponentFilteredPackages)"
- Condition="$(SharedRepositoryReferenceString.Contains(';%(RepoOrigin);')) and !$([System.String]::new(';$(BootstrapArcadeRepos);').Contains(';%(RepoOrigin);'))" />
-
-
-
-
- <_ItemsToRemoveString>@(_ItemsToRemove->'%(Identity)::%(Version)', ';')
-
-
-
- <_SharedComponentFilteredPackages Remove="@(_SharedComponentFilteredPackages)"
- Condition="'@(_ItemsToRemove)' != '' and
- '$(_ItemsToRemoveString)' != '' and
- $(_ItemsToRemoveString.Contains($([System.String]::Concat('%(Identity)', '::', '%(Version)'))))" />
-
-
-
diff --git a/Directory.Packages.props b/Directory.Packages.props
index d54bcf6c82dc..144830a2968b 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,5 +1,8 @@
+
+
+
true
true
@@ -10,6 +13,9 @@
+
+
+
@@ -18,10 +24,15 @@
+
+
+
+
+
@@ -29,7 +40,6 @@
-
diff --git a/NuGet.config b/NuGet.config
index 5d682a461ed3..2cdbcd1c13e1 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -9,12 +9,11 @@
+
+
+
-
-
-
-
diff --git a/README.md b/README.md
index 0afab37865af..70b39bebf18e 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,7 @@ For the latest information about Source-Build support for new .NET versions, ple
## Code flow
-The VMR's code flow operates in two directions. Individual repositories flow source changes into the VMR upon promotion of their local official builds (forward flow). The VMR changes are checked in, an official build happens, and then source changes + packages flows backward into the constituent repositories (back flow). For more details on code flow and code flow pull requests, please see this information on [Code Flow PRs](src/arcade/Documentation/UnifiedBuild/Codeflow-PRs.md).
+The contents of the VMR are two-way synchronized with the product repositories via code flow PRs. Individual repositories flow source changes into the VMR upon promotion of their local official builds (forward flow). The VMR changes are checked in, an official build happens, and then source changes + packages flow backward into the constituent repositories (back flow). For more details on code flow and code flow pull requests, please see this information on [Code Flow PRs](docs/Codeflow-PRs.md).
## Contribution
@@ -193,11 +193,11 @@ Usually, this means the [dotnet/dotnet repository](https://github.com/dotnet/dot
In practice, this means that when calling the main build script, you need to provide additional arguments when building outside of a context of a git repository.
Alternatively, you can also provide a manifest file where this information can be read from. This file (`release.json`) can be found attached with the [dotnet/dotnet release](https://github.com/dotnet/dotnet/releases).
-### Synchronizing code into the VMR
+### Manually synchronizing code with the VMR
-Sometimes you want to make a change in a repository and test that change in the VMR. You could of course make the change in the VMR directly, but in case it's already available in your repository, you can synchronize it locally into your clone of the VMR, commit, and then open a PR.
+Sometimes you want to make a change in a repository and test that change in the VMR locally (or vice versa). You could of course make the change in the VMR directly, but in case it's already available in your repository, you can synchronize it locally into your clone of the VMR, commit, and then open a PR.
-To do this, you need to use the [`darc vmr forwardflow` command](https://github.com/dotnet/arcade-services/blob/main/docs/Darc.md#forwardflow) which can move your changes from your repository's dev branch into a local VMR one. Please refer to command's documentation (`--help`) for more details.
+To do this, you need to use the [`darc vmr forwardflow`](https://github.com/dotnet/arcade-services/blob/main/docs/Darc.md#forwardflow) or [`darc vmr backflow`](https://github.com/dotnet/arcade-services/blob/main/docs/Darc.md#backflow) commands which can move your changes from your repository's dev branch into a local VMR one. Please refer to command's documentation (`--help`) for more details.
## Filing Issues
diff --git a/SECURITY.md b/SECURITY.md
index e0dfff56a956..fc35b099d319 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -10,11 +10,9 @@ If you believe you have found a security vulnerability in any Microsoft-owned re
**Please do not report security vulnerabilities through public GitHub issues.**
-Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
+Please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
-If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
-
-You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
+You should receive a response within 24 hours. If for some reason you do not, please follow up via the [MSRC Researcher Portal](https://msrc.microsoft.com/report/vulnerability/), using the Message functionality found at the bottom of the Activity tab on your vulnerability report.
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
diff --git a/THIRD-PARTY-NOTICES.txt b/THIRD-PARTY-NOTICES.txt
index 5878c2c180e2..cdabd1859a1f 100644
--- a/THIRD-PARTY-NOTICES.txt
+++ b/THIRD-PARTY-NOTICES.txt
@@ -3270,57 +3270,6542 @@ Copyright: (c) Microsoft Corporation
License: https://visualstudio.microsoft.com/license-terms/mt736442/
#############################################
-### roslyn-analyzers
+### roslyn
#############################################
-Roslyn-Analyzers uses third-party libraries or other resources that may be
-distributed under licenses different than the Roslyn-Analyzers software.
+NOTICES AND INFORMATION
+Do Not Translate or Localize
+
+This software incorporates material from third parties.
+Microsoft makes certain open source code available at https://3rdpartysource.microsoft.com,
+or you may send a check or money order for US $5.00, including the product name,
+the open source component name, platform, and version number, to:
+
+Source Code Compliance Team
+Microsoft Corporation
+One Microsoft Way
+Redmond, WA 98052
+USA
+
+Notwithstanding any other terms, you may reverse engineer this software to the extent
+required to debug changes to any libraries licensed under the GNU Lesser General Public License.
+
+---------------------------------------------------------
+
+JSONTestSuite
+
+https://github.com/nst/JSONTestSuite
+
+Copyright (c) 2016 Nicolas Seriot
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+BasicUndo 0.9.3 - Apache-2.0
+
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Castle.Core 4.3.1 - Apache-2.0
+
+
+(c) 2004-2018 Castle Project - http://www.castleproject.org
+Copyright 2004-2016 Castle Project - http://www.castleproject.org
+Copyright (c) 2004-2018 Castle Project - http://www.castleproject.org
+
+Copyright 2004-2016 Castle Project - http://www.castleproject.org/
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+DiffPlex 1.7.2 - Apache-2.0
+
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Common 6.3.4 - Apache-2.0
+
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Configuration 6.3.4 - Apache-2.0
+
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Frameworks 6.3.4 - Apache-2.0
+
+
+(c) Microsoft Corporation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Packaging 6.3.4 - Apache-2.0
+
+
+(c) Microsoft Corporation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Protocol 6.3.4 - Apache-2.0
+
+
+(c) Microsoft Corporation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Resolver 6.3.4 - Apache-2.0
+
+
+(c) Microsoft Corporation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.SolutionRestoreManager.Interop 4.8.0 - Apache-2.0
+
+
+(c) Microsoft Corporation.
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NuGet.Versioning 6.3.4 - Apache-2.0
+
+
+(c) Microsoft Corporation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+SQLitePCLRaw.bundle_green 2.1.0 - Apache-2.0
+
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+SQLitePCLRaw.core 2.1.0 - Apache-2.0
+
+
+Copyright 2014-2022 SourceGear, LLC
+Copyright 2014-2022 SourceGear, LLC SSQLitePCLRaw
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+SQLitePCLRaw.lib.e_sqlite3 2.1.0 - Apache-2.0
+
+
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+SQLitePCLRaw.provider.dynamic_cdecl 2.1.0 - Apache-2.0
+
+
+Copyright 2014-2022 SourceGear, LLC
+Copyright 2014-2022 SourceGear, LLC SSQLitePCLRaw
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+SQLitePCLRaw.provider.e_sqlite3 2.1.0 - Apache-2.0
+
+
+Copyright 2014-2022 SourceGear, LLC
+Copyright 2014-2022 SourceGear, LLC SSQLitePCLRaw
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.abstractions 2.0.1 - Apache-2.0
+
+
+Copyright (c) Outercurve Foundation
+Copyright (c) Outercurve Foundation WrapNonExceptionThrows RSDS
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.abstractions 2.0.3 - Apache-2.0
+
+
+Copyright (c) Outercurve Foundation
+Copyright (c) Outercurve Foundation WrapNonExceptionThrows RSDS
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.analyzers 1.17.0 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) .NET Foundation xUnit.net
+Copyright (c) .NET Foundation xunit.analyzers, analyzers, roslyn, xunit, xunit.net
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.assert 2.9.2 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) .NET Foundation xUnit.net
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.core 2.9.2 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.extensibility.core 2.2.0 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) .NET Foundation RSDSk C BuildAgent
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.extensibility.core 2.9.2 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) .NET Foundation xUnit.net
+Copyright (c) .NET Foundation 0xUnit.net
+Copyright (c) .NET Foundation xUnit.net Runner Utility
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.extensibility.execution 2.9.2 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) .NET Foundation xUnit.net
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.runner.utility 2.9.2 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) .NET Foundation xUnit.net Runner Utility
+Copyright (c) .NET Foundation ,xUnit.net Runner Utility
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+xunit.runner.visualstudio 3.1.3 - Apache-2.0
+
+
+Copyright (c) .NET Foundation
+Copyright (c) Outercurve Foundation
+
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+
+
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+
+
+ "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+
+
+ "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+
+
+ "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+
+ "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+ (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+
+you may not use this file except in compliance with the License.
+
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+
+distributed under the License is distributed on an "AS IS" BASIS,
+
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+
+See the License for the specific language governing permissions and
+
+limitations under the License.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Moq 4.10.1 - BSD-3-Clause
+
+
+Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors
+
+Copyright (c) . All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+LibGit2Sharp.NativeBinaries 2.0.306 - GPL-2.0-only WITH GCC-exception-2.0
+
+
+Copyright Rich Salz.
+Copyright 1995-2017 Mark Adler
+Copyright (c) 2007 Francois Gouget
+Copyright (c) 2011 by Vicent Marti
+Copyright (c) 2011-2015 Vicent Marti
+Copyright 1995-2017 Mark Adler +3 CScs DEFG
+copyrighted by the Free Software Foundation
+Copyright (c) 2017 Marc Stevens Cryptology Group
+Copyright 2006-2010 The Apache Software Foundation
+Copyright 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright 2010 Volkan Yazici
+Copyright (c) 1989, 1991 Free Software Foundation, Inc.
+Copyright (c) 1991, 1999 Free Software Foundation, Inc.
+Copyright (c) 1995-2010 Jean-loup Gailly and Mark Adler
+CopyrightInfo AbstractInfo FormattingImplementationInfo
+Copyright (c) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008 Free Software Foundation, Inc.
+
+GPL-2.0-only WITH GCC-exception-2.0
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VsSDK.CompatibilityAnalyzer 17.14.1043-preview2 - LGPL-2.1-or-later AND Apache-2.0 AND Apache-2.0 AND Apache-2.0 AND MPL-2.0 AND BSD-2-Clause AND BSD-3-Clause AND LicenseRef-scancode-ms-net-library-2019-06 AND LicenseRef-scancode-ms-net-library-2018-11 AND LicenseRef-scancode-ms-vs-addons-ext-17.2.0 AND MIT AND MS-PL AND MS-RL
+
+
+(c) Andrew Arnott
+copyright company
+(c) Microsoft 2023
+(c) Microsoft 2024
+(c) Microsoft 2025
+Copyright (c) 2021
+(c) 2003-2004 Various
+(c) 2019 GitHub, Inc.
+(c) 2022 GitHub, Inc.
+(c) 2023 GitHub, Inc.
+(c) 2006 Entrust, Inc.
+Copyright (c) Microsoft
+Copyright 2015 The gRPC
+Copyright 2019 The gRPC
+Copyright Nate McMaster
+Copyright (c) Six Labors
+Copyright Microsoft 2015
+(c) Microsoft Corporation
+Copyright (c) Hank McCord
+Copyright (c) Manuel Romer
+Copyright (c) Andrew Arnott
+Copyright (c) Nate McMaster
+Copyright 2015, Google Inc.
+Copyright 2019 LLVM Project
+(c) 1999 Entrust.net Limited
+(c) 2009 Entrust, Inc. - for
+(c) 2012 Entrust, Inc. - for
+(c) 2015 Entrust, Inc. - for
+Copyright (c) 1998 Microsoft
+Copyright 2012 Andrew Arnott
+Copyright 2018 Daniel Lemire
+Copyright Andrew Arnott 2012
+Copyright (c) .NET Foundation
+Copyright (c) Six Labors Gets
+Copyright (c) by P.J. Plauger
+Copyright 2012 the V8 project
+Copyright 1995-2017 Mark Adler
+Copyright 1995-2022 Mark Adler
+Copyright 2008 - 2018 Jb Evain
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+Copyright (c) 2023 Sergio Pedri
+Copyright 2000-2022 SharpZipLib
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) Rackspace, US Inc.
+Copyright James Newton-King 2008
+Copyright James Newton-King 2017
+Copyright (c) 2013 Scott Kirkland
+Copyright (c) 2014, Karlis Gangis
+Copyright (c) 2015 Dennis Fischer
+Copyright (c) 2022, Wojciech Mula
+Copyright 2012 Andrew Arnott RSA1
+Copyright 2012-2017 Mehdi Khalili
+Copyright (c) 2008 - 2015 Jb Evain
+Copyright (c) 2015 .NET Foundation
+Copyright (c) 2015 Christian Klutz
+Copyright (c) 2017 Marcos Lopez C.
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright EvidenceFile FileVersion
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) Outercurve Foundation
+Copyright LibGit2Sharp contributors
+(c) Yoshifumi Kawai and contributors
+ACopyright (c) Microsoft Corporation
+CCopyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) James Newton-King 2008
+Copyright (c) James Newton-King 2017
+Copyright Nate McMaster Command-line
+DCopyright (c) Microsoft Corporation
+OCopyright (c) Microsoft Corporation
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2012-2014 Mehdi Khalili
+Copyright (c) 2013-2014 Omar Khudeira
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008 - 2011 Novell, Inc.
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) .NET Foundation xUnit.net
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Portions (c) International Organization
+Copyright (c) .NET Foundation 0xUnit.net
+Copyright 2014 Giovanni Bassi and Elemar
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) Sven Groot (Ookii.org) 2009
+Copyright (c) The Internet Society (2003)
+Copyright James Newton-King 2008 Json.NET
+Copyright (c) .NET Foundation Contributors
+Copyright (c) 2021 Copyright (c) Six Labors
+Copyright (c) 2020 Mara Bos
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) Tunnel Vision Laboratories, LLC.
+Copyright Tunnel Vision Laboratories, LLC 2015
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) Copyright (c) 2015 Dennis Fischer
+Copyright 2024 Dr.-Ing. Mario Heiderich, Cure53
+Copyright AssemblyCompany AssemblyConfiguration
+Copyright (c) 2005 - 2020 Giacomo Stelluti Scala
+copyright tag should contain a non-empty company
+Copyright (c) 2024 http://microsoft.com Microsoft
+Copyright (c) 2017 Yoshifumi Kawai and contributors
+Copyright 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+(c) 2005 - 2020 Giacomo Stelluti Scala & Contributors
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright 2012-2016 Copyright 2012-2017 Mehdi Khalili
+Copyright (c) .NET Foundation xUnit.net Runner Utility
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2013-2014 Omar Khudeira (http://omar.io)
+(c) 2006 Entrust, Inc. Label Entrust Root Certification
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
+Unknown Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) .NET Foundation xUnit.net Runner Reporters
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) Andrew Arnott InputValidation IntegrityCheck
+(c) 2004-2022 Castle Project - http://www.castleproject.org
+Copyright (c) .NET Foundation xUnit.net Console Test Runner
+Copyright (c) .NET Foundation -xUnit.net Console Test Runner
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Copyright (c) 2005 - 2015 Giacomo Stelluti Scala & Contributors
+Copyright (c) 2005 - 2020 Giacomo Stelluti Scala & Contributors
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright 2004-2021 Castle Project - http://www.castleproject.org
+Copyright (c) .NET Foundation and Contributors. Visual Studio 2019
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 2004-2022 Castle Project - http://www.castleproject.org
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright (c) 2023 Sergio Pedri OriginalFilename PolySharp.SourceGenerators.dll
+Copyright 2015, Google Inc. Protocol Buffers Binary Serialization Format Google
+(c) Cure53 and other contributors Copyright 2024 Dr.-Ing. Mario Heiderich, Cure53
+Copyright (c) .NET Foundation xunit.analyzers, analyzers, roslyn, xunit, xunit.net
+(c) 1999 Entrust.net Limited Label Entrust.net Premium 2048 Secure Server CA Serial
+Copyright (c) .NET Foundation and Contributors. xUnit.net Testing Framework +xUnit.net
+Copyright 2015 Tunnel Vision Laboratories, LLC StyleCop DotNetAnalyzers Roslyn Diagnostic
+Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors
+Copyright 2018 Tunnel Vision Laboratories, LLC Documentation DotNetAnalyzers Roslyn Diagnostic
+Copyright Tunnel Vision Laboratories, LLC 2018 1Copyright Tunnel Vision Laboratories, LLC 2018
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+MICROSOFT SOFTWARE LICENSE TERMS
+MICROSOFT VISUAL STUDIO ADD-ONs and EXTENSIONS
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to use solely with
+Visual Studio Community
+Visual Studio Professional
+Visual Studio Enterprise
+Visual Studio Code
+2. THIRD PARTY COMPONENTS.
+The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
+3. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the software documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft's privacy statement to your users. The Microsoft privacy statement is located here https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use from the software documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr.
+4. SCOPE OF LICENSE. The software is licensed, not sold. These license terms only give you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in these license terms. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. In addition, you may not
+* work around any technical limitations in the software;
+* reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;
+* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+* use the software in any way that is against the law;
+* share, publish, rent, or lease the software; or
+* provide the software as a stand-alone offering or combine it with any of your applications for others to use, or transfer the software or this agreement to any third party.
+5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+6. SUPPORT SERVICES. Because this software is "as is", we may not provide support services for it.
+7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+9. CONSUMER RIGHTS; REGIONAL VARIATIONS. These license terms describe certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. You may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b. Canada. You may stop receiving updates on your device by turning off Internet access. If and when you re-connect to the Internet, the software will resume checking for and installing updates.
+c. Germany and Austria.
+(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in the case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+Subject to the preceding sentence (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
+10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED "AS-IS". YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.TeamFoundation.DistributedTask.Common.Contracts 19.232.0-preview - LicenseRef-scancode-ms-net-library-2018-11
+
+
+(c) Microsoft 2024
+(c) Microsoft Corporation
+
+MICROSOFT SOFTWARE LICENSE TERMS
+
+MICROSOFT .NET LIBRARY
+
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to design, develop and test you�re applications. You may modify, copy, distribute or deploy any .js files contained in the software as part of your applications.
+
+2. THIRD PARTY COMPONENTS. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
+3. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.
+a. DISTRIBUTABLE CODE. In addition to the .js files described above, the software is comprised of Distributable Code. �Distributable Code� is code that you are permitted to distribute in programs you develop if you comply with the terms below.
+i. Right to Use and Distribute.
+� You may copy and distribute the object code form of the software.
+
+� Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.
+
+ii. Distribution Requirements. For any Distributable Code you distribute, you must
+� use the Distributable Code in your programs and not as a standalone distribution;
+
+� require distributors and external end users to agree to terms that protect it at least as much as this agreement;
+
+� display your valid copyright notice on your programs; and
+
+� indemnify, defend, and hold harmless Microsoft from any claims, including attorneys� fees, related to the distribution or use of your applications, except to the extent that any claim is based solely on the Distributable Code.
+
+iii. Distribution Restrictions. You may not
+� alter any copyright, trademark or patent notice in the Distributable Code;
+
+� use Microsoft�s trademarks in your programs� names or in a way that suggests your programs come from or are endorsed by Microsoft;
+
+� include Distributable Code in malicious, deceptive or unlawful programs; or
+
+� modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that
+
+� the code be disclosed or distributed in source code form; or
+
+� others have the right to modify it.
+
+4. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft�s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at http://go.microsoft.com/?linkid=9840733.
+5. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not
+� work around any technical limitations in the software;
+
+� reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software;
+
+� remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+
+� use the software in any way that is against the law; or
+
+� share, publish, rent or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.
+
+6. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+7. SUPPORT SERVICES. Because this software is �as is,� we may not provide support services for it.
+8. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+9. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+10. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
+c) Germany and Austria.
+(i) Warranty. The software will perform substantially as described in any Microsoft materials that accompany it. However, Microsoft gives no contractual guarantee in relation to the software.
+
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+
+Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence
+11. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED �AS-IS.� YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+12. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.
+
+
+
+Remarque : Ce logiciel �tant distribu� au Qu�bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran�ais.
+
+
+
+EXON�RATION DE GARANTIE. Le logiciel vis� par une licence est offert � tel quel �. Toute utilisation de ce logiciel est � votre seule risque et p�ril. Microsoft n�accorde aucune autre garantie expresse. Vous pouvez b�n�ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit� marchande, d�ad�quation � un usage particulier et d�absence de contrefa�on sont exclues.
+
+
+
+LIMITATION DES DOMMAGES-INT�R�TS ET EXCLUSION DE RESPONSABILIT� POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement � hauteur de 5,00 $ US. Vous ne pouvez pr�tendre � aucune indemnisation pour les autres dommages, y compris les dommages sp�ciaux, indirects ou accessoires et pertes de b�n�fices.
+
+
+
+Cette limitation concerne:
+
+� tout ce qui est reli� au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et
+
+� les r�clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit� stricte, de n�gligence ou d�une autre faute dans la limite autoris�e par la loi en vigueur.
+
+
+
+Elle s�applique �galement, m�me si Microsoft connaissait ou devrait conna�tre l��ventualit� d�un tel dommage. Si votre pays n�autorise pas l�exclusion ou la limitation de responsabilit� pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l�exclusion ci-dessus ne s�appliquera pas � votre �gard.
+
+
+
+EFFET JURIDIQUE. Le pr�sent contrat d�crit certains droits juridiques. Vous pourriez avoir d�autres droits pr�vus par les lois de votre pays. Le pr�sent contrat ne modifie pas les droits que vous conf�rent les lois de votre pays si celles-ci ne le permettent pas.
+
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.TeamFoundationServer.Client 19.232.0-preview - LicenseRef-scancode-ms-net-library-2018-11
+
+
+(c) Microsoft 2023
+(c) Microsoft Corporation
+
+MICROSOFT SOFTWARE LICENSE TERMS
+
+MICROSOFT .NET LIBRARY
+
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to design, develop and test you�re applications. You may modify, copy, distribute or deploy any .js files contained in the software as part of your applications.
+
+2. THIRD PARTY COMPONENTS. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
+3. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.
+a. DISTRIBUTABLE CODE. In addition to the .js files described above, the software is comprised of Distributable Code. �Distributable Code� is code that you are permitted to distribute in programs you develop if you comply with the terms below.
+i. Right to Use and Distribute.
+� You may copy and distribute the object code form of the software.
+
+� Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.
+
+ii. Distribution Requirements. For any Distributable Code you distribute, you must
+� use the Distributable Code in your programs and not as a standalone distribution;
+
+� require distributors and external end users to agree to terms that protect it at least as much as this agreement;
+
+� display your valid copyright notice on your programs; and
+
+� indemnify, defend, and hold harmless Microsoft from any claims, including attorneys� fees, related to the distribution or use of your applications, except to the extent that any claim is based solely on the Distributable Code.
+
+iii. Distribution Restrictions. You may not
+� alter any copyright, trademark or patent notice in the Distributable Code;
+
+� use Microsoft�s trademarks in your programs� names or in a way that suggests your programs come from or are endorsed by Microsoft;
+
+� include Distributable Code in malicious, deceptive or unlawful programs; or
+
+� modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that
+
+� the code be disclosed or distributed in source code form; or
+
+� others have the right to modify it.
+
+4. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft�s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at http://go.microsoft.com/?linkid=9840733.
+5. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not
+� work around any technical limitations in the software;
+
+� reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software;
+
+� remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+
+� use the software in any way that is against the law; or
+
+� share, publish, rent or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.
+
+6. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+7. SUPPORT SERVICES. Because this software is �as is,� we may not provide support services for it.
+8. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+9. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+10. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
+c) Germany and Austria.
+(i) Warranty. The software will perform substantially as described in any Microsoft materials that accompany it. However, Microsoft gives no contractual guarantee in relation to the software.
+
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+
+Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence
+11. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED �AS-IS.� YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+12. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.
+
+
+
+Remarque : Ce logiciel �tant distribu� au Qu�bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran�ais.
+
+
+
+EXON�RATION DE GARANTIE. Le logiciel vis� par une licence est offert � tel quel �. Toute utilisation de ce logiciel est � votre seule risque et p�ril. Microsoft n�accorde aucune autre garantie expresse. Vous pouvez b�n�ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit� marchande, d�ad�quation � un usage particulier et d�absence de contrefa�on sont exclues.
+
+
+
+LIMITATION DES DOMMAGES-INT�R�TS ET EXCLUSION DE RESPONSABILIT� POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement � hauteur de 5,00 $ US. Vous ne pouvez pr�tendre � aucune indemnisation pour les autres dommages, y compris les dommages sp�ciaux, indirects ou accessoires et pertes de b�n�fices.
+
+
+
+Cette limitation concerne:
+
+� tout ce qui est reli� au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et
+
+� les r�clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit� stricte, de n�gligence ou d�une autre faute dans la limite autoris�e par la loi en vigueur.
+
+
+
+Elle s�applique �galement, m�me si Microsoft connaissait ou devrait conna�tre l��ventualit� d�un tel dommage. Si votre pays n�autorise pas l�exclusion ou la limitation de responsabilit� pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l�exclusion ci-dessus ne s�appliquera pas � votre �gard.
+
+
+
+EFFET JURIDIQUE. Le pr�sent contrat d�crit certains droits juridiques. Vous pourriez avoir d�autres droits pr�vus par les lois de votre pays. Le pr�sent contrat ne modifie pas les droits que vous conf�rent les lois de votre pays si celles-ci ne le permettent pas.
+
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Services.Client 19.232.0-preview - LicenseRef-scancode-ms-net-library-2018-11
+
+
+(c) Microsoft 2024
+(c) Microsoft Corporation
+
+MICROSOFT SOFTWARE LICENSE TERMS
+
+MICROSOFT .NET LIBRARY
+
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to design, develop and test you�re applications. You may modify, copy, distribute or deploy any .js files contained in the software as part of your applications.
+
+2. THIRD PARTY COMPONENTS. The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
+3. ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.
+a. DISTRIBUTABLE CODE. In addition to the .js files described above, the software is comprised of Distributable Code. �Distributable Code� is code that you are permitted to distribute in programs you develop if you comply with the terms below.
+i. Right to Use and Distribute.
+� You may copy and distribute the object code form of the software.
+
+� Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.
+
+ii. Distribution Requirements. For any Distributable Code you distribute, you must
+� use the Distributable Code in your programs and not as a standalone distribution;
+
+� require distributors and external end users to agree to terms that protect it at least as much as this agreement;
+
+� display your valid copyright notice on your programs; and
+
+� indemnify, defend, and hold harmless Microsoft from any claims, including attorneys� fees, related to the distribution or use of your applications, except to the extent that any claim is based solely on the Distributable Code.
+
+iii. Distribution Restrictions. You may not
+� alter any copyright, trademark or patent notice in the Distributable Code;
+
+� use Microsoft�s trademarks in your programs� names or in a way that suggests your programs come from or are endorsed by Microsoft;
+
+� include Distributable Code in malicious, deceptive or unlawful programs; or
+
+� modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that
+
+� the code be disclosed or distributed in source code form; or
+
+� others have the right to modify it.
+
+4. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the product documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft�s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at http://go.microsoft.com/?linkid=9840733.
+5. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not
+� work around any technical limitations in the software;
+
+� reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software, except and to the extent required by third party licensing terms governing use of certain open source components that may be included in the software;
+
+� remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+
+� use the software in any way that is against the law; or
+
+� share, publish, rent or lease the software, provide the software as a stand-alone offering for others to use, or transfer the software or this agreement to any third party.
+
+6. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+7. SUPPORT SERVICES. Because this software is �as is,� we may not provide support services for it.
+8. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+9. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+10. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b) Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to turn off updates for your specific device or software.
+c) Germany and Austria.
+(i) Warranty. The software will perform substantially as described in any Microsoft materials that accompany it. However, Microsoft gives no contractual guarantee in relation to the software.
+
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as in case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+
+Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence
+11. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED �AS-IS.� YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+12. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your state or country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.
+
+
+
+Remarque : Ce logiciel �tant distribu� au Qu�bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran�ais.
+
+
+
+EXON�RATION DE GARANTIE. Le logiciel vis� par une licence est offert � tel quel �. Toute utilisation de ce logiciel est � votre seule risque et p�ril. Microsoft n�accorde aucune autre garantie expresse. Vous pouvez b�n�ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit� marchande, d�ad�quation � un usage particulier et d�absence de contrefa�on sont exclues.
+
+
+
+LIMITATION DES DOMMAGES-INT�R�TS ET EXCLUSION DE RESPONSABILIT� POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement � hauteur de 5,00 $ US. Vous ne pouvez pr�tendre � aucune indemnisation pour les autres dommages, y compris les dommages sp�ciaux, indirects ou accessoires et pertes de b�n�fices.
+
+
+
+Cette limitation concerne:
+
+� tout ce qui est reli� au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et
+
+� les r�clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit� stricte, de n�gligence ou d�une autre faute dans la limite autoris�e par la loi en vigueur.
+
+
+
+Elle s�applique �galement, m�me si Microsoft connaissait ou devrait conna�tre l��ventualit� d�un tel dommage. Si votre pays n�autorise pas l�exclusion ou la limitation de responsabilit� pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l�exclusion ci-dessus ne s�appliquera pas � votre �gard.
+
+
+
+EFFET JURIDIQUE. Le pr�sent contrat d�crit certains droits juridiques. Vous pourriez avoir d�autres droits pr�vus par les lois de votre pays. Le pr�sent contrat ne modifie pas les droits que vous conf�rent les lois de votre pays si celles-ci ne le permettent pas.
+
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Debugger.InteropA 17.0.31902.203 - LicenseRef-scancode-ms-vs-addons-ext-17.2.0
+
+
+(c) Microsoft 2024
+(c) Microsoft Corporation
+
+MICROSOFT SOFTWARE LICENSE TERMS
+MICROSOFT VISUAL STUDIO ADD-ONs and EXTENSIONS
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to use solely with
+Visual Studio Community
+Visual Studio Professional
+Visual Studio Enterprise
+Visual Studio Code
+2. THIRD PARTY COMPONENTS.� The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.�
+3. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the software documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft�s privacy statement to your users. The Microsoft privacy statement is located here https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use from the software documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr.
+4. SCOPE OF LICENSE. The software is licensed, not sold. These license terms only give you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in these license terms. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. In addition, you may not
+* work around any technical limitations in the software;
+* reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;
+* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+* use the software in any way that is against the law;
+* share, publish, rent, or lease the software; or
+* provide the software as a stand-alone offering or combine it with any of your applications for others to use, or transfer the software or this agreement to any third party.
+5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+6. SUPPORT SERVICES. Because this software is �as is�, we may not provide support services for it.
+7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+9. CONSUMER RIGHTS; REGIONAL VARIATIONS. These license terms describe certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. You may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b. Canada. You may stop receiving updates on your device by turning off Internet access. If and when you re-connect to the Internet, the software will resume checking for and installing updates.
+c. Germany and Austria.
+(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in the case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+Subject to the preceding sentence (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
+10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED �AS-IS�. YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Interop 17.0.31902.203 - LicenseRef-scancode-ms-vs-addons-ext-17.2.0
+
+
+(c) Microsoft 2024
+(c) Microsoft Corporation
+
+MICROSOFT SOFTWARE LICENSE TERMS
+MICROSOFT VISUAL STUDIO ADD-ONs and EXTENSIONS
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to use solely with
+Visual Studio Community
+Visual Studio Professional
+Visual Studio Enterprise
+Visual Studio Code
+2. THIRD PARTY COMPONENTS.� The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.�
+3. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the software documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft�s privacy statement to your users. The Microsoft privacy statement is located here https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use from the software documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr.
+4. SCOPE OF LICENSE. The software is licensed, not sold. These license terms only give you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in these license terms. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. In addition, you may not
+* work around any technical limitations in the software;
+* reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;
+* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+* use the software in any way that is against the law;
+* share, publish, rent, or lease the software; or
+* provide the software as a stand-alone offering or combine it with any of your applications for others to use, or transfer the software or this agreement to any third party.
+5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+6. SUPPORT SERVICES. Because this software is �as is�, we may not provide support services for it.
+7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+9. CONSUMER RIGHTS; REGIONAL VARIATIONS. These license terms describe certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. You may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b. Canada. You may stop receiving updates on your device by turning off Internet access. If and when you re-connect to the Internet, the software will resume checking for and installing updates.
+c. Germany and Austria.
+(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in the case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+Subject to the preceding sentence (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
+10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED �AS-IS�. YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VSSDK.BuildTools 17.14.1043-preview2 - LicenseRef-scancode-ms-vs-addons-ext-17.2.0
+
+
+(c) Andrew Arnott
+copyright company
+(c) Microsoft 2023
+(c) Microsoft 2024
+(c) Microsoft 2025
+Copyright (c) 2021
+(c) 2003-2004 Various
+(c) 2019 GitHub, Inc.
+(c) 2022 GitHub, Inc.
+(c) 2023 GitHub, Inc.
+(c) 2006 Entrust, Inc.
+Copyright (c) Microsoft
+Copyright 2015 The gRPC
+Copyright 2019 The gRPC
+Copyright Nate McMaster
+Copyright (c) Six Labors
+Copyright Microsoft 2010
+Copyright Microsoft 2015
+(c) Microsoft Corporation
+Copyright (c) Hank McCord
+Copyright (c) Manuel Romer
+Copyright (c) Andrew Arnott
+Copyright (c) Nate McMaster
+Copyright 2015, Google Inc.
+Copyright 2019 LLVM Project
+(c) 1999 Entrust.net Limited
+(c) 2009 Entrust, Inc. - for
+(c) 2012 Entrust, Inc. - for
+(c) 2015 Entrust, Inc. - for
+Copyright (c) 1998 Microsoft
+Copyright 2012 Andrew Arnott
+Copyright 2018 Daniel Lemire
+Copyright Andrew Arnott 2012
+Copyright (c) .NET Foundation
+Copyright (c) Six Labors Gets
+Copyright (c) by P.J. Plauger
+Copyright 2012 the V8 project
+Copyright 1995-2017 Mark Adler
+Copyright 1995-2022 Mark Adler
+Copyright 2008 - 2018 Jb Evain
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+Copyright (c) 2023 Sergio Pedri
+Copyright 2000-2022 SharpZipLib
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) Rackspace, US Inc.
+Copyright James Newton-King 2008
+Copyright James Newton-King 2017
+Copyright (c) 2013 Scott Kirkland
+Copyright (c) 2014, Karlis Gangis
+Copyright (c) 2015 Dennis Fischer
+Copyright (c) 2022, Wojciech Mula
+Copyright 2012 Andrew Arnott RSA1
+Copyright 2012-2017 Mehdi Khalili
+Copyright (c) 2008 - 2015 Jb Evain
+Copyright (c) 2015 .NET Foundation
+Copyright (c) 2015 Christian Klutz
+Copyright (c) 2017 Marcos Lopez C.
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright EvidenceFile FileVersion
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) Outercurve Foundation
+Copyright LibGit2Sharp contributors
+Copyright Microsoft 2010 TraceEvent
+(c) Yoshifumi Kawai and contributors
+ACopyright (c) Microsoft Corporation
+CCopyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) James Newton-King 2008
+Copyright (c) James Newton-King 2017
+Copyright Nate McMaster Command-line
+DCopyright (c) Microsoft Corporation
+OCopyright (c) Microsoft Corporation
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2012-2014 Mehdi Khalili
+Copyright (c) 2013-2014 Omar Khudeira
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008 - 2011 Novell, Inc.
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright Microsoft 2010 Serialization
+Copyright (c) .NET Foundation xUnit.net
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Portions (c) International Organization
+Copyright (c) .NET Foundation 0xUnit.net
+Copyright 2014 Giovanni Bassi and Elemar
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) Sven Groot (Ookii.org) 2009
+Copyright (c) The Internet Society (2003)
+Copyright 1995-2003 Microsoft Corporation
+Copyright 1996-1997 Microsoft Corporation
+Copyright 1996-2000 Microsoft Corporation
+Copyright 1996-2003 Microsoft Corporation
+Copyright 1997-1998 Microsoft Corporation
+Copyright 1997-2002 Microsoft Corporation
+Copyright James Newton-King 2008 Json.NET
+Copyright (c) .NET Foundation Contributors
+Copyright (c) 2021 Copyright (c) Six Labors
+Copyright (c) 2020 Mara Bos
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 1997-2000, Microsoft Corporation
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) Tunnel Vision Laboratories, LLC.
+Copyright Tunnel Vision Laboratories, LLC 2015
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) Copyright (c) 2015 Dennis Fischer
+Copyright 2024 Dr.-Ing. Mario Heiderich, Cure53
+Copyright AssemblyCompany AssemblyConfiguration
+Copyright (c) 2005 - 2020 Giacomo Stelluti Scala
+copyright tag should contain a non-empty company
+Copyright (c) 2024 http://microsoft.com Microsoft
+Copyright (c) 2017 Yoshifumi Kawai and contributors
+Copyright 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) 1998 - 2003 Microsoft Corporation Inc.
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright Microsoft 2010 Operating System Extensions
+(c) 2005 - 2020 Giacomo Stelluti Scala & Contributors
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright 2012-2016 Copyright 2012-2017 Mehdi Khalili
+Copyright (c) .NET Foundation xUnit.net Runner Utility
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2013-2014 Omar Khudeira (http://omar.io)
+(c) 2006 Entrust, Inc. Label Entrust Root Certification
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
+Unknown Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) .NET Foundation xUnit.net Runner Reporters
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) Andrew Arnott InputValidation IntegrityCheck
+(c) 2004-2022 Castle Project - http://www.castleproject.org
+Copyright (c) .NET Foundation xUnit.net Console Test Runner
+Copyright (c) .NET Foundation -xUnit.net Console Test Runner
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Copyright (c) 2005 - 2015 Giacomo Stelluti Scala & Contributors
+Copyright (c) 2005 - 2020 Giacomo Stelluti Scala & Contributors
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright 2004-2021 Castle Project - http://www.castleproject.org
+Copyright (c) .NET Foundation and Contributors. Visual Studio 2019
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 2004-2022 Castle Project - http://www.castleproject.org
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright (c) 2023 Sergio Pedri OriginalFilename PolySharp.SourceGenerators.dll
+Copyright 2015, Google Inc. Protocol Buffers Binary Serialization Format Google
+(c) Cure53 and other contributors Copyright 2024 Dr.-Ing. Mario Heiderich, Cure53
+Copyright (c) .NET Foundation xunit.analyzers, analyzers, roslyn, xunit, xunit.net
+(c) 1999 Entrust.net Limited Label Entrust.net Premium 2048 Secure Server CA Serial
+Copyright (c) .NET Foundation and Contributors. xUnit.net Testing Framework +xUnit.net
+Copyright 2015 Tunnel Vision Laboratories, LLC StyleCop DotNetAnalyzers Roslyn Diagnostic
+Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors
+Copyright 2018 Tunnel Vision Laboratories, LLC Documentation DotNetAnalyzers Roslyn Diagnostic
+Copyright Tunnel Vision Laboratories, LLC 2018 1Copyright Tunnel Vision Laboratories, LLC 2018
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+MICROSOFT SOFTWARE LICENSE TERMS
+MICROSOFT VISUAL STUDIO ADD-ONs and EXTENSIONS
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to use solely with
+Visual Studio Community
+Visual Studio Professional
+Visual Studio Enterprise
+Visual Studio Code
+2. THIRD PARTY COMPONENTS.
+The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.
+3. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the software documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft's privacy statement to your users. The Microsoft privacy statement is located here https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use from the software documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr.
+4. SCOPE OF LICENSE. The software is licensed, not sold. These license terms only give you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in these license terms. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. In addition, you may not
+* work around any technical limitations in the software;
+* reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;
+* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+* use the software in any way that is against the law;
+* share, publish, rent, or lease the software; or
+* provide the software as a stand-alone offering or combine it with any of your applications for others to use, or transfer the software or this agreement to any third party.
+5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+6. SUPPORT SERVICES. Because this software is "as is", we may not provide support services for it.
+7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+9. CONSUMER RIGHTS; REGIONAL VARIATIONS. These license terms describe certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. You may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b. Canada. You may stop receiving updates on your device by turning off Internet access. If and when you re-connect to the Internet, the software will resume checking for and installing updates.
+c. Germany and Austria.
+(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in the case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+Subject to the preceding sentence (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
+10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED "AS-IS". YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.NETFramework.ReferenceAssemblies.net472 1.0.3 - LicenseRef-scancode-unknown
+
+
+(c) 2024 GitHub, Inc.
+Copyright Init Default
+(c) Microsoft Corporation
+Copyright SevenBit SetBit
+(c) Communication Foundation
+Copyright (c) .NET Foundation
+Copyright (c) Microsoft Corp.
+Copyright PagefileLimit TimeLimit
+Copyright (c) Microsoft Corporation
+Copyright Microsoft Corp. 1990-2001
+Copyright (c) Microsoft Corporation 2005
+Copyright (c) 1998 Hewlett-Packard Company
+Copyright (c) 2019 Microsoft,','Permission
+CCopyright (c) Microsoft Corporation 1996-2005
+
+LicenseRef-scancode-unknown
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Azure.Core 1.25.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Azure.Core 1.41.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Azure.Storage.Blobs 12.13.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Azure.Storage.Common 12.12.0 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net100 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net20 1.8.3 - MIT
+
+
+Copyright (c) Microsoft Corporation
+CCopyright (c) Microsoft Corporation 1996-2005
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net40 1.8.3 - MIT
+
+
+Copyright SevenBit SetBit
+(c) Communication Foundation
+Copyright (c) Microsoft Corp.
+Copyright PagefileLimit TimeLimit
+Copyright ConvertExplicit Constant
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft Corporation 2005
+Copyright (c) 1998 Hewlett-Packard Company
+CCopyright (c) Microsoft Corporation 1996-2005
+Copyright (c) 1997 Microsoft Corp.1 Microsoft Corporation1!0 Microsoft Root
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net461 1.8.3 - MIT
+
+
+Copyright Init Default
+Copyright SevenBit SetBit
+(c) Communication Foundation
+Copyright (c) Microsoft Corp.
+Copyright PagefileLimit TimeLimit
+Copyright (c) Microsoft Corporation
+Copyright (c) Microsoft Corporation 2005
+Copyright (c) 1998 Hewlett-Packard Company
+CCopyright (c) Microsoft Corporation 1996-2005
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net50 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net60 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net70 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net80 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.Net90 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.NetStandard13 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Basic.Reference.Assemblies.NetStandard20 1.8.3 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Humanizer.Core 2.14.1 - MIT
+
+
+Copyright .NET Foundation and Contributors
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+ICSharpCode.Decompiler 9.1.0.7988 - MIT
+
+
+Copyright 2011-2025 AlphaSierraPapa C Decompiler
+Copyright 2011-2025 AlphaSierraPapa ICSharpCode.Decompiler
+Copyright 2011-2025 AlphaSierraPapa LegalTrademarks OriginalFilename
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+LibGit2Sharp 0.26.2 - MIT
+
+
+Copyright LibGit2Sharp contributors
+Copyright (c) LibGit2Sharp contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+MessagePack 2.5.198 - MIT
+
+
+(c) Yoshifumi Kawai and contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+MessagePack.Annotations 2.5.198 - MIT
+
+
+(c) Yoshifumi Kawai and contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+MessagePackAnalyzer 2.5.124 - MIT
+
+
+(c) Yoshifumi Kawai and contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.Build.Locator 1.8.1 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.Common 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.CSharp 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) Microsoft Corporation
+ACopyright (c) Microsoft Corporation
+CCopyright (c) Microsoft Corporation
+DCopyright (c) Microsoft Corporation
+OCopyright (c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.CSharp.Features 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.CSharp.Workspaces 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.Elfie 1.0.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.Features 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.Scripting.Common 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.VisualBasic 4.12.0 - MIT
+
+
+(c) Key (c)
+(c) Microsoft Corporation
+Copyright (c) Microsoft Corporation
+ACopyright (c) Microsoft Corporation
+CCopyright (c) Microsoft Corporation
+DCopyright (c) Microsoft Corporation
+OCopyright (c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.VisualBasic.Features 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.VisualBasic.Workspaces 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.Workspaces.Common 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.CodeAnalysis.Workspaces.MSBuild 4.12.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright James Newton-King 2008
+Copyright James Newton-King 2008 Json.NET
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.Identity.Client 4.61.3 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.IdentityModel.JsonWebTokens 6.34.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.IdentityModel.Logging 6.34.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.IdentityModel.Tokens 6.34.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.ILVerification 9.0.7 - MIT
+
+
+Copyright (c) 2021
+Copyright (c) Six Labors
+(c) Microsoft Corporation
+Copyright (c) 2022 FormatJS
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2015 Andrew Gallant
+Copyright (c) 2022, Wojciech Mula
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2018 Nemanja Mijailovic
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2015-2018, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+(c) 1995-2024 Jean-loup Gailly and Mark Adler
+Copyright (c) 2020 Mara Bos
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.IO.Redist 6.0.1 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1998 Microsoft. To
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright 2012 the V8 project authors
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.IO.Redist 6.1.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.NET.StringTools 17.6.3 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) 2015 Christian Klutz
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.TestPlatform.TranslationLayer 17.13.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) 2008 - 2015 Jb Evain
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2008 - 2011 Novell, Inc.
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualBasic 10.3.0 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 1991-2017 Unicode, Inc.
+Portions (c) International Organization
+Copyright (c) 2015 The Chromium Authors.
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Composition 16.1.8 - MIT
+
+
+(c) Microsoft Corporation.
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Composition.NetFxAttributes 16.1.8 - MIT
+
+
+(c) Microsoft Corporation.
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.SDK.Analyzers 17.7.47 - MIT
+
+
+(c) Andrew Arnott
+copyright company
+(c) 2019 GitHub, Inc.
+(c) 2023 GitHub, Inc.
+Copyright (c) Microsoft
+(c) Microsoft Corporation
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright 2012 the V8 project
+Copyright 1995-2022 Mark Adler
+Copyright 2008 - 2018 Jb Evain
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1998 Microsoft. To
+Copyright (c) Rackspace, US Inc.
+Copyright James Newton-King 2008
+Copyright (c) 2013 Scott Kirkland
+Copyright (c) 2014, Karlis Gangis
+Copyright (c) 2015 Dennis Fischer
+Copyright (c) 2008 - 2015 Jb Evain
+Copyright (c) 2015 Christian Klutz
+Copyright (c) 2017 Marcos Lopez C.
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) Microsoft Corporation
+Copyright (c) Outercurve Foundation
+(c) Yoshifumi Kawai and contributors
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) James Newton-King 2008
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 2012-2014 Mehdi Khalili
+Copyright (c) 2013-2014 Omar Khudeira
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2008 - 2011 Novell, Inc.
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) .NET Foundation xUnit.net
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Portions (c) International Organization
+Copyright (c) .NET Foundation 0xUnit.net
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright James Newton-King 2008 Json.NET
+Copyright (c) .NET Foundation Contributors
+Copyright 2014 Giovanni Bassi and Elemar Jr
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) Tunnel Vision Laboratories, LLC.
+Copyright Tunnel Vision Laboratories, LLC 2015
+Copyright (c) Copyright (c) 2015 Dennis Fischer
+copyright tag should contain a non-empty company
+Copyright (c) 2017 Yoshifumi Kawai and contributors
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright 2012-2016 Copyright 2012-2017 Mehdi Khalili
+Copyright (c) .NET Foundation xUnit.net Runner Utility
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright 1995-2022 Mark Adler +3 CScs 0123456789ABCDEF
+Copyright (c) .NET Foundation xUnit.net Runner Reporters
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) .NET Foundation xUnit.net Console Test Runner
+Copyright (c) .NET Foundation -xUnit.net Console Test Runner
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Copyright (c) Outercurve Foundation WrapNonExceptionThrows RSDS
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) .NET Foundation xunit.analyzers, analyzers, roslyn, xunit, xunit.net
+Copyright (c) .NET Foundation and Contributors. xUnit.net Testing Framework +xUnit.net
+Copyright 2015 Tunnel Vision Laboratories, LLC StyleCop DotNetAnalyzers Roslyn Diagnostic Analyzer
+Copyright Tunnel Vision Laboratories, LLC 2018 1Copyright Tunnel Vision Laboratories, LLC 2018 NAn
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright 2018 Tunnel Vision Laboratories, LLC Documentation DotNetAnalyzers Roslyn Diagnostic Analyzer
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass. To
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.SolutionPersistence 1.0.52 - MIT
+
+
+(c) Andrew Arnott
+copyright company
+Copyright (c) 2021
+(c) 2022 GitHub, Inc.
+(c) 2023 GitHub, Inc.
+Copyright (c) Six Labors
+(c) Microsoft Corporation
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright 1995-2022 Mark Adler
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+Copyright (c) 2023 Sergio Pedri
+(c) 1997-2005 Sean Eron Anderson
+Copyright James Newton-King 2008
+Copyright (c) 2013 Scott Kirkland
+Copyright (c) 2022, Wojciech Mula
+Copyright (c) 2017 Marcos Lopez C.
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) Outercurve Foundation
+Copyright LibGit2Sharp contributors
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) James Newton-King 2008
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2012-2014 Mehdi Khalili
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Portions (c) International Organization
+Copyright 2014 Giovanni Bassi and Elemar
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright James Newton-King 2008 Json.NET
+Copyright (c) .NET Foundation Contributors
+Copyright (c) 2020 Mara Bos
+Copyright (c) Tunnel Vision Laboratories, LLC
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright Tunnel Vision Laboratories, LLC 2015
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) Copyright (c) 2015 Dennis Fischer
+Copyright AssemblyCompany AssemblyConfiguration
+copyright tag should contain a non-empty company
+Copyright (c) 2024 http://microsoft.com Microsoft
+Copyright 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2013-2014 Omar Khudeira (http://omar.io)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright (c) 2023 Sergio Pedri OriginalFilename PolySharp.SourceGenerators.dll
+Copyright 2015 Tunnel Vision Laboratories, LLC StyleCop DotNetAnalyzers Roslyn Diagnostic
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Threading.Only 17.14.15 - MIT
+
+
+(c) Andrew Arnott
+copyright company
+(c) Microsoft 2024
+Copyright (c) 2021
+(c) 2023 GitHub, Inc.
+Copyright (c) Six Labors
+(c) Microsoft Corporation
+Copyright (c) Manuel Romer
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+(c) (c) Microsoft Corporation
+Copyright (c) .NET Foundation
+Copyright (c) Six Labors Gets
+Copyright 2012 the V8 project
+Copyright 1995-2017 Mark Adler
+Copyright 1995-2022 Mark Adler
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+Copyright (c) 2023 Sergio Pedri
+Copyright 2020 Aaron R Robinson
+Copyright 2023 Aaron R Robinson
+copyright IsUncaught FileSought
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) Rackspace, US Inc.
+Copyright James Newton-King 2008
+Copyright (c) 2013 Scott Kirkland
+Copyright (c) 2014, Karlis Gangis
+Copyright (c) 2015 Dennis Fischer
+Copyright (c) 2022, Wojciech Mula
+Copyright 2012-2017 Mehdi Khalili
+Copyright (c) 2015 .NET Foundation
+Copyright (c) 2017 Marcos Lopez C.
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) Outercurve Foundation
+Copyright LibGit2Sharp contributors
+(c) Yoshifumi Kawai and contributors
+ACopyright (c) Microsoft Corporation
+CCopyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) James Newton-King 2008
+DCopyright (c) Microsoft Corporation
+OCopyright (c) Microsoft Corporation
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2012-2014 Mehdi Khalili
+Copyright (c) 2013-2014 Omar Khudeira
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) .NET Foundation xUnit.net
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Portions (c) International Organization
+Copyright (c) .NET Foundation 0xUnit.net
+Copyright 2014 Giovanni Bassi and Elemar
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright James Newton-King 2008 Json.NET
+Copyright (c) .NET Foundation Contributors
+Copyright .NET Foundation and Contributors
+Copyright 2012-2016 (c) 2008 VeriSign, Inc.
+Copyright (c) 2020 Mara Bos
+(c) Antoine Aubry and contributors 2008 - 2019
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) Tunnel Vision Laboratories, LLC.
+Copyright Tunnel Vision Laboratories, LLC 2015
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) Copyright (c) 2015 Dennis Fischer
+Copyright AssemblyCompany AssemblyConfiguration
+copyright tag should contain a non-empty company
+Copyright (c) 2024 http://microsoft.com Microsoft
+Copyright 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) .NET Foundation xUnit.net Runner Utility
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2013-2014 Omar Khudeira (http://omar.io)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 1995-2022 Jean-loup Gailly and Mark Adler
+Copyright (c) .NET Foundation xUnit.net Runner Reporters
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) Antoine Aubry and contributors 2008 - 2019
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+(c) 2004-2022 Castle Project - http://www.castleproject.org
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Copyright 2004-2021 Castle Project - http://www.castleproject.org
+Copyright (c) .NET Foundation and Contributors. Visual Studio 2019
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 2004-2022 Castle Project - http://www.castleproject.org
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright (c) 2023 Sergio Pedri OriginalFilename PolySharp.SourceGenerators.dll
+Copyright (c) .NET Foundation xunit.analyzers, analyzers, roslyn, xunit, xunit.net
+Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Antoine Aubry and contributors
+Copyright 2015 Tunnel Vision Laboratories, LLC StyleCop DotNetAnalyzers Roslyn Diagnostic
+Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors
+Copyright 2018 Tunnel Vision Laboratories, LLC Documentation DotNetAnalyzers Roslyn Diagnostic
+Copyright Tunnel Vision Laboratories, LLC 2018 1Copyright Tunnel Vision Laboratories, LLC 2018
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Validation 15.0.82 - MIT
+
+
+(c) Microsoft Corporation.
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudioEng.MicroBuild.Core 1.0.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) 2024 http://microsoft.com Microsoft
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Mono.Options 6.6.0.161 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) 1990-2009 Info-ZIP.
+Copyright (c) .NET Foundation Contributors
+copyrighted by the Free Software Foundation
+Copyright (c) 1989, 1991 Free Software Foundation, Inc.
+Copyright 2006 James Newton-King http://www.newtonsoft.com
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+MSBuild.StructuredLogger 2.2.386 - MIT
+
+
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Nerdbank.Streams 2.12.87 - MIT
+
+
+(c) Andrew Arnott
+Copyright (c) .NET Foundation and Contributors
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NETStandard.Library 2.0.0 - MIT
+
+
+copyright Unmanaged32Bit Required32Bit
+Copyright (c) .NET Foundation and Contributors
+
+The MIT License (MIT)
+
+Copyright (c) .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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+NETStandard.Library 2.0.3 - MIT
+
+
+copyright Unmanaged32Bit Required32Bit
+Copyright (c) .NET Foundation and Contributors
+
+The MIT License (MIT)
+
+Copyright (c) .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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Newtonsoft.Json 13.0.1 - MIT
+
+
+Copyright James Newton-King 2008
+Copyright (c) 2007 James Newton-King
+Copyright (c) James Newton-King 2008
+Copyright James Newton-King 2008 Json.NET
+
+The MIT License (MIT)
+
+Copyright (c) 2007 James Newton-King
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Newtonsoft.Json 13.0.3 - MIT
+
+
+Copyright James Newton-King 2008
+Copyright (c) 2007 James Newton-King
+Copyright (c) James Newton-King 2008
+Copyright James Newton-King 2008 Json.NET
+
+The MIT License (MIT)
+
+Copyright (c) 2007 James Newton-King
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Newtonsoft.Json.Bson 1.0.1 - MIT
+
+
+Copyright James Newton-King 2017
+Copyright (c) James Newton-King 2017
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+runtime.native.System.Data.SqlClient.sni 4.7.0 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) .NET Foundation.
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Portions (c) International Organization
+Copyright (c) 2015 The Chromium Authors.
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Buffers 4.5.1 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Buffers 4.6.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.ClientModel 1.0.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Collections.Immutable 9.0.0 - MIT
+
+
+Copyright (c) 2021
+Copyright (c) Six Labors
+(c) Microsoft Corporation
+Copyright (c) 2022 FormatJS
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2015 Andrew Gallant
+Copyright (c) 2022, Wojciech Mula
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2018 Nemanja Mijailovic
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2015-2018, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+(c) 1995-2024 Jean-loup Gailly and Mark Adler
+Copyright (c) 2020 Mara Bos
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.ComponentModel.Composition 4.5.0 - MIT
+
+
+(c) 2025 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Data.DataSetExtensions 4.5.0 - MIT
+
+
+(c) 2025 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Diagnostics.DiagnosticSource 9.0.0 - MIT
+
+
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.IdentityModel.Tokens.Jwt 6.34.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Memory 4.5.4 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Memory 4.5.5 - MIT
+
+
+(c) 2022 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Memory 4.6.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Memory.Data 1.0.2 - MIT
+
+
+(c) Microsoft Corporation.
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Numerics.Vectors 4.5.0 - MIT
+
+
+(c) 2023 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Numerics.Vectors 4.6.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Reflection.Emit 4.7.0 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) .NET Foundation.
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Portions (c) International Organization
+Copyright (c) 2015 The Chromium Authors.
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Reflection.Emit.ILGeneration 4.7.0 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) .NET Foundation.
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Portions (c) International Organization
+Copyright (c) 2015 The Chromium Authors.
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Reflection.Emit.Lightweight 4.7.0 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) .NET Foundation.
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Portions (c) International Organization
+Copyright (c) 2015 The Chromium Authors.
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Reflection.Metadata 9.0.0 - MIT
+
+
+Copyright (c) 2021
+Copyright (c) Six Labors
+Gets the Copyright Table
+(c) Microsoft Corporation
+Copyright (c) 2022 FormatJS
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2015 Andrew Gallant
+Copyright (c) 2022, Wojciech Mula
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2018 Nemanja Mijailovic
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2015-2018, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+(c) 1995-2024 Jean-loup Gailly and Mark Adler
+Copyright (c) 2020 Mara Bos
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Runtime.CompilerServices.Unsafe 6.1.0 - MIT
+
+
+(c) Microsoft Corporation
+
+MIT License
+
+Copyright (c)
+
+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.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Security.AccessControl 6.0.0 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) Andrew Arnott
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 2012-2014, Yann Collet
+Copyright (c) 1991-2020 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright 2012 the V8 project authors
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Security.Cryptography.ProtectedData 4.4.0 - MIT
+
+
+(c) Microsoft Corporation.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 1991-2017 Unicode, Inc.
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Security.Permissions 4.5.0 - MIT
+
+
+(c) Microsoft Corporation.
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson.
+Copyright (c) 1991-2017 Unicode, Inc.
+Portions (c) International Organization
+Copyright (c) 2015 The Chromium Authors.
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers THIS WORK IS PROVIDED AS
+
+The MIT License (MIT)
+
+Copyright (c) .NET Foundation and Contributors
+
+All rights reserved.
+
+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.
+
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+System.Text.Encodings.Web 4.7.2 - MIT
+
+
+(c) Microsoft Corporation
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
+
+The MIT License (MIT)
-In the event that we accidentally failed to list a required notice, please
-bring it to our attention. Post an issue or email us:
+Copyright (c) .NET Foundation and Contributors
- dotnet@microsoft.com
+All rights reserved.
-The attached notices are provided for information only.
+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.
-License notice for MSBuild Locator
--------------------------------------
+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.
-https://github.com/Microsoft/MSBuildLocator
-Copyright (c) 2018 .NET Foundation and Contributors
+---------------------------------------------------------
-This software is licensed subject to the MIT license, available at
-https://opensource.org/licenses/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:
+System.Threading.Tasks.Dataflow 9.0.0 - MIT
-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.
+Copyright (c) 2021
+Copyright (c) Six Labors
+(c) Microsoft Corporation
+Copyright (c) 2022 FormatJS
+Copyright (c) Andrew Arnott
+Copyright 2019 LLVM Project
+Copyright (c) 1998 Microsoft
+Copyright 2018 Daniel Lemire
+Copyright (c) .NET Foundation
+Copyright (c) 2011, Google Inc.
+Copyright (c) 2020 Dan Shechter
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 2015 Andrew Gallant
+Copyright (c) 2022, Wojciech Mula
+Copyright (c) 2017 Yoshifumi Kawai
+Copyright (c) 2022, Geoff Langdale
+Copyright (c) 2005-2020 Rich Felker
+Copyright (c) 2012-2021 Yann Collet
+Copyright (c) Microsoft Corporation
+Copyright (c) 2007 James Newton-King
+Copyright (c) 1991-2022 Unicode, Inc.
+Copyright (c) 2013-2017, Alfred Klomp
+Copyright (c) 2018 Nemanja Mijailovic
+Copyright 2012 the V8 project authors
+Copyright (c) 1999 Lucent Technologies
+Copyright (c) 2008-2016, Wojciech Mula
+Copyright (c) 2011-2020 Microsoft Corp
+Copyright (c) 2015-2017, Wojciech Mula
+Copyright (c) 2015-2018, Wojciech Mula
+Copyright (c) 2005-2007, Nick Galbreath
+Copyright (c) 2015 The Chromium Authors
+Copyright (c) 2018 Alexander Chermyanin
+Copyright (c) The Internet Society 1997
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) 2011-2015 Intel Corporation
+Copyright (c) 2013-2017, Milosz Krajewski
+Copyright (c) 2016-2017, Matthieu Darbois
+Copyright (c) The Internet Society (2003)
+Copyright (c) .NET Foundation Contributors
+(c) 1995-2024 Jean-loup Gailly and Mark Adler
+Copyright (c) 2020 Mara Bos
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2012 - present, Victor Zverovich
+Copyright (c) 2006 Jb Evain (jbevain@gmail.com)
+Copyright (c) 2008-2020 Advanced Micro Devices, Inc.
+Copyright (c) 2019 Microsoft Corporation, Daan Leijen
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) 2014 Ryan Juckett http://www.ryanjuckett.com
+Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
+Portions (c) International Organization for Standardization 1986
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang) Disclaimers
+Copyright (c) 2015 THL A29 Limited, a Tencent company, and Milo Yip
+Copyright (c) 1980, 1986, 1993 The Regents of the University of California
+Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the University of California
+Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & Digital Equipment Corporation, Maynard, Mass
+The MIT License (MIT)
-License notice for Roslyn Clr Heap Allocation Analyzer
--------------------------------------
+Copyright (c) .NET Foundation and Contributors
-https://github.com/Microsoft/RoslynClrHeapAllocationAnalyzer
+All rights reserved.
-Copyright (c) 2018 Microsoft Corporation
+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:
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
-http://www.apache.org/licenses/LICENSE-2.0
+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.
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+---------------------------------------------------------
-License notice for StyleCop Analyzers
--------------------------------------
+---------------------------------------------------------
+
+System.Threading.Tasks.Extensions 4.5.4 - MIT
+
+
+(c) 2023 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
The MIT License (MIT)
-Copyright (c) Tunnel Vision Laboratories, LLC
+Copyright (c) .NET Foundation and Contributors
All rights reserved.
@@ -3343,29 +9828,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-#############################################
-### roslyn
-#############################################
-
-Roslyn uses third-party libraries or other resources that may be
-distributed under licenses different than the Roslyn software.
-
-In the event that we accidentally failed to list a required notice, please
-bring it to our attention. Post an issue or email us:
+---------------------------------------------------------
- dotnet@microsoft.com
+---------------------------------------------------------
-The attached notices are provided for information only.
+System.Threading.Tasks.Extensions 4.6.0 - MIT
-License notice for .NET Core Libraries (CoreFX)
--------------------------------------
-https://github.com/dotnet/corefx
+(c) Microsoft Corporation
-Copyright (c) 2018 .NET Foundation and Contributors
+MIT License
-This software is licensed subject to the MIT license, available at
-https://opensource.org/licenses/MIT
+Copyright (c)
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:
@@ -3373,37 +9847,69 @@ The above copyright notice and this permission notice shall be included in all c
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 DotNetTools
--------------------------------------
+---------------------------------------------------------
+
+System.ValueTuple 4.5.0 - MIT
+
+
+(c) 2023 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) 2011, Google Inc.
+(c) 1997-2005 Sean Eron Anderson
+Copyright (c) 1991-2017 Unicode, Inc.
+Copyright (c) 2015 The Chromium Authors
+Portions (c) International Organization
+Copyright (c) 2004-2006 Intel Corporation
+Copyright (c) .NET Foundation Contributors
+Copyright (c) .NET Foundation and Contributors
+Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+Copyright (c) 1995-2017 Jean-loup Gailly and Mark Adler
+Copyright (c) 2015 Xamarin, Inc (http://www.xamarin.com)
+Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors
+Copyright (c) YEAR W3C(r) (MIT, ERCIM, Keio, Beihang). Disclaimers
-https://github.com/aspnet/DotNetTools
+The MIT License (MIT)
Copyright (c) .NET Foundation and Contributors
All rights reserved.
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use
-this file except in compliance with the License. You may obtain a copy of the
-License at
+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:
- http://www.apache.org/licenses/LICENSE-2.0
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
-Unless required by applicable law or agreed to in writing, software distributed
-under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied. See the License for the
-specific language governing permissions and limitations under the License.
+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 DocFX
--------------------------------------
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+vswhere 3.1.7 - MIT
-https://github.com/dotnet/docfx
+(c) 2023 GitHub, Inc.
+(c) Microsoft Corporation
+Copyright (c) by P.J. Plauger
Copyright (c) Microsoft Corporation
-This software is licensed subject to the MIT license, available at
-https://opensource.org/licenses/MIT
+MIT License
+
+Copyright (c)
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:
@@ -3411,16 +9917,18 @@ The above copyright notice and this permission notice shall be included in all c
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 MSBuild Locator
--------------------------------------
+---------------------------------------------------------
-https://github.com/Microsoft/MSBuildLocator
+XunitXml.TestLogger 3.1.17 - MIT
-Copyright (c) Microsoft Corporation. All rights reserved.
-This software is licensed subject to the MIT license, available at
-https://opensource.org/licenses/MIT
+Copyright 2020 Spekt Contributors
+
+MIT License
+
+Copyright (c)
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:
@@ -3428,73 +9936,164 @@ The above copyright notice and this permission notice shall be included in all c
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 Json.NET
--------------------------------------
+---------------------------------------------------------
-https://github.com/JamesNK/Newtonsoft.Json
+InputSimulatorPlus 1.0.7 - MS-PL
-Copyright (c) 2007 James Newton-King
-This software is licensed subject to the MIT license, available at
-https://opensource.org/licenses/MIT
+Copyright 2009-2018
+Copyright michaelnoonan 2010
+LCopyright michaelnoonan 2010
+Copyright Theodoros Chatzigiannakis 2018
-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:
+Microsoft Public License (Ms-PL)
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use 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.
+ 1. Definitions
+ The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution.
-JSON Parsing Test Suite
--------------------------------------
+ 2. Grant of Rights
-https://github.com/nst/JSONTestSuite
+ (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
-Copyright (c) 2016 Nicolas Seriot
+ (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
-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:
+ 3. Conditions and Limitations
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
-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.
+ (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
+ (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
-MSBuild Structured Logging
--------------------------------------
+ (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
-https://github.com/KirillOsenkov/MSBuildStructuredLog
+ (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
-Copyright (c) 2016 Kirill Osenkov
+---------------------------------------------------------
-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.
+UIAComWrapper 1.1.0.14 - MS-PL
-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.
-ICSharpCode.Decompiler
--------------------------------------
-https://github.com/icsharpcode/ILSpy
+Microsoft Public License (Ms-PL)
-Copyright (c) 2011-2023 AlphaSierraPapa for the ILSpy team
+This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
-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:
+ 1. Definitions
+
+ The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution.
+
+ 2. Grant of Rights
+
+ (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
+
+ (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
+
+ 3. Conditions and Limitations
+
+ (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
+
+ (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
+
+ (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
+
+ (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
+
+ (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Xunit.Combinatorial 1.6.24 - MS-PL
+
+
+(c) Andrew Arnott
+
+Microsoft Public License (Ms-PL)
+
+This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
+
+ 1. Definitions
+
+ The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. A "contribution" is the original software, or any additions or changes to the software. A "contributor" is any person that distributes its contribution under this license. "Licensed patents" are a contributor's patent claims that read directly on its contribution.
+
+ 2. Grant of Rights
+
+ (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
+
+ (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
+
+ 3. Conditions and Limitations
+
+ (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
+
+ (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
+
+ (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
+
+ (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
+
+ (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees, or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
+
+---------------------------------------------------------
+
+---------------------------------------------------------
+
+Microsoft.VisualStudio.Debugger.Interop.11.0 17.0.31902.203
+
+
+(c) Microsoft 2024
+(c) Microsoft Corporation
+
+MICROSOFT SOFTWARE LICENSE TERMS
+MICROSOFT VISUAL STUDIO ADD-ONs and EXTENSIONS
+These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft services or updates for the software, except to the extent those have different terms.
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.
+1. INSTALLATION AND USE RIGHTS.
+You may install and use any number of copies of the software to use solely with
+Visual Studio Community
+Visual Studio Professional
+Visual Studio Enterprise
+Visual Studio Code
+2. THIRD PARTY COMPONENTS.� The software may include third party components with separate legal notices or governed by other agreements, as may be described in the ThirdPartyNotices file(s) accompanying the software.�
+3. DATA.
+a. Data Collection. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the software documentation. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications and you should provide a copy of Microsoft�s privacy statement to your users. The Microsoft privacy statement is located here https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use from the software documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Online Services Terms to all customers effective May 25, 2018, at https://docs.microsoft.com/en-us/legal/gdpr.
+4. SCOPE OF LICENSE. The software is licensed, not sold. These license terms only give you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in these license terms. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. In addition, you may not
+* work around any technical limitations in the software;
+* reverse engineer, decompile or disassemble the software, or otherwise attempt to derive the source code for the software except, and only to the extent required by third party licensing terms governing the use of certain open source components that may be included in the software;
+* remove, minimize, block or modify any notices of Microsoft or its suppliers in the software;
+* use the software in any way that is against the law;
+* share, publish, rent, or lease the software; or
+* provide the software as a stand-alone offering or combine it with any of your applications for others to use, or transfer the software or this agreement to any third party.
+5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the software, which include restrictions on destinations, end users, and end use. For further information on export restrictions, visit www.microsoft.com/exporting.
+6. SUPPORT SERVICES. Because this software is �as is�, we may not provide support services for it.
+7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.
+8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software in any other country, its laws apply.
+9. CONSUMER RIGHTS; REGIONAL VARIATIONS. These license terms describe certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. You may also have rights with respect to the party from which you acquired the software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the below regions, or mandatory country law applies, then the following provisions apply to you:
+a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights.
+b. Canada. You may stop receiving updates on your device by turning off Internet access. If and when you re-connect to the Internet, the software will resume checking for and installing updates.
+c. Germany and Austria.
+(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany the software. However, Microsoft gives no contractual guarantee in relation to the licensed software.
+(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in the case of death or personal or physical injury, Microsoft is liable according to the statutory law.
+Subject to the preceding sentence (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence.
+10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED �AS-IS�. YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.
+This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.
+It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
+
+
+---------------------------------------------------------
-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.
#############################################
### runtime
@@ -3604,33 +10203,6 @@ http://www.apache.org/licenses/
Copyright The OpenTelemetry Authors
-License notice for LinuxTracepoints
------------------------------------
-
-https://github.com/microsoft/LinuxTracepoints/blob/main/LICENSE
-
-Copyright (c) Microsoft Corporation.
-
-MIT License
-
-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 Mono
-------------------------------
diff --git a/build.proj b/build.proj
index 548f325cc2c2..fd8460bc80d7 100644
--- a/build.proj
+++ b/build.proj
@@ -9,6 +9,14 @@
+
+
+
+
+
-
diff --git a/build.sh b/build.sh
index 01556a9f9f03..35ba7a0c975f 100755
--- a/build.sh
+++ b/build.sh
@@ -15,7 +15,12 @@ usage()
echo " --rid, --target-rid Overrides the rid that is produced by the build. e.g. alpine.3.18-arm64, fedora.37-x64, freebsd.13-arm64, ubuntu.19.10-x64"
echo " --os, --target-os Target operating system: e.g. linux, osx, freebsd. Note: this is the base OS name, not the distro"
echo " --arch, --target-arch Target architecture: e.g. x64, x86, arm64, arm, riscv64"
- echo " --branding Specify versioning for shipping packages/assets. 'preview' will produce assets suffixed with '.final', 'rtm' will not contain a pre-release suffix. Default or unspecified will use VMR repo defaults."
+ echo " --branding Specify the branding suffix for shipping packages/assets. By default uses VMR branding defaults (RepoDotNetFinalVersionKind property in eng/Versions.props)"
+ echo " for release branch builds or otherwise repo branding defaults."
+ echo " 'repodefault' uses the repo branding defaults."
+ echo " 'unstable' produces assets with the repo specified branding suffix."
+ echo " 'preview' produces assets with a '.final' branding suffix."
+ echo " 'release' produces assets without a branding suffix."
echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)"
echo " --with-system-libs Use system versions of these libraries. Combine with a plus. 'all' will use all supported libraries. e.g. brotli+libunwind+rapidjson+zlib"
echo " --official-build-id Official build ID to use for the build. This is used to set the OfficialBuildId MSBuild property."
@@ -59,23 +64,6 @@ usage()
echo "Arguments can also be passed in with a single hyphen."
}
-function SetBranding()
-{
- local brandingValue="$1"
-
- if [[ "$brandingValue" == "preview" ]]; then
- properties+=( "/p:DotNetFinalVersionKind=prerelease" )
- elif [[ "$brandingValue" == "rtm" ]]; then
- properties+=( "/p:DotNetFinalVersionKind=release" )
- elif [[ "$brandingValue" == "default" ]]; then
- # default branding; no extra property needed
- :
- else
- echo "ERROR: Invalid branding '$brandingValue'. Allowed values are 'preview', 'rtm', or 'default'."
- exit 1
- fi
-}
-
function SetOfficialBuildId()
{
local officialBuildIdValue="$1"
@@ -103,19 +91,19 @@ binary_log=''
configuration='Release'
verbosity='minimal'
officialBuildId=''
-branding=''
# Actions
clean=false
test=false
# Source-only settings
+prep=false
sourceOnly=false
releaseManifest=''
sourceRepository=''
sourceVersion=''
-CUSTOM_PACKAGES_DIR=''
-CUSTOM_SDK_DIR=''
+customPackagesDir=''
+customSdkDir=''
packagesDir="$scriptroot/prereqs/packages/"
packagesArchiveDir="${packagesDir}archive/"
packagesPreviouslySourceBuiltDir="${packagesDir}previously-source-built/"
@@ -127,6 +115,8 @@ exclude_ci_binary_log=''
node_reuse=''
prepare_machine=''
warn_as_error=''
+targetOS=''
+targetArch=''
properties=()
while [[ $# > 0 ]]; do
@@ -149,15 +139,32 @@ while [[ $# > 0 ]]; do
;;
-os|-target-os)
properties+=( "/p:TargetOS=$2" )
+ targetOS="$2"
shift
;;
-arch|-target-arch)
properties+=( "/p:TargetArchitecture=$2" )
+ targetArch="$2"
shift
;;
-branding)
- branding="$2"
- SetBranding "$branding"
+ if [ -z ${2+x} ]; then
+ echo "No branding type supplied. See help (--help) for supported values." 1>&2
+ exit 1
+ fi
+ passedBrandingType="$(echo "$2" | tr "[:upper:]" "[:lower:]")"
+ case "$passedBrandingType" in
+ repodefault|unstable|preview|release)
+ ;;
+ *)
+ echo "Unsupported branding type '$2'."
+ echo "The allowed values are repodefault, unstable, preview or release."
+ echo ""
+ echo "IMPORTANT: If you previously passed in the '-branding rtm' argument for .NET 10, remove it entirely. The default is now set correctly (VMR branding defaults for release branch builds or otherwise repo branding defaults)."
+ exit 1
+ ;;
+ esac
+ properties+=( "/p:RepoDotNetFinalVersionKind=$passedBrandingType" )
shift
;;
-with-system-libs)
@@ -218,9 +225,9 @@ while [[ $# > 0 ]]; do
shift
;;
-with-packages)
- CUSTOM_PACKAGES_DIR="$(cd -P "$2" && pwd)"
- if [ ! -d "$CUSTOM_PACKAGES_DIR" ]; then
- echo "Custom previously built packages directory '$CUSTOM_PACKAGES_DIR' does not exist"
+ customPackagesDir="$(cd -P "$2" && pwd)"
+ if [ ! -d "$customPackagesDir" ]; then
+ echo "Custom previously built packages directory '$customPackagesDir' does not exist"
exit 1
fi
shift
@@ -235,21 +242,12 @@ while [[ $# > 0 ]]; do
shift
;;
-with-sdk)
- CUSTOM_SDK_DIR="$(cd -P "$2" && pwd)"
- if [ ! -d "$CUSTOM_SDK_DIR" ]; then
- echo "Custom SDK directory '$CUSTOM_SDK_DIR' does not exist"
- exit 1
- fi
- if [ ! -x "$CUSTOM_SDK_DIR/dotnet" ]; then
- echo "Custom SDK '$CUSTOM_SDK_DIR/dotnet' does not exist or is not executable"
- exit 1
- fi
+ customSdkDir="$(cd -P "$2" && pwd)"
shift
;;
-prep)
- "$scriptroot/prep-source-build.sh"
+ prep=true
;;
-
# Advanced settings
-build-repo-tests)
properties+=( "/p:DotNetBuildTests=true" )
@@ -295,7 +293,8 @@ if [[ "$ci" == true ]]; then
fi
fi
-. "$scriptroot/eng/common/tools.sh"
+source "$scriptroot/eng/common/tools.sh"
+source "$scriptroot/eng/source-build-toolset-init.sh"
# Default properties
properties+=( "/p:RepoRoot=$repo_root" )
@@ -314,29 +313,6 @@ if [[ "$test" == true ]]; then
fi
function Build {
- # Source-only toolset prep steps
- if [[ "$sourceOnly" == "true" ]]; then
- InitializeBuildTool
-
- initSourceOnlyBinaryLog=""
- if [[ "$binary_log" == true ]]; then
- initSourceOnlyBinaryLog="/bl:\"$log_dir/init-source-only.binlog\""
- fi
-
- "$_InitializeBuildTool" build-server shutdown --msbuild
- MSBuild-Core "$scriptroot/eng/init-source-only.proj" $initSourceOnlyBinaryLog "${properties[@]}"
- # kill off the MSBuild server so that on future invocations we pick up our custom SDK Resolver
- "$_InitializeBuildTool" build-server shutdown --msbuild
-
- local bootstrapArcadeDir=$(cat "$scriptroot/artifacts/toolset/bootstrap-sdks.txt" | grep "microsoft.dotnet.arcade.sdk")
- local arcadeBuildStepsDir="$bootstrapArcadeDir/tools/"
-
- # Point MSBuild to the custom SDK resolvers folder, so it will pick up our custom SDK Resolver
- export MSBUILDADDITIONALSDKRESOLVERSFOLDER="$scriptroot/artifacts/toolset/VSSdkResolvers/"
-
- # Set _InitializeToolset so that eng/common/tools.sh doesn't attempt to restore the arcade toolset again.
- _InitializeToolset="${arcadeBuildStepsDir}/Build.proj"
- fi
local bl=""
if [[ "$binary_log" == true ]]; then
@@ -371,21 +347,28 @@ fi
# Initialize __DistroRid and __PortableTargetOS
source $scriptroot/eng/common/native/init-os-and-arch.sh
source $scriptroot/eng/common/native/init-distro-rid.sh
+
initDistroRidGlobal "$os" "$arch" ""
+if [[ -n "$__DistroRid" ]]; then
+ properties+=( "/p:BuildRid=$__DistroRid" )
+fi
+
+# if targetOS and targetArch were provided, recompute __PortableTargetOS
+if [[ -n "$targetOS" && -n "$targetArch" ]]; then
+ unset __PortableTargetOS
+ initDistroRidGlobal "$targetOS" "$targetArch" ""
+fi
+
+properties+=( "/p:PortableTargetOS=$__PortableTargetOS" )
+
# Source-only settings
if [[ "$sourceOnly" == "true" ]]; then
- # Don't use the global nuget cache folder when building source-only which
- # restores prebuilt packages that should never get into the global nuget cache.
- export NUGET_PACKAGES="$scriptroot/.packages/"
-
- if [[ "$test" == true ]]; then
- # Use a custom package cache for tests to make prebuilt detection work.
- export NUGET_PACKAGES="${NUGET_PACKAGES}tests/"
+ # Run prep if requested
+ if [[ "$prep" == true ]]; then
+ "$scriptroot/prep-source-build.sh" --configuration "$configuration"
fi
- echo "NuGet packages cache: '${NUGET_PACKAGES}'"
-
# For build purposes, we need to make sure we have all the SourceLink information
if [ "$test" != "true" ]; then
get_property() {
@@ -395,7 +378,16 @@ if [[ "$sourceOnly" == "true" ]]; then
}
GIT_DIR="$scriptroot/.git"
- if [ -f "$GIT_DIR/index" ]; then # We check for index because if outside of git, we create config and HEAD manually
+ # Check if exist .git file
+ if [ -f "$GIT_DIR" ]; then
+ if ! grep -iq '^gitdir: ' "$GIT_DIR"; then
+ echo "ERROR: $GIT_DIR exist, but does not contain a valid 'gitdir:' pointer."
+ exit 1
+ else
+ GIT_DIR=$(grep '^gitdir: ' "$GIT_DIR" | awk -F'gitdir: ' '{ print $2 }')
+ fi
+ fi
+ if [ -f "$GIT_DIR/config" ] && [ -f "$GIT_DIR/HEAD" ]; then # We check for config/HEAD because if outside of git, we create config and HEAD manually
if [ -n "$sourceRepository" ] || [ -n "$sourceVersion" ] || [ -n "$releaseManifest" ]; then
echo "ERROR: Source Link arguments cannot be used in a git repository"
exit 1
@@ -438,111 +430,24 @@ if [[ "$sourceOnly" == "true" ]]; then
|| (echo "ERROR: Failed to find officialBuildId in $releaseManifest" && exit 1)
SetOfficialBuildId "$officialBuildId"
fi
-
- # If branding was not provided, extract it from the release manifest
- if [[ "$branding" == "" ]]; then
- branding=$(get_property "$releaseManifest" branding) \
- || (echo "ERROR: Failed to find branding in $releaseManifest" && exit 1)
- SetBranding "$branding"
- fi
fi
- fi
-
- # Support custom source built package locations
- if [ "$CUSTOM_PACKAGES_DIR" != "" ]; then
- if [ "$test" == "true" ]; then
- properties+=( "/p:CustomSourceBuiltPackagesPath=$CUSTOM_PACKAGES_DIR" )
- else
- properties+=( "/p:CustomPreviouslySourceBuiltPackagesPath=$CUSTOM_PACKAGES_DIR" )
- fi
- fi
-
- if [ ! -d "$scriptroot/.git" ]; then
- echo "ERROR: $scriptroot is not a git repository."
- exit 1
- fi
-
- # Allow a custom SDK directory to be specified
- if [ -d "$CUSTOM_SDK_DIR" ]; then
- export SDK_VERSION=$("$CUSTOM_SDK_DIR/dotnet" --version)
- export CLI_ROOT="$CUSTOM_SDK_DIR"
- echo "Using custom bootstrap SDK from '$CLI_ROOT', version '$SDK_VERSION'"
+ # else, running tests
else
- sdkLine=$(grep -m 1 'dotnet' "$scriptroot/global.json")
- sdkPattern="\"dotnet\" *: *\"(.*)\""
- if [[ $sdkLine =~ $sdkPattern ]]; then
- export SDK_VERSION=${BASH_REMATCH[1]}
- export CLI_ROOT="$scriptroot/.dotnet"
- fi
+ properties+=( "/p:DisableSharedComponentValidation=true" )
fi
- # Set _InitializeDotNetCli & DOTNET_INSTALL_DIR so that eng/common/tools.sh doesn't attempt to restore the SDK.
- export _InitializeDotNetCli="$CLI_ROOT"
- export DOTNET_INSTALL_DIR="$CLI_ROOT"
-
- # Find the Arcade SDK version and set env vars for the msbuild sdk resolver
- packageVersionsPath=''
-
- if [[ "$CUSTOM_PACKAGES_DIR" != "" && -f "$CUSTOM_PACKAGES_DIR/PackageVersions.props" ]]; then
- packageVersionsPath="$CUSTOM_PACKAGES_DIR/PackageVersions.props"
- elif [ -d "$packagesArchiveDir" ]; then
- sourceBuiltArchive=$(find "$packagesArchiveDir" -maxdepth 1 -name 'Private.SourceBuilt.Artifacts*.tar.gz')
- if [ -f "${packagesPreviouslySourceBuiltDir}PackageVersions.props" ]; then
- packageVersionsPath=${packagesPreviouslySourceBuiltDir}PackageVersions.props
- elif [ -f "$sourceBuiltArchive" ]; then
- tar -xzf "$sourceBuiltArchive" -C /tmp PackageVersions.props
- packageVersionsPath=/tmp/PackageVersions.props
- fi
+ # Support custom source built package locations
+ if [ "$customPackagesDir" != "" ]; then
+ properties+=( "/p:CustomPreviouslySourceBuiltPackagesPath=$customPackagesDir" )
fi
- if [ ! -f "$packageVersionsPath" ]; then
- echo "Cannot find PackagesVersions.props. Debugging info:"
- echo " Attempted custom PVP path: $CUSTOM_PACKAGES_DIR/PackageVersions.props"
- echo " Attempted previously-source-built path: ${packagesPreviouslySourceBuiltDir}PackageVersions.props"
- echo " Attempted archive path: $packagesArchiveDir"
+ if [ ! -e "$scriptroot/.git" ]; then
+ echo "ERROR: $scriptroot is not a git repository/worktree."
exit 1
fi
- # Extract toolset packages
-
- # Ensure that by default, the bootstrap version of the toolset SDK is used. Source-build infra
- # projects use bootstrap toolset SDKs, and would fail to find it in the build. The repo
- # projects overwrite this so that they use the source-built toolset SDK instad.
-
- # 1. Microsoft.DotNet.Arcade.Sdk
- arcadeSdkLine=$(grep -m 1 'MicrosoftDotNetArcadeSdkVersion' "$packageVersionsPath")
- arcadeSdkPattern="(.*)"
- if [[ $arcadeSdkLine =~ $arcadeSdkPattern ]]; then
- export ARCADE_BOOTSTRAP_VERSION=${BASH_REMATCH[1]}
-
- export SOURCE_BUILT_SDK_ID_ARCADE=Microsoft.DotNet.Arcade.Sdk
- export SOURCE_BUILT_SDK_VERSION_ARCADE=$ARCADE_BOOTSTRAP_VERSION
- export SOURCE_BUILT_SDK_DIR_ARCADE=${NUGET_PACKAGES}BootstrapPackages/microsoft.dotnet.arcade.sdk/$ARCADE_BOOTSTRAP_VERSION
- fi
-
- # 2. Microsoft.Build.NoTargets
- notargetsSdkLine=$(grep -m 1 'Microsoft.Build.NoTargets' "$scriptroot/global.json")
- notargetsSdkPattern="\"Microsoft\.Build\.NoTargets\" *: *\"(.*)\""
- if [[ $notargetsSdkLine =~ $notargetsSdkPattern ]]; then
- export NOTARGETS_BOOTSTRAP_VERSION=${BASH_REMATCH[1]}
-
- export SOURCE_BUILT_SDK_ID_NOTARGETS=Microsoft.Build.NoTargets
- export SOURCE_BUILT_SDK_VERSION_NOTARGETS=$NOTARGETS_BOOTSTRAP_VERSION
- export SOURCE_BUILT_SDK_DIR_NOTARGETS=${NUGET_PACKAGES}BootstrapPackages/microsoft.build.notargets/$NOTARGETS_BOOTSTRAP_VERSION
- fi
-
- # 3. Microsoft.Build.Traversal
- traversalSdkLine=$(grep -m 1 'Microsoft.Build.Traversal' "$scriptroot/global.json")
- traversalSdkPattern="\"Microsoft\.Build\.Traversal\" *: *\"(.*)\""
- if [[ $traversalSdkLine =~ $traversalSdkPattern ]]; then
- export TRAVERSAL_BOOTSTRAP_VERSION=${BASH_REMATCH[1]}
-
- export SOURCE_BUILT_SDK_ID_TRAVERSAL=Microsoft.Build.Traversal
- export SOURCE_BUILT_SDK_VERSION_TRAVERSAL=$TRAVERSAL_BOOTSTRAP_VERSION
- export SOURCE_BUILT_SDK_DIR_TRAVERSAL=${NUGET_PACKAGES}BootstrapPackages/microsoft.build.traversal/$TRAVERSAL_BOOTSTRAP_VERSION
- fi
-
- echo "Found bootstrap versions: SDK $SDK_VERSION, Arcade $ARCADE_BOOTSTRAP_VERSION, NoTargets $NOTARGETS_BOOTSTRAP_VERSION and Traversal $TRAVERSAL_BOOTSTRAP_VERSION"
+ # Initialize source-only toolset (includes custom SDK setup, MSBuild resolver, and source-built resolver)
+ source_only_toolset_init "$customSdkDir" "$customPackagesDir" "$binary_log" "$test" "${properties[@]}"
fi
Build
diff --git a/docs/Repository-Onboarding.md b/docs/Repository-Onboarding.md
new file mode 100644
index 000000000000..2bf768846674
--- /dev/null
+++ b/docs/Repository-Onboarding.md
@@ -0,0 +1,81 @@
+# VMR Repository Onboarding Guide
+
+This document provides a step-by-step guide for onboarding repositories into the VMR (Virtual Monolithic Repository).
+For background on VMR concepts and architecture, see [VMR Design and Operation](./VMR-Design-And-Operation.md).
+
+## Prerequisites
+
+Before onboarding a repository to the VMR, ensure the following are met:
+
+- Repository is a dependency of the .NET product (e.g. a dependency of the SDK)
+- Repository is onboarded to the [Arcade SDK](https://github.com/dotnet/arcade/blob/main/Documentation/StartHere.md) and its builds are registered in [BAR](https://github.com/dotnet/arcade-services/blob/main/docs/Darc.md#locating-the-bar-build-id-for-a-build).
+ - If not, see if it can be added via an [external source-build-reference-package](https://github.com/dotnet/source-build-reference-packages/blob/main/README.md#external)
+- Repository is compatible with [source build](https://github.com/dotnet/source-build/blob/main/Documentation/sourcebuild-in-repos/README.md)
+- Open an [issue](https://github.com/dotnet/dotnet/issues/new/choose) tracking this work and mention [@dotnet/product-construction](https://github.com/orgs/dotnet/teams/product-construction)
+
+## Onboarding Steps
+
+### Step 1: Configure Source Mappings
+
+Add your repository to `/src/source-mappings.json` and open a PR to merge the change.
+For detailed configuration options, see [Repository Source Mappings](./VMR-Full-Code-Flow.md#repository-source-mappings).
+
+### Step 2: Define the Darc Code Flow Subscriptions
+
+Define the appropriate Darc [code flow subscriptions](./Codeflow-PRs.md).
+After defined manually trigger the forward flow subscription via `darc` or [Maestro](https://maestro.dot.net/subscriptions).
+This will open a [VMR PR](https://github.com/dotnet/dotnet/pulls?q=is%3Apr+is%3Aopen+%22Source+code+updates%22) that brings in the repo's source code.
+Add the `NO-MERGE` label to the PR while completing the next steps necessary to integrate the repo into the VMR.
+
+#### Step 3: Ensure no Checked in Binaries
+
+The VMR has restrictions on checked-in binaries.
+PR and CI validation exists to ensure the [binary policy](./VMR-Permissible-Sources.md#binary-policy) is satisfied.
+If the code flow PR is green, the repo complies with the binary policy.
+
+#### Step 4: Validate OSS Compliant Licenses
+
+The VMR has restrictions on allowed licenses.
+Before the code flow PR is merged, queue a run of the [license scan pipeline](https://dev.azure.com/dnceng/internal/_build?definitionId=1490) (internal Microsoft link) to validate the repo complies with the [license policy](./VMR-Permissible-Sources.md#license-policy).
+
+### Step 5: Update Ownership Assignment Policy
+
+Add an entry in `/.github/policies/assign_ownership.yml` to automatically assign reviewers when changes are detected in your repository's source directory.
+Add an event responder task that matches the pattern `src//.*` and specifies an appropriate GitHub team as the `teamReviewer`.
+This helps ensure that the right team is notified when changes are made to your repository within the VMR.
+
+### Step 6: Create Repository Project File
+
+Create a `/repo-projects/.proj` that integrates the repo's build into to the VMR's build.
+Browse the existing [`repo-projects`](https://github.com/dotnet/dotnet/tree/main/repo-projects) for examples.
+Ensure the correct dependencies are defined within the new and existing projects.
+
+### Step 7: Build and Validate
+
+[Build](./README.md#building) the VMR with the new repo.
+Push changes to the PR to get complete valdation.
+Resolve any build issues that arise.
+This may require adjusting the [repository project file](#step-6-create-repository-project-file) and utilizing the [VMR controls](./VMR-Controls.md) to adjust how the repo is built within the VMR.
+
+Validate the assets produced from the build by checking the `/artifacts` directory contents.
+
+### Step 8: Merge PR
+
+Once your PR is green and the artifacts have been validated, remove the `NO-MERGE` label from the PR.
+Get approval from the repo experts and [@dotnet/product-construction](https://github.com/orgs/dotnet/teams/product-construction) before merging the PR.
+
+### Step 9: Post Merge Validation
+
+After your PR has been merged validate the following:
+
+1. Validate the [CI builds](https://dev.azure.com/dnceng/internal/_build?definitionId=1330) are passing.
+1. Ensure the [forward and back code flows](https://maestro.dot.net) work correctly
+
+### Step 10: Enable Repo Level VMR PR Validation
+
+Consider enabling [repo level VMR PR validation](https://github.com/dotnet/arcade/blob/main/Documentation/VmrValidation.md) as either an optional or required check.
+
+## Getting Help
+
+- Utilize the issue created in [Repository Requirements](#prerequisites) to discuss any issues encountered.
+- For source build specific issues mention [@dotnet/source-build](https://github.com/orgs/dotnet/teams/source-build) in your issue.
diff --git a/docs/VMR-Official-Build-Bar.md b/docs/VMR-Official-Build-Bar.md
new file mode 100644
index 000000000000..5416513a820b
--- /dev/null
+++ b/docs/VMR-Official-Build-Bar.md
@@ -0,0 +1,50 @@
+# Defining the Bar for Processes in the VMR Official Build
+
+## Purpose
+
+To establish clear criteria and a decision-making framework for determining which processes should be included in the VMR official build. This ensures that the build is efficient, reliable, and maintains the necessary quality standards for shipping assets, while supporting code flow velocity and minimizing unnecessary delays.
+
+## Principles
+
+- **Shippability** - The offical build must produce assets and information to ship .NET in a confident and compliant manner.
+- **Velocity**: The build must meet our SLAs (currently 4 hours unsigned, 7 hours signed).
+- **Reliability**: The official build must be reliable, with minimal flakiness or unnecessary failures that could block code flow.
+
+## Description of the Bar
+
+Processes that do not contribute to the essential production or validation of shipping assets, or that introduce unnecessary delays, flakiness, or complexity, should be excluded. The goal is that we should never stage (ready for release) any failed build. *Note that this does not mean that a green build is ready for release. Plenty of additional validation processes may be performed (e.g. VS insertion, CTI signoff etc.)*. Any process excluded from the official build must have a compensating mechanism to ensure its results are still considered before shipping or sign-off.
+
+## Rubric
+
+Evaluate each of the questions in order. You reach the end without answering "yes", then the process might be excluded.
+
+- Is the process required to produce assets necessary for shipping the product or downstream builds? **If so, it should be included.**
+- Does the process directly support the integrity and readiness and compliance of shipping assets for release, without putting the official build SLAs or reliability at risk? **If so, it should be included.**
+- Even if inclusion puts SLAs at risk, is there no possible alternative or compensating mechanism to ensure the process’s results are considered before shipping or sign-off? **If so, it should be included.**
+
+## Examples
+
+### Example: Processes That Meet the Bar
+
+- **Source-build CentOS jobs**
+ - These jobs produce assets used by distro partners to bootstrap their builds. They can't ship without them.
+
+- **Scenario Tests**
+ - Scenario tests aren't required to produce shipping assets.
+ - These tests **do** validate the basic quality of the build. A failure means that the build is not shippable. They're also quick and reliable.
+
+
+### Example: Process That Does Not Meet the Bar
+
+- **Source build License scanning**
+ - Does not produce shipping assets
+ - Is critical validation, but is very expensive.
+ - Can be run async in a separate pipelione
+- **SDK Diff testing**
+ - Does not produce shipping assets
+ - Is necessary validation, but failure does not necessarily mean an unshippable product.
+ - Validation can be run as a separate, async pipeline.
+- **Mono Source Build Validation Legs**:
+ - Mono Source build legs do not produce shipping assets.
+ - Mono Source build legs do validate our distro partners' ability to bootstrap on non-MS supported archictures, but the builds can be flaky.
+ - There is a possibility of a compensating mechanism, a separate validation job which runs the mono validation.
diff --git a/docs/VMR-Servicing-Workflows.md b/docs/VMR-Servicing-Workflows.md
new file mode 100644
index 000000000000..ce0a2a50e139
--- /dev/null
+++ b/docs/VMR-Servicing-Workflows.md
@@ -0,0 +1,368 @@
+# The Unified Build Almanac (TUBA) - Servicing Workflow
+
+This document describes the workflow for branching, branding, and build management in servicing for 10.0. An alternative model is included later for comparison.
+
+Terminology for the info below:
+- **Current Month** – The month being built, but not yet released.
+- **Current+1 Month** – The next release after the current month.
+- **Current+2 Month** – The next release after the current+1 month.
+- **Release Specific** – Refers to a specific release, rather than an overall release train (e.g. `release/10.0.101`).
+- **General Servicing** – Refers to an overall servicing train (e.g. `release/10.0.1xx`).
+
+## Branch the VMR for each release
+
+Utilizes a **continuously** open servicing branch. A new VMR **Release Specific** branch is created off of this branch for each actual release (e.g. `release/10.0.101` and `release/10.0.200`) with additional temporary validation branches. These **Release Specific** branches may receive late-breaking fixes without endangering a future release.
+
+### TL;DR
+
+- Release builds are cut from short-lived servicing branches.
+- Long-lived servicing branches are always open.
+- Day-to-day validation occurs against long-lived validation and repository branches.
+- Final validation occurs against short-lived servicing branches.
+- Developers switch where they check in based on the point in time during the month.
+
+### Detailed Description
+
+- Tactics approves bugs continuously. These bugs are approved for a specific release (milestone). The target release may change (e.g., delayed to align with another product). Changes are **immediately** checked into the branch that matches the milestone, if it exists. This target shifts depending on where we are in the month.
+- On a specified day after the **Current Month** content is code complete (validation may not yet be complete), **Release Specific** VMR and validation branches are created:
+ - Public **Release Specific** VMR: `release/10.0.Nxx` -> `release/10.0.NOM` (off HEAD)
+ - Internal **Release Specific** VMR: `internal/release/10.0.Nxx` -> `internal/release/10.0.NOM` (off HEAD)
+ - Internal **Release Specific** VMR validation branches: `validation/release/10.0.N[0M]` off the last forward-flow SHAs.
+- **Current Month** changes then move to being checked into the following locations:
+ - Public **Release Specific** VMR branches (`release/10.0.NOM`) – for public VMR fixes.
+ - Internal **Release Specific** VMR branches (`internal/release/10.0.NOM`) – for internal fixes.
+- The Public VMR branches are rebranded for **Current+1 Month**.
+- After rebranding for **Current+1 Month** and until the next branch point, **General Servicing** branches are open for **Current+1 Month** changes. While the **General Servicing** VMR branch represents **Current+1 Month**, changes for **Current+1 Month** may be checked into the following locations:
+ - Public **General Servicing** component repository branches (e.g., SDK @ `release/10.0.1xx`, runtime @ `release/10.0`) – flows to public VMR (`release/10.0.Nxx`) via forward flow.
+ - Public **General Servicing** VMR branches (`release/10.0.Nxx`) – for public VMR fixes.
+ - Internal **General Servicing** VMR branches (`internal/release/10.0.Nxx`) – for internal fixes.
+- Changes in public VMR branches automatically merge into internal VMR branches (`release/10.0.Nxx` -> `internal/release/10.0.Nxx`, `release/10.0.NOM` -> `internal/release/10.0.NOM`). This happens continuously for both **Release Specific** and **General Servicing**.
+- Automated validation for changes is provided in the following ways:
+ - **General Servicing** – Public forward flows from component repositories receive validation on the public PRs to those repositories (e.g., `my-fix-12345` validated before merging to runtime @ `release/10.0`).
+ - **General Servicing** and **Release Specific** – Public VMR-targeted changes are validated before merge via VMR PR pipelines and scenario testing.
+ - **General Servicing** and **Release Specific** – Internal VMR-targeted changes are validated before merge via VMR PR pipelines and scenario testing.
+ - **General Servicing** and **Release Specific** – Internal component repository changes may be validated before cherry-picking into the VMR via PRs against internal validation branches (e.g., runtime @ `validation/release/10.0`, SDK @ `validation/release/10.0.202`). These changes may be merged into the validation branch but do not flow further.
+ - **General Servicing** – Public VMR builds of servicing branches backflow to the public **General Servicing** component repository branches (e.g., builds of the VMR applying to channel .NET 10.0.1xx SDK backflow to runtime @ `release/10.0` and SDK @ `release/10.0.1xx`). PR validation occurs on those backflows. This covers VMR-only changes and validates component repository sources against the latest built dependency packages.
+ - **General Servicing** and **Release Specific** – Internal VMR builds of servicing branches backflow to internal component repository validation branches (e.g., runtime @ `validation/release/10.0` and runtime @ `validation/release/10.0.2`).
+- On the release day for the **Current Month**:
+ - The product is released.
+ - The VMR release tag is merged back into the public **General Servicing** and **Release Specific** VMR release branches (e.g., `v10.0.101` -> `release/10.0.1xx`, `v10.0.200` -> `release/10.0.2xx`, `v10.0.101` -> `release/10.0.102`, `v10.0.200` -> `release/10.0.201`).
+ - The VMR bootstrap SDK is updated (the version of the SDK used to build the VMR) in the **General Servicing** branch.
+ - Arcade gets the new bootstrap SDK version, which then flows to component repositories.
+- Approved changes that do not meet the bar for **Current+1 Month** are marked with the **Current+2 Month** milestone.
+
+### Pros
+
+- **General Servicing** is always open.
+- Roughly similar to current servicing workflow.
+- Relatively simple branch and flow setup.
+- Because **General Servicing** is always open and building regularly as new fixes are approved and merged, there is a higher chance of catching infrastructure rot before it causes schedule pressure.
+
+### Cons
+
+- Developers need to know where to check in to meet the current release. If the **Release Specific** branch point is too early, this could be an issue.
+- Some fixes may have to wait if they are not approved for a currently active branch.
+- For late-breaking changes, there is no forward flow.
+- Care is required around branch time to ensure all approved fixes make it into the VMR before the branch point. For example: a runtime fix is approved, checked into the runtime repo, and begins flowing into the VMR via a PR. If the release branch is cut before that PR merges, the fix misses the release. Tooling can mitigate this risk. *Note: A similar situation exists today; long-lived branches likely reduce the chance of missing a change.*
+
+### Sample Schedule
+
+```mermaid
+gantt
+ title Alt Branch Model
+ dateFormat YYYY-MM-DD
+ axisFormat %m/%d
+
+ section General Servicing (GS)
+ GS-Feb Branch Cut (from GS HEAD) :milestone, rs_mar_cut, 2026-01-20, 0d
+ GS-Rebrand -> March (from GS HEAD) :milestone, gs_to_mar, 2026-01-20, 0d
+ GS-March Dev :gs_mar_dev, 2026-01-20, 35d
+ GS-Merge From Feb Release Tag :milestone, 2026-02-10, 0d
+ GS-Mar Branch Cut (from GS HEAD) :milestone, rs_mar_cut, 2026-02-24, 0d
+ GS Rebrand → April :milestone, gs_to_apr, 2026-02-24, 0d
+ GS April Development :gs_apr_dev, 2026-02-24, 29d
+ GS-Merge From Mar Release Tag :milestone, 2026-03-10, 0d
+
+ section RS-Feb (release/10.0.103)
+ RS-Feb Stabilization / Late Fixes :rs_feb_stab, 2026-01-20, 7d
+ RS-Feb Validation :rs_feb_build, 2026-01-27, 5d
+ RS-Feb Staging / Release :rs_feb_build, 2026-02-01, 9d
+ RS-Feb Release :milestone, 2026-02-10, 0d
+
+
+ section RS-Mar (release/10.0.104)
+ RS-Mar Stabilization Phase / Late Fixes :rs_mar_stab, 2026-02-24, 3d
+ RS-Mar Validation :rs_mar_build2, 2026-02-27, 3d
+ RS-Mar Staging / Release :rs_feb_build, 2026-03-01, 9d
+ RS-Mar Release :milestone, 2026-03-10, 0d
+```
+#### Notes on schedule
+
+- Choosing the RS branch day is a key component. The branch day should balance the following:
+ - **Late enough** to avoid requiring devs to switch check-in targets as much as possible (devs should primarily care about GS branches).
+ - **Early enough** to avoid 'parking' too many approved fixes while waiting for the matching GS branch to open.
+
+#### Developer – Public Fix
+
+1. Developer prepares source for their fix in their component repository, or in the VMR if the fix is VMR-specific.
+2. Developer prepares an approval template and brings the fix to Tactics.
+3. Tactics approves the bug for a specific release (e.g. 10.0.3 or 10.0.4)
+4. Developer merges the fix based on the current branch status and schedule, choosing the appropriate place to check in:
+ - If the approved milestone corresponds to the **Release Specific** branch, then the PR is targeted to the public VMR **Release Specific** branch and merged.
+ - If the approved milestone corresponds to the current state of the **General Servicing** branch (the branch is branded for that milestone), then the PR is targeted to the public VMR **General Servicing** branch, or the component repository **General Servicing** branch and merged.
+ - If the approved milestone does not correspond to any currently open branch, the fix is parked until a **General Servicing** VMR/component repo branch matches the milestone, and then the fix is merged.
+5. Confirm that the fix flowed into the VMR servicing branch matching the approved milestone.
+6. Wait for a validation build.
+7. Validate the fix in the shipping product.
+
+#### Developer – Internal Fix
+
+1. Developer prepares source for their fix. This can be done in two ways:
+ - In the internal validation branch of their component repository (to enable repo-specific PR validation), followed by cherry-picking to the internal VMR servicing branch.
+ - Directly in the internal VMR servicing branch.
+2. Developer prepares an approval template and brings the fix to .NET Tactics.
+3. Tactics approves the bug for a specific release (e.g. 10.0.3 or 10.0.4)
+4. Developer merges the fix based on the current branch status and schedule, choosing the appropriate place to check-in:
+ - If the approved milestone corresponds to the **Release Specific** branch, then the PR is targeted to the internal VMR **Release Specific** branch and merged.
+ - If the approved milestone corresponds to the current state of the **General Servicing** branch (the branch is branded for that milestone), then the PR is targeted to the internal VMR **General Servicing** branch and merged.
+ - If the approved milestone does not correspond to any currently open branch, the fix is parked until a **General Servicing** internal VMR branch matches the milestone, and then the fix is merged.
+5. Confirm that the fix made it into the VMR servicing branch matching the approved milestone.
+6. Wait for a validation build.
+7. Validate the fix in the shipping product.
+
+#### Repository Owner - Preparing for Upcoming Release
+
+1. Continually review approved fixes. Ensure that any approved fixes are merged to a branch that matches their milestone.
+2. Before the **Release Specific** branch date, ensure that all approved fixes have been merged into the VMR **General Servicing** branch. *Note: Tooling for this will be available*.
+3. After **Release Specific** branching, ensure that fixes approved for the milestone matching the **Release Specific** VMR branch are merged into the **Release Specific** branch.
+
+#### Repository Owner – Release Sign-off
+
+1. Regularly review status of **General Servicing** validation flows. The status of these branches represents the future shipping release before **Release Specific** branching is completed.
+ - Public and internal validation PRs should be passing
+2. Receive release candidate build for signoff, typically via the [release tracker](https://aka.ms/release-tracker) or signoff mails sent to Tactics.
+3. Ensure that expected shas and fixes from component repository are included in the build via inspection of the release tracker metadata, BarViz, or the VMR src/source-manifest.json file.
+4. Perform validations on component scenarios. This may include validations for specific fixes as well as general scenarios.
+5. Review status of internal **Release Specific** backflow validation PRs to your component repository.
+ - PRs should be passing.
+ - Backflow should be from latest internal VMR build (release candidate, or later if additional builds were completed.)
+6. Review additional rolling CI jobs as per repository validation requirements (e.g. rolling gcstress)
+
+#### Coherency QB Tasks
+
+The coherency QB would be called upon to complete the following tasks:
+
+##### Update branding, create internal validation branches
+
+On branding update day, the coherency QB will update branding to the next version via the VMR and create **Release Specific** internal validation branches. This will use the NETMechanic tool.
+
+```
+# Exact command TBD. Command NYI.
+NETMechanic.dll prepare-for-servicing --config net10.json --previous-release-sha 12345 --next-release 10.0.1,10.0.103,10.0.200
+```
+
+##### Merge in internal release tags
+
+On release day, the coherency QB will merge internal release tags to the public branches. This will use the NETMechanic tool.
+
+```
+# Exact command TBD. Command NYI.
+NETMechanic.dll merge-latest-release-tags --config net10.json
+```
+
+#### Coherency QB/Release QB/Repository Owners/Devs - Ensure desired changes are in build.
+
+Various parties may want to validate that a set of approved fixes from a specific milestone exist in the VMR build. .NET will invest in mechanisms to ensure that all intended fixes make it from their source locations into the validated build. This includes:
+- [Services Approved Fixes Tooling](https://github.com/dotnet/release/issues/1586)
+- [Linking PRs in forward flows](https://github.com/dotnet/arcade-services/pull/5355)
+
+### Special Considerations - Cherry-pick Release Specific to General Servicing?
+
+When a fix is made directly to a **Release Specific** branch, that fix will make its way back into **General Servicing** on release day, when the VMR tag is merged in. However, this is primarily an insurance measure, and cannot account for:
+- Additional special case **Release Specific** branches created before the release day.
+- The **General Servicing** branch not having a fix required for release available in daily validation.
+- Current infrastructure issues in the **General Servicing** branch resolved by the fix.
+
+It is recommended, though not required, that fixes made directly to the **Release Specific** VMR branch be merged back into the appropriate **General Servicing** branch (public->public, internal->internal).
+
+### Special Considerations - OOB Releases
+
+There are times when an OOB release is required. These are releases that contain a minimal set of fixes with new branding. These typically come in two forms:
+- A full release that includes a new runtime and new SDKs. The current in-progress release becomes N+1.
+- An SDK-only release. The SDKs move forward to N+1.
+
+#### Process
+
+- Tactics decides that an OOB release is required.
+- Tactics defines the content of this OOB release. This includes:
+ - **Release Base** – What is the basis for the release? (e.g., an SDK-only OOB after January might base off the unreleased .NET 10.0.102 SDK.)
+ - **Release Versioning** – What version should this release use, and how does that affect in-flight versions?
+ - **Release Scope** – Which components are released?
+ - **Release Content** – Additional content or changes required:
+ - Required fixes (may include the primary fix plus any supporting fixes such as NuGet thumbprint updates).
+ - Ancillary changes (e.g., implicit versions).
+- Based on the release base and content, the coherency QB chooses a branch point. This is *usually*, but not always, the previous (or soon-to-be-released) VMR SHA.
+- The coherency QB performs the branching and branding process (roughly equivalent to the monthly branching process), possibly with an additional step to move in-process release branding forward.
+ - Rebrand and rename any active **Release Specific** branches that need to change based on the introduction of a new release. For example, if an SDK-only OOB for 10.0.102 is to be released and `release/10.0.102` already exists, that branch is rebranded and then renamed to `release/10.0.103`. Typically, versions increase by 1 to leave space. The original `release/10.0.102` is deleted (it will be recreated with new content).
+ - Rebrand any active **General Release** branches that need updating (typically increment the patch version by 1).
+ - Use the `NETMechanic` tool to create a new **Release Specific** VMR branch with associated validation branches from the desired VMR base sha.
+ - As necessary, update **Release Specific** branch(es) to match desired release scope. (E.g., for an SDK-only 1xx release, disable the runtime build.)
+ - Update content in the **Release Specific** VMR branch to match approved content. This may include:
+ - *SDK-only releases*: Update to required runtime.
+ - Approved fixes
+ - Implicit versions
+ - ...
+ - As necessary, update in-progress releases to ensure that they will have the required content. This typically involves integrating the OOB release fixes into the **General Release** and **Release Specific** branches.
+- Build the release and perform validation (see sign-off tasks for more info).
+- On release day:
+ - Release the OOB.
+ - Merge the VMR OOB release tag back into the **General Release** VMR branch.
+ - If there is still runway, merge the tag back into yet-unreleased **Release Specific** VMR branches.
+
+## Alternative considered - General Servicing branches only
+
+This approach closely matches the workflow used in 9.0 and prior releases, with adjustments required due to the VMR workflow.
+
+### TL;DR
+
+- Release builds are cut from a long-lived servicing branch.
+- Validation occurs against long-lived validation and repository branches.
+- Branches are closed for a period during stabilization and validation.
+
+### Detailed Description
+
+- Tactics approves bugs continuously. Bugs are approved for a specific release (milestone) based on whether we have reached code complete for the **Current Month**.
+- On a specified day after the **Current Month** has been signed off and is on its way out the door, the public VMR branches (`release/10.0.Nxx`) are rebranded to the **Current+1 Month** release.
+- Internal component repository validation branches (e.g., SDK @ `validation/release/10.0.1xx`) are force-reset to the last forward flow of the corresponding component repositories of the internal VMR branch (which should match public).
+- After rebranding for **Current+1 Month**, branches open for changes. Approved **Current+1 Month** changes are checked into:
+ - Public component repository branches (e.g., SDK @ `release/10.0.1xx`, runtime @ `release/10.0`) – flows to public VMR (`release/10.0.Nxx`) via forward flow.
+ - Public VMR branches (`release/10.0.Nxx`) – public VMR fixes.
+ - Internal VMR branches (`internal/release/10.0.Nxx`) – internal fixes.
+- Changes in public VMR branches automatically merge into internal VMR branches (`release/10.0.Nxx` -> `internal/release/10.0.Nxx`) continuously.
+- Automated validation for changes is provided in the following ways:
+ - Public forward flows from component repositories receive validation on the original public PRs (e.g., `my-fix-12345` validated before merging to runtime @ `release/10.0`).
+ - Public VMR-targeted changes are validated before merge via the VMR PR pipelines and scenario testing.
+ - Internal VMR-targeted changes are validated before merge via the VMR PR pipelines and scenario testing.
+ - Internal component repository changes may be validated before cherry-picking into the VMR by PRs against the internal validation branches (e.g. runtime @ validation/release/10.0).
+ These changes may be merged into the validation branch, but do not flow anywhere if they are.
+ - Public VMR builds of servicing branches backflow to public component repositories (e.g., builds applying to channel .NET 10.0.1xx SDK backflow to runtime @ `release/10.0` and SDK @ `release/10.0.1xx`). PR validation covers VMR-only changes and dependency coherency.
+ - Internal VMR builds of servicing branches back flow to internal component repository validation branches (e.g. runtime @ validation/release/10.0).
+ These changes may be merged into the validation branch, but do not flow anywhere if they are.
+- On the release day for the **Current Month**:
+ - The VMR release tag is merged back into the public VMR release branch (e.g., `v10.0.101` -> `release/10.0.1xx`, `v10.0.200` -> `release/10.0.2xx`).
+ - The VMR bootstrap SDK is updated (the version of the SDK used to build the VMR).
+ - Arcade receives the new bootstrap SDK version, which then flows to component repositories.
+- **Current+1 Month** builds as new changes merge into the VMR. Validation occurs via backflow, CTI teams, VS insertion, etc. Approved changes for **Current+1 Month** are allowed as quality, risk, and time permit.
+- Approved changes that do not meet the bar for **Current+1 Month** are marked with the **Current+2 Month** milestone.
+
+### Pros
+
+- Well-trodden servicing workflow
+- Simplest dependency flow and code flow strategy
+- Fewest places for devs to merge code.
+
+### Cons
+
+- Branches 'close' for a period of time while building **Current+1 Month**, but before branding for **Current+2 Month** is complete. This period allows for a stable, predictable branch while validation
+ is completed. If critical changes are required for **Current+1 Month**, they can be made in component repositories or the VMR directly without inadvertently bringing in **Current+2 Month** changes.
+- Because branches close for a period of time, there is a higher likelihood that infrastructure 'rot' will be discovered when a servicing release is closer to the end of its build or validation window. This can cause schedule pressure.
+
+### Sample Schedule
+
+Schedule
+
+```mermaid
+gantt
+ title .NET 10 Servicing – February & March 2026
+ dateFormat YYYY-MM-DD
+ axisFormat %m/%d
+
+ %% FEBRUARY (Current)
+ section February Release (Current)
+ Release Day (Ship February) :milestone, feb_release, 2026-02-10, 0d
+ Post-Release Tag Merge & Validation Branch Reset (Feb) :milestone, feb_reset, 2026-02-10, 0d
+
+ %% MARCH (Current+1 before Feb 10; becomes Current after Feb 10)
+ section March Release (Current+1)
+ March Branding Update :milestone, mar_branding, 2026-02-03, 0d
+ Merge Approved Fixes for Current+1 :milestone, 2026-02-03, 0d
+ March Branches Open :mar_open, 2026-02-03, 10d
+ March Build / Validation Window :mar_build, 2026-02-10, 9d
+ March Staging :mar_staging, 2026-02-19, 10d
+ March Release Day (Ship March) :milestone, mar_release, 2026-03-10, 0d
+ March Post-Release Tag Merge & Reset :milestone, mar_reset, 2026-03-10, 0d
+
+ %% APRIL (Emerging Current+2 → becomes Current+1 after Mar 10)
+ section April Release (Current+2)
+ April Branding Update :milestone, apr_branding, 2026-03-03, 0d
+ Merge Approved Fixes for Current+2 :milestone, 2026-03-03, 0d
+ April Branches Open :apr_open, 2026-03-03, 10d
+```
+
+### Participant Workflows
+
+#### Developer – Public Fix
+
+1. Developer prepares source for their fix in their component repository, or in the VMR if the fix is VMR-specific.
+2. Developer prepares an approval template and brings the fix to Tactics.
+3. Tactics approves the bug for a specific release (e.g. 10.0.3 or 10.0.4)
+4. Developer merges the fix based on current branch status and schedule:
+ - If release branches are currently closed, or the component release branch/VMR servicing branch corresponds to a different milestone, the fix is parked until the branch opens for that milestone.
+ - If the branch corresponds to the approved milestone (i.e., branded for that month) and is open, the fix is merged immediately.
+5. If the fix was made to the component repository, confirm that the fix flowed into the VMR servicing branch via a merged forward flow PR.
+6. Wait for a validation build.
+7. Validate the fix in the shipping product.
+
+#### Developer – Internal Fix
+
+1. Developer prepares source for their fix. This can be done in two ways:
+ - In the internal validation branch of their component repository (enables repo-specific PR validation), then cherry-pick to the internal VMR servicing branch.
+ - Directly in the internal VMR servicing branch.
+2. Developer prepares an approval template and brings the fix to .NET Tactics.
+3. Tactics approves the bug for a specific release (e.g. 10.0.3 or 10.0.4)
+4. Developer merges the fix based on current branch status and schedule:
+ - If release branches are currently closed, or the internal VMR servicing branch corresponds to a different milestone, the fix is parked until the branch opens for that milestone.
+ - If the branch corresponds to the approved milestone (i.e., branded for that month) and is open, the fix is merged immediately.
+5. Wait for a validation build.
+6. Validate the fix in the shipping product.
+
+#### Repository Owner – Release Sign-off
+
+1. Receive release candidate build for signoff, typically via the [release tracker](https://aka.ms/release-tracker) or signoff mails sent to Tactics.
+2. Ensure that expected shas and fixes from component repository are included in the build via inspection of the release tracker metadata, BarViz, or the VMR src/source-manifest.json file.
+3. Perform validations on component scenarios. May include validations for specific fixes as well as general scenarios.
+4. Review status of internal backflow validation PRs to your component repository.
+ - PRs should be passing.
+ - Backflow should be from latest internal VMR build (release candidate, or later if additional builds were completed.)
+5. Review status of public validation PRs to your component repository
+ - PRs should be passing.
+ - Backflow should be from latest internal VMR build (release candidate, or later if additional builds were completed.)
+6. Review additional rolling CI jobs as per repository validation requirements (e.g. rolling gcstress)
+
+#### Coherency QB Tasks
+
+The coherency QB would be called upon to complete the following tasks:
+
+##### Update branding and reset internal validation branches
+
+On branding update day, the coherency QB will update branding to the next version via the VMR and reset the internal validation branches to the known state. This will use the NETMechanic tool.
+
+```
+# Exact command TBD. Command NYI.
+NETMechanic.dll prepare-for-servicing --config net10.json --previous-release-sha 12345 --next-release 10.0.1,10.0.103,10.0.200
+```
+
+##### Merge in internal release tags
+
+On release day, the coherency QB will merge internal release tags to the public branches. This will use the NETMechanic tool.
+
+```
+# Exact command TBD. Command NYI.
+NETMechanic.dll merge-latest-release-tags --config net10.json
+```
+
+#### Coherency QB/Release QB/Repository Owners/Devs - Ensure desired changes are in build.
+
+Various parties may be interested in validating that a set of approved fixes from a specific milestone exist in the VMR build. .NET will invest in various ways to ensure that all fixes intended for a given servicing release make it from their various source locations and into the validated build. This includes:
+- [Services Approved Fixes Tooling](https://github.com/dotnet/release/issues/1586)
+- [Linking PRs in forward flows](https://github.com/dotnet/arcade-services/pull/5355)
diff --git a/docs/builds-table.md b/docs/builds-table.md
index 27bde87c4047..1f5f88889da6 100644
--- a/docs/builds-table.md
+++ b/docs/builds-table.md
@@ -1,162 +1,304 @@
+> [!NOTE]
+> When acquiring installers from the .NET SDK latest builds table, be aware that the installers are the **latest bits**. With development builds, internal NuGet feeds are necessary for some scenarios (for example, to acquire the runtime pack for self-contained apps). You can use the following NuGet.config to configure these feeds. See the following document [Configuring NuGet behavior](https://docs.microsoft.com/nuget/consume-packages/configuring-nuget-behavior) for more information on where to modify your NuGet.config to apply the changes.
+
+### For .NET 11 builds
+```xml
+
+
+
+
+
+```
+
+### For .NET 10 builds
+```xml
+
+
+
+
+
+```
+
### Supported Platforms
---------------------------------------------------------------------------------------
-| Platform | main
(10.0.x Runtime) | 10.0.1xx-preview7
(10.0-preview7 Runtime) |
+--------------------------------------------------------------------------------------------------------------------------------
+| Platform | main
(11.0.x Runtime) | 10.0.2xx
(10.0.2xx Runtime) |
| :--------- | :----------: | :----------: |
-| **Windows x64** | [![][win-x64-badge-main]][win-x64-version-main]
[Installer][win-x64-installer-main] - [Checksum][win-x64-installer-checksum-main]
[zip][win-x64-zip-main] - [Checksum][win-x64-zip-checksum-main] | [![][win-x64-badge-10.0.1XX-preview7]][win-x64-version-10.0.1XX-preview7]
[Installer][win-x64-installer-10.0.1XX-preview7] - [Checksum][win-x64-installer-checksum-10.0.1XX-preview7]
[zip][win-x64-zip-10.0.1XX-preview7] - [Checksum][win-x64-zip-checksum-10.0.1XX-preview7] |
-| **Windows x86** | [![][win-x86-badge-main]][win-x86-version-main]
[Installer][win-x86-installer-main] - [Checksum][win-x86-installer-checksum-main]
[zip][win-x86-zip-main] - [Checksum][win-x86-zip-checksum-main] | [![][win-x86-badge-10.0.1XX-preview7]][win-x86-version-10.0.1XX-preview7]
[Installer][win-x86-installer-10.0.1XX-preview7] - [Checksum][win-x86-installer-checksum-10.0.1XX-preview7]
[zip][win-x86-zip-10.0.1XX-preview7] - [Checksum][win-x86-zip-checksum-10.0.1XX-preview7] |
-| **Windows arm64** | [![][win-arm64-badge-main]][win-arm64-version-main]
[Installer][win-arm64-installer-main] - [Checksum][win-arm64-installer-checksum-main]
[zip][win-arm64-zip-main] - [Checksum][win-arm64-zip-checksum-main] | [![][win-arm64-badge-10.0.1XX-preview7]][win-arm64-version-10.0.1XX-preview7]
[Installer][win-arm64-installer-10.0.1XX-preview7] - [Checksum][win-arm64-installer-checksum-10.0.1XX-preview7]
[zip][win-arm64-zip-10.0.1XX-preview7] |
-| **macOS x64** | [![][osx-x64-badge-main]][osx-x64-version-main]
[Installer][osx-x64-installer-main] - [Checksum][osx-x64-installer-checksum-main]
[tar.gz][osx-x64-targz-main] - [Checksum][osx-x64-targz-checksum-main] | [![][osx-x64-badge-10.0.1XX-preview7]][osx-x64-version-10.0.1XX-preview7]
[Installer][osx-x64-installer-10.0.1XX-preview7] - [Checksum][osx-x64-installer-checksum-10.0.1XX-preview7]
[tar.gz][osx-x64-targz-10.0.1XX-preview7] - [Checksum][osx-x64-targz-checksum-10.0.1XX-preview7] |
-| **macOS arm64** | [![][osx-arm64-badge-main]][osx-arm64-version-main]
[Installer][osx-arm64-installer-main] - [Checksum][osx-arm64-installer-checksum-main]
[tar.gz][osx-arm64-targz-main] - [Checksum][osx-arm64-targz-checksum-main] | [![][osx-arm64-badge-10.0.1XX-preview7]][osx-arm64-version-10.0.1XX-preview7]
[Installer][osx-arm64-installer-10.0.1XX-preview7] - [Checksum][osx-arm64-installer-checksum-10.0.1XX-preview7]
[tar.gz][osx-arm64-targz-10.0.1XX-preview7] - [Checksum][osx-arm64-targz-checksum-10.0.1XX-preview7] |
-| **Linux x64** | [![][linux-badge-main]][linux-version-main]
[DEB Installer][linux-DEB-installer-main] - [Checksum][linux-DEB-installer-checksum-main]
[RPM Installer][linux-RPM-installer-main] - [Checksum][linux-RPM-installer-checksum-main]
_see installer note below_1
[tar.gz][linux-targz-main] - [Checksum][linux-targz-checksum-main] | [![][linux-badge-10.0.1XX-preview7]][linux-version-10.0.1XX-preview7]
[DEB Installer][linux-DEB-installer-10.0.1XX-preview7] - [Checksum][linux-DEB-installer-checksum-10.0.1XX-preview7]
[RPM Installer][linux-RPM-installer-10.0.1XX-preview7] - [Checksum][linux-RPM-installer-checksum-10.0.1XX-preview7]
_see installer note below_1
[tar.gz][linux-targz-10.0.1XX-preview7] - [Checksum][linux-targz-checksum-10.0.1XX-preview7] |
-| **Linux arm** | [![][linux-arm-badge-main]][linux-arm-version-main]
[tar.gz][linux-arm-targz-main] - [Checksum][linux-arm-targz-checksum-main] | [![][linux-arm-badge-10.0.1XX-preview7]][linux-arm-version-10.0.1XX-preview7]
[tar.gz][linux-arm-targz-10.0.1XX-preview7] - [Checksum][linux-arm-targz-checksum-10.0.1XX-preview7] |
-| **Linux arm64** | [![][linux-arm64-badge-main]][linux-arm64-version-main]
[tar.gz][linux-arm64-targz-main] - [Checksum][linux-arm64-targz-checksum-main] | [![][linux-arm64-badge-10.0.1XX-preview7]][linux-arm64-version-10.0.1XX-preview7]
[tar.gz][linux-arm64-targz-10.0.1XX-preview7] - [Checksum][linux-arm64-targz-checksum-10.0.1XX-preview7] |
-| **Linux-musl-x64** | [![][linux-musl-x64-badge-main]][linux-musl-x64-version-main]
[tar.gz][linux-musl-x64-targz-main] - [Checksum][linux-musl-x64-targz-checksum-main] | [![][linux-musl-x64-badge-10.0.1XX-preview7]][linux-musl-x64-version-10.0.1XX-preview7]
[tar.gz][linux-musl-x64-targz-10.0.1XX-preview7] - [Checksum][linux-musl-x64-targz-checksum-10.0.1XX-preview7] |
-| **Linux-musl-arm** | [![][linux-musl-arm-badge-main]][linux-musl-arm-version-main]
[tar.gz][linux-musl-arm-targz-main] - [Checksum][linux-musl-arm-targz-checksum-main] | [![][linux-musl-arm-badge-10.0.1XX-preview7]][linux-musl-arm-version-10.0.1XX-preview7]
[tar.gz][linux-musl-arm-targz-10.0.1XX-preview7] - [Checksum][linux-musl-arm-targz-checksum-10.0.1XX-preview7] |
-| **Linux-musl-arm64** | [![][linux-musl-arm64-badge-main]][linux-musl-arm64-version-main]
[tar.gz][linux-musl-arm64-targz-main] - [Checksum][linux-musl-arm64-targz-checksum-main] | [![][linux-musl-arm64-badge-10.0.1XX-preview7]][linux-musl-arm64-version-10.0.1XX-preview7]
[tar.gz][linux-musl-arm64-targz-10.0.1XX-preview7] - [Checksum][linux-musl-arm64-targz-checksum-10.0.1XX-preview7] |
-
-Reference notes:
-> **1**: Our Debian packages are put together slightly differently than the other OS specific installers. Instead of combining everything, we have separate component packages that depend on each other. If you're installing the SDK from the .deb file (via dpkg or similar), then you'll need to install the corresponding dependencies first:
-> * [Host, Host FX Resolver, and Shared Framework](https://github.com/dotnet/runtime/blob/main/docs/project/dogfooding.md#nightly-builds-table)
-> * [ASP.NET Core Shared Framework](https://github.com/aspnet/AspNetCore/blob/main/docs/DailyBuilds.md)
-
-#### Manually construct a link to download an SDK msi (example for dotnet-sdk msi for win-x64):
-> `https://ci.dot.net/public/Sdk//dotnet-sdk--win-x64.exe`
-
-[win-x64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/win_x64_Release_version_badge.svg?no-cache
-[win-x64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-win-x64.txt
-[win-x64-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x64.exe
-[win-x64-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x64.exe.sha512
-[win-x64-zip-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x64.zip
-[win-x64-zip-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x64.zip.sha512
-
-[win-x64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/win_x64_Release_version_badge.svg?no-cache
-[win-x64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-win-x64.txt
-[win-x64-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x64.exe
-[win-x64-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x64.exe.sha512
-[win-x64-zip-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x64.zip
-[win-x64-zip-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x64.zip.sha512
-
-[win-x86-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/win_x86_Release_version_badge.svg?no-cache
-[win-x86-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-win-x86.txt
-[win-x86-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x86.exe
-[win-x86-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x86.exe.sha512
-[win-x86-zip-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x86.zip
-[win-x86-zip-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-x86.zip.sha512
-
-[win-x86-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/win_x86_Release_version_badge.svg?no-cache
-[win-x86-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-win-x86.txt
-[win-x86-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x86.exe
-[win-x86-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x86.exe.sha512
-[win-x86-zip-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x86.zip
-[win-x86-zip-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-x86.zip.sha512
-
-[osx-x64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/osx_x64_Release_version_badge.svg?no-cache
-[osx-x64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-osx-x64.txt
-[osx-x64-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-x64.pkg
-[osx-x64-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-x64.pkg.sha512
-[osx-x64-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-x64.tar.gz
-[osx-x64-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-x64.pkg.tar.gz.sha512
-
-[osx-x64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/osx_x64_Release_version_badge.svg?no-cache
-[osx-x64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-osx-x64.txt
-[osx-x64-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-x64.pkg
-[osx-x64-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-x64.pkg.sha512
-[osx-x64-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-x64.tar.gz
-[osx-x64-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-x64.pkg.tar.gz.sha512
-
-[osx-arm64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/osx_arm64_Release_version_badge.svg?no-cache
-[osx-arm64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-osx-arm64.txt
-[osx-arm64-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-arm64.pkg
-[osx-arm64-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-arm64.pkg.sha512
-[osx-arm64-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-arm64.tar.gz
-[osx-arm64-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-osx-arm64.pkg.tar.gz.sha512
-
-[osx-arm64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/osx_arm64_Release_version_badge.svg?no-cache
-[osx-arm64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-osx-arm64.txt
-[osx-arm64-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-arm64.pkg
-[osx-arm64-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-arm64.pkg.sha512
-[osx-arm64-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-arm64.tar.gz
-[osx-arm64-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-osx-arm64.pkg.tar.gz.sha512
-
-[linux-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/linux_x64_Release_version_badge.svg?no-cache
-[linux-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-linux-x64.txt
-[linux-DEB-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-x64.deb
-[linux-DEB-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-x64.deb.sha512
-[linux-RPM-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-x64.rpm
-[linux-RPM-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-x64.rpm.sha512
-[linux-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-x64.tar.gz
-[linux-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-x64.tar.gz.sha512
-
-[linux-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/linux_x64_Release_version_badge.svg?no-cache
-[linux-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-linux-x64.txt
-[linux-DEB-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-x64.deb
-[linux-DEB-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-x64.deb.sha512
-[linux-RPM-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-x64.rpm
-[linux-RPM-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-x64.rpm.sha512
-[linux-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-x64.tar.gz
-[linux-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-x64.tar.gz.sha512
-
-[linux-arm-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/linux_arm_Release_version_badge.svg?no-cache
-[linux-arm-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-linux-arm.txt
-[linux-arm-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-arm.tar.gz
-[linux-arm-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-arm.tar.gz.sha512
-
-[linux-arm-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/linux_arm_Release_version_badge.svg?no-cache
-[linux-arm-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-linux-arm.txt
-[linux-arm-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-arm.tar.gz
-[linux-arm-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-arm.tar.gz.sha512
-
-[linux-arm64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/linux_arm64_Release_version_badge.svg?no-cache
-[linux-arm64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-linux-arm64.txt
-[linux-arm64-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-arm64.tar.gz
-[linux-arm64-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-arm64.tar.gz.sha512
-
-[linux-arm64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/linux_arm64_Release_version_badge.svg?no-cache
-[linux-arm64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-linux-arm64.txt
-[linux-arm64-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-arm64.tar.gz
-[linux-arm64-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-arm64.tar.gz.sha512
-
-[linux-musl-x64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/linux_musl_x64_Release_version_badge.svg?no-cache
-[linux-musl-x64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-linux-musl-x64.txt
-[linux-musl-x64-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-musl-x64.tar.gz
-[linux-musl-x64-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-musl-x64.tar.gz.sha512
-
-[linux-musl-x64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/linux_musl_x64_Release_version_badge.svg?no-cache
-[linux-musl-x64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-linux-musl-x64.txt
-[linux-musl-x64-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-musl-x64.tar.gz
-[linux-musl-x64-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-musl-x64.tar.gz.sha512
-
-[linux-musl-arm-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/linux_musl_arm_Release_version_badge.svg?no-cache
-[linux-musl-arm-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-linux-musl-arm.txt
-[linux-musl-arm-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-musl-arm.tar.gz
-[linux-musl-arm-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-musl-arm.tar.gz.sha512
-
-[linux-musl-arm-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/linux_musl_arm_Release_version_badge.svg?no-cache
-[linux-musl-arm-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-linux-musl-arm.txt
-[linux-musl-arm-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-musl-arm.tar.gz
-[linux-musl-arm-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-musl-arm.tar.gz.sha512
-
-[linux-musl-arm64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/linux_musl_arm64_Release_version_badge.svg?no-cache
-[linux-musl-arm64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-linux-musl-arm64.txt
-[linux-musl-arm64-targz-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-musl-arm64.tar.gz
-[linux-musl-arm64-targz-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-linux-musl-arm64.tar.gz.sha512
-
-[linux-musl-arm64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/linux_musl_arm64_Release_version_badge.svg?no-cache
-[linux-musl-arm64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-linux-musl-arm64.txt
-[linux-musl-arm64-targz-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-musl-arm64.tar.gz
-[linux-musl-arm64-targz-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-linux-musl-arm64.tar.gz.sha512
-
-[win-arm64-badge-main]: https://aka.ms/dotnet/10.0.1xx/daily/win_arm64_Release_version_badge.svg?no-cache
-[win-arm64-version-main]: https://aka.ms/dotnet/10.0.1xx/daily/productCommit-win-arm64.txt
-[win-arm64-installer-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-arm64.exe
-[win-arm64-installer-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-arm64.exe.sha512
-[win-arm64-zip-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-arm64.zip
-[win-arm64-zip-checksum-main]: https://aka.ms/dotnet/10.0.1xx/daily/dotnet-sdk-win-arm64.zip.sha512
-
-[win-arm64-badge-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/win_arm64_Release_version_badge.svg?no-cache
-[win-arm64-version-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/productCommit-win-arm64.txt
-[win-arm64-installer-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-arm64.exe
-[win-arm64-installer-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-arm64.exe.sha512
-[win-arm64-zip-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-arm64.zip
-[win-arm64-zip-checksum-10.0.1XX-preview7]: https://aka.ms/dotnet/10.0.1xx-preview7/daily/dotnet-sdk-win-arm64.zip.sha512
+| **Windows x64** | [![][win-x64-badge-main]][win-x64-version-main]
[Installer][win-x64-installer-main] - [Checksum][win-x64-installer-checksum-main]
[zip][win-x64-zip-main] - [Checksum][win-x64-zip-checksum-main] | [![][win-x64-badge-10.0.2XX]][win-x64-version-10.0.2XX]
[Installer][win-x64-installer-10.0.2XX] - [Checksum][win-x64-installer-checksum-10.0.2XX]
[zip][win-x64-zip-10.0.2XX] - [Checksum][win-x64-zip-checksum-10.0.2XX] |
+| **Windows x86** | [![][win-x86-badge-main]][win-x86-version-main]
[Installer][win-x86-installer-main] - [Checksum][win-x86-installer-checksum-main]
[zip][win-x86-zip-main] - [Checksum][win-x86-zip-checksum-main] | [![][win-x86-badge-10.0.2XX]][win-x86-version-10.0.2XX]
[Installer][win-x86-installer-10.0.2XX] - [Checksum][win-x86-installer-checksum-10.0.2XX]
[zip][win-x86-zip-10.0.2XX] - [Checksum][win-x86-zip-checksum-10.0.2XX] |
+| **Windows arm64** | [![][win-arm64-badge-main]][win-arm64-version-main]
[Installer][win-arm64-installer-main] - [Checksum][win-arm64-installer-checksum-main]
[zip][win-arm64-zip-main] - [Checksum][win-arm64-zip-checksum-main] | [![][win-arm64-badge-10.0.2XX]][win-arm64-version-10.0.2XX]
[Installer][win-arm64-installer-10.0.2XX] - [Checksum][win-arm64-installer-checksum-10.0.2XX]
[zip][win-arm64-zip-10.0.2XX] |
+| **macOS arm64**(M-series CPUs) | [![][osx-arm64-badge-main]][osx-arm64-version-main]
[Installer][osx-arm64-installer-main] - [Checksum][osx-arm64-installer-checksum-main]
[tar.gz][osx-arm64-targz-main] - [Checksum][osx-arm64-targz-checksum-main] | [![][osx-arm64-badge-10.0.2XX]][osx-arm64-version-10.0.2XX]
[Installer][osx-arm64-installer-10.0.2XX] - [Checksum][osx-arm64-installer-checksum-10.0.2XX]
[tar.gz][osx-arm64-targz-10.0.2XX] - [Checksum][osx-arm64-targz-checksum-10.0.2XX] |
+| **macOS x64**(Intel CPUs) | [![][osx-x64-badge-main]][osx-x64-version-main]
[Installer][osx-x64-installer-main] - [Checksum][osx-x64-installer-checksum-main]
[tar.gz][osx-x64-targz-main] - [Checksum][osx-x64-targz-checksum-main] | [![][osx-x64-badge-10.0.2XX]][osx-x64-version-10.0.2XX]
[Installer][osx-x64-installer-10.0.2XX] - [Checksum][osx-x64-installer-checksum-10.0.2XX]
[tar.gz][osx-x64-targz-10.0.2XX] - [Checksum][osx-x64-targz-checksum-10.0.2XX] |
+| **Linux x64** | [![][linux-badge-main]][linux-version-main]
[DEB Installer][linux-DEB-installer-main] - [Checksum][linux-DEB-installer-checksum-main]
[RPM Installer][linux-RPM-installer-main] - [Checksum][linux-RPM-installer-checksum-main]
_see installer note below_1
[tar.gz][linux-targz-main] - [Checksum][linux-targz-checksum-main] | [![][linux-badge-10.0.2XX]][linux-version-10.0.2XX]
[DEB Installer][linux-DEB-installer-10.0.2XX] - [Checksum][linux-DEB-installer-checksum-10.0.2XX]
[RPM Installer][linux-RPM-installer-10.0.2XX] - [Checksum][linux-RPM-installer-checksum-10.0.2XX]
_see installer note below_1
[tar.gz][linux-targz-10.0.2XX] - [Checksum][linux-targz-checksum-10.0.2XX] |
+| **Linux arm** | [![][linux-arm-badge-main]][linux-arm-version-main]
[tar.gz][linux-arm-targz-main] - [Checksum][linux-arm-targz-checksum-main] | [![][linux-arm-badge-10.0.2XX]][linux-arm-version-10.0.2XX]
[tar.gz][linux-arm-targz-10.0.2XX] - [Checksum][linux-arm-targz-checksum-10.0.2XX] |
+| **Linux arm64** | [![][linux-arm64-badge-main]][linux-arm64-version-main]
[tar.gz][linux-arm64-targz-main] - [Checksum][linux-arm64-targz-checksum-main] | [![][linux-arm64-badge-10.0.2XX]][linux-arm64-version-10.0.2XX]
[tar.gz][linux-arm64-targz-10.0.2XX] - [Checksum][linux-arm64-targz-checksum-10.0.2XX] |
+| **Linux-musl-x64** | [![][linux-musl-x64-badge-main]][linux-musl-x64-version-main]
[tar.gz][linux-musl-x64-targz-main] - [Checksum][linux-musl-x64-targz-checksum-main] | [![][linux-musl-x64-badge-10.0.2XX]][linux-musl-x64-version-10.0.2XX]
[tar.gz][linux-musl-x64-targz-10.0.2XX] - [Checksum][linux-musl-x64-targz-checksum-10.0.2XX] |
+| **Linux-musl-arm** | [![][linux-musl-arm-badge-main]][linux-musl-arm-version-main]
[tar.gz][linux-musl-arm-targz-main] - [Checksum][linux-musl-arm-targz-checksum-main] | [![][linux-musl-arm-badge-10.0.2XX]][linux-musl-arm-version-10.0.2XX]
[tar.gz][linux-musl-arm-targz-10.0.2XX] - [Checksum][linux-musl-arm-targz-checksum-10.0.2XX] |
+| **Linux-musl-arm64** | [![][linux-musl-arm64-badge-main]][linux-musl-arm64-version-main]
[tar.gz][linux-musl-arm64-targz-main] - [Checksum][linux-musl-arm64-targz-checksum-main] | [![][linux-musl-arm64-badge-10.0.2XX]][linux-musl-arm64-version-10.0.2XX]
[tar.gz][linux-musl-arm64-targz-10.0.2XX] - [Checksum][linux-musl-arm64-targz-checksum-10.0.2XX] |
+
+# .NET SDK Daily Builds
+
+## Installation Instructions
+
+### Windows
+
+Download the latest SDK installer or binaries from the builds table above.
+
+Windows SDK and Runtime installers are complete packages and do not require separate dependency installation.
+
+### Linux (DEB and RPM Packages)
+
+#### SDK Packages
+
+Download the appropriate SDK package for your distribution:
+- **Debian/Ubuntu:** `dotnet-sdk--x64.deb`
+- **Red Hat/Fedora/CentOS:** `dotnet-sdk--x64.rpm`
+
+#### Dependencies
+
+The following runtime packages are required dependencies and must be installed before installing the SDK:
+
+**For Debian/Ubuntu (.deb):**
+- `dotnet-host--x64.deb`
+- `dotnet-targeting-pack--x64.deb`
+- `dotnet-hostfxr--x64.deb`
+- `dotnet-apphost-pack--x64.deb`
+- `dotnet-runtime-deps--x64.deb`
+- `dotnet-runtime--x64.deb`
+
+**For Red Hat/Fedora/CentOS (.rpm):**
+- `dotnet-host--x64.rpm`
+- `dotnet-targeting-pack--x64.rpm`
+- `dotnet-hostfxr--x64.rpm`
+- `dotnet-apphost-pack--x64.rpm`
+- `dotnet-runtime-deps--x64.rpm`
+- `dotnet-runtime--x64.rpm`
+
+The following ASP.NET Core packages are required for ASP.NET Core development:
+
+**For Debian/Ubuntu (.deb):**
+- `aspnetcore-targeting-pack--x64.deb`
+- `aspnetcore-runtime--x64.deb`
+
+**For Red Hat/Fedora/CentOS (.rpm):**
+- `aspnetcore-targeting-pack--x64.rpm`
+- `aspnetcore-runtime--x64.rpm`
+
+These packages can be downloaded from:
+
+**Runtime packages:**
+```
+https://ci.dot.net/public/Runtime//dotnet-host--x64.
+https://ci.dot.net/public/Runtime//dotnet-targeting-pack--x64.
+https://ci.dot.net/public/Runtime//dotnet-hostfxr--x64.
+https://ci.dot.net/public/Runtime//dotnet-apphost-pack--x64.
+https://ci.dot.net/public/Runtime//dotnet-runtime-deps--x64.
+https://ci.dot.net/public/Runtime//dotnet-runtime--x64.
+```
+
+**ASP.NET Core packages:**
+```
+https://ci.dot.net/public/aspnetcore/Runtime//aspnetcore-targeting-pack--x64.
+https://ci.dot.net/public/aspnetcore/Runtime//aspnetcore-runtime--x64.
+```
+
+Where:
+- `` is the same for both SDK and runtime (can be obtained from the version badge links or productCommit files in the table above)
+- `` is either `deb` for Debian/Ubuntu or `rpm` for Red Hat/Fedora/CentOS
+
+#### Installation Order
+
+Install the packages in the following order:
+
+1. Runtime dependencies (in order):
+ - `dotnet-host--x64.`
+ - `dotnet-targeting-pack--x64.`
+ - `dotnet-hostfxr--x64.`
+ - `dotnet-apphost-pack--x64.`
+ - `dotnet-runtime-deps--x64.`
+ - `dotnet-runtime--x64.`
+
+2. ASP.NET Core dependencies (if needed):
+ - `aspnetcore-targeting-pack--x64.`
+ - `aspnetcore-runtime--x64.`
+
+3. Finally, install the SDK:
+ - `dotnet-sdk--x64.`
+
+**Example installation commands:**
+
+For Debian/Ubuntu:
+```bash
+sudo dpkg -i dotnet-host--x64.deb
+sudo dpkg -i dotnet-targeting-pack--x64.deb
+sudo dpkg -i dotnet-hostfxr--x64.deb
+sudo dpkg -i dotnet-apphost-pack--x64.deb
+sudo dpkg -i dotnet-runtime-deps--x64.deb
+sudo dpkg -i dotnet-runtime--x64.deb
+sudo dpkg -i aspnetcore-targeting-pack--x64.deb
+sudo dpkg -i aspnetcore-runtime--x64.deb
+sudo dpkg -i dotnet-sdk--x64.deb
+```
+
+For Red Hat/Fedora/CentOS:
+```bash
+sudo rpm -i dotnet-host--x64.rpm
+sudo rpm -i dotnet-targeting-pack--x64.rpm
+sudo rpm -i dotnet-hostfxr--x64.rpm
+sudo rpm -i dotnet-apphost-pack--x64.rpm
+sudo rpm -i dotnet-runtime-deps--x64.rpm
+sudo rpm -i dotnet-runtime--x64.rpm
+sudo rpm -i aspnetcore-targeting-pack--x64.rpm
+sudo rpm -i aspnetcore-runtime--x64.rpm
+sudo rpm -i dotnet-sdk--x64.rpm
+```
+
+### macOS
+
+Download the latest SDK installer or binaries from the builds table above.
+
+macOS SDK and Runtime installers are complete packages and do not require separate dependency installation.
+
+## Version Information
+
+For the 1xx band, the runtime and SDK are built together in the same build. They will differ on patch version (e.g. SDK version 10.0.100 == runtime patch version 10.0.0). The build suffix (e.g. -rc2.1234.105) will always match.
+
+For the 2xx and later bands, the 1xx runtime flows to 2xx+. The version of the runtime that will be used in the 2xx SDK can be found in sdk's `eng/Version.Details.xml` file. Look for the version of the `Microsoft.NETCore.App.Ref` dependency.
+
+[win-x64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/win_x64_Release_version_badge.svg?no-cache
+[win-x64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-win-x64.txt
+[win-x64-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x64.exe
+[win-x64-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x64.exe.sha512
+[win-x64-zip-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x64.zip
+[win-x64-zip-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x64.zip.sha512
+
+[win-x64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/win_x64_Release_version_badge.svg?no-cache
+[win-x64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-win-x64.txt
+[win-x64-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x64.exe
+[win-x64-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x64.exe.sha512
+[win-x64-zip-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x64.zip
+[win-x64-zip-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x64.zip.sha512
+
+[win-x86-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/win_x86_Release_version_badge.svg?no-cache
+[win-x86-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-win-x86.txt
+[win-x86-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x86.exe
+[win-x86-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x86.exe.sha512
+[win-x86-zip-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x86.zip
+[win-x86-zip-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-x86.zip.sha512
+
+[win-x86-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/win_x86_Release_version_badge.svg?no-cache
+[win-x86-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-win-x86.txt
+[win-x86-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x86.exe
+[win-x86-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x86.exe.sha512
+[win-x86-zip-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x86.zip
+[win-x86-zip-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-x86.zip.sha512
+
+[osx-x64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/osx_x64_Release_version_badge.svg?no-cache
+[osx-x64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-osx-x64.txt
+[osx-x64-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-x64.pkg
+[osx-x64-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-x64.pkg.sha512
+[osx-x64-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-x64.tar.gz
+[osx-x64-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-x64.pkg.tar.gz.sha512
+
+[osx-x64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/osx_x64_Release_version_badge.svg?no-cache
+[osx-x64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-osx-x64.txt
+[osx-x64-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-x64.pkg
+[osx-x64-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-x64.pkg.sha512
+[osx-x64-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-x64.tar.gz
+[osx-x64-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-x64.pkg.tar.gz.sha512
+
+[osx-arm64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/osx_arm64_Release_version_badge.svg?no-cache
+[osx-arm64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-osx-arm64.txt
+[osx-arm64-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-arm64.pkg
+[osx-arm64-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-arm64.pkg.sha512
+[osx-arm64-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-arm64.tar.gz
+[osx-arm64-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-osx-arm64.pkg.tar.gz.sha512
+
+[osx-arm64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/osx_arm64_Release_version_badge.svg?no-cache
+[osx-arm64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-osx-arm64.txt
+[osx-arm64-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-arm64.pkg
+[osx-arm64-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-arm64.pkg.sha512
+[osx-arm64-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-arm64.tar.gz
+[osx-arm64-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-osx-arm64.pkg.tar.gz.sha512
+
+[linux-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/linux_x64_Release_version_badge.svg?no-cache
+[linux-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-linux-x64.txt
+[linux-DEB-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-x64.deb
+[linux-DEB-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-x64.deb.sha512
+[linux-RPM-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-x64.rpm
+[linux-RPM-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-x64.rpm.sha512
+[linux-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-x64.tar.gz
+[linux-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-x64.tar.gz.sha512
+
+[linux-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/linux_x64_Release_version_badge.svg?no-cache
+[linux-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-linux-x64.txt
+[linux-DEB-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-x64.deb
+[linux-DEB-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-x64.deb.sha512
+[linux-RPM-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-x64.rpm
+[linux-RPM-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-x64.rpm.sha512
+[linux-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-x64.tar.gz
+[linux-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-x64.tar.gz.sha512
+
+[linux-arm-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/linux_arm_Release_version_badge.svg?no-cache
+[linux-arm-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-linux-arm.txt
+[linux-arm-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-arm.tar.gz
+[linux-arm-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-arm.tar.gz.sha512
+
+[linux-arm-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/linux_arm_Release_version_badge.svg?no-cache
+[linux-arm-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-linux-arm.txt
+[linux-arm-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-arm.tar.gz
+[linux-arm-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-arm.tar.gz.sha512
+
+[linux-arm64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/linux_arm64_Release_version_badge.svg?no-cache
+[linux-arm64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-linux-arm64.txt
+[linux-arm64-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-arm64.tar.gz
+[linux-arm64-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-arm64.tar.gz.sha512
+
+[linux-arm64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/linux_arm64_Release_version_badge.svg?no-cache
+[linux-arm64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-linux-arm64.txt
+[linux-arm64-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-arm64.tar.gz
+[linux-arm64-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-arm64.tar.gz.sha512
+
+[linux-musl-x64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/linux_musl_x64_Release_version_badge.svg?no-cache
+[linux-musl-x64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-linux-musl-x64.txt
+[linux-musl-x64-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-musl-x64.tar.gz
+[linux-musl-x64-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-musl-x64.tar.gz.sha512
+
+[linux-musl-x64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/linux_musl_x64_Release_version_badge.svg?no-cache
+[linux-musl-x64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-linux-musl-x64.txt
+[linux-musl-x64-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-musl-x64.tar.gz
+[linux-musl-x64-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-musl-x64.tar.gz.sha512
+
+[linux-musl-arm-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/linux_musl_arm_Release_version_badge.svg?no-cache
+[linux-musl-arm-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-linux-musl-arm.txt
+[linux-musl-arm-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-musl-arm.tar.gz
+[linux-musl-arm-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-musl-arm.tar.gz.sha512
+
+[linux-musl-arm-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/linux_musl_arm_Release_version_badge.svg?no-cache
+[linux-musl-arm-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-linux-musl-arm.txt
+[linux-musl-arm-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-musl-arm.tar.gz
+[linux-musl-arm-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-musl-arm.tar.gz.sha512
+
+[linux-musl-arm64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/linux_musl_arm64_Release_version_badge.svg?no-cache
+[linux-musl-arm64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-linux-musl-arm64.txt
+[linux-musl-arm64-targz-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-musl-arm64.tar.gz
+[linux-musl-arm64-targz-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-linux-musl-arm64.tar.gz.sha512
+
+[linux-musl-arm64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/linux_musl_arm64_Release_version_badge.svg?no-cache
+[linux-musl-arm64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-linux-musl-arm64.txt
+[linux-musl-arm64-targz-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-musl-arm64.tar.gz
+[linux-musl-arm64-targz-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-linux-musl-arm64.tar.gz.sha512
+
+[win-arm64-badge-main]: https://aka.ms/dotnet/11.0.1xx/daily/win_arm64_Release_version_badge.svg?no-cache
+[win-arm64-version-main]: https://aka.ms/dotnet/11.0.1xx/daily/productCommit-win-arm64.txt
+[win-arm64-installer-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-arm64.exe
+[win-arm64-installer-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-arm64.exe.sha512
+[win-arm64-zip-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-arm64.zip
+[win-arm64-zip-checksum-main]: https://aka.ms/dotnet/11.0.1xx/daily/dotnet-sdk-win-arm64.zip.sha512
+
+[win-arm64-badge-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/win_arm64_Release_version_badge.svg?no-cache
+[win-arm64-version-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/productCommit-win-arm64.txt
+[win-arm64-installer-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-arm64.exe
+[win-arm64-installer-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-arm64.exe.sha512
+[win-arm64-zip-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-arm64.zip
+[win-arm64-zip-checksum-10.0.2XX]: https://aka.ms/dotnet/10.0.2XX/daily/dotnet-sdk-win-arm64.zip.sha512
diff --git a/eng/PublishSourceBuild.props b/eng/PublishSourceBuild.props
index a09901f786b7..380cfb96e7ed 100644
--- a/eng/PublishSourceBuild.props
+++ b/eng/PublishSourceBuild.props
@@ -1,4 +1,6 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -80,17 +90,33 @@
+
+ $(SharedComponentFilter_NonToolingOnly)
+ DiscoverArtifacts;GetOutputsForCreatePrivateSourceBuiltArtifactsArchive
+
+ $(CreatePrivateSourceBuiltArtifactsArchiveDependsOn);GetFilteredSharedComponentPackages
+
+
+
+ Outputs="$(SourceBuiltTarballName);$(SourceBuiltVersionName);$(AllPackageVersionsPropsName);$(SourceBuiltMergedAssetManifestName)">
+
+
+ true
+
+
+ true
+
+
+
-
@@ -117,7 +143,7 @@
UseSymbolicLinksIfPossible="true" />
-
+
+
+
+
+ Package
+
+
+
+
+
+
+
+ dotnet-sdk-
+
+
+
+
+
+
+
+
+
+
+
+
+ Blob
+ true
+
+
+
+ Blob
+ true
+
+
+
+ Blob
+ true
+
+
+
+ Blob
+ true
+
+
+ true
+ Blob
+ %(Filename)%(Extension)
+
+
+
+
+ <_SourceBuildArtifactsDir>$(ArtifactsAssetsDir)/source-build/
+ $(_SourceBuildArtifactsDir)/$(SdkFileNamePrefix)$(SourceBuiltSdkNonStableVersion)-$(TargetRid)$(ArchiveExtension)
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ Blob
+ $([System.IO.Path]::GetFileName($(SourceBuiltPublishAssetsDir)))/%(Filename)%(Extension)
+
+
+
+
+
diff --git a/eng/Publishing.props b/eng/Publishing.props
index 8375db8485ea..4115c507150d 100644
--- a/eng/Publishing.props
+++ b/eng/Publishing.props
@@ -9,6 +9,7 @@
$(ArtifactsDir)/staging/
$(ArtifactsStagingDir)/artifacts
$(ArtifactsPublishStagingDir)/assets/$(Configuration)
+ $(SourceBuiltAssetsDir)/source-build
$(ArtifactsPublishStagingDir)/packages/$(Configuration)/Shipping
$(ArtifactsPublishStagingDir)/packages/$(Configuration)/NonShipping
$(ArtifactsPublishStagingDir)/manifests/$(Configuration)
@@ -82,44 +83,6 @@
-
-
-
- Blob
- true
-
-
-
-
-
-
- Blob
- true
-
-
-
- Blob
- true
-
-
- true
- Blob
- %(Filename)%(Extension)
-
-
-
-
-
-
- true
- Blob
- source-build/%(Filename)%(Extension)
-
-
-
linux
+ linux-musl
osx
freebsd
netbsd
@@ -43,7 +44,6 @@
- $(__DistroRid)
$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)
win-$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant)
@@ -52,10 +52,10 @@
- false
+ false
true
- $(__PortableTargetOS)-$(TargetArchitecture)
+ $(PortableTargetOS)-$(TargetArchitecture)
freebsd-$(TargetArchitecture)
osx-$(TargetArchitecture)
linux-$(TargetArchitecture)
diff --git a/eng/SignCheckExclusionsFile.txt b/eng/SignCheckExclusionsFile.txt
index 5d4a5146c6cc..bb82a95e4c77 100644
--- a/eng/SignCheckExclusionsFile.txt
+++ b/eng/SignCheckExclusionsFile.txt
@@ -20,6 +20,12 @@ dotnet-*-internal-*-osx-*.pkg;*.pkg;; https://github.com/dotnet/source-build/iss
Valleysoft.DockerCredsProvider.dll;; IGNORE-STRONG-NAME, https://github.com/dotnet/source-build/issues/4985
ILVerify.dll;; IGNORE-STRONG-NAME, https://github.com/dotnet/source-build/issues/4985
ILCompiler.Build.Tasks.dll;; IGNORE-STRONG-NAME, https://github.com/dotnet/source-build/issues/4985
+Humanizer.dll;; IGNORE-STRONG-NAME
+Microsoft.ApplicationInsights.dll;; IGNORE-STRONG-NAME
+Microsoft.Build.Locator.dll;; IGNORE-STRONG-NAME
+Mono.Cecil.*dll;; IGNORE-STRONG-NAME
+Newtonsoft.Json.dll;; IGNORE-STRONG-NAME
+Spectre.Console.dll;; IGNORE-STRONG-NAME
*.mibc;; IGNORE-STRONG-NAME, .mibc files are not strong-named
;; ## MACH-O ##
diff --git a/eng/Version.Details.props b/eng/Version.Details.props
index 88d450b941a9..c939d51d3226 100644
--- a/eng/Version.Details.props
+++ b/eng/Version.Details.props
@@ -1,4 +1,3 @@
-
- 10.0.0-beta.25411.109
- 10.0.0-beta.25411.109
+ 11.0.0-beta.25618.104
+ 11.0.0-beta.25618.104
+ 1.1.0-beta.25619.4
@@ -17,5 +17,6 @@ This file should be imported by eng/Versions.props
$(MicrosoftDotNetArcadeSdkPackageVersion)
$(MicrosoftDotNetBuildManifestPackageVersion)
+ $(MicrosoftDotNetDarcLibPackageVersion)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 2e837d8485ce..2317e2139993 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -2,17 +2,21 @@
-
+
https://github.com/dotnet/dotnet
- 520c71b5277fc1f72dbec14da03ca55205d6c8e5
+ a8faa5ebe301d5a258c5622975df78254e5395db
-
+
https://github.com/dotnet/dotnet
- 520c71b5277fc1f72dbec14da03ca55205d6c8e5
+ a8faa5ebe301d5a258c5622975df78254e5395db
-
+
https://github.com/dotnet/arcade-services
- 396eba49bd539a8791adbe3ef60fcbaa02d60b13
+ db9ea03a5ea7330d52ca996e08d50ba2f3d09ad9
+
+
+ https://github.com/dotnet/arcade-services
+ db9ea03a5ea7330d52ca996e08d50ba2f3d09ad9
diff --git a/eng/Versions.props b/eng/Versions.props
index 859b9ab8a1b9..9ee88d12244a 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -1,12 +1,28 @@
-
-
+
+
+
- 0.1.0
- alpha.1
- true
1
+ 11
+ 0
+ $(MajorVersion).$(MinorVersion).$(VersionSDKMinor)00
+ alpha
+
+
+
+ repodefault
+
+
+ true
+
- 10.0.100-rc.1.25411.109
- 10.0.100-rc.1.25411.109
+ 11.0.100-alpha.1.25618.104
+ 11.0.100-alpha.1.25618.104
2.0.0-beta5.25208.1
- 17.12.36
+ 17.12.50
6.13.1
6.13.1
+
+ 4.4.0
- 9.0.0
- 9.0.0
- 9.0.0
+ 10.0.0
+ 10.0.0
+ 10.0.0
+ 10.0.0
+
+ 10.0.100
- 13.0.3
- 10.0.0
+ 13.0.4
+
diff --git a/eng/VmrLayout.props b/eng/VmrLayout.props
index 183f71c9de88..46e1bf3f758f 100644
--- a/eng/VmrLayout.props
+++ b/eng/VmrLayout.props
@@ -38,18 +38,19 @@
$(PreviouslySourceBuiltPackagesPath)PackageVersions.props
$([MSBuild]::NormalizeDirectory('$(PrereqsPackagesDir)', 'shared-components'))
$([MSBuild]::EnsureTrailingSlash('$(CustomSharedComponentsArtifactsPath)'))
+ $(SharedComponentsArtifactsPath)VerticalManifest.xml
+ $([MSBuild]::NormalizeDirectory('$(PrereqsPackagesDir)', 'extra-test-dependencies'))
$([MSBuild]::NormalizeDirectory('$(SrcDir)', 'source-build-reference-packages', 'src'))
$([MSBuild]::NormalizeDirectory('$(PrereqsPackagesDir)', 'reference'))
- SourceBuildReferencePackages
- $([MSBuild]::NormalizeDirectory('$(PreviouslySourceBuiltPackagesPath)', '$(PreviouslySourceBuiltReferencePackagesDirName)'))
+ $([MSBuild]::NormalizeDirectory('$(PrereqsPackagesDir)', 'archive'))
Private.SourceBuilt.Artifacts
Private.SourceBuilt.SharedComponents
Private.SourceBuilt.Prebuilts
+ dotnet-source
dotnet-symbols-all
dotnet-symbols-sdk
- $(ToolsDir)prebuilt-baseline.xml
$([MSBuild]::NormalizeDirectory('$(ArtifactsObjDir)', 'PackageVersions'))
@@ -65,8 +66,12 @@
- .prebuilt.xml
- $(ArtifactsLogDir)poison-catalog.xml
+ .prebuilt.xml
+ $(ArtifactsLogDir)poison-prebuilt-catalog.xml
+ .previously-source-built.xml
+ $(ArtifactsLogDir)poison-previously-source-built-catalog.xml
+ .shared-component.xml
+ $(ArtifactsLogDir)poison-shared-component-catalog.xml
$(ArtifactsLogDir)poisoned.txt
$(ArtifactsLogDir)poison-usage.xml
@@ -93,6 +98,13 @@
+
+
+
+
+ @(SharedComponentsPrereqsArchivePathItem)
+
+
@@ -103,7 +115,6 @@
-
diff --git a/eng/allowed-sb-binaries.txt b/eng/allowed-sb-binaries.txt
index c3612631e390..d3845b3e5bfe 100644
--- a/eng/allowed-sb-binaries.txt
+++ b/eng/allowed-sb-binaries.txt
@@ -9,6 +9,7 @@ artifacts/
.git/
.packages/
prereqs/packages/
+MicroBuild/ # This is introduced in real and test signed CI builds. Remove with https://github.com/dotnet/arcade/issues/15731
**/*.bmp
**/*.doc
diff --git a/eng/allowed-vmr-binaries.txt b/eng/allowed-vmr-binaries.txt
index cc918a471b70..0bacaa9e1ff6 100644
--- a/eng/allowed-vmr-binaries.txt
+++ b/eng/allowed-vmr-binaries.txt
@@ -5,8 +5,6 @@
# Import the allowed souce-build binaries (a stricter set).
import:allowed-sb-binaries.txt
-MicroBuild/
-
**/testCert*.pfx
**/TestCert*.pfx
@@ -105,7 +103,6 @@ src/runtime/src/mono/mono/eglib/test/*.txt
src/runtime/src/mono/mono/tests/exiting/*.out
src/runtime/src/mono/wasm/testassets/**/*.dat
src/runtime/src/mono/wasm/testassets/**/*.o
-src/runtime/src/native/external/LinuxTracepoints/TestOutput/EventHeaderInterceptorLE64.dat
src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/AOT_PROFILED/*.mibc
src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/AOT_PROFILED/*.nettrace
src/runtime/src/tests/FunctionalTests/Android/Device_Emulator/gRPC/grpc-dotnet/testassets/Certs/InteropTests/server1.pfx
diff --git a/eng/build.ps1 b/eng/build.ps1
index 3d4fcc1c056d..4d6eaa269c1d 100644
--- a/eng/build.ps1
+++ b/eng/build.ps1
@@ -7,8 +7,8 @@ Param(
[string][Alias('os')]$targetOS,
[string][Alias('arch')]$targetArch,
[string][Alias('v')]$verbosity = "minimal",
- [Parameter()][ValidateSet("preview", "rtm", "default")]
- [string]$branding = "default",
+ [Parameter()][ValidateSet("repodefault", "unstable", "preview", "release")]
+ [string]$branding,
[Parameter()][ValidatePattern("^\d{8}\.\d{1,3}$")]
[string][Alias('obid')]$officialBuildId,
@@ -39,7 +39,12 @@ function Get-Usage() {
Write-Host " -os, -targetOS Target operating system: e.g. windows."
Write-Host " -arch, -targetArch Target architecture: e.g. x64, x86, arm64, arm, riscv64"
Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)"
- Write-Host " -branding Specify versioning for shipping packages/assets. 'preview' will produce assets suffixed with '.final', 'rtm' will not contain a pre-release suffix. Default or unspecified will use VMR repo defaults."
+ Write-Host " -branding Specify the branding suffix for shipping packages/assets. By default uses VMR branding defaults (RepoDotNetFinalVersionKind property in eng/Versions.props)"
+ Write-Host " for release branch builds or otherwise repo branding defaults."
+ Write-Host " 'repodefault' uses the repo branding defaults."
+ Write-Host " 'unstable' produces assets with the repo specified branding suffix."
+ Write-Host " 'preview' produces assets with a '.final' branding suffix."
+ Write-Host " 'release' produces assets without a branding suffix."
Write-Host " -officialBuildId Official build ID to use for the build. This is used to set the OfficialBuildId MSBuild property."
Write-Host ""
@@ -91,13 +96,7 @@ if ($targetArch) { $arguments += "/p:TargetArchitecture=$targetArch" }
if ($sign) { $arguments += "/p:DotNetBuildSign=true" }
if ($buildRepoTests) { $arguments += "/p:DotNetBuildTests=true" }
if ($cleanWhileBuilding) { $arguments += "/p:CleanWhileBuilding=true" }
-if ($branding) {
- switch ($branding) {
- "preview" { $arguments += "/p:DotNetFinalVersionKind=prerelease" }
- "rtm" { $arguments += "/p:DotNetFinalVersionKind=release" }
- "default" { $arguments += "" }
- }
-}
+if ($branding) { $arguments += "/p:RepoDotNetFinalVersionKind=$branding" }
if ($officialBuildId) { $arguments += "/p:OfficialBuildId=$officialBuildId" }
function Build {
diff --git a/eng/clean-shared-components.proj b/eng/clean-shared-components.proj
new file mode 100644
index 000000000000..96cf4115f292
--- /dev/null
+++ b/eng/clean-shared-components.proj
@@ -0,0 +1,33 @@
+
+
+
+
+ $(NetCurrent)
+ true
+ $(SharedComponentFilter_BootstrapOnly)
+
+
+
+
+
+
+
+
+
+ <_BootstrapPackagesToDelete Include="@(SharedComponentFilteredPackages->'%(PackagePath)')" />
+
+
+
+
+
+
+
diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1
index 5db4ad71ee2f..fc8d618014e0 100644
--- a/eng/common/SetupNugetSources.ps1
+++ b/eng/common/SetupNugetSources.ps1
@@ -7,11 +7,11 @@
# See example call for this script below.
#
# - task: PowerShell@2
-# displayName: Setup Private Feeds Credentials
+# displayName: Setup internal Feeds Credentials
# condition: eq(variables['Agent.OS'], 'Windows_NT')
# inputs:
-# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
-# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
+# filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+# arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token
# env:
# Token: $(dn-bot-dnceng-artifact-feeds-rw)
#
@@ -34,19 +34,28 @@ Set-StrictMode -Version 2.0
. $PSScriptRoot\tools.ps1
+# Adds or enables the package source with the given name
+function AddOrEnablePackageSource($sources, $disabledPackageSources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) {
+ if ($disabledPackageSources -eq $null -or -not (EnableInternalPackageSource -DisabledPackageSources $disabledPackageSources -Creds $creds -PackageSourceName $SourceName)) {
+ AddPackageSource -Sources $sources -SourceName $SourceName -SourceEndPoint $SourceEndPoint -Creds $creds -Username $userName -pwd $Password
+ }
+}
+
# Add source entry to PackageSources
function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) {
$packageSource = $sources.SelectSingleNode("add[@key='$SourceName']")
if ($packageSource -eq $null)
{
+ Write-Host "Adding package source $SourceName"
+
$packageSource = $doc.CreateElement("add")
$packageSource.SetAttribute("key", $SourceName)
$packageSource.SetAttribute("value", $SourceEndPoint)
$sources.AppendChild($packageSource) | Out-Null
}
else {
- Write-Host "Package source $SourceName already present."
+ Write-Host "Package source $SourceName already present and enabled."
}
AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd
@@ -59,6 +68,8 @@ function AddCredential($creds, $source, $username, $pwd) {
return;
}
+ Write-Host "Inserting credential for feed: " $source
+
# Looks for credential configuration for the given SourceName. Create it if none is found.
$sourceElement = $creds.SelectSingleNode($Source)
if ($sourceElement -eq $null)
@@ -91,24 +102,27 @@ function AddCredential($creds, $source, $username, $pwd) {
$passwordElement.SetAttribute("value", $pwd)
}
-function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) {
- $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]")
-
- Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds."
-
- ForEach ($PackageSource in $maestroPrivateSources) {
- Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key
- AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd
+# Enable all darc-int package sources.
+function EnableMaestroInternalPackageSources($DisabledPackageSources, $Creds) {
+ $maestroInternalSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]")
+ ForEach ($DisabledPackageSource in $maestroInternalSources) {
+ EnableInternalPackageSource -DisabledPackageSources $DisabledPackageSources -Creds $Creds -PackageSourceName $DisabledPackageSource.key
}
}
-function EnablePrivatePackageSources($DisabledPackageSources) {
- $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]")
- ForEach ($DisabledPackageSource in $maestroPrivateSources) {
- Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource"
+# Enables an internal package source by name, if found. Returns true if the package source was found and enabled, false otherwise.
+function EnableInternalPackageSource($DisabledPackageSources, $Creds, $PackageSourceName) {
+ $DisabledPackageSource = $DisabledPackageSources.SelectSingleNode("add[@key='$PackageSourceName']")
+ if ($DisabledPackageSource) {
+ Write-Host "Enabling internal source '$($DisabledPackageSource.key)'."
+
# Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries
$DisabledPackageSources.RemoveChild($DisabledPackageSource)
+
+ AddCredential -Creds $creds -Source $DisabledPackageSource.Key -Username $userName -pwd $Password
+ return $true
}
+ return $false
}
if (!(Test-Path $ConfigFile -PathType Leaf)) {
@@ -121,15 +135,17 @@ $doc = New-Object System.Xml.XmlDocument
$filename = (Get-Item $ConfigFile).FullName
$doc.Load($filename)
-# Get reference to or create one if none exist already
+# Get reference to - fail if none exist
$sources = $doc.DocumentElement.SelectSingleNode("packageSources")
if ($sources -eq $null) {
- $sources = $doc.CreateElement("packageSources")
- $doc.DocumentElement.AppendChild($sources) | Out-Null
+ Write-PipelineTelemetryError -Category 'Build' -Message "Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. NuGet config file must contain a packageSources section: $ConfigFile"
+ ExitWithExitCode 1
}
$creds = $null
+$feedSuffix = "v3/index.json"
if ($Password) {
+ $feedSuffix = "v2"
# Looks for a node. Create it if none is found.
$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
if ($creds -eq $null) {
@@ -138,33 +154,22 @@ if ($Password) {
}
}
+$userName = "dn-bot"
+
# Check for disabledPackageSources; we'll enable any darc-int ones we find there
$disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources")
if ($disabledSources -ne $null) {
Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node"
- EnablePrivatePackageSources -DisabledPackageSources $disabledSources
-}
-
-$userName = "dn-bot"
-
-# Insert credential nodes for Maestro's private feeds
-InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password
-
-# 3.1 uses a different feed url format so it's handled differently here
-$dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']")
-if ($dotnet31Source -ne $null) {
- AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password
- 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
+ EnableMaestroInternalPackageSources -DisabledPackageSources $disabledSources -Creds $creds
}
-
-$dotnetVersions = @('5','6','7','8','9')
+$dotnetVersions = @('5','6','7','8','9','10')
foreach ($dotnetVersion in $dotnetVersions) {
$feedPrefix = "dotnet" + $dotnetVersion;
$dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']")
if ($dotnetSource -ne $null) {
- AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password
- AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password
+ AddOrEnablePackageSource -Sources $sources -DisabledPackageSources $disabledSources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/$feedSuffix" -Creds $creds -Username $userName -pwd $Password
+ AddOrEnablePackageSource -Sources $sources -DisabledPackageSources $disabledSources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/$feedSuffix" -Creds $creds -Username $userName -pwd $Password
}
}
diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh
index 4604b61b0323..b97cc536379d 100644
--- a/eng/common/SetupNugetSources.sh
+++ b/eng/common/SetupNugetSources.sh
@@ -11,8 +11,8 @@
# - task: Bash@3
# displayName: Setup Internal Feeds
# inputs:
-# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
-# arguments: $(Build.SourcesDirectory)/NuGet.config
+# filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.sh
+# arguments: $(System.DefaultWorkingDirectory)/NuGet.config
# condition: ne(variables['Agent.OS'], 'Windows_NT')
# - task: NuGetAuthenticate@1
#
@@ -52,78 +52,124 @@ if [[ `uname -s` == "Darwin" ]]; then
TB=''
fi
-# Ensure there is a ... section.
-grep -i "" $ConfigFile
-if [ "$?" != "0" ]; then
- echo "Adding ... section."
- ConfigNodeHeader=""
- PackageSourcesTemplate="${TB}${NL}${TB}"
+# Enables an internal package source by name, if found. Returns 0 if found and enabled, 1 if not found.
+EnableInternalPackageSource() {
+ local PackageSourceName="$1"
+
+ # Check if disabledPackageSources section exists
+ grep -i "" "$ConfigFile" > /dev/null
+ if [ "$?" != "0" ]; then
+ return 1 # No disabled sources section
+ fi
+
+ # Check if this source name is disabled
+ grep -i " /dev/null
+ if [ "$?" == "0" ]; then
+ echo "Enabling internal source '$PackageSourceName'."
+ # Remove the disabled entry (including any surrounding comments or whitespace on the same line)
+ sed -i.bak "//d" "$ConfigFile"
+
+ # Add the source name to PackageSources for credential handling
+ PackageSources+=("$PackageSourceName")
+ return 0 # Found and enabled
+ fi
+
+ return 1 # Not found in disabled sources
+}
+
+# Add source entry to PackageSources
+AddPackageSource() {
+ local SourceName="$1"
+ local SourceEndPoint="$2"
+
+ # Check if source already exists
+ grep -i " /dev/null
+ if [ "$?" == "0" ]; then
+ echo "Package source $SourceName already present and enabled."
+ PackageSources+=("$SourceName")
+ return
+ fi
+
+ echo "Adding package source $SourceName"
+ PackageSourcesNodeFooter=""
+ PackageSourceTemplate="${TB}"
+
+ sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" "$ConfigFile"
+ PackageSources+=("$SourceName")
+}
+
+# Adds or enables the package source with the given name
+AddOrEnablePackageSource() {
+ local SourceName="$1"
+ local SourceEndPoint="$2"
+
+ # Try to enable if disabled, if not found then add new source
+ EnableInternalPackageSource "$SourceName"
+ if [ "$?" != "0" ]; then
+ AddPackageSource "$SourceName" "$SourceEndPoint"
+ fi
+}
- sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" $ConfigFile
-fi
+# Enable all darc-int package sources
+EnableMaestroInternalPackageSources() {
+ # Check if disabledPackageSources section exists
+ grep -i "" "$ConfigFile" > /dev/null
+ if [ "$?" != "0" ]; then
+ return # No disabled sources section
+ fi
+
+ # Find all darc-int disabled sources
+ local DisabledDarcIntSources=()
+ DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' "$ConfigFile" | tr -d '"')
+
+ for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do
+ if [[ $DisabledSourceName == darc-int* ]]; then
+ EnableInternalPackageSource "$DisabledSourceName"
+ fi
+ done
+}
-# Ensure there is a ... section.
-grep -i "" $ConfigFile
+# Ensure there is a ... section.
+grep -i "" $ConfigFile
if [ "$?" != "0" ]; then
- echo "Adding ... section."
-
- PackageSourcesNodeFooter=""
- PackageSourceCredentialsTemplate="${TB}${NL}${TB}"
-
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile
+ Write-PipelineTelemetryError -Category 'Build' "Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. NuGet config file must contain a packageSources section: $ConfigFile"
+ ExitWithExitCode 1
fi
PackageSources=()
-# Ensure dotnet3.1-internal and dotnet3.1-internal-transport are in the packageSources if the public dotnet3.1 feeds are present
-grep -i "... section.
+ grep -i "" $ConfigFile
if [ "$?" != "0" ]; then
- echo "Adding dotnet3.1-internal to the packageSources."
- PackageSourcesNodeFooter=""
- PackageSourceTemplate="${TB}"
+ echo "Adding ... section."
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
- fi
- PackageSources+=('dotnet3.1-internal')
-
- grep -i "" $ConfigFile
- if [ "$?" != "0" ]; then
- echo "Adding dotnet3.1-internal-transport to the packageSources."
PackageSourcesNodeFooter=""
- PackageSourceTemplate="${TB}"
+ PackageSourceCredentialsTemplate="${TB}${NL}${TB}"
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
+ sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile
fi
- PackageSources+=('dotnet3.1-internal-transport')
fi
-DotNetVersions=('5' '6' '7' '8' '9')
+# Check for disabledPackageSources; we'll enable any darc-int ones we find there
+grep -i "" $ConfigFile > /dev/null
+if [ "$?" == "0" ]; then
+ echo "Checking for any darc-int disabled package sources in the disabledPackageSources node"
+ EnableMaestroInternalPackageSources
+fi
+
+DotNetVersions=('5' '6' '7' '8' '9' '10')
for DotNetVersion in ${DotNetVersions[@]} ; do
FeedPrefix="dotnet${DotNetVersion}";
- grep -i " /dev/null
if [ "$?" == "0" ]; then
- grep -i ""
-
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
- fi
- PackageSources+=("$FeedPrefix-internal")
-
- grep -i "" $ConfigFile
- if [ "$?" != "0" ]; then
- echo "Adding $FeedPrefix-internal-transport to the packageSources."
- PackageSourcesNodeFooter=""
- PackageSourceTemplate="${TB}"
-
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
- fi
- PackageSources+=("$FeedPrefix-internal-transport")
+ AddOrEnablePackageSource "$FeedPrefix-internal" "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$FeedPrefix-internal/nuget/$FeedSuffix"
+ AddOrEnablePackageSource "$FeedPrefix-internal-transport" "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$FeedPrefix-internal-transport/nuget/$FeedSuffix"
fi
done
@@ -139,29 +185,12 @@ if [ "$CredToken" ]; then
# Check if there is no existing credential for this FeedName
grep -i "<$FeedName>" $ConfigFile
if [ "$?" != "0" ]; then
- echo "Adding credentials for $FeedName."
+ echo " Inserting credential for feed: $FeedName"
PackageSourceCredentialsNodeFooter=""
- NewCredential="${TB}${TB}<$FeedName>${NL}${NL}${NL}$FeedName>"
+ NewCredential="${TB}${TB}<$FeedName>${NL}${TB}${NL}${TB}${TB}${NL}${TB}${TB}$FeedName>"
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
-if [ "$?" == "0" ]; then
- DisabledDarcIntSources=()
- echo "Re-enabling any disabled \"darc-int\" package sources in $ConfigFile"
- DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' $ConfigFile | tr -d '"')
- for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do
- if [[ $DisabledSourceName == darc-int* ]]
- then
- OldDisableValue=""
- NewDisableValue=""
- sed -i.bak "s|$OldDisableValue|$NewDisableValue|" $ConfigFile
- echo "Neutralized disablePackageSources entry for '$DisabledSourceName'"
- fi
- done
-fi
diff --git a/eng/common/build.sh b/eng/common/build.sh
index 9767bb411a4f..ec3e80d189ea 100755
--- a/eng/common/build.sh
+++ b/eng/common/build.sh
@@ -92,7 +92,7 @@ runtime_source_feed=''
runtime_source_feed_key=''
properties=()
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
-help|-h)
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
index d9013251542c..748c4f07a64d 100644
--- a/eng/common/core-templates/job/job.yml
+++ b/eng/common/core-templates/job/job.yml
@@ -19,6 +19,8 @@ parameters:
# publishing defaults
artifacts: ''
enableMicrobuild: false
+ enablePreviewMicrobuild: false
+ microbuildPluginVersion: 'latest'
enableMicrobuildForMacAndLinux: false
microbuildUseESRP: true
enablePublishBuildArtifacts: false
@@ -71,6 +73,8 @@ jobs:
templateContext: ${{ parameters.templateContext }}
variables:
+ - name: AllowPtrToDetectTestRunRetryFiles
+ value: true
- ${{ if ne(parameters.enableTelemetry, 'false') }}:
- name: DOTNET_CLI_TELEMETRY_PROFILE
value: '$(Build.Repository.Uri)'
@@ -128,6 +132,8 @@ jobs:
- template: /eng/common/core-templates/steps/install-microbuild.yml
parameters:
enableMicrobuild: ${{ parameters.enableMicrobuild }}
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildPluginVersion: ${{ parameters.microbuildPluginVersion }}
enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}
microbuildUseESRP: ${{ parameters.microbuildUseESRP }}
continueOnError: ${{ parameters.continueOnError }}
@@ -153,6 +159,8 @@ jobs:
- template: /eng/common/core-templates/steps/cleanup-microbuild.yml
parameters:
enableMicrobuild: ${{ parameters.enableMicrobuild }}
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildPluginVersion: ${{ parameters.microbuildPluginVersion }}
enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}
continueOnError: ${{ parameters.continueOnError }}
@@ -163,7 +171,7 @@ jobs:
inputs:
testResultsFormat: 'xUnit'
testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/TestResults/$(_BuildConfig)'
testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
mergeTestResults: ${{ parameters.mergeTestResults }}
continueOnError: true
@@ -174,7 +182,7 @@ jobs:
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '*.trx'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/TestResults/$(_BuildConfig)'
testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
mergeTestResults: ${{ parameters.mergeTestResults }}
continueOnError: true
@@ -218,7 +226,7 @@ jobs:
- task: CopyFiles@2
displayName: Gather buildconfiguration for build retry
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/eng/common/BuildConfiguration'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration'
continueOnError: true
diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml
index 8bf7d23355bc..c5788829a872 100644
--- a/eng/common/core-templates/job/onelocbuild.yml
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -8,7 +8,7 @@ parameters:
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)
+ SourcesDirectory: $(System.DefaultWorkingDirectory)
CreatePr: true
AutoCompletePr: false
ReusePr: true
@@ -68,7 +68,7 @@ jobs:
- ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:
- task: Powershell@2
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/generate-locproject.ps1
arguments: $(_GenerateLocProjectArguments)
displayName: Generate LocProject.json
condition: ${{ parameters.condition }}
@@ -103,7 +103,7 @@ jobs:
- task: CopyFiles@2
displayName: Copy LocProject.json
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/eng/Localize/'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/eng/Localize/'
Contents: 'LocProject.json'
TargetFolder: '$(Build.ArtifactStagingDirectory)/loc'
condition: ${{ parameters.condition }}
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
index d5303229c97e..8b5c635fe807 100644
--- a/eng/common/core-templates/job/publish-build-assets.yml
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -38,6 +38,10 @@ parameters:
# Optional: A minimatch pattern for the asset manifests to publish to BAR
assetManifestsPattern: '*/manifests/**/*.xml'
+ repositoryAlias: self
+
+ officialBuildId: ''
+
jobs:
- job: Asset_Registry_Publish
@@ -60,6 +64,11 @@ jobs:
value: false
# unconditional - needed for logs publishing (redactor tool version)
- template: /eng/common/core-templates/post-build/common-variables.yml
+ - name: OfficialBuildId
+ ${{ if ne(parameters.officialBuildId, '') }}:
+ value: ${{ parameters.officialBuildId }}
+ ${{ else }}:
+ value: $(Build.BuildNumber)
pool:
# We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
@@ -78,12 +87,12 @@ jobs:
- '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
+ - checkout: ${{ parameters.repositoryAlias }}
fetchDepth: 3
clean: true
- - ${{ if eq(parameters.isAssetlessBuild, 'false') }}:
- - ${{ if eq(parameters.publishingVersion, 3) }}:
+ - ${{ if eq(parameters.isAssetlessBuild, 'false') }}:
+ - ${{ if eq(parameters.publishingVersion, 3) }}:
- task: DownloadPipelineArtifact@2
displayName: Download Asset Manifests
inputs:
@@ -108,24 +117,35 @@ jobs:
flattenFolders: true
condition: ${{ parameters.condition }}
continueOnError: ${{ parameters.continueOnError }}
-
+
- task: NuGetAuthenticate@1
+ # Populate internal runtime variables.
+ - template: /eng/common/templates/steps/enable-internal-sources.yml
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ parameters:
+ legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - template: /eng/common/templates/steps/enable-internal-runtimes.yml
+
- task: AzureCLI@2
displayName: Publish Build Assets
inputs:
azureSubscription: "Darc: Maestro Production"
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/sdk-task.ps1
arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet
/p:ManifestsPath='$(Build.StagingDirectory)/AssetManifests'
/p:IsAssetlessBuild=${{ parameters.isAssetlessBuild }}
/p:MaestroApiEndpoint=https://maestro.dot.net
- /p:OfficialBuildId=$(Build.BuildNumber)
+ /p:OfficialBuildId=$(OfficialBuildId)
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
+
condition: ${{ parameters.condition }}
continueOnError: ${{ parameters.continueOnError }}
-
+
- task: powershell@2
displayName: Create ReleaseConfigs Artifact
inputs:
@@ -137,7 +157,7 @@ jobs:
Add-Content -Path $filePath -Value "$(DefaultChannels)"
Add-Content -Path $filePath -Value $(IsStableBuild)
- $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt"
+ $symbolExclusionfile = "$(System.DefaultWorkingDirectory)/eng/SymbolPublishingExclusionsFile.txt"
if (Test-Path -Path $symbolExclusionfile)
{
Write-Host "SymbolExclusionFile exists"
@@ -153,7 +173,7 @@ jobs:
artifactName: AssetManifests
displayName: 'Publish Merged Manifest'
retryCountOnTaskFailure: 10 # for any logs being locked
- sbomEnabled: false # we don't need SBOM for logs
+ sbomEnabled: false # we don't need SBOM for logs
- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
parameters:
@@ -170,6 +190,11 @@ jobs:
BARBuildId: ${{ parameters.BARBuildId }}
PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ # Darc is targeting 8.0, so make sure it's installed
+ - task: UseDotNet@2
+ inputs:
+ version: 8.0.x
- task: AzureCLI@2
displayName: Publish Using Darc
@@ -177,7 +202,7 @@ jobs:
azureSubscription: "Darc: Maestro Production"
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1
arguments: >
-BuildId $(BARBuildId)
-PublishingInfraVersion 3
@@ -186,9 +211,11 @@ jobs:
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
-SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
-SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
- ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- template: /eng/common/core-templates/steps/publish-logs.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
- JobLabel: 'Publish_Artifacts_Logs'
+ JobLabel: 'Publish_Artifacts_Logs'
diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml
index d805d5faeb94..9d820f974211 100644
--- a/eng/common/core-templates/job/source-build.yml
+++ b/eng/common/core-templates/job/source-build.yml
@@ -60,10 +60,10 @@ jobs:
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
+ demands: ImageOverride -equals build.ubuntu.2204.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
+ image: 1es-azurelinux-3
os: linux
${{ else }}:
pool:
diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml
index 30530359a5d6..76baf5c27258 100644
--- a/eng/common/core-templates/job/source-index-stage1.yml
+++ b/eng/common/core-templates/job/source-index-stage1.yml
@@ -3,7 +3,7 @@ parameters:
sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
preSteps: []
binlogPath: artifacts/log/Debug/Build.binlog
- condition: ''
+ condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
dependsOn: ''
pool: ''
is1ESPipeline: ''
@@ -25,10 +25,10 @@ jobs:
pool:
${{ if eq(variables['System.TeamProject'], 'public') }}:
name: $(DncEngPublicBuildPool)
- image: windows.vs2022.amd64.open
+ image: windows.vs2026preview.scout.amd64.open
${{ if eq(variables['System.TeamProject'], 'internal') }}:
name: $(DncEngInternalBuildPool)
- image: windows.vs2022.amd64
+ image: windows.vs2026preview.scout.amd64
steps:
- ${{ if eq(parameters.is1ESPipeline, '') }}:
@@ -41,4 +41,4 @@ jobs:
- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
parameters:
- binLogPath: ${{ parameters.binLogPath }}
\ No newline at end of file
+ binLogPath: ${{ parameters.binLogPath }}
diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml
index 693b00b37044..dbc14ac580a2 100644
--- a/eng/common/core-templates/jobs/codeql-build.yml
+++ b/eng/common/core-templates/jobs/codeql-build.yml
@@ -24,7 +24,7 @@ jobs:
- name: DefaultGuardianVersion
value: 0.109.0
- name: GuardianPackagesConfigFile
- value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
+ value: $(System.DefaultWorkingDirectory)\eng\common\sdl\packages.config
- name: GuardianVersion
value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml
index 2f992b2c6ecc..01ada7476651 100644
--- a/eng/common/core-templates/jobs/jobs.yml
+++ b/eng/common/core-templates/jobs/jobs.yml
@@ -43,6 +43,8 @@ parameters:
artifacts: {}
is1ESPipeline: ''
+ repositoryAlias: self
+ officialBuildId: ''
# 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.
@@ -114,3 +116,5 @@ jobs:
enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
+ repositoryAlias: ${{ parameters.repositoryAlias }}
+ officialBuildId: ${{ parameters.officialBuildId }}
diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml
index a151fd811e3e..06864cd1feb8 100644
--- a/eng/common/core-templates/post-build/post-build.yml
+++ b/eng/common/core-templates/post-build/post-build.yml
@@ -1,106 +1,106 @@
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: requireDefaultChannels
- displayName: Fail the build if there are no default channel(s) registrations for the current build
- type: boolean
- default: false
-
- - name: SDLValidationParameters
- type: object
- default:
- enable: false
- publishGdn: false
- continueOnError: false
- params: ''
- artifactNames: ''
- downloadArtifacts: true
-
- - name: isAssetlessBuild
- type: boolean
- displayName: Is Assetless Build
- default: false
-
- # 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
+# 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: requireDefaultChannels
+ displayName: Fail the build if there are no default channel(s) registrations for the current build
+ type: boolean
+ default: false
+
+- name: SDLValidationParameters
+ type: object
+ default:
+ enable: false
+ publishGdn: false
+ continueOnError: false
+ params: ''
+ artifactNames: ''
+ downloadArtifacts: true
+
+- name: isAssetlessBuild
+ type: boolean
+ displayName: Is Assetless Build
+ default: false
+
+# 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')) }}:
@@ -108,10 +108,10 @@ stages:
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 }}
+ - 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
@@ -127,35 +127,35 @@ stages:
${{ else }}:
${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
- image: windows.vs2022.amd64
+ image: windows.vs2026preview.scout.amd64
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026preview.scout.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/
+ - 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: $(System.DefaultWorkingDirectory)/eng/common/post-build/nuget-validation.ps1
+ arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
- job:
displayName: Signing Validation
@@ -169,54 +169,54 @@ stages:
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
image: 1es-windows-2022
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026preview.scout.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
-
- # 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)
+ - 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
+
+ # 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='$(System.DefaultWorkingDirectory)/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
@@ -230,41 +230,41 @@ stages:
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
image: 1es-windows-2022
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026preview.scout.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
+ - 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: $(System.DefaultWorkingDirectory)/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
@@ -274,10 +274,10 @@ stages:
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 }}
+ - 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
@@ -291,30 +291,41 @@ stages:
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ ${{ 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
+ 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: >
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: NuGetAuthenticate@1
+
+ # Populate internal runtime variables.
+ - template: /eng/common/templates/steps/enable-internal-sources.yml
+ parameters:
+ legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - template: /eng/common/templates/steps/enable-internal-runtimes.yml
+
+ - task: UseDotNet@2
+ inputs:
+ version: 8.0.x
+
+ - task: AzureCLI@2
+ displayName: Publish Using Darc
+ inputs:
+ azureSubscription: "Darc: Maestro Production"
+ scriptType: ps
+ scriptLocation: scriptPath
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: >
-BuildId $(BARBuildId)
-PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
-AzdoToken '$(System.AccessToken)'
@@ -323,3 +334,5 @@ stages:
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
-SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
-SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml
index f7602980dbe7..a7abd58c4bb6 100644
--- a/eng/common/core-templates/post-build/setup-maestro-vars.yml
+++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -36,7 +36,7 @@ steps:
$AzureDevOpsBuildId = $Env:Build_BuildId
}
else {
- . $(Build.SourcesDirectory)\eng\common\tools.ps1
+ . $(System.DefaultWorkingDirectory)\eng\common\tools.ps1
$darc = Get-Darc
$buildInfo = & $darc get-build `
--id ${{ parameters.BARBuildId }} `
diff --git a/eng/common/core-templates/steps/enable-internal-sources.yml b/eng/common/core-templates/steps/enable-internal-sources.yml
index 64f881bffc3c..4085512b6909 100644
--- a/eng/common/core-templates/steps/enable-internal-sources.yml
+++ b/eng/common/core-templates/steps/enable-internal-sources.yml
@@ -17,8 +17,8 @@ steps:
- task: PowerShell@2
displayName: Setup Internal Feeds
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
- arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token
env:
Token: ${{ parameters.legacyCredential }}
# If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate.
@@ -29,8 +29,8 @@ steps:
- task: PowerShell@2
displayName: Setup Internal Feeds
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
- arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config
- ${{ else }}:
- template: /eng/common/templates/steps/get-federated-access-token.yml
parameters:
@@ -39,8 +39,8 @@ steps:
- 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)
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(System.DefaultWorkingDirectory)/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).
diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml
index 44a9636cdff9..003f7eae0fa5 100644
--- a/eng/common/core-templates/steps/generate-sbom.yml
+++ b/eng/common/core-templates/steps/generate-sbom.yml
@@ -5,8 +5,8 @@
# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
parameters:
- PackageVersion: 10.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ PackageVersion: 11.0.0
+ BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
PackageName: '.NET'
ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
IgnoreDirectories: ''
diff --git a/eng/common/core-templates/steps/install-microbuild-impl.yml b/eng/common/core-templates/steps/install-microbuild-impl.yml
new file mode 100644
index 000000000000..b9e0143ee92a
--- /dev/null
+++ b/eng/common/core-templates/steps/install-microbuild-impl.yml
@@ -0,0 +1,34 @@
+parameters:
+ - name: microbuildTaskInputs
+ type: object
+ default: {}
+
+ - name: microbuildEnv
+ type: object
+ default: {}
+
+ - name: enablePreviewMicrobuild
+ type: boolean
+ default: false
+
+ - name: condition
+ type: string
+
+ - name: continueOnError
+ type: boolean
+
+steps:
+- ${{ if eq(parameters.enablePreviewMicrobuild, 'true') }}:
+ - task: MicroBuildSigningPluginPreview@4
+ displayName: Install Preview MicroBuild plugin
+ inputs: ${{ parameters.microbuildTaskInputs }}
+ env: ${{ parameters.microbuildEnv }}
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: ${{ parameters.condition }}
+- ${{ else }}:
+ - task: MicroBuildSigningPlugin@4
+ displayName: Install MicroBuild plugin
+ inputs: ${{ parameters.microbuildTaskInputs }}
+ env: ${{ parameters.microbuildEnv }}
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: ${{ parameters.condition }}
diff --git a/eng/common/core-templates/steps/install-microbuild.yml b/eng/common/core-templates/steps/install-microbuild.yml
index d6b9878f54db..4f4b56ed2a6b 100644
--- a/eng/common/core-templates/steps/install-microbuild.yml
+++ b/eng/common/core-templates/steps/install-microbuild.yml
@@ -4,6 +4,8 @@ parameters:
# Enable install tasks for MicroBuild on Mac and Linux
# Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'
enableMicrobuildForMacAndLinux: false
+ # Enable preview version of MB signing plugin
+ enablePreviewMicrobuild: false
# Determines whether the ESRP service connection information should be passed to the signing plugin.
# This overlaps with _SignType to some degree. We only need the service connection for real signing.
# It's important that the service connection not be passed to the MicroBuildSigningPlugin task in this place.
@@ -11,9 +13,10 @@ parameters:
# Unfortunately, _SignType can't be used to exclude the use of the service connection in non-real sign scenarios. The
# variable is not available in template expression. _SignType has a very large proliferation across .NET, so replacing it is tough.
microbuildUseESRP: true
- # Location of the MicroBuild output folder
- # NOTE: There's something that relies on this being in the "default" source directory for tasks such as Signing to work properly.
- microBuildOutputFolder: '$(Build.SourcesDirectory)'
+ # Microbuild installation directory
+ microBuildOutputFolder: $(Agent.TempDirectory)/MicroBuild
+ # Microbuild version
+ microbuildPluginVersion: 'latest'
continueOnError: false
@@ -26,8 +29,27 @@ steps:
inputs:
packageType: sdk
version: 8.0.x
- installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet
- workingDirectory: ${{ parameters.microBuildOutputFolder }}
+ installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet-microbuild
+ condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
+
+ - script: |
+ set -euo pipefail
+
+ # UseDotNet@2 prepends the dotnet executable path to the PATH variable, so we can call dotnet directly
+ version=$(dotnet --version)
+ cat << 'EOF' > ${{ parameters.microBuildOutputFolder }}/global.json
+ {
+ "sdk": {
+ "version": "$version",
+ "paths": [
+ "${{ parameters.microBuildOutputFolder }}/.dotnet-microbuild"
+ ],
+ "errorMessage": "The .NET SDK version $version is required to install the MicroBuild signing plugin."
+ }
+ }
+ EOF
+ displayName: 'Add global.json to MicroBuild Installation path'
+ workingDirectory: ${{ parameters.microBuildOutputFolder }}
condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
- script: |
@@ -51,41 +73,46 @@ steps:
# YAML expansion, and Windows vs. Linux/Mac uses different service connections. However,
# we can avoid including the MB install step if not enabled at all. This avoids a bunch of
# extra pipeline authorizations, since most pipelines do not sign on non-Windows.
- - task: MicroBuildSigningPlugin@4
- displayName: Install MicroBuild plugin (Windows)
- inputs:
- signType: $(_SignType)
- zipSources: false
- feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
- ${{ if eq(parameters.microbuildUseESRP, true) }}:
- ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)'
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea
- ${{ else }}:
- ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca
- env:
- TeamName: $(_TeamName)
- MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- continueOnError: ${{ parameters.continueOnError }}
- condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test'))
-
- - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, true) }}:
- - task: MicroBuildSigningPlugin@4
- displayName: Install MicroBuild plugin (non-Windows)
- inputs:
+ - template: /eng/common/core-templates/steps/install-microbuild-impl.yml@self
+ parameters:
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildTaskInputs:
signType: $(_SignType)
zipSources: false
feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ version: ${{ parameters.microbuildPluginVersion }}
${{ if eq(parameters.microbuildUseESRP, true) }}:
ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)'
${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39
+ ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea
${{ else }}:
- ConnectedPMEServiceName: c24de2a5-cc7a-493d-95e4-8e5ff5cad2bc
- env:
+ ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca
+ microbuildEnv:
TeamName: $(_TeamName)
MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
continueOnError: ${{ parameters.continueOnError }}
- condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'), eq(variables['_SignType'], 'real'))
+ condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test'))
+
+ - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, true) }}:
+ - template: /eng/common/core-templates/steps/install-microbuild-impl.yml@self
+ parameters:
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildTaskInputs:
+ signType: $(_SignType)
+ zipSources: false
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ version: ${{ parameters.microbuildPluginVersion }}
+ workingDirectory: ${{ parameters.microBuildOutputFolder }}
+ ${{ if eq(parameters.microbuildUseESRP, true) }}:
+ ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)'
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39
+ ${{ else }}:
+ ConnectedPMEServiceName: c24de2a5-cc7a-493d-95e4-8e5ff5cad2bc
+ microbuildEnv:
+ TeamName: $(_TeamName)
+ MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'), eq(variables['_SignType'], 'real'))
diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml
index de24d0087c58..5a927b4c7bcb 100644
--- a/eng/common/core-templates/steps/publish-logs.yml
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -12,22 +12,24 @@ steps:
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}}/
+ New-Item -ItemType Directory $(System.DefaultWorkingDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
+ Move-Item -Path $(System.DefaultWorkingDirectory)/artifacts/log/Debug/* $(System.DefaultWorkingDirectory)/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
+ filePath: $(System.DefaultWorkingDirectory)/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'
+ # Sensitive data can as well be added to $(System.DefaultWorkingDirectory)/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'
+ arguments: -InputPath '$(System.DefaultWorkingDirectory)/PostBuildLogs'
+ -BinlogToolVersion '${{parameters.BinlogToolVersion}}'
+ -TokensFilePath '$(System.DefaultWorkingDirectory)/eng/BinlogSecretsRedactionFile.txt'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
'$(publishing-dnceng-devdiv-code-r-build-re)'
'$(MaestroAccessToken)'
'$(dn-bot-all-orgs-artifact-feeds-rw)'
@@ -44,7 +46,7 @@ steps:
- task: CopyFiles@2
displayName: Gather post build logs
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/PostBuildLogs'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
condition: always()
diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml
index c2917c1efc1c..ac019e2d0337 100644
--- a/eng/common/core-templates/steps/source-index-stage1-publish.yml
+++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml
@@ -1,6 +1,6 @@
parameters:
- sourceIndexUploadPackageVersion: 2.0.0-20250425.2
- sourceIndexProcessBinlogPackageVersion: 1.0.1-20250515.1
+ sourceIndexUploadPackageVersion: 2.0.0-20250906.1
+ sourceIndexProcessBinlogPackageVersion: 1.0.1-20250906.1
sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
binlogPath: artifacts/log/Debug/Build.binlog
@@ -14,13 +14,13 @@ steps:
workingDirectory: $(Agent.TempDirectory)
- script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
displayName: "Source Index: Download netsourceindex 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: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
+- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(System.DefaultWorkingDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
displayName: "Source Index: Process Binlog into indexable sln"
- ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index 8abfb71f7275..9b7eede4e50f 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -72,7 +72,7 @@ __AlpinePackages+=" krb5-dev"
__AlpinePackages+=" openssl-dev"
__AlpinePackages+=" zlib-dev"
-__FreeBSDBase="13.4-RELEASE"
+__FreeBSDBase="13.5-RELEASE"
__FreeBSDPkg="1.21.3"
__FreeBSDABI="13"
__FreeBSDPackages="libunwind"
@@ -383,7 +383,7 @@ while :; do
;;
freebsd14)
__CodeName=freebsd
- __FreeBSDBase="14.2-RELEASE"
+ __FreeBSDBase="14.3-RELEASE"
__FreeBSDABI="14"
__SkipUnmount=1
;;
diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh
index e889f439b8dc..9f5ad6b763b5 100755
--- a/eng/common/darc-init.sh
+++ b/eng/common/darc-init.sh
@@ -5,7 +5,7 @@ darcVersion=''
versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20'
verbosity='minimal'
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
--darcversion)
diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh
index 7b9d97e3bd4d..61f302bb6775 100755
--- a/eng/common/dotnet-install.sh
+++ b/eng/common/dotnet-install.sh
@@ -18,7 +18,7 @@ architecture=''
runtime='dotnet'
runtimeSourceFeed=''
runtimeSourceFeedKey=''
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
-version|-v)
diff --git a/eng/common/dotnet.sh b/eng/common/dotnet.sh
index 2ef68235675f..f6d24871c1d4 100644
--- a/eng/common/dotnet.sh
+++ b/eng/common/dotnet.sh
@@ -19,7 +19,7 @@ source $scriptroot/tools.sh
InitializeDotNetCli true # install
# Invoke acquired SDK with args if they are provided
-if [[ $# > 0 ]]; then
+if [[ $# -gt 0 ]]; then
__dotnetDir=${_InitializeDotNetCli}
dotnetPath=${__dotnetDir}/dotnet
${dotnetPath} "$@"
diff --git a/eng/common/generate-locproject.ps1 b/eng/common/generate-locproject.ps1
index 524aaa57f2b7..fa1cdc2b3007 100644
--- a/eng/common/generate-locproject.ps1
+++ b/eng/common/generate-locproject.ps1
@@ -33,15 +33,27 @@ $jsonTemplateFiles | ForEach-Object {
$jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\\strings\.json" } # current winforms pattern
+$wxlFilesV3 = @()
+$wxlFilesV5 = @()
$wxlFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\.+\.wxl" -And -Not( $_.Directory.Name -Match "\d{4}" ) } # localized files live in four digit lang ID directories; this excludes them
if (-not $wxlFiles) {
$wxlEnFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\1033\\.+\.wxl" } # pick up en files (1033 = en) specifically so we can copy them to use as the neutral xlf files
if ($wxlEnFiles) {
- $wxlFiles = @()
- $wxlEnFiles | ForEach-Object {
- $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)"
- $wxlFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru
- }
+ $wxlFiles = @()
+ $wxlEnFiles | ForEach-Object {
+ $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)"
+ $content = Get-Content $_.FullName -Raw
+
+ # Split files on schema to select different parser settings in the generated project.
+ if ($content -like "*http://wixtoolset.org/schemas/v4/wxl*")
+ {
+ $wxlFilesV5 += Copy-Item $_.FullName -Destination $destinationFile -PassThru
+ }
+ elseif ($content -like "*http://schemas.microsoft.com/wix/2006/localization*")
+ {
+ $wxlFilesV3 += Copy-Item $_.FullName -Destination $destinationFile -PassThru
+ }
+ }
}
}
@@ -114,7 +126,32 @@ $locJson = @{
CloneLanguageSet = "WiX_CloneLanguages"
LssFiles = @( "wxl_loc.lss" )
LocItems = @(
- $wxlFiles | ForEach-Object {
+ $wxlFilesV3 | ForEach-Object {
+ $outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\"
+ $continue = $true
+ foreach ($exclusion in $exclusions.Exclusions) {
+ if ($_.FullName.Contains($exclusion)) {
+ $continue = $false
+ }
+ }
+ $sourceFile = ($_.FullName | Resolve-Path -Relative)
+ if ($continue)
+ {
+ return @{
+ SourceFile = $sourceFile
+ CopyOption = "LangIDOnPath"
+ OutputPath = $outputPath
+ }
+ }
+ }
+ )
+ },
+ @{
+ LanguageSet = $LanguageSet
+ CloneLanguageSet = "WiX_CloneLanguages"
+ LssFiles = @( "P210WxlSchemaV4.lss" )
+ LocItems = @(
+ $wxlFilesV5 | ForEach-Object {
$outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\"
$continue = $true
foreach ($exclusion in $exclusions.Exclusions) {
diff --git a/eng/common/internal-feed-operations.ps1 b/eng/common/internal-feed-operations.ps1
index 92b77347d990..c282d3ae403a 100644
--- a/eng/common/internal-feed-operations.ps1
+++ b/eng/common/internal-feed-operations.ps1
@@ -26,7 +26,7 @@ function SetupCredProvider {
$url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1'
Write-Host "Writing the contents of 'installcredprovider.ps1' locally..."
- Invoke-WebRequest $url -OutFile installcredprovider.ps1
+ Invoke-WebRequest $url -UseBasicParsing -OutFile installcredprovider.ps1
Write-Host 'Installing plugin...'
.\installcredprovider.ps1 -Force
diff --git a/eng/common/internal-feed-operations.sh b/eng/common/internal-feed-operations.sh
index 9378223ba095..6299e7effd4c 100755
--- a/eng/common/internal-feed-operations.sh
+++ b/eng/common/internal-feed-operations.sh
@@ -100,7 +100,7 @@ operation=''
authToken=''
repoName=''
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
--operation)
diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh
index 477a44f335be..64b87d0bcc3c 100755
--- a/eng/common/native/install-dependencies.sh
+++ b/eng/common/native/install-dependencies.sh
@@ -27,9 +27,11 @@ case "$os" in
libssl-dev libkrb5-dev pigz cpio
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
- elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then
+ elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos"]; then
pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)"
$pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
+ elif [ "$ID" = "amzn" ]; then
+ dnf install -y cmake llvm lld lldb clang python libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
elif [ "$ID" = "alpine" ]; then
apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio
else
diff --git a/eng/common/post-build/nuget-verification.ps1 b/eng/common/post-build/nuget-verification.ps1
index a365194a9389..eea88e653c91 100644
--- a/eng/common/post-build/nuget-verification.ps1
+++ b/eng/common/post-build/nuget-verification.ps1
@@ -30,7 +30,7 @@
[CmdletBinding(PositionalBinding = $false)]
param(
[string]$NuGetExePath,
- [string]$PackageSource = "https://api.nuget.org/v3/index.json",
+ [string]$PackageSource = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json",
[string]$DownloadPath,
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$args
@@ -65,7 +65,7 @@ if ($NuGetExePath) {
Write-Host "Downloading nuget.exe from $nugetExeUrl..."
$ProgressPreference = 'SilentlyContinue'
try {
- Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe
+ Invoke-WebRequest $nugetExeUrl -UseBasicParsing -OutFile $downloadedNuGetExe
$ProgressPreference = 'Continue'
} catch {
$ProgressPreference = 'Continue'
diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1
index 1eda208a3bbf..48e55598bdd2 100644
--- a/eng/common/post-build/publish-using-darc.ps1
+++ b/eng/common/post-build/publish-using-darc.ps1
@@ -7,7 +7,9 @@ param(
[Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters,
[Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters,
[Parameter(Mandatory=$false)][string] $RequireDefaultChannels,
- [Parameter(Mandatory=$false)][string] $SkipAssetsPublishing
+ [Parameter(Mandatory=$false)][string] $SkipAssetsPublishing,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeed,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey
)
try {
diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1
index b7fc19591507..fc0218a013d1 100644
--- a/eng/common/post-build/redact-logs.ps1
+++ b/eng/common/post-build/redact-logs.ps1
@@ -7,7 +7,9 @@ param(
# 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
+ [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeed,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey
)
try {
diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1
index a9d2a2d26996..b64b66a6275b 100644
--- a/eng/common/sdk-task.ps1
+++ b/eng/common/sdk-task.ps1
@@ -7,13 +7,16 @@ Param(
[switch] $restore,
[switch] $prepareMachine,
[switch][Alias('nobl')]$excludeCIBinaryLog,
+ [switch]$noWarnAsError,
[switch] $help,
+ [string] $runtimeSourceFeed = '',
+ [string] $runtimeSourceFeedKey = '',
[Parameter(ValueFromRemainingArguments=$true)][String[]]$properties
)
$ci = $true
$binaryLog = if ($excludeCIBinaryLog) { $false } else { $true }
-$warnAsError = $true
+$warnAsError = if ($noWarnAsError) { $false } else { $true }
. $PSScriptRoot\tools.ps1
@@ -67,7 +70,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.13.0" -MemberType NoteProperty
+ $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "18.0.0" -MemberType NoteProperty
}
if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") {
$xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true
diff --git a/eng/common/sdk-task.sh b/eng/common/sdk-task.sh
index 2f83adc0269f..3270f83fa9a7 100755
--- a/eng/common/sdk-task.sh
+++ b/eng/common/sdk-task.sh
@@ -10,6 +10,7 @@ show_usage() {
echo "Advanced settings:"
echo " --excludeCIBinarylog Don't output binary log (short: -nobl)"
+ echo " --noWarnAsError Do not warn as error"
echo ""
echo "Command line arguments not listed above are passed thru to msbuild."
}
@@ -52,6 +53,7 @@ exclude_ci_binary_log=false
restore=false
help=false
properties=''
+warnAsError=true
while (($# > 0)); do
lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
@@ -73,6 +75,10 @@ while (($# > 0)); do
exclude_ci_binary_log=true
shift 1
;;
+ --noWarnAsError)
+ warnAsError=false
+ shift 1
+ ;;
--help)
help=true
shift 1
@@ -85,7 +91,6 @@ while (($# > 0)); do
done
ci=true
-warnAsError=true
if $help; then
show_usage
diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md
index 98bbc1ded0ba..4bf4cf41bd7c 100644
--- a/eng/common/template-guidance.md
+++ b/eng/common/template-guidance.md
@@ -50,7 +50,7 @@ extends:
- task: CopyFiles@2
displayName: Gather build output
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/artifacts/marvel'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel'
```
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index a8a943287458..92a0664f5647 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -3,7 +3,7 @@ parameters:
enableSbom: true
runAsPublic: false
PackageVersion: 9.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
jobs:
- template: /eng/common/core-templates/job/job.yml
diff --git a/eng/common/templates-official/variables/sdl-variables.yml b/eng/common/templates-official/variables/sdl-variables.yml
index dbdd66d4a4b3..f1311bbb1b33 100644
--- a/eng/common/templates-official/variables/sdl-variables.yml
+++ b/eng/common/templates-official/variables/sdl-variables.yml
@@ -4,4 +4,4 @@ variables:
- name: DefaultGuardianVersion
value: 0.109.0
- name: GuardianPackagesConfigFile
- value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
\ No newline at end of file
+ value: $(System.DefaultWorkingDirectory)\eng\common\sdl\packages.config
\ No newline at end of file
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 7cbf668c22bc..238fa0818f7b 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -6,7 +6,7 @@ parameters:
enableSbom: true
runAsPublic: false
PackageVersion: 9.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
jobs:
- template: /eng/common/core-templates/job/job.yml
@@ -77,7 +77,7 @@ jobs:
parameters:
is1ESPipeline: false
args:
- targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration'
+ targetPath: '$(System.DefaultWorkingDirectory)\eng\common\BuildConfiguration'
artifactName: 'BuildConfiguration'
displayName: 'Publish build retry configuration'
continueOnError: true
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index d4cfd9ccd806..f6bde2683794 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -157,9 +157,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
return $global:_DotNetInstallDir
}
- # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism
- $env:DOTNET_MULTILEVEL_LOOKUP=0
-
# Disable first run since we do not need all ASP.NET packages restored.
$env:DOTNET_NOLOGO=1
@@ -225,7 +222,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
# Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build
Write-PipelinePrependPath -Path $dotnetRoot
- Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0'
Write-PipelineSetVariable -Name 'DOTNET_NOLOGO' -Value '1'
return $global:_DotNetInstallDir = $dotnetRoot
@@ -277,7 +273,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) {
Retry({
Write-Host "GET $uri"
- Invoke-WebRequest $uri -OutFile $installScript
+ Invoke-WebRequest $uri -UseBasicParsing -OutFile $installScript
})
}
@@ -394,8 +390,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
# If the version of msbuild is going to be xcopied,
# use this version. Version matches a package here:
- # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.13.0
- $defaultXCopyMSBuildVersion = '17.13.0'
+ # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/18.0.0
+ $defaultXCopyMSBuildVersion = '18.0.0'
if (!$vsRequirements) {
if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {
@@ -510,7 +506,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) {
Write-Host "Downloading $packageName $packageVersion"
$ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
Retry({
- Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath
+ Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -UseBasicParsing -OutFile $packagePath
})
if (!(Test-Path $packagePath)) {
@@ -544,7 +540,8 @@ function LocateVisualStudio([object]$vsRequirements = $null){
if (Get-Member -InputObject $GlobalJson.tools -Name 'vswhere') {
$vswhereVersion = $GlobalJson.tools.vswhere
} else {
- $vswhereVersion = '2.5.2'
+ # keep this in sync with the VSWhereVersion in DefaultVersions.props
+ $vswhereVersion = '3.1.7'
}
$vsWhereDir = Join-Path $ToolsDir "vswhere\$vswhereVersion"
@@ -552,25 +549,33 @@ function LocateVisualStudio([object]$vsRequirements = $null){
if (!(Test-Path $vsWhereExe)) {
Create-Directory $vsWhereDir
- Write-Host 'Downloading vswhere'
+ Write-Host "Downloading vswhere $vswhereVersion"
+ $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
Retry({
- Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe
+ Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -UseBasicParsing -OutFile $vswhereExe
})
}
- if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs }
+ if (!$vsRequirements) {
+ if (Get-Member -InputObject $GlobalJson.tools -Name 'vs' -ErrorAction SilentlyContinue) {
+ $vsRequirements = $GlobalJson.tools.vs
+ } else {
+ $vsRequirements = $null
+ }
+ }
+
$args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*')
if (!$excludePrereleaseVS) {
$args += '-prerelease'
}
- if (Get-Member -InputObject $vsRequirements -Name 'version') {
+ if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'version' -ErrorAction SilentlyContinue)) {
$args += '-version'
$args += $vsRequirements.version
}
- if (Get-Member -InputObject $vsRequirements -Name 'components') {
+ if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'components' -ErrorAction SilentlyContinue)) {
foreach ($component in $vsRequirements.components) {
$args += '-requires'
$args += $component
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index c1841c9dfd0f..6c121300ac7d 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -115,9 +115,6 @@ function InitializeDotNetCli {
local install=$1
- # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism
- export DOTNET_MULTILEVEL_LOOKUP=0
-
# Disable first run since we want to control all package sources
export DOTNET_NOLOGO=1
@@ -166,7 +163,6 @@ function InitializeDotNetCli {
# build steps from using anything other than what we've downloaded.
Write-PipelinePrependPath -path "$dotnet_root"
- Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0"
Write-PipelineSetVariable -name "DOTNET_NOLOGO" -value "1"
# return value
diff --git a/eng/dependabot/Directory.Packages.props b/eng/dependabot/Directory.Packages.props
new file mode 100644
index 000000000000..25a158bb5f38
--- /dev/null
+++ b/eng/dependabot/Directory.Packages.props
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/eng/dependabot/global.json b/eng/dependabot/global.json
new file mode 100644
index 000000000000..9e26dfeeb6e6
--- /dev/null
+++ b/eng/dependabot/global.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/eng/download-source-built-archive.sh b/eng/download-source-built-archive.sh
new file mode 100755
index 000000000000..9d50110add14
--- /dev/null
+++ b/eng/download-source-built-archive.sh
@@ -0,0 +1,188 @@
+#!/bin/bash
+
+# Common helper functions for downloading archives based on versions in XML files
+
+# Get the repository root directory
+REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+PACKAGE_VERSIONS_PATH="$REPO_ROOT/eng/Versions.props"
+PACKAGE_VERSION_DETAILS_PATH="$REPO_ROOT/eng/Version.Details.props"
+
+# Helper to extract a property value from an XML file
+function GetXmlPropertyValue {
+ local propName="$1"
+ local filePath="$2"
+ local value=""
+ local line pattern
+ line=$(grep -m 1 "<$propName>" "$filePath" || :)
+ pattern="<$propName>(.*)$propName>"
+ if [[ $line =~ $pattern ]]; then
+ value="${BASH_REMATCH[1]}"
+ fi
+ echo "$value"
+}
+
+# Helper to download a file with retries
+function DownloadWithRetries {
+ local url="$1"
+ local targetDir="$2"
+ (
+ cd "$targetDir" &&
+ for i in {1..5}; do
+ if curl -fL --retry 5 -O "$url"; then
+ return 0
+ else
+ local exitCode=$?
+ case $exitCode in
+ 22)
+ # HTTP error (including 404) - don't retry
+ return 22
+ ;;
+ *)
+ # For all other errors (including partial transfers), sleep and retry
+ sleep 3
+ ;;
+ esac
+ fi
+ done
+ return 1
+ )
+}
+
+# Generic function to download an archive based on property name
+function DownloadArchive {
+ local label="$1"
+ local propertyName="$2"
+ local isRequired="$3"
+ local artifactsRid="$4"
+ local outputDir="$5"
+ local destinationFileNamePrefix="${6:-}"
+ local versionPropertyOverride="${7:-}"
+ local storageKey="${8:-}"
+
+ local notFoundMessage="No $label found to download..."
+
+ local archiveVersion
+ local versionsPath
+ local versionProperty="${versionPropertyOverride:-$propertyName}"
+ if [[ "$versionProperty" == "MicrosoftNETSdkPackageVersion" ]]; then
+ versionsPath="$PACKAGE_VERSION_DETAILS_PATH"
+ else
+ versionsPath="$PACKAGE_VERSIONS_PATH"
+ fi
+ archiveVersion=$(GetXmlPropertyValue "$versionProperty" "$versionsPath")
+ if [[ -z "$archiveVersion" ]]; then
+ if [ "$isRequired" == true ]; then
+ echo " ERROR: $notFoundMessage"
+ return 1
+ else
+ echo " $notFoundMessage"
+ return 0
+ fi
+ fi
+
+ local archiveUrl
+ local artifactsBaseFileName="Private.SourceBuilt.Artifacts"
+ local prebuiltsBaseFileName="Private.SourceBuilt.Prebuilts"
+ local sdkBaseFileName="dotnet-sdk"
+ local defaultArtifactsRid='centos.10-x64'
+
+ local versionDelimiter="."
+ if [[ "$propertyName" == "PrivateSourceBuiltSdkVersion" ]]; then
+ versionDelimiter="-"
+ fi
+
+ archiveVersion="${versionDelimiter}${archiveVersion}${versionDelimiter}"
+
+ # Build array of base URL entries to try in order
+ # Each entry is in the format "url" or "url=storageKey"
+ local baseUrls=()
+
+ # Assets for the default RID are hosted in builds.dotnet.microsoft.com first
+ if [[ $artifactsRid == $defaultArtifactsRid ]]; then
+ baseUrls+=("https://builds.dotnet.microsoft.com/dotnet/source-build")
+ fi
+
+ # Always try public CI location
+ baseUrls+=("https://ci.dot.net/public/source-build")
+
+ # Try internal CI location if storage key is provided
+ if [[ -n "$storageKey" ]]; then
+ baseUrls+=("https://ci.dot.net/internal/source-build=$storageKey")
+ fi
+
+ # Determine the archive filename based on property name
+ local archiveFileName
+ if [[ "$propertyName" == "PrivateSourceBuiltPrebuiltsVersion" ]]; then
+ archiveFileName="${prebuiltsBaseFileName}${archiveVersion}${defaultArtifactsRid}.tar.gz"
+ elif [[ "$propertyName" == "PrivateSourceBuiltArtifactsVersion" ]]; then
+ archiveFileName="${artifactsBaseFileName}${archiveVersion}${artifactsRid}.tar.gz"
+ elif [[ "$propertyName" == "PrivateSourceBuiltSdkVersion" ]]; then
+ archiveFileName="${sdkBaseFileName}${archiveVersion}${artifactsRid}.tar.gz"
+ else
+ echo " ERROR: Unknown archive property name: $propertyName"
+ return 1
+ fi
+
+ local archiveUrl
+ local displayUrl
+ local downloadedFilename=$(basename "${archiveFileName}")
+ local downloadSucceeded=false
+
+ # Try each base URL in order
+ for entry in "${baseUrls[@]}"; do
+ # Parse the entry: "url" or "url=storageKey"
+ local baseUrl="${entry%%=*}"
+ local entryStorageKey=""
+ if [[ "$entry" == *"="* ]]; then
+ entryStorageKey="${entry#*=}"
+ fi
+
+ archiveUrl="${baseUrl}/${archiveFileName}"
+ displayUrl="$archiveUrl"
+
+ # Append storage key as query parameter if present
+ if [[ -n "$entryStorageKey" ]]; then
+ local decodedKey
+ decodedKey=$(echo "$entryStorageKey" | base64 -d)
+ archiveUrl="${archiveUrl}?${decodedKey}"
+ displayUrl="${displayUrl}?[redacted]"
+ fi
+
+ echo " Downloading $label from $displayUrl..."
+ if DownloadWithRetries "$archiveUrl" "$outputDir"; then
+ downloadSucceeded=true
+ break
+ else
+ local downloadResult=$?
+ # Only continue to next URL if it was a 404
+ if [[ $downloadResult -ne 22 ]]; then
+ echo " ERROR: Failed to download $displayUrl"
+ return 1
+ fi
+ echo " Not found, trying next location..."
+ fi
+ done
+
+ if [[ "$downloadSucceeded" == false ]]; then
+ echo " ERROR: Failed to download from all available locations"
+ return 1
+ fi
+
+ # Rename the file if a destination filename prefix is provided
+ if [[ -n "$destinationFileNamePrefix" ]]; then
+ # Extract the suffix from the downloaded filename
+ local baseFilenameForSuffix="$artifactsBaseFileName"
+ if [[ "$propertyName" == *Prebuilts* ]]; then
+ baseFilenameForSuffix="$prebuiltsBaseFileName"
+ elif [[ "$propertyName" == *Sdk* ]]; then
+ baseFilenameForSuffix="$sdkBaseFileName"
+ fi
+ local suffix="${downloadedFilename#$baseFilenameForSuffix}"
+ local newFilename="$destinationFileNamePrefix$suffix"
+ mv "$outputDir/$downloadedFilename" "$outputDir/$newFilename"
+ echo " Renamed $downloadedFilename to $newFilename"
+ fi
+
+ return 0
+}
diff --git a/eng/finish-source-only.proj b/eng/finish-source-only.proj
index 5fda89ea08d5..f6ab5c028cc5 100644
--- a/eng/finish-source-only.proj
+++ b/eng/finish-source-only.proj
@@ -6,7 +6,8 @@
false
- $(ArtifactsLogDir)prebuilt-usage.xml
+ $(ArtifactsLogDir)prebuilt-usage.xml
+ $(ArtifactsLogDir)prebuilt-annotated-usage.xml
$(ArtifactsLogDir)all-project-assets-json-files.zip
$([MSBuild]::NormalizeDirectory('$(ArtifactsLogDir)', 'prebuilt-packages'))
@@ -65,18 +66,19 @@
-
+
+
+
@@ -101,45 +103,38 @@
-
-
-
+
-
- false
-
-
-
-
-
- false
- true
+
+
+
+
+ Prebuilt packages are not allowed in source-only builds.%0A%0A
+ $(PrebuiltErrorMessage)Detected @(DetectedPrebuiltPackage->Count()) prebuilt package(s):%0A
+ $(PrebuiltErrorMessage)@(DetectedPrebuiltPackage->' - %(Identity)', '%0A')%0A%0A
+ $(PrebuiltErrorMessage)For detailed usage information, see: $(PrebuiltAnnotatedUsageReportFile)%0A%0A
+ $(PrebuiltErrorMessage)See https://aka.ms/dotnet/prebuilts for guidance on what prebuilts are and how to eliminate them.
-
+
@@ -169,7 +164,8 @@
- $([System.Text.RegularExpressions.Regex]::Split('$([System.IO.File]::ReadAllText('%(SdkVersionFileItem.Identity)'))', '\r\n|\r|\n')[3])
+ %(SdkVersionFileItem.Identity)
+ $([System.Text.RegularExpressions.Regex]::Split('$([System.IO.File]::ReadAllText('$(SourceBuiltSdkVersionFile)'))', '\r\n|\r|\n')[3])
@@ -177,26 +173,10 @@
-
-
-
-
-
-
-
- unknown commit SHA
-
-
-
-
-
-
-
-
+
+
+
+
+
+
Validate
- $(RepositoryEngineeringDir)allowed-vmr-binaries.txt
+ $(RepositoryEngineeringDir)allowed-vmr-binaries.txt
+ $(RepositoryEngineeringDir)allowed-sb-binaries.txt
+ $(AllowedVmrBinariesFile)
+ BeforeTargets="Build"
+ Condition="'$(SkipBinaryScan)' != 'true'"
+ Inputs="$(AllowedBinariesFile);$(AllowedVmrBinariesFile);$(AllowedSbBinariesFile);$(BinaryToolKitAssembly)"
+ Outputs="$(BaseIntermediateOutputPath)DetectBinaries$(BinariesMode).complete">
+
+
diff --git a/eng/init-poison.proj b/eng/init-poison.proj
index 24420ddce6e9..dad11f1784bb 100644
--- a/eng/init-poison.proj
+++ b/eng/init-poison.proj
@@ -6,17 +6,18 @@
+
+
+
-
-
- .source-built.xml
- $(ArtifactsLogDir)poison-source-built-catalog.xml
-
+ Outputs="$(BaseIntermediateOutputPath)PoisonPackages.complete">
@@ -32,7 +33,7 @@
+ Properties="SharedComponentFilterMode=$(SharedComponentFilter_ToolingOnly)">
@@ -40,18 +41,14 @@
Text="Expected NuGet packages to be present from shared components artifacts." />
- <_SharedToolingComponentFilenames Include="@(_FilteredSharedComponentPackages)">
- $(SharedComponentsArtifactsPath)$([System.IO.Path]::GetFileName('%(PipelineArtifactPath)'))
-
-
+
-
-
-
+
+
+
diff --git a/eng/init-source-only.proj b/eng/init-source-only.proj
index 8ceeca2f04db..ec2b67ccc083 100644
--- a/eng/init-source-only.proj
+++ b/eng/init-source-only.proj
@@ -13,12 +13,9 @@
-
- $([MSBuild]::NormalizeDirectory('$(PrereqsPackagesDir)', 'archive'))
-
-
@@ -40,7 +37,13 @@
@(SharedComponentsPrereqsArchivePathItem)
-
+
+
+
+
+
@@ -64,7 +67,7 @@
@@ -78,6 +81,13 @@
+
+
+
+
+
+
@@ -98,7 +108,6 @@
-
@@ -109,10 +118,6 @@
-
-
-
-
@@ -172,24 +178,8 @@
-
-
-
-
-
-
+
+
diff --git a/eng/pipelines/official.yml b/eng/pipelines/official.yml
index 6a0889659660..cc77a3da5171 100644
--- a/eng/pipelines/official.yml
+++ b/eng/pipelines/official.yml
@@ -42,16 +42,24 @@ parameters:
- name: desiredFinalVersionKind
displayName: 'Final version kind'
type: string
- default: 'Default (repo specifies)'
+ default: 'Default (uses VMR branding defaults for release branch builds or otherwise repo branding defaults)'
values:
- - Default (repo specifies)
- - Stable Preview
- - Stable Final
+ - Default (uses VMR branding defaults for release branch builds or otherwise repo branding defaults)
+ - Repo default (uses the repo branding defaults)
+ - Unstable (produces assets with the repo specified branding suffix)
+ - Preview (produces assets with a '.final' branding suffix)
+ - Release (produces assets without a branding suffix)
variables:
- name: isScheduleTrigger
value: ${{ eq(variables['Build.Reason'], 'Schedule') }}
+- name: GDN_EXTRACT_TOOLS
+ value: 'binskim,bandit,roslynanalyzers'
+
+- name: GDN_EXTRACT_FILTER
+ value: 'f|**/*.zip;f|**/*.nupkg;f|**/*.vsix;f|**/*.cspkg;f|**/*.sfpkg;f|**/*.package'
+
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- name: skipComponentGovernanceDetection # we run CG on internal builds only
value: true
@@ -73,7 +81,10 @@ extends:
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
parameters:
featureFlags:
+ binskimScanAllExtensions: true
incrementalSDLBinaryAnalysis: true
+ autoEnablePREfastWithNewRuleset: false
+ autoEnableRoslynWithNewRuleset: false
sdl:
sourceAnalysisPool:
name: $(DncEngInternalBuildPool)
@@ -93,17 +104,12 @@ extends:
tsaEnabled: true
binskim:
enabled: true
- # This may need to be updated to exclude files we don't want scanned.
- # This pattern was pulled from dotnet/sdk, with the ESRPClient added.
- # When binskim supports scanning of archive contents, this can be removed altogether.
- # This is of the form: ;
- # +:f| - Include glob
- # -:f| - Exclude glob
- analyzeTargetGlob: +:f|eng\**\*.props;+:f|**\artifacts\bin\**\*.dll;+:f|**\artifacts\bin\**\*.exe;-:f|**\artifacts\bin\**\msdia140.dll;-:f|**\artifacts\bin\**\pgort140.dll;-:f|**\artifacts\bin\*Tests\**;-:f|**\Microsoft.NET.Runtime.Emscripten**\tools\**;-:f|**\CodeCoverage\**;-:f|**\artifacts\bin\**\capstone.dll;-:f|**\Microsoft.EsrpClient\**;
policheck:
enabled: true
tsa:
enabled: true
+ credscan:
+ suppressionsFile: $(Build.SourcesDirectory)/.config/CredScanSuppressions.json
containers:
${{ variables.almaLinuxContainerName }}:
@@ -167,3 +173,6 @@ extends:
desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
isOfficialBuild: true
scope: full
+ # Exclude runtime dependent jobs for any branch not producing a 1xx version since runtime-related repos aren't built in that context
+ # This is enabled for all branches except main and 1xx
+ excludeRuntimeDependentJobs: false
diff --git a/eng/pipelines/pr.yml b/eng/pipelines/pr.yml
index 407821d5569e..e1d08edfb549 100644
--- a/eng/pipelines/pr.yml
+++ b/eng/pipelines/pr.yml
@@ -13,14 +13,30 @@ pr:
include:
- main
- release/*
+ paths:
+ include:
+ - '*'
+ exclude:
+ - 'docs/*'
+ - '*.md'
schedules:
- - cron: "0 1 * * *" # run at 01:00 (UTC)
+ - cron: "0 14 * * *" # run at 14:00 (UTC)
branches:
include:
- main
always: false # run only if there were changes since the last successful scheduled run.
+parameters:
+- name: buildScope
+ displayName: 'Build Scope'
+ type: string
+ default: 'auto'
+ values:
+ - auto
+ - lite
+ - full
+
variables:
- name: isScheduleTrigger
value: ${{ eq(variables['Build.Reason'], 'Schedule') }}
@@ -40,9 +56,53 @@ variables:
stages:
- template: /eng/pipelines/templates/stages/vmr-build.yml
parameters:
- ${{ if or(eq(variables.isScheduleTrigger, 'true'), contains(variables['Build.DefinitionName'], '-full')) }}:
- scope: full
- ${{ elseif eq(variables.isPRTrigger, 'true') }}:
- scope: lite
+ ${{ if eq(parameters.buildScope, 'auto') }}:
+ ${{ if or(eq(variables.isScheduleTrigger, 'true'), contains(variables['Build.DefinitionName'], '-full')) }}:
+ scope: full
+ ${{ elseif eq(variables.isPRTrigger, 'true') }}:
+ scope: lite
+ ${{ else }}:
+ scope: full
${{ else }}:
scope: full
+ # Exclude runtime dependent jobs for any branch not producing a 1xx version since runtime-related repos aren't built in that context
+ # This is enabled for all branches except main and 1xx
+ excludeRuntimeDependentJobs: false
+
+- stage: ValidateUserChanges
+ displayName: Validate user changes in VMR
+ dependsOn: []
+ condition: and(
+ eq(variables['isPRTrigger'], 'true'),
+ and(
+ not(startsWith(variables['System.PullRequest.SourceBranch'], 'refs/heads/darc-')),
+ not(startsWith(variables['System.PullRequest.SourceBranch'], 'darc-'))
+ )
+ )
+ jobs:
+ - job: Validate
+ displayName: Run Validation Script
+ pool:
+ vmImage: windows-latest
+ steps:
+ - checkout: self
+ fetchDepth: 0
+
+ - powershell: |
+ Write-Host "Fetching target branch: $(System.PullRequest.TargetBranch)"
+ git fetch origin $(System.PullRequest.TargetBranch)
+ displayName: Fetch target branch
+
+ - powershell: |
+ . "$(Build.SourcesDirectory)\eng\common\tools.ps1"
+ InitializeDotNetCli -install $true
+ Write-Host "##vso[task.setvariable variable=DOTNET_INSTALL_DIR]$env:DOTNET_INSTALL_DIR"
+ displayName: Initialize .NET CLI
+
+ - powershell: |
+ & "$(DOTNET_INSTALL_DIR)\dotnet.exe" run --project eng/tools/ChangeValidation/ChangeValidation.csproj
+ displayName: Run ChangeValidation tool
+ env:
+ SYSTEM_PULLREQUEST_TARGETBRANCH: $(System.PullRequest.TargetBranch)
+ SYSTEM_PULLREQUEST_SOURCEBRANCH: $(System.PullRequest.SourceBranch)
+ SYSTEM_PULLREQUEST_PULLREQUESTNUMBER: $(System.PullRequest.PullRequestNumber)
diff --git a/eng/pipelines/scout-build.yml b/eng/pipelines/scout-build.yml
index c4e8ea5bb2fe..0cb923a5b9d5 100644
--- a/eng/pipelines/scout-build.yml
+++ b/eng/pipelines/scout-build.yml
@@ -32,3 +32,6 @@ stages:
- template: /eng/pipelines/templates/stages/vmr-build.yml
parameters:
scope: scout
+ # Exclude runtime dependent jobs for any branch not producing a 1xx version since runtime-related repos aren't built in that context
+ # This is enabled for all branches except main and 1xx
+ excludeRuntimeDependentJobs: false
diff --git a/eng/pipelines/source-build-outer-loop.yml b/eng/pipelines/source-build-outer-loop.yml
new file mode 100644
index 000000000000..ab417c177a32
--- /dev/null
+++ b/eng/pipelines/source-build-outer-loop.yml
@@ -0,0 +1,61 @@
+trigger:
+ batch: true
+ branches:
+ include:
+ - main
+ - release/*.0.1xx-preview*
+ - internal/release/*.0.1xx*
+
+variables:
+- name: skipComponentGovernanceDetection
+ value: true
+
+- name: Codeql.Enabled
+ value: false
+
+- template: /eng/common/templates-official/variables/pool-providers.yml@self
+- template: /eng/pipelines/templates/variables/vmr-build.yml@self
+
+resources:
+ repositories:
+ - repository: 1ESPipelineTemplates
+ type: git
+ name: 1ESPipelineTemplates/1ESPipelineTemplates
+ ref: refs/tags/release
+
+extends:
+ template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
+ parameters:
+ featureFlags:
+ incrementalSDLBinaryAnalysis: true
+ sdl:
+ sourceAnalysisPool:
+ name: $(DncEngInternalBuildPool)
+ image: 1es-windows-2022
+ os: windows
+
+ spotBugs:
+ enabled: false
+
+ codeql:
+ compiled:
+ enabled: false
+ runSourceLanguagesInSourceAnalysis: false
+ tsaEnabled: false
+ binskim:
+ enabled: false
+ policheck:
+ enabled: false
+ tsa:
+ enabled: false
+
+ containers:
+ ${{ variables.centOSStreamContainerName }}:
+ image: ${{ variables.centOSStreamContainerImage }}
+ options: ${{ variables.defaultContainerOptions }}
+
+ stages:
+ - template: /eng/pipelines/templates/stages/vmr-build.yml@self
+ parameters:
+ isOfficialBuild: false
+ scope: source-build-outer-loop
diff --git a/eng/pipelines/source-build-sdk-diff-tests.yml b/eng/pipelines/source-build-sdk-diff-tests.yml
index ed3ecb21c70f..8981cd1a054d 100644
--- a/eng/pipelines/source-build-sdk-diff-tests.yml
+++ b/eng/pipelines/source-build-sdk-diff-tests.yml
@@ -2,8 +2,13 @@ schedules:
- cron: "0 12 * * 1-5"
displayName: Run on weekdays at 12pm UTC
branches:
+ # The 2xx, 3xx, 4xx triggers exist to cover the feature band pre-release time periods.
+ # They can be removed once released as the pipeline triggers below will handle the branches after release.
include:
- main
+ - release/*.0.2xx*
+ - release/*.0.3xx*
+ - release/*.0.4xx*
# Relies on dotnet-unified-build being in the same repo as this pipeline
# https://learn.microsoft.com/en-us/azure/devops/pipelines/process/pipeline-triggers?view=azure-devops#branch-considerations
@@ -17,7 +22,7 @@ resources:
branches:
include:
- refs/heads/release/*.0.1xx-preview*
- - refs/heads/internal/release/*.0.1xx*
+ - refs/heads/internal/release/*.0.?xx*
# Trigger on build stages vs successful pipeline completion for a higher run frequency when there are
# publish/validation failures.
stages:
@@ -27,11 +32,9 @@ resources:
- pipeline: dotnet-source-build-pre10.0
source: dotnet-source-build-pre10.0
# For releases branches only run on internal/release branches because that's where dependencies flow.
- # Previews don't have internal/release branches so they must be run from non-internal release branches.
trigger:
branches:
include:
- - refs/heads/release/*.0.1xx-preview*
- refs/heads/internal/release/*.0.1xx*
repositories:
diff --git a/eng/pipelines/templates/jobs/sdk-diff-tests.yml b/eng/pipelines/templates/jobs/sdk-diff-tests.yml
index 27ec52de16e2..6fd0d4829882 100644
--- a/eng/pipelines/templates/jobs/sdk-diff-tests.yml
+++ b/eng/pipelines/templates/jobs/sdk-diff-tests.yml
@@ -127,14 +127,18 @@ jobs:
eng/common/build.sh -bl --projects $(Build.SourcesDirectory)/test/Microsoft.DotNet.SourceBuild.Tests/Microsoft.DotNet.SourceBuild.Tests.csproj --restore
+ source ./eng/common/tools.sh
+ InitializeDotNetCli true
+
echo "##vso[task.setvariable variable=MsftSdkTarballPath]$(Pipeline.Workspace)/Artifacts/$msft_sdk_tarball_name"
echo "##vso[task.setvariable variable=SdkTarballPath]$(Pipeline.Workspace)/Artifacts/$sdk_tarball_name"
echo "##vso[task.setvariable variable=SourceBuiltArtifactsPath]$(Pipeline.Workspace)/Artifacts/$artifacts_path"
+ echo "##vso[task.setvariable variable=DotNetPath]$_InitializeDotNetCli"
displayName: Prepare Tests
workingDirectory: $(Build.SourcesDirectory)
- script: >
- .dotnet/dotnet test
+ $(DotNetPath)/dotnet test
$(Build.SourcesDirectory)/test/Microsoft.DotNet.SourceBuild.Tests/Microsoft.DotNet.SourceBuild.Tests.csproj
--filter "Category=SdkContent"
--logger:'trx;LogFileName=$(Agent.JobName)_SDKDiffTests.trx'
@@ -161,6 +165,7 @@ jobs:
find artifacts/TestResults/ -type f -name "*.binlog" -exec cp {} --parents -t ${targetFolder} \;
find artifacts/TestResults/ -type f -name "*.log" -exec cp {} --parents -t ${targetFolder} \;
find artifacts/TestResults/ -type f -name "*.diff" -exec cp {} --parents -t ${targetFolder} \;
+ find artifacts/TestResults/ -type f -name "*.suppression" -exec cp {} --parents -t ${targetFolder} \;
find artifacts/TestResults/ -type f -name "Updated*.txt" -exec cp {} --parents -t ${targetFolder} \;
displayName: Prepare BuildLogs staging directory
continueOnError: true
@@ -181,6 +186,7 @@ jobs:
- ${{ if and(eq(parameters.publishTestResultsPr, 'true'), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release'))) }}:
- template: ../steps/create-baseline-update-pr.yml
parameters:
+ dotnetPath: $(DotNetPath)
pipeline: sdk
repo: dotnet/dotnet
originalFilesDirectory: test/Microsoft.DotNet.SourceBuild.Tests/assets/SdkContentTests
diff --git a/eng/pipelines/templates/jobs/vmr-build.yml b/eng/pipelines/templates/jobs/vmr-build.yml
index 07e3c7a50424..bc4d15ba77c2 100644
--- a/eng/pipelines/templates/jobs/vmr-build.yml
+++ b/eng/pipelines/templates/jobs/vmr-build.yml
@@ -1,755 +1,818 @@
-### This job builds https://github.com/dotnet/dotnet with given parameters
-### If run in an sdk PR, new changes are applied to a local copy of the VMR, then it is built and tested
-
-parameters:
-- name: artifactsRid
- type: string
- default: ''
-
-- name: buildName
- type: string
-
-- name: buildPass
- type: string
- default: ''
-
-- name: configuration
- type: string
- default: 'Release'
-
-- name: container
- type: object
- default:
- image: ''
- name: ''
-
-- name: crossRootFs
- type: string
- default: ''
-
-- name: pool
- type: object
-
-- name: targetOS
- type: string
- default: ''
-
-- name: targetArchitecture
- type: string
- default: ''
-
-- name: useMonoRuntime
- displayName: True when build output uses the mono runtime
- type: boolean
- default: false
-
-- name: sign
- displayName: True when build output should be signed (includes dry runs)
- type: boolean
- default: false
-
-- name: signType
- displayName: Signing type
- type: string
- default: ''
-
-- name: signDac
- displayName: True when the diagnostic files should be signed
- type: boolean
- default: false
-
- # Remove with https://github.com/dotnet/source-build/issues/5288
-- name: enableCoreDumpGeneration
- displayName: True when core dump generation should be enabled
- type: boolean
- default: false
-
-# Overrides the rid that is produced by the build.
-- name: targetRid
- type: string
- default: ''
-
-# Enables IBC data on when building internally.
-- name: enableIBCOptimization
- type: boolean
- default: false
-
-# Name of previous job(s) (from the same template as this) whose output will be used to build this job
-# The SDK from its artifacts is copied to $(sourcesPath)/.dotnet
-- name: reuseBuildArtifactsFrom
- type: object
- default: ''
-
-# Enables usage of the system libraries when building.
-- name: useSystemLibraries
- type: boolean
- default: false
-
-#### SOURCE-ONLY parameters ####
-
-# Instead of building the VMR directly, exports the sources into a tarball and builds from that
-- name: buildFromArchive
- type: boolean
- default: false
-
-# Enable for source-building the VMR
-- name: buildSourceOnly
- type: boolean
- default: false
-
-- name: enablePoison
- type: boolean
- default: false
-
-# Allow downloading artifacts from the internet during the build
-- name: runOnline
- type: boolean
- default: true
-
-- name: runTests
- type: boolean
- default: true
-
-# Freeform field for extra values to pass to build.sh for special build modes
-- name: extraProperties
- type: string
- default: ''
-
-# Use the previous version's SDK to build the current one
-- name: withPreviousSDK
- type: boolean
- default: false
-
-# Skip the build step (this would be used when wanting to run tests only)
-- name: skipBuild
- type: boolean
- default: false
-
-# Custom steps to run before running tests
-- name: testInitSteps
- type: stepList
- default: []
-
-#### repo parameters ####
-
-- name: isBuiltFromVmr
- displayName: True when build is running from dotnet/dotnet directly
- type: boolean
-
-jobs:
-- job: ${{ parameters.buildName }}_${{ parameters.targetArchitecture }}${{ replace(format('_BuildPass{0}', coalesce(parameters.buildPass, '1')), '_BuildPass1', '') }}
- pool: ${{ parameters.pool }}
-
- # 1ES pipeline template requires that the container is specified in the job level.
- # If we are using a container image, we set the container to correct name.
- # Otherwise, we set the container to host so that the job runs on the host agent.
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- ${{ if ne(parameters.container.name, '') }}:
- container: ${{ parameters.container.name }}
- ${{ else }}:
- container: host
-
- # For public projects, we always use the container image if it is specified.
- ${{ else }}:
- ${{ if ne(parameters.container.image, '') }}:
- container:
- image: ${{ parameters.container.image }}
- options: $(defaultContainerOptions)
-
- ${{ if ne(parameters.reuseBuildArtifactsFrom, '') }}:
- ${{ if eq(parameters.buildPass, '') }}:
- # For PR builds, skip the stage 2 build if the stage 1 build fails.
- # Otherwise, run the stage 2 build even if the stage 1 build fails so that we can get a complete assessment of the build status.
- # The build shortcuts when stage 1 build fails and doesn't produce the SDK.
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
- condition: succeeded()
- ${{ else }}:
- condition: succeededOrFailed()
- ${{ else }}:
- condition: succeeded()
- dependsOn:
- - ${{ if ne(parameters.reuseBuildArtifactsFrom, '') }}:
- - ${{ parameters.reuseBuildArtifactsFrom }}
- variables:
- - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - group: AzureDevOps-Artifact-Feeds-Pats
- - ${{ if eq(parameters.enableIBCOptimization, 'true') }}:
- - group: DotNet-VSTS-Infra-Access
- - ${{ else }}:
- - name: BotAccount-dotnet-bot-repo-PAT
- value: N/A
- - name: additionalBuildArgs
- value: ''
- - name: runTestsTimeout
- value: 30
-
- - ${{ if parameters.isBuiltFromVmr }}:
- - name: vmrPath
- value: $(Build.SourcesDirectory)
- - ${{ else }}:
- - name: vmrPath
- value: $(Agent.BuildDirectory)/vmr
-
- # Location of the VMR sources
- # We either build the repo directly, or we extract them outside (which is what partners do)
- - ${{ if parameters.buildFromArchive }}:
- - name: sourcesPath
- value: $(Agent.TempDirectory)/dotnet-sources/
- - ${{ else }}:
- - name: sourcesPath
- value: $(vmrPath)
-
- - name: artifactsStagingDir
- value: $(Build.ArtifactStagingDirectory)/artifacts
-
- - name: artifactsPrepublishDir
- value: $(Build.ArtifactStagingDirectory)/prepublish
-
- - name: successfulJobArtifactName
- value: $(Agent.JobName)_Artifacts
-
- - name: failedJobArtifactName
- value: $(successfulJobArtifactName)_Attempt$(System.JobAttempt)
-
- # manually disable CodeQL until https://dev.azure.com/mseng/1ES/_workitems/edit/2211548 is implemented
- # CodeQL doesn't work on arm64 macOS, see https://portal.microsofticm.com/imp/v5/incidents/details/532165079/summary
- - ${{ if eq(parameters.pool.os, 'macOS') }}:
- - name: ONEES_ENFORCED_CODEQL_ENABLED
- value: false
-
- # Build up the command line variables. We avoid doing this in the script sections below
- # because AzDO will not echo command lines if they are more than a single line.
-
- ## Build command line
-
- ### Command line prefix
- - name: commandPrefix
- ${{ if eq(parameters.targetOS, 'windows') }}:
- value: '-'
- ${{ else }}:
- value: '--'
-
- ### Basic arguments
- - name: cleanArgument
- # Don't clean-while-building on OSs that have enough disk space to keep
- # intermediates for compliance scanners.
- ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(parameters.targetOS, 'osx')) }}:
- value: ''
- ${{ else }}:
- ${{ if eq(parameters.targetOS, 'windows') }}:
- value: $(commandPrefix)cleanWhileBuilding
- ${{ else }}:
- value: $(commandPrefix)clean-while-building
-
- - name: brandingArgument
- value: $(commandPrefix)branding $(brandingType)
-
- - ${{ if and(eq(variables['System.TeamProject'], 'internal'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- - name: officialBuildArgument
- ${{ if eq(parameters.targetOS, 'windows') }}:
- value: $(commandPrefix)officialBuildId $(Build.BuildNumber)
- ${{ else }}:
- value: $(commandPrefix)official-build-id $(Build.BuildNumber)
- - ${{ else }}:
- - name: officialBuildArgument
- value: ''
-
- - name: useSystemLibrariesArgument
- ${{ if eq(parameters.useSystemLibraries, 'true') }}:
- # Do not use all (or include libunwind) because of the issues described in https://github.com/dotnet/source-build/issues/5288
- value: $(commandPrefix)with-system-libs brotli+rapidjson+zlib
- ${{ else }}:
- value: ''
-
- - name: baseArguments
- value: $(commandPrefix)ci $(cleanArgument) $(commandPrefix)prepareMachine -c ${{ parameters.configuration }} $(brandingArgument) $(useSystemLibrariesArgument) $(officialBuildArgument)
-
- - name: baseProperties
- value: $(officialBuildProperties) /p:VerticalName=$(Agent.JobName)
-
- - name: targetProperties
- ${{ if and(ne(parameters.targetOS, ''), ne(parameters.targetArchitecture, '')) }}:
- value: -os ${{ parameters.targetOS }} -arch ${{ parameters.targetArchitecture }}
- ${{ elseif ne(parameters.targetOS, '') }}:
- value: -os ${{ parameters.targetOS }}
- ${{ else }}:
- value: -arch ${{ parameters.targetArchitecture }}
-
- ### Signing
- - name: _SignDiagnosticFilesArgs
- value: ''
- - ${{ if eq(parameters.sign, 'True') }}:
- - name: signArguments
- value: $(commandPrefix)sign
- - ${{ if eq(parameters.signType, 'DryRun') }}:
- # The _SignType variable is used by microbuild installation
- - name: _SignType
- value: ''
- - name: signProperties
- value: /p:ForceDryRunSigning=true
- - ${{ else }}:
- - name: _SignType
- value: ${{ parameters.signType }}
- - name: signProperties
- value: /p:DotNetSignType=${{ parameters.signType }} /p:TeamName=$(_TeamName)
- - ${{ else }}:
- - name: signArguments
- value: ''
- - name: signProperties
- value: ''
- - name: _SignType
- value: ''
-
- ### Build Pass
- - ${{ if ne(parameters.buildPass, '') }}:
- - name: buildPassProperties
- value: /p:DotNetBuildPass=${{ parameters.buildPass }}
- - ${{ else }}:
- - name: buildPassProperties
- value: ''
-
- ### Additional properties
- - ${{ if eq(parameters.enableIBCOptimization, 'true') }}:
- - name: ibcProperties
- value: '/p:EnableIBCOptimization=true /p:IBCDropAccessToken=$(dn-bot-devdiv-drop-r-code-r)'
- - ${{ else }}:
- - name: ibcProperties
- value: ''
-
- # Timeout
- ## Real signing takes a while - increase the timeout to allow for that
- ${{ if eq(variables['_SignType'], 'real') }}:
- timeoutInMinutes: 720
- ## Currently, CodeQL slows the build down too much
- ## https://github.com/dotnet/source-build/issues/4276
- ${{ elseif and(parameters.isBuiltFromVmr, startswith(parameters.buildName, 'Windows'), eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}:
- timeoutInMinutes: 720
- ${{ else }}:
- timeoutInMinutes: 240
-
- templateContext:
- outputParentDirectory: $(Build.ArtifactStagingDirectory)
- outputs:
- - output: pipelineArtifact
- displayName: Publish BuildLogs
- condition: succeededOrFailed()
- targetPath: $(Build.ArtifactStagingDirectory)/BuildLogs
- artifactName: $(Agent.JobName)_BuildLogs_Attempt$(System.JobAttempt)
- sbomEnabled: false
-
- # Both publishing steps are necessary to ensure artifacts are published on both success and failure.
- # This prevents overwrite conflicts in the event of a failed build followed by a rerun.
- # Additionally, the 'Download Previous Build *' steps depend on a fixed name to acquire specific assets in multi-stage builds.
- - output: pipelineArtifact
- path: $(Build.ArtifactStagingDirectory)/artifacts
- artifact: $(successfulJobArtifactName)
- displayName: Publish Artifacts (On Success)
- condition: succeeded()
- sbomEnabled: true
-
- - output: pipelineArtifact
- path: $(artifactsPrepublishDir)
- artifact: $(failedJobArtifactName)
- displayName: Publish Artifacts (On Failure)
- condition: failed()
- continueOnError: true
- sbomEnabled: true
-
- # Using build artifacts to enable publishing the vertical manifests to a single artifact from different jobs
- - ${{ if ne(parameters.buildSourceOnly, true) }}:
- - output: buildArtifacts
- PathtoPublish: $(Build.ArtifactStagingDirectory)/artifacts/manifests/${{ parameters.configuration }}/$(Agent.JobName).xml
- ArtifactName: VerticalManifests
- displayName: Publish Vertical Manifest
- sbomEnabled: false
-
- steps:
- - checkout: self
- fetchDepth: 1
-
- - ${{ if not(parameters.isBuiltFromVmr) }}:
- # Synchronize new content in the VMR during PRs
- - template: /eng/common/templates/steps/vmr-sync.yml@self
- parameters:
- vmrPath: $(vmrPath)
- targetRef: $(Build.SourceVersion) # Synchronize the current repo commit
-
- - ${{ if parameters.buildFromArchive }}:
- - script: |
- set -ex
- cp -r "$(vmrPath)" "$(sourcesPath)"
- rm -rf "$(sourcesPath)/.git"
- displayName: Export VMR sources
- workingDirectory: $(Build.ArtifactStagingDirectory)
-
- - ${{ if ne(parameters.reuseBuildArtifactsFrom,'') }}:
- - ${{ each reuseBuildArtifacts in parameters.reuseBuildArtifactsFrom }}:
- - ${{ if eq(parameters.buildSourceOnly, true) }}:
- - template: ../steps/download-artifacts.yml
- parameters:
- artifactDescription: Previous Build (${{ reuseBuildArtifacts }} - Source Build artifacts)
- artifactName: ${{ reuseBuildArtifacts }}_Artifacts
- downloadFilePatterns: |
- **/Private.SourceBuilt.Artifacts.*.tar.gz
- **/dotnet-sdk-*.tar.gz
- copyDestination: $(sourcesPath)/prereqs/packages/archive/
- flattenDirs: true
-
- - ${{ else }}:
- - task: DownloadPipelineArtifact@2
- inputs:
- artifactName: ${{ reuseBuildArtifacts }}_Artifacts
- targetPath: $(sourcesPath)/artifacts/
- displayName: Download Previous Build (${{ reuseBuildArtifacts }})
-
- - ${{ if eq(parameters.withPreviousSDK, 'true') }}:
- - script: |
- set -euo pipefail
-
- if [[ '${{ parameters.artifactsRid }}' == '' ]]; then
- echo "'artifactsRid' is not specified. Cannot download source-built SDK."
- exit 1
- fi
-
- packageVersionsPath="$(sourcesPath)/eng/Versions.props"
- notFoundMessage="No source-built SDK found to download..."
-
- echo "Looking for source-built SDK to download..."
- archiveVersionLine=$(grep -m 1 "" "$packageVersionsPath" || :)
- versionPattern="(.*)"
-
- if [[ $archiveVersionLine =~ $versionPattern ]]; then
- archiveVersion="${BASH_REMATCH[1]}"
- archiveUrl="https://builds.dotnet.microsoft.com/source-built-artifacts/sdks/dotnet-sdk-$archiveVersion-${{ parameters.artifactsRid }}.tar.gz"
- downloadDir="$(sourcesPath)/prereqs/packages/archive/"
-
- echo "Downloading source-built SDK from $archiveUrl..."
- (cd "$downloadDir" && curl --retry 5 -O "$archiveUrl")
- else
- echo "$notFoundMessage"
- exit 1
- fi
- displayName: Setup Previously Source-Built SDK
-
- # https://github.com/dotnet/dotnet/issues/1758
- # After a re-boostrap:
- # - Uncomment the line below, replacing the one after it.
- # - Uncomment the two parameter lines at the end of the template parameters.
- # - ${{ if and(eq(parameters.sign, 'True'), ne(parameters.signType, 'DryRun')) }}:
- - ${{ if and(eq(parameters.sign, 'True'), eq(parameters.signType, 'Real')) }}:
- - template: ${{ variables['Build.SourcesDirectory'] }}/eng/common/core-templates/steps/install-microbuild.yml
- parameters:
- enableMicrobuild: true
- enableMicrobuildForMacAndLinux: true
- # ${{ if ne(parameters.signType, 'Real') }}:
- # microbuildUseESRP: false
-
- # When building internal, authenticate to internal feeds that may be in use
- # We do not need these for source-only builds
- - ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(parameters.buildSourceOnly, 'True')) }}:
- # Authenticate with service connections to be able to pull packages to external nuget feeds.
- - task: NuGetAuthenticate@1
- inputs:
- nuGetServiceConnections: devdiv/engineering, devdiv/dotnet-core-internal-tooling
-
- - ${{ if eq(parameters.targetOS, 'windows') }}:
- # Node 20.x is a toolset dependency to build aspnetcore
- # Keep in sync with aspnetcore: https://github.com/dotnet/aspnetcore/blob/7d5309210d8f7bae8fa074da495e9d009d67f1b4/.azure/pipelines/ci.yml#L719-L722
- - task: NodeTool@0
- displayName: Install Node 20.x
- inputs:
- versionSpec: 20.x
-
- - ${{ if eq(parameters.signDac, 'true') }}:
- # TODO: Once we turn off the dotnet/runtime official build, move these templates into the VMR's eng folder.
- - template: ../steps/setup-diagnostics-esrp.yml@self
- parameters:
- isOfficialBuild: true
- serviceConnectionGuid: 0a3b81f8-02bd-434b-960a-1e45cfcca801
- serviceConnectionName: 'diagnostics-esrp-kvcertuser-pme'
- scriptRoot: '${{ variables.sourcesPath }}/src/runtime/eng/native/signing'
-
-
- - script: build.cmd
- $(baseArguments)
- $(signArguments)
- $(baseProperties)
- /p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory)
- $(targetProperties)
- $(signProperties)
- $(buildPassProperties)
- $(ibcProperties)
- $(_SignDiagnosticFilesArgs)
- ${{ parameters.extraProperties }}
- displayName: Build
- workingDirectory: ${{ variables.sourcesPath }}
- ${{ if eq(parameters.sign, 'true') }}:
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- ${{ if eq(parameters.signDac, 'true') }}:
- ESRP_TOKEN: $(System.AccessToken)
-
- - ${{ if eq(parameters.runTests, 'True') }}:
- - script: build.cmd
- $(baseArguments)
- $(targetProperties)
- $(buildPassProperties)
- ${{ parameters.extraProperties }}
- -test
- -excludeCIBinarylog
- /bl:artifacts/log/Release/Test.binlog
- displayName: Run Tests
- workingDirectory: ${{ variables.sourcesPath }}
- timeoutInMinutes: ${{ variables.runTestsTimeout }}
-
- - ${{ else }}:
- - ${{ if eq(parameters.targetOS, 'osx') }}:
- - script: |
- $(sourcesPath)/eng/common/native/install-dependencies.sh osx
- displayName: Install dependencies
- - ${{ if eq(parameters.buildSourceOnly, 'true') }}:
- - script: |
- set -ex
-
- customPrepArgs=""
- prepSdk=true
-
- if [[ -n '${{ parameters.artifactsRid }}' ]]; then
- customPrepArgs="${customPrepArgs} --artifacts-rid ${{ parameters.artifactsRid }}"
- fi
-
- if [[ '${{ parameters.withPreviousSDK }}' == 'True' ]]; then
- # Using previous SDK implies we do not want to bootstrap.
- customPrepArgs="${customPrepArgs} --no-sdk --no-bootstrap"
- prepSdk=false
- elif [[ '${{ length(parameters.reuseBuildArtifactsFrom) }}' -gt '0' ]]; then
- customPrepArgs="${customPrepArgs} --no-sdk --no-artifacts"
- prepSdk=false
- fi
-
- if [[ "$prepSdk" == "false" ]]; then
- mkdir $(sourcesPath)/.dotnet
- previousSdkPath="$(sourcesPath)/prereqs/packages/archive/dotnet-sdk-*.tar.gz"
- eval tar -ozxf "$previousSdkPath" -C "$(sourcesPath)/.dotnet"
- eval rm -f "$previousSdkPath"
-
- echo "##vso[task.setvariable variable=additionalBuildArgs]--with-sdk $(sourcesPath)/.dotnet"
- fi
-
- ./prep-source-build.sh $customPrepArgs
- displayName: Prep the Build
- workingDirectory: $(sourcesPath)
-
- - ${{ if ne(parameters.skipBuild, 'true') }}:
-
- - script: |
- set -ex
- df -h
-
- customEnvVars=""
- customPreBuildArgs=""
- customBuildArgs="$(baseArguments) $(signArguments) $(_SignDiagnosticFilesArgs)"
- extraBuildProperties="$(baseProperties) /p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory) $(targetProperties) $(signProperties) $(buildPassProperties) ${{ parameters.extraProperties }}"
-
- if [[ '${{ parameters.runOnline }}' == 'True' ]]; then
- customBuildArgs="$customBuildArgs --online"
- else
- customPreBuildArgs="$customPreBuildArgs sudo -E unshare -n"
- fi
-
- if [[ '${{ parameters.enablePoison }}' == 'True' ]]; then
- customBuildArgs="$customBuildArgs --poison"
- fi
-
- if [[ '${{ parameters.buildFromArchive }}' == 'True' ]]; then
- customBuildArgs="$customBuildArgs --source-repository https://github.com/dotnet/dotnet"
- customBuildArgs="$customBuildArgs --source-version $(git -C "$(vmrPath)" rev-parse HEAD)"
- fi
-
- if [[ '${{ parameters.buildSourceOnly }}' == 'True' ]]; then
- customBuildArgs="$customBuildArgs --source-only"
- extraBuildProperties="$extraBuildProperties /p:ReportSbrpUsage=true"
- fi
-
- if [[ '${{ parameters.useMonoRuntime }}' == 'True' ]]; then
- customBuildArgs="$customBuildArgs --use-mono-runtime"
- fi
-
- if [[ -n "${{ parameters.targetRid }}" ]]; then
- customBuildArgs="$customBuildArgs --target-rid ${{ parameters.targetRid }}"
- fi
-
- if [[ -n "${{ parameters.crossRootFs }}" ]]; then
- customEnvVars="$customEnvVars ROOTFS_DIR=${{ parameters.crossRootFs}}"
- if [[ '${{ parameters.targetArchitecture }}' != 'wasm' ]]; then
- extraBuildProperties="$extraBuildProperties /p:CrossBuild=true"
- fi
- fi
-
- # Temporarily enable core dump generation to diagnose https://github.com/dotnet/source-build/issues/5288
- if [[ '${{ parameters.enableCoreDumpGeneration }}' == 'True' ]]; then
- echo "$(sourcesPath)artifacts/log/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
- ulimit -c unlimited
- fi
-
- buildArgs="$(additionalBuildArgs) $customBuildArgs $extraBuildProperties"
-
- for envVar in $customEnvVars; do
- customEnvVarsWithBashSyntax="$customEnvVarsWithBashSyntax export $envVar;"
- done
-
- eval $customEnvVarsWithBashSyntax
- $customPreBuildArgs ./build.sh $buildArgs
- displayName: Build
- workingDirectory: $(sourcesPath)
- ${{ if eq(parameters.sign, 'true') }}:
- env:
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
-
- - ${{ if ne(parameters.runOnline, 'True' )}}:
- - script: |
- set -ex
- # Update the owner of the staging directory to the current user
- sudo chown -R $(whoami) $(Build.ArtifactStagingDirectory)
- displayName: Update owner of artifacts staging directory
-
- # Only run tests if enabled
- - ${{ if eq(parameters.runTests, 'True') }}:
- - ${{ parameters.testInitSteps }}
-
- # Setup the NuGet sources used by the tests to use private feeds. This is necessary when testing internal-only product
- # builds where the packages are only available in the private feeds. This allows the tests to restore from those feeds.
- - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - task: Bash@3
- displayName: Setup Private Feeds Credentials
- inputs:
- filePath: $(sourcesPath)/src/sdk/eng/common/SetupNugetSources.sh
- arguments: $(sourcesPath)/src/sdk/NuGet.config $Token
- env:
- Token: $(dn-bot-dnceng-artifact-feeds-rw)
-
- - script: cp "$(sourcesPath)/src/sdk/NuGet.config" "$(sourcesPath)/test/Microsoft.DotNet.SourceBuild.Tests/assets/online.NuGet.Config"
- displayName: Copy Test NuGet Config for Smoke Tests
-
- - script: |
- set -ex
-
- customPreBuildArgs=''
- customBuildArgs="--test --excludeCIBinarylog /bl:artifacts/log/Release/Test.binlog $(baseArguments)"
- extraBuildProperties="$(baseProperties) /p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory) $(targetProperties) ${{ parameters.extraProperties }}"
-
- if [[ '${{ parameters.runOnline }}' == 'False' ]]; then
- customPreBuildArgs="$customPreBuildArgs sudo"
- fi
-
- if [[ '${{ parameters.buildSourceOnly }}' == 'True' ]]; then
- if [[ '${{ parameters.enablePoison }}' == 'True' ]]; then
- customBuildArgs="$customBuildArgs --poison"
- fi
- customBuildArgs="$customBuildArgs --source-only"
- fi
-
- if [[ -n "${{ parameters.targetRid }}" ]]; then
- customBuildArgs="$customBuildArgs --target-rid ${{ parameters.targetRid }}"
- fi
-
- buildArgs="$(additionalBuildArgs) $customBuildArgs $extraBuildProperties"
- buildArgs=$(echo $buildArgs | xargs) # Remove extra spaces
-
- cd $(sourcesPath)
- $customPreBuildArgs ./build.sh $buildArgs
-
- displayName: Run Tests
- timeoutInMinutes: ${{ variables.runTestsTimeout }}
-
- - ${{ if and(eq(parameters.sign, 'True'), ne(parameters.buildSourceOnly, 'True'), eq(variables['System.TeamProject'], 'internal')) }}:
- - template: ${{ variables['Build.SourcesDirectory'] }}/eng/common/core-templates/steps/cleanup-microbuild.yml
- parameters:
- enableMicrobuild: true
- enableMicrobuildForMacAndLinux: true
-
- - task: CopyFiles@2
- displayName: Prepare BuildLogs staging directory
- inputs:
- SourceFolder: '$(sourcesPath)'
- Contents: |
- artifacts/log/**
- artifacts/TestResults/**/*.binlog
- artifacts/TestResults/**/*.diff
- artifacts/TestResults/**/Updated*.txt
- artifacts/TestResults/**/*.trx
- artifacts/TestResults/**/*.xml
- TargetFolder: '$(Build.ArtifactStagingDirectory)/BuildLogs'
- CleanTargetFolder: true
- continueOnError: true
- condition: succeededOrFailed()
-
- - task: CopyFiles@2
- displayName: Copy unmerged artifacts to staging directory
- inputs:
- SourceFolder: '$(sourcesPath)/artifacts'
- Contents: |
- packages/**/*
- assets/**/*
- obj/manifests/**/*
- TargetFolder: '$(artifactsPrepublishDir)'
- CleanTargetFolder: true
- condition: failed()
- continueOnError: true
-
- - ${{ if or(ne(variables['System.TeamProject'], 'internal'), eq(variables['Build.Reason'], 'PullRequest')) }}:
- - publish: $(Build.ArtifactStagingDirectory)/BuildLogs
- artifact: $(Agent.JobName)_BuildLogs_Attempt$(System.JobAttempt)
- displayName: Publish BuildLogs
- continueOnError: true
- condition: always()
-
- # Only upload test results if enabled
- - ${{ if eq(parameters.runTests, 'True') }}:
- - task: PublishTestResults@2
- displayName: Publish Test Results
- condition: succeededOrFailed()
- continueOnError: true
- inputs:
- testRunner: VSTest
- testResultsFiles: 'artifacts/TestResults/Release/*.trx'
- searchFolder: $(sourcesPath)
- mergeTestResults: true
- publishRunAttachments: true
- testRunTitle: Tests_$(Agent.JobName)
-
- - task: PublishTestResults@2
- displayName: Publish Scenario Test Results
- condition: and(eq(variables['hasScenarioTestResults'], 'true'), succeededOrFailed())
- continueOnError: true
- inputs:
- testRunner: xUnit
- testResultsFiles: 'artifacts/TestResults/**/scenario-tests/*.xml'
- searchFolder: $(sourcesPath)
- mergeTestResults: true
- publishRunAttachments: true
- testRunTitle: ScenarioTests_$(Agent.JobName)
-
- - ${{ if or(ne(variables['System.TeamProject'], 'internal'), eq(variables['Build.Reason'], 'PullRequest')) }}:
- # Both publishing steps are necessary to ensure artifacts are published on both success and failure.
- # This prevents overwrite conflicts in the event of a failed build followed by a rerun.
- # Additionally, the 'Download Previous Build *' steps depend on a fixed name to acquire specific assets in multi-stage builds.
- - publish: $(Build.ArtifactStagingDirectory)/artifacts
- artifact: $(successfulJobArtifactName)
- displayName: Publish Artifacts (On Success)
- condition: succeeded()
- continueOnError: true
-
- - publish: $(artifactsPrepublishDir)
- artifact: $(failedJobArtifactName)
- displayName: Publish Artifacts (On Failure)
- condition: failed()
- continueOnError: true
-
- # Using build artifacts to enable publishing the vertical manifests to a single artifact from different jobs
- - ${{ if ne(parameters.buildSourceOnly, true) }}:
- - task: PublishBuildArtifacts@1
- inputs:
- PathtoPublish: $(Build.ArtifactStagingDirectory)/artifacts/manifests/${{ parameters.configuration }}/$(Agent.JobName).xml
- ArtifactName: VerticalManifests
- displayName: Publish Vertical Manifest
+### This job builds https://github.com/dotnet/dotnet with given parameters
+### If run in an sdk PR, new changes are applied to a local copy of the VMR, then it is built and tested
+
+parameters:
+- name: artifactsRid
+ type: string
+ default: ''
+
+- name: buildName
+ type: string
+
+- name: buildPass
+ type: string
+ default: ''
+
+- name: configuration
+ type: string
+ default: 'Release'
+
+- name: container
+ type: object
+ default:
+ image: ''
+ name: ''
+
+- name: crossRootFs
+ type: string
+ default: ''
+
+- name: pool
+ type: object
+
+- name: targetOS
+ type: string
+ default: ''
+
+- name: targetArchitecture
+ type: string
+ default: ''
+
+- name: useMonoRuntime
+ displayName: True when build output uses the mono runtime
+ type: boolean
+ default: false
+
+- name: sign
+ displayName: True when build output should be signed (includes dry runs)
+ type: boolean
+ default: false
+
+- name: signType
+ displayName: Signing type
+ type: string
+ default: ''
+
+- name: signDac
+ displayName: True when the diagnostic files should be signed
+ type: boolean
+ default: false
+
+# Overrides the rid that is produced by the build.
+- name: targetRid
+ type: string
+ default: ''
+
+# Enables IBC data on when building internally.
+- name: enableIBCOptimization
+ type: boolean
+ default: false
+
+# Name of previous job(s) (from the same template as this) whose output will be used to build this job
+# The SDK from its artifacts is copied to $(sourcesPath)/.dotnet
+- name: reuseBuildArtifactsFrom
+ type: object
+ default: ''
+
+# Enables usage of the system libraries when building.
+- name: useSystemLibraries
+ type: boolean
+ default: false
+
+# Indicates whether to runtime dependent jobs are excluded in the build (this occurs for non-1xx branches).
+- name: excludeRuntimeDependentJobs
+ type: boolean
+ default: false
+
+#### SOURCE-ONLY parameters ####
+
+# Instead of building the VMR directly, exports the sources into a tarball and builds from that
+- name: buildFromArchive
+ type: boolean
+ default: false
+
+# Enable for source-building the VMR
+- name: buildSourceOnly
+ type: boolean
+ default: false
+
+- name: enablePoison
+ type: boolean
+ default: false
+
+# Allow downloading artifacts from the internet during the build
+- name: runOnline
+ type: boolean
+ default: true
+
+- name: runTests
+ type: boolean
+ default: true
+
+# Freeform field for extra values to pass to build.sh for special build modes
+- name: extraProperties
+ type: string
+ default: ''
+
+# Use the previous version's SDK to build the current one
+- name: withPreviousSDK
+ type: boolean
+ default: false
+
+# Create and publish the source artifact
+- name: createSourceArtifact
+ type: boolean
+ default: false
+
+# Skip the build step (this would be used when wanting to run tests only)
+- name: skipBuild
+ type: boolean
+ default: false
+
+# Custom steps to run before running tests
+- name: testInitSteps
+ type: stepList
+ default: []
+
+#### repo parameters ####
+
+- name: isBuiltFromVmr
+ displayName: True when build is running from dotnet/dotnet directly
+ type: boolean
+
+jobs:
+- job: ${{ parameters.buildName }}_${{ parameters.targetArchitecture }}${{ replace(format('_BuildPass{0}', coalesce(parameters.buildPass, '1')), '_BuildPass1', '') }}
+ pool: ${{ parameters.pool }}
+
+ # 1ES pipeline template requires that the container is specified in the job level.
+ # If we are using a container image, we set the container to correct name.
+ # Otherwise, we set the container to host so that the job runs on the host agent.
+ ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ ${{ if ne(parameters.container.name, '') }}:
+ container: ${{ parameters.container.name }}
+ ${{ else }}:
+ container: host
+
+ # For public projects, we always use the container image if it is specified.
+ ${{ else }}:
+ ${{ if ne(parameters.container.image, '') }}:
+ container:
+ image: ${{ parameters.container.image }}
+ options: $(defaultContainerOptions)
+
+ ${{ if ne(parameters.reuseBuildArtifactsFrom, '') }}:
+ ${{ if eq(parameters.buildPass, '') }}:
+ # For PR builds, skip the stage 2 build if the stage 1 build fails.
+ # Otherwise, run the stage 2 build even if the stage 1 build fails so that we can get a complete assessment of the build status.
+ # The build shortcuts when stage 1 build fails and doesn't produce the SDK.
+ ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
+ condition: succeeded()
+ ${{ else }}:
+ condition: succeededOrFailed()
+ ${{ else }}:
+ condition: succeeded()
+ dependsOn:
+ - ${{ if ne(parameters.reuseBuildArtifactsFrom, '') }}:
+ - ${{ parameters.reuseBuildArtifactsFrom }}
+ variables:
+ - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ - group: AzureDevOps-Artifact-Feeds-Pats
+ - ${{ if eq(parameters.enableIBCOptimization, 'true') }}:
+ - group: DotNet-VSTS-Infra-Access
+ - ${{ else }}:
+ - name: BotAccount-dotnet-bot-repo-PAT
+ value: N/A
+ - name: additionalBuildArgs
+ value: ''
+ - name: runTestsTimeout
+ value: 30
+
+ - ${{ if parameters.buildSourceOnly }}:
+ - name: sharedComponentsDir
+ value: $(Agent.TempDirectory)/shared-components
+
+ - ${{ if parameters.isBuiltFromVmr }}:
+ - name: vmrPath
+ value: $(Build.SourcesDirectory)
+ - ${{ else }}:
+ - name: vmrPath
+ value: $(Agent.BuildDirectory)/vmr
+
+ # Location of the VMR sources
+ # We either build the repo directly, or we extract them outside (which is what partners do)
+ - ${{ if parameters.buildFromArchive }}:
+ - name: sourcesPath
+ value: $(Agent.TempDirectory)/dotnet-sources/
+ - ${{ else }}:
+ - name: sourcesPath
+ value: $(vmrPath)
+
+ - name: artifactsStagingDir
+ value: $(Build.ArtifactStagingDirectory)/artifacts
+
+ - name: artifactsPrepublishDir
+ value: $(Build.ArtifactStagingDirectory)/prepublish
+
+ - name: successfulJobArtifactName
+ value: $(Agent.JobName)_Artifacts
+
+ - name: failedJobArtifactName
+ value: $(successfulJobArtifactName)_Attempt$(System.JobAttempt)
+
+ # manually disable CodeQL until https://dev.azure.com/mseng/1ES/_workitems/edit/2211548 is implemented
+ # CodeQL doesn't work on arm64 macOS, see https://portal.microsofticm.com/imp/v5/incidents/details/532165079/summary
+ - ${{ if eq(parameters.pool.os, 'macOS') }}:
+ - name: ONEES_ENFORCED_CODEQL_ENABLED
+ value: false
+
+ # Build up the command line variables. We avoid doing this in the script sections below
+ # because AzDO will not echo command lines if they are more than a single line.
+
+ ## Build command line
+
+ ### Command line prefix
+ - name: commandPrefix
+ ${{ if eq(parameters.targetOS, 'windows') }}:
+ value: '-'
+ ${{ else }}:
+ value: '--'
+
+ ### Basic arguments
+ - name: cleanArgument
+ # Don't clean-while-building on internal builds to keep intermediates for compliance scanners.
+ ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ value: ''
+ ${{ else }}:
+ ${{ if eq(parameters.targetOS, 'windows') }}:
+ value: $(commandPrefix)cleanWhileBuilding
+ ${{ else }}:
+ value: $(commandPrefix)clean-while-building
+
+ - name: brandingArgument
+ ${{ if ne(variables['brandingType'], '') }}:
+ value: $(commandPrefix)branding $(brandingType)
+ ${{ else }}:
+ value: ''
+
+ - ${{ if and(eq(variables['System.TeamProject'], 'internal'), notin(variables['Build.Reason'], 'PullRequest')) }}:
+ - name: officialBuildArgument
+ ${{ if eq(parameters.targetOS, 'windows') }}:
+ value: $(commandPrefix)officialBuildId $(Build.BuildNumber)
+ ${{ else }}:
+ value: $(commandPrefix)official-build-id $(Build.BuildNumber)
+ - ${{ else }}:
+ - name: officialBuildArgument
+ value: ''
+
+ - name: useSystemLibrariesArgument
+ ${{ if eq(parameters.useSystemLibraries, 'true') }}:
+ # Do not use all (or include libunwind) because of the issues described in https://github.com/dotnet/source-build/issues/5288
+ value: $(commandPrefix)with-system-libs brotli+rapidjson+zlib
+ ${{ else }}:
+ value: ''
+
+ - name: baseArguments
+ value: $(commandPrefix)ci $(cleanArgument) $(commandPrefix)prepareMachine -c ${{ parameters.configuration }} $(brandingArgument) $(useSystemLibrariesArgument) $(officialBuildArgument)
+
+ - name: baseProperties
+ value: $(officialBuildProperties) /p:VerticalName=$(Agent.JobName)
+
+ - name: targetProperties
+ ${{ if and(ne(parameters.targetOS, ''), ne(parameters.targetArchitecture, '')) }}:
+ value: -os ${{ parameters.targetOS }} -arch ${{ parameters.targetArchitecture }}
+ ${{ elseif ne(parameters.targetOS, '') }}:
+ value: -os ${{ parameters.targetOS }}
+ ${{ else }}:
+ value: -arch ${{ parameters.targetArchitecture }}
+
+ ### Signing
+ - name: _SignDiagnosticFilesArgs
+ value: ''
+ - ${{ if eq(parameters.sign, 'True') }}:
+ - name: signArguments
+ value: $(commandPrefix)sign
+ # MB test signing is not supported on non-Windows platforms for now.
+ # In those cases, force to dryrun.
+ - ${{ if or(eq(parameters.signType, 'DryRun'), and(ne(parameters.targetOS, 'windows'), eq(parameters.signType, 'Test'))) }}:
+ # The _SignType variable is used by microbuild installation
+ - name: _SignType
+ value: ''
+ - name: signProperties
+ value: /p:ForceDryRunSigning=true
+ - ${{ else }}:
+ - name: _SignType
+ value: ${{ parameters.signType }}
+ - name: signProperties
+ value: /p:DotNetSignType=${{ parameters.signType }} /p:TeamName=$(_TeamName)
+ - ${{ else }}:
+ - name: signArguments
+ value: ''
+ - name: signProperties
+ value: ''
+ - name: _SignType
+ value: ''
+
+ ### Build Pass
+ - ${{ if ne(parameters.buildPass, '') }}:
+ - name: buildPassProperties
+ value: /p:DotNetBuildPass=${{ parameters.buildPass }}
+ - ${{ else }}:
+ - name: buildPassProperties
+ value: ''
+
+ ### Additional properties
+ - ${{ if eq(parameters.enableIBCOptimization, 'true') }}:
+ - name: ibcProperties
+ value: '/p:EnableIBCOptimization=true /p:IBCDropAccessToken=$(dn-bot-devdiv-drop-r-code-r)'
+ - ${{ else }}:
+ - name: ibcProperties
+ value: ''
+
+ # Timeout
+ ## Real signing takes a while - increase the timeout to allow for that
+ ${{ if eq(variables['_SignType'], 'real') }}:
+ timeoutInMinutes: 720
+ ## Currently, CodeQL slows the build down too much
+ ## https://github.com/dotnet/source-build/issues/4276
+ ${{ elseif and(parameters.isBuiltFromVmr, eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}:
+ timeoutInMinutes: 720
+ ${{ elseif and(startswith(parameters.buildName, 'OSX'), ne(variables['System.TeamProject'], 'internal')) }}:
+ timeoutInMinutes: 360
+ ${{ else }}:
+ timeoutInMinutes: 240
+
+ templateContext:
+ outputParentDirectory: $(Build.ArtifactStagingDirectory)
+ outputs:
+ - output: pipelineArtifact
+ displayName: Publish BuildLogs
+ condition: succeededOrFailed()
+ targetPath: $(Build.ArtifactStagingDirectory)/BuildLogs
+ artifactName: $(Agent.JobName)_BuildLogs_Attempt$(System.JobAttempt)
+ sbomEnabled: false
+
+ # Both publishing steps are necessary to ensure artifacts are published on both success and failure.
+ # This prevents overwrite conflicts in the event of a failed build followed by a rerun.
+ # Additionally, the 'Download Previous Build *' steps depend on a fixed name to acquire specific assets in multi-stage builds.
+ - output: pipelineArtifact
+ path: $(Build.ArtifactStagingDirectory)/artifacts
+ artifact: $(successfulJobArtifactName)
+ displayName: Publish Artifacts (On Success)
+ condition: succeeded()
+ sbomEnabled: true
+
+ - output: pipelineArtifact
+ path: $(artifactsPrepublishDir)
+ artifact: $(failedJobArtifactName)
+ displayName: Publish Artifacts (On Failure)
+ condition: failed()
+ continueOnError: true
+ sbomEnabled: true
+
+ # Using build artifacts to enable publishing the vertical manifests to a single artifact from different jobs
+ - ${{ if ne(parameters.buildSourceOnly, true) }}:
+ - output: buildArtifacts
+ PathtoPublish: $(Build.ArtifactStagingDirectory)/artifacts/manifests/${{ parameters.configuration }}/$(Agent.JobName).xml
+ ArtifactName: VerticalManifests
+ displayName: Publish Vertical Manifest
+ sbomEnabled: false
+
+ steps:
+ - checkout: self
+ fetchDepth: 1
+
+ - ${{ if not(parameters.isBuiltFromVmr) }}:
+ # Synchronize new content in the VMR during PRs
+ - template: /eng/common/templates/steps/vmr-sync.yml@self
+ parameters:
+ vmrPath: $(vmrPath)
+ targetRef: $(Build.SourceVersion) # Synchronize the current repo commit
+
+ - ${{ if parameters.buildFromArchive }}:
+ - script: |
+ set -ex
+ cp -r "$(vmrPath)" "$(sourcesPath)"
+ rm -rf "$(sourcesPath)/.git"
+ displayName: Export VMR sources
+ workingDirectory: $(Build.ArtifactStagingDirectory)
+
+ - ${{ if ne(parameters.reuseBuildArtifactsFrom,'') }}:
+ - ${{ each reuseBuildArtifacts in parameters.reuseBuildArtifactsFrom }}:
+ - ${{ if eq(parameters.buildSourceOnly, true) }}:
+ - template: ../steps/download-artifacts.yml
+ parameters:
+ artifactDescription: Previous Build (${{ reuseBuildArtifacts }} - Source Build artifacts)
+ artifactName: ${{ reuseBuildArtifacts }}_Artifacts
+ downloadFilePatterns: |
+ assets/*/Private.SourceBuilt.Artifacts.*.tar.gz
+ assets/*/dotnet-sdk-*.tar.gz
+ copyDestination: $(sourcesPath)/prereqs/packages/archive/
+ flattenDirs: true
+
+ - ${{ else }}:
+ - task: DownloadPipelineArtifact@2
+ inputs:
+ artifactName: ${{ reuseBuildArtifacts }}_Artifacts
+ targetPath: $(sourcesPath)/artifacts/
+ displayName: Download Previous Build (${{ reuseBuildArtifacts }})
+
+ - ${{ if eq(parameters.withPreviousSDK, 'true') }}:
+ - script: |
+ source "$(sourcesPath)/eng/download-source-built-archive.sh"
+ DownloadArchive "source-built SDK" "PrivateSourceBuiltSdkVersion" false "${{ parameters.artifactsRid }}" "$(sourcesPath)/prereqs/packages/archive/"
+ displayName: Download Previously Source-Built SDK
+
+ - template: /eng/common/templates/steps/enable-internal-runtimes.yml
+
+ - ${{ if and(parameters.excludeRuntimeDependentJobs, eq(parameters.reuseBuildArtifactsFrom, ''), not(parameters.withPreviousSDK)) }}:
+ - script: |
+ source "$(sourcesPath)/eng/download-source-built-archive.sh"
+ if [[ $SYSTEM_TEAMPROJECT == "internal" ]]; then
+ storageKey="$(dotnetbuilds-internal-container-read-token-base64)"
+ else
+ storageKey=""
+ fi
+ # Download the 1xx source-built SDK
+ DownloadArchive "1xx source-built SDK" "PrivateSourceBuiltSdkVersion" false "${{ parameters.artifactsRid }}" "$(sourcesPath)/prereqs/packages/archive/" "" "" $storageKey
+ displayName: Download 1xx SDK
+
+ - ${{ if parameters.excludeRuntimeDependentJobs }}:
+ - script: |
+ source "$(sourcesPath)/eng/download-source-built-archive.sh"
+ if [[ $SYSTEM_TEAMPROJECT == "internal" ]]; then
+ storageKey="$(dotnetbuilds-internal-container-read-token-base64)"
+ else
+ storageKey=""
+ fi
+ mkdir -p "$(sharedComponentsDir)"
+ DownloadArchive "shared component artifacts" "PrivateSourceBuiltArtifactsVersion" false "${{ parameters.artifactsRid }}" "$(sharedComponentsDir)" "Private.SourceBuilt.SharedComponents" "MicrosoftNETSdkPackageVersion" $storageKey
+ tar -xzf $(sharedComponentsDir)/Private.SourceBuilt.SharedComponents.*.tar.gz -C "$(sharedComponentsDir)"
+ rm -f $(sharedComponentsDir)/Private.SourceBuilt.SharedComponents.*.tar.gz
+ displayName: Download Shared Component Artifacts
+
+ - ${{ if and(eq(parameters.sign, 'True'), ne(parameters.signType, 'DryRun')) }}:
+ - template: ${{ variables['Build.SourcesDirectory'] }}/eng/common/core-templates/steps/install-microbuild.yml
+ parameters:
+ enableMicrobuild: true
+ enableMicrobuildForMacAndLinux: true
+ ${{ if ne(parameters.signType, 'Real') }}:
+ microbuildUseESRP: false
+
+ # When building internal, authenticate to internal feeds that may be in use
+ # We do not need these for source-only builds
+ - ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(parameters.buildSourceOnly, 'True')) }}:
+ # Authenticate with service connections to be able to pull packages to external nuget feeds.
+ - task: NuGetAuthenticate@1
+ inputs:
+ nuGetServiceConnections: devdiv/engineering, devdiv/dotnet-core-internal-tooling
+
+ - ${{ if eq(parameters.targetOS, 'windows') }}:
+ # Node 20.x is a toolset dependency to build aspnetcore
+ # Keep in sync with aspnetcore: https://github.com/dotnet/aspnetcore/blob/7d5309210d8f7bae8fa074da495e9d009d67f1b4/.azure/pipelines/ci.yml#L719-L722
+ - task: NodeTool@0
+ displayName: Install Node 20.x
+ inputs:
+ versionSpec: 20.x
+
+ - ${{ if eq(parameters.signDac, 'true') }}:
+ # TODO: Once we turn off the dotnet/runtime official build, move these templates into the VMR's eng folder.
+ - template: ../steps/setup-diagnostics-esrp.yml@self
+ parameters:
+ isOfficialBuild: true
+ serviceConnectionGuid: 0a3b81f8-02bd-434b-960a-1e45cfcca801
+ serviceConnectionName: 'diagnostics-esrp-kvcertuser-pme'
+ scriptRoot: '${{ variables.sourcesPath }}/src/runtime/eng/native/signing'
+
+
+ - script: build.cmd
+ $(baseArguments)
+ $(signArguments)
+ $(baseProperties)
+ /p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory)
+ $(targetProperties)
+ $(signProperties)
+ $(buildPassProperties)
+ $(ibcProperties)
+ $(_SignDiagnosticFilesArgs)
+ ${{ parameters.extraProperties }}
+ displayName: Build
+ workingDirectory: ${{ variables.sourcesPath }}
+ ${{ if eq(parameters.sign, 'true') }}:
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ ${{ if eq(parameters.signDac, 'true') }}:
+ ESRP_TOKEN: $(System.AccessToken)
+
+ - ${{ if eq(parameters.runTests, 'True') }}:
+ - script: build.cmd
+ $(baseArguments)
+ $(targetProperties)
+ $(buildPassProperties)
+ ${{ parameters.extraProperties }}
+ -test
+ -excludeCIBinarylog
+ /bl:artifacts/log/Release/Test.binlog
+ displayName: Run Tests
+ workingDirectory: ${{ variables.sourcesPath }}
+ timeoutInMinutes: ${{ variables.runTestsTimeout }}
+
+ - ${{ else }}:
+ - ${{ if or(eq(parameters.targetOS, 'osx'), eq(parameters.targetOS, 'ios'), eq(parameters.targetOS, 'iossimulator'), eq(parameters.targetOS, 'tvos'), eq(parameters.targetOS, 'tvossimulator'), eq(parameters.targetOS, 'maccatalyst')) }}:
+ - script: |
+ xcrun simctl runtime delete all
+ displayName: Reclaim disk space from unused simulator runtimes
+ - ${{ if eq(parameters.targetOS, 'osx') }}:
+ - script: |
+ $(sourcesPath)/eng/common/native/install-dependencies.sh osx
+ displayName: Install dependencies
+ - ${{ if eq(parameters.buildSourceOnly, 'true') }}:
+ - script: |
+ set -ex
+
+ customPrepArgs="-c ${{ parameters.configuration }}"
+ prepSdk=true
+
+ if [[ '${{ parameters.excludeRuntimeDependentJobs }}' == 'True' ]]; then
+ prepSdk=false
+ fi
+
+ if [[ '${{ parameters.withPreviousSDK }}' == 'True' ]]; then
+ # Using source-built SDK implies we do not want to bootstrap.
+ customPrepArgs="${customPrepArgs} --no-bootstrap"
+ prepSdk=false
+ elif [[ '${{ length(parameters.reuseBuildArtifactsFrom) }}' -gt '0' ]]; then
+ customPrepArgs="${customPrepArgs} --no-artifacts"
+ prepSdk=false
+ fi
+
+ if [[ "$prepSdk" == "false" ]]; then
+ customPrepArgs="${customPrepArgs} --no-sdk"
+ rm -rf $(sourcesPath)/.dotnet
+ mkdir $(sourcesPath)/.dotnet
+ previousSdkPath="$(sourcesPath)/prereqs/packages/archive/dotnet-sdk-*.tar.gz"
+ eval tar -ozxf "$previousSdkPath" -C "$(sourcesPath)/.dotnet"
+ eval rm -f "$previousSdkPath"
+
+ echo "##vso[task.setvariable variable=additionalBuildArgs]--with-sdk $(sourcesPath)/.dotnet"
+ fi
+
+ ./prep-source-build.sh $customPrepArgs
+ displayName: Prep the Build
+ workingDirectory: $(sourcesPath)
+
+ - ${{ if ne(parameters.skipBuild, 'true') }}:
+
+ - script: |
+ set -ex
+ df -h
+
+ customEnvVars=""
+ customPreBuildArgs=""
+ customBuildArgs="$(baseArguments)"
+ extraBuildProperties="$(baseProperties) /p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory) $(targetProperties) $(buildPassProperties) ${{ parameters.extraProperties }}"
+
+ if [[ '${{ parameters.buildSourceOnly }}' != 'True' ]]; then
+ # We shouldn't pass signing arguments to the build script when building source-only
+ # because signing source-built artifacts happens post-build.
+ customBuildArgs="$customBuildArgs $(signArguments) $(_SignDiagnosticFilesArgs)"
+ extraBuildProperties="$extraBuildProperties $(signProperties)"
+ else
+ customBuildArgs="$customBuildArgs --source-only"
+ extraBuildProperties="$extraBuildProperties /p:ReportSbrpUsage=true"
+ if [[ '${{ parameters.sign }}' == 'True' ]]; then
+ # Set up for signing source-built artifacts post-build.
+ extraBuildProperties="$extraBuildProperties /p:DotNetSourceOnlyPostBuildSign=true"
+ fi
+
+ if [[ '${{ parameters.excludeRuntimeDependentJobs }}' == 'True' ]]; then
+ customBuildArgs="$customBuildArgs --with-shared-components $(sharedComponentsDir)"
+ fi
+ fi
+
+ if [[ '${{ parameters.runOnline }}' == 'True' ]]; then
+ customBuildArgs="$customBuildArgs --online"
+ else
+ customPreBuildArgs="$customPreBuildArgs sudo -E unshare -n"
+ fi
+
+ if [[ '${{ parameters.enablePoison }}' == 'True' ]]; then
+ customBuildArgs="$customBuildArgs --poison"
+ fi
+
+ if [[ '${{ parameters.buildFromArchive }}' == 'True' ]]; then
+ customBuildArgs="$customBuildArgs --source-repository https://github.com/dotnet/dotnet"
+ customBuildArgs="$customBuildArgs --source-version $(git -C "$(vmrPath)" rev-parse HEAD)"
+ if [[ '${{ parameters.createSourceArtifact }}' == 'True' ]]; then
+ # Do not enable source artifact creation when not building from a git repo.
+ # We strip the .git/ directory when building from archive,
+ # so it's not possible to create the artifact in that mode.
+ echo "Cannot create source artifact when building from archive."
+ exit 1
+ fi
+ fi
+
+ if [[ '${{ parameters.createSourceArtifact }}' == 'True' ]]; then
+ extraBuildProperties="$extraBuildProperties /p:CreateSourceArtifact=true"
+ fi
+
+ if [[ '${{ parameters.useMonoRuntime }}' == 'True' ]]; then
+ customBuildArgs="$customBuildArgs --use-mono-runtime"
+ fi
+
+ if [[ -n "${{ parameters.targetRid }}" ]]; then
+ customBuildArgs="$customBuildArgs --target-rid ${{ parameters.targetRid }}"
+ fi
+
+ if [[ -n "${{ parameters.crossRootFs }}" ]]; then
+ customEnvVars="$customEnvVars ROOTFS_DIR=${{ parameters.crossRootFs}}"
+ if [[ '${{ parameters.targetArchitecture }}' != 'wasm' ]]; then
+ extraBuildProperties="$extraBuildProperties /p:CrossBuild=true"
+ fi
+ fi
+
+ buildArgs="$(additionalBuildArgs) $customBuildArgs $extraBuildProperties"
+
+ for envVar in $customEnvVars; do
+ customEnvVarsWithBashSyntax="$customEnvVarsWithBashSyntax export $envVar;"
+ done
+
+ eval $customEnvVarsWithBashSyntax
+ $customPreBuildArgs ./build.sh $buildArgs
+ displayName: Build
+ workingDirectory: $(sourcesPath)
+ ${{ if eq(parameters.sign, 'true') }}:
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+
+ - ${{ if ne(parameters.runOnline, 'True' )}}:
+ - script: |
+ set -ex
+ # Update the owner of the staging directory to the current user
+ sudo chown -R $(whoami) $(Build.ArtifactStagingDirectory)
+ displayName: Update owner of artifacts staging directory
+
+ # Only run tests if enabled
+ - ${{ if eq(parameters.runTests, 'True') }}:
+ - ${{ parameters.testInitSteps }}
+
+ # Setup the NuGet sources used by the tests to use private feeds. This is necessary when testing internal-only product
+ # builds where the packages are only available in the private feeds. This allows the tests to restore from those feeds.
+ - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ - task: Bash@3
+ displayName: Setup Private Feeds Credentials
+ inputs:
+ filePath: $(sourcesPath)/src/sdk/eng/common/SetupNugetSources.sh
+ arguments: $(sourcesPath)/src/sdk/NuGet.config $Token
+ env:
+ Token: $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - script: cp "$(sourcesPath)/src/sdk/NuGet.config" "$(sourcesPath)/test/Microsoft.DotNet.SourceBuild.Tests/assets/online.NuGet.Config"
+ displayName: Copy Test NuGet Config for Smoke Tests
+
+ - script: |
+ set -ex
+
+ customPreBuildArgs=''
+ customBuildArgs="--test --excludeCIBinarylog /bl:artifacts/log/Release/Test.binlog $(baseArguments)"
+ extraBuildProperties="$(baseProperties) /p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory) $(targetProperties) ${{ parameters.extraProperties }}"
+
+ if [[ '${{ parameters.runOnline }}' == 'False' ]]; then
+ customPreBuildArgs="$customPreBuildArgs sudo"
+ fi
+
+ if [[ '${{ parameters.buildSourceOnly }}' == 'True' ]]; then
+ if [[ '${{ parameters.enablePoison }}' == 'True' ]]; then
+ customBuildArgs="$customBuildArgs --poison"
+ fi
+ customBuildArgs="$customBuildArgs --source-only"
+ fi
+
+ if [[ -n "${{ parameters.targetRid }}" ]]; then
+ customBuildArgs="$customBuildArgs --target-rid ${{ parameters.targetRid }}"
+ fi
+
+ buildArgs="$(additionalBuildArgs) $customBuildArgs $extraBuildProperties"
+ buildArgs=$(echo $buildArgs | xargs) # Remove extra spaces
+
+ cd $(sourcesPath)
+ $customPreBuildArgs ./build.sh $buildArgs
+
+ displayName: Run Tests
+ timeoutInMinutes: ${{ variables.runTestsTimeout }}
+
+ - ${{ if eq(parameters.sign, 'True') }}:
+ - ${{ if eq(parameters.buildSourceOnly, 'true') }}:
+ - script: |
+ sign_properties="$(signProperties) $(_SignDiagnosticFilesArgs)"
+
+ customPreBuildArgs=""
+ if [[ '${{ parameters.runOnline }}' == 'False' ]]; then
+ customPreBuildArgs="sudo -E"
+ export MICROBUILDOUTPUTFOLDEROVERRIDE
+ fi
+
+ $customPreBuildArgs bash -c '
+ set -euo pipefail
+ . eng/common/tools.sh
+ MSBuild eng/sign-source-built-artifacts.proj -restore \
+ "/p:SignProperties='"$sign_properties"'" \
+ "/p:ArtifactsStagingDir=$(Build.ArtifactStagingDirectory)" \
+ "/p:OfficialBuildId=$(Build.BuildNumber)" \
+ "/bl:artifacts/log/outer-sign-source-built-artifacts.binlog"
+ '
+ displayName: Sign Source-Built Artifacts
+ workingDirectory: $(Build.SourcesDirectory)
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+
+ - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
+ - template: ${{ variables['Build.SourcesDirectory'] }}/eng/common/core-templates/steps/cleanup-microbuild.yml
+ parameters:
+ enableMicrobuild: true
+ enableMicrobuildForMacAndLinux: true
+
+ - task: CopyFiles@2
+ displayName: Prepare BuildLogs staging directory
+ inputs:
+ SourceFolder: '$(sourcesPath)'
+ Contents: |
+ artifacts/log/**
+ artifacts/TestResults/**/*.binlog
+ artifacts/TestResults/**/*.diff
+ artifacts/TestResults/**/Updated*.txt
+ artifacts/TestResults/**/*.trx
+ artifacts/TestResults/**/*.xml
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/BuildLogs'
+ CleanTargetFolder: true
+ continueOnError: true
+ condition: succeededOrFailed()
+
+ - task: CopyFiles@2
+ displayName: Copy unmerged artifacts to staging directory
+ inputs:
+ SourceFolder: '$(sourcesPath)/artifacts'
+ Contents: |
+ packages/**/*
+ assets/**/*
+ obj/manifests/**/*
+ TargetFolder: '$(artifactsPrepublishDir)'
+ CleanTargetFolder: true
+ condition: failed()
+ continueOnError: true
+
+ - ${{ if or(ne(variables['System.TeamProject'], 'internal'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ - publish: $(Build.ArtifactStagingDirectory)/BuildLogs
+ artifact: $(Agent.JobName)_BuildLogs_Attempt$(System.JobAttempt)
+ displayName: Publish BuildLogs
+ continueOnError: true
+ condition: always()
+
+ # Only upload test results if enabled
+ - ${{ if eq(parameters.runTests, 'True') }}:
+ - task: PublishTestResults@2
+ displayName: Publish Test Results
+ condition: succeededOrFailed()
+ continueOnError: true
+ inputs:
+ testRunner: VSTest
+ testResultsFiles: 'artifacts/TestResults/Release/*.trx'
+ searchFolder: $(sourcesPath)
+ mergeTestResults: true
+ publishRunAttachments: true
+ testRunTitle: Tests_$(Agent.JobName)
+
+ - task: PublishTestResults@2
+ displayName: Publish Scenario Test Results
+ condition: and(eq(variables['hasScenarioTestResults'], 'true'), succeededOrFailed())
+ continueOnError: true
+ inputs:
+ testRunner: xUnit
+ testResultsFiles: 'artifacts/TestResults/**/scenario-tests/*.xml'
+ searchFolder: $(sourcesPath)
+ mergeTestResults: true
+ publishRunAttachments: true
+ testRunTitle: ScenarioTests_$(Agent.JobName)
+
+ - ${{ if or(ne(variables['System.TeamProject'], 'internal'), eq(variables['Build.Reason'], 'PullRequest')) }}:
+ # Both publishing steps are necessary to ensure artifacts are published on both success and failure.
+ # This prevents overwrite conflicts in the event of a failed build followed by a rerun.
+ # Additionally, the 'Download Previous Build *' steps depend on a fixed name to acquire specific assets in multi-stage builds.
+ - publish: $(Build.ArtifactStagingDirectory)/artifacts
+ artifact: $(successfulJobArtifactName)
+ displayName: Publish Artifacts (On Success)
+ condition: succeeded()
+ continueOnError: true
+
+ - publish: $(artifactsPrepublishDir)
+ artifact: $(failedJobArtifactName)
+ displayName: Publish Artifacts (On Failure)
+ condition: failed()
+ continueOnError: true
+
+ # Using build artifacts to enable publishing the vertical manifests to a single artifact from different jobs
+ - ${{ if ne(parameters.buildSourceOnly, true) }}:
+ - task: PublishBuildArtifacts@1
+ inputs:
+ PathtoPublish: $(Build.ArtifactStagingDirectory)/artifacts/manifests/${{ parameters.configuration }}/$(Agent.JobName).xml
+ ArtifactName: VerticalManifests
+ displayName: Publish Vertical Manifest
\ No newline at end of file
diff --git a/eng/pipelines/templates/stages/source-build-and-validate.yml b/eng/pipelines/templates/stages/source-build-and-validate.yml
index 6d46acfce8f3..758931c0ee98 100644
--- a/eng/pipelines/templates/stages/source-build-and-validate.yml
+++ b/eng/pipelines/templates/stages/source-build-and-validate.yml
@@ -16,10 +16,28 @@ parameters:
type: boolean
default: true
+# True when the build is a build run from the production pipeline
+- name: isOfficialBuild
+ type: boolean
+ default: false
+
+- name: desiredSigning
+ type: string
+ default: ''
+
- name: desiredFinalVersionKind
type: string
default: ''
+# Indicates whether runtime dependent jobs are excluded.
+- name: excludeRuntimeDependentJobs
+ type: boolean
+ default: false
+
+- name: extraProperties
+ type: string
+ default: ''
+
stages:
- stage: VMR_SourceOnly_Build
displayName: VMR Source-Only Build
@@ -28,6 +46,8 @@ stages:
- template: ../variables/vmr-build.yml
parameters:
buildSourceOnly: true
+ isOfficialBuild: ${{ parameters.isOfficialBuild }}
+ desiredSigning: ${{ parameters.desiredSigning }}
desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
jobs:
- ${{ each leg in parameters.legs }}:
@@ -39,21 +59,20 @@ stages:
container:
name: ${{ variables.centOSStreamContainerName }}
image: ${{ variables.centOSStreamContainerImage }}
+ artifactsRid: ${{ variables.centOSStreamX64Rid }}
${{ if ne(leg.reuseBuildArtifactsFrom, '') }}:
reuseBuildArtifactsFrom:
- ${{ format(leg.reuseBuildArtifactsFrom, variables.centOSStreamName) }}
- ${{ if and(contains(leg.buildNameFormat, 'Previous'), eq(leg.targetArchitecture, 'x64')) }}:
- artifactsRid: ${{ variables.centOSStreamX64Rid }}
# Fedora
${{ elseif eq(leg.distro, 'fedora') }}:
buildName: ${{ format(leg.buildNameFormat, variables.fedoraName) }}
container:
name: ${{ variables.fedoraContainerName }}
image: ${{ variables.fedoraContainerImage }}
+ artifactsRid: ${{ variables.fedoraX64Rid }}
${{ if ne(leg.reuseBuildArtifactsFrom, '') }}:
reuseBuildArtifactsFrom:
- ${{ format(leg.reuseBuildArtifactsFrom, variables.fedoraName) }}
- enableCoreDumpGeneration: ${{ leg.enableCoreDumpGeneration }}
# Ubuntu
${{ elseif eq(leg.distro, 'ubuntu') }}:
buildName: ${{ format(leg.buildNameFormat, variables.ubuntuName) }}
@@ -65,6 +84,10 @@ stages:
container:
name: ${{ variables.ubuntuContainerName }}
image: ${{ variables.ubuntuContainerImage }}
+ ${{ if eq(leg.targetArchitecture, 'arm64') }}:
+ artifactsRid: ${{ variables.ubuntuArm64Rid }}
+ ${{ else }}:
+ artifactsRid: ${{ variables.ubuntuX64Rid }}
${{ if ne(leg.reuseBuildArtifactsFrom, '') }}:
reuseBuildArtifactsFrom:
- ${{ format(leg.reuseBuildArtifactsFrom, variables.centOSStreamName) }}
@@ -74,20 +97,22 @@ stages:
container:
name: ${{ variables.almaLinuxContainerName }}
image: ${{ variables.almaLinuxContainerImage }}
+ artifactsRid: ${{ variables.almaLinuxX64Rid }}
+ targetRid: ${{ variables.almaLinuxX64Rid }}
${{ if ne(leg.reuseBuildArtifactsFrom, '') }}:
reuseBuildArtifactsFrom:
- ${{ format(leg.reuseBuildArtifactsFrom, variables.centOSStreamName) }}
- targetRid: ${{ variables.almaLinuxX64Rid }}
# Alpine
${{ elseif eq(leg.distro, 'alpine') }}:
buildName: ${{ format(leg.buildNameFormat, variables.alpineName) }}
container:
name: ${{ variables.alpineContainerName }}
image: ${{ variables.alpineContainerImage }}
+ artifactsRid: ${{ variables.alpineX64Rid }}
+ targetRid: ${{ variables.alpineX64Rid }}
${{ if ne(leg.reuseBuildArtifactsFrom, '') }}:
reuseBuildArtifactsFrom:
- ${{ format(leg.reuseBuildArtifactsFrom, variables.centOSStreamName) }}
- targetRid: ${{ variables.alpineX64Rid }}
targetArchitecture: ${{ leg.targetArchitecture }}
isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
@@ -104,10 +129,17 @@ stages:
useMonoRuntime: ${{ leg.useMonoRuntime }}
useSystemLibraries: ${{ leg.useSystemLibraries }}
withPreviousSDK: ${{ leg.withPreviousSDK }}
+ createSourceArtifact: ${{ leg.createSourceArtifact }}
+ ${{ if eq(leg.disableSigning, false) }}:
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ excludeRuntimeDependentJobs: ${{ parameters.excludeRuntimeDependentJobs }}
# We only want to publish SB artifacts for each distinct distro/version/arch combination
${{ if and(endsWith(leg.buildNameFormat, 'Offline_MsftSdk'), not(contains(leg.buildNameFormat, '_Mono_'))) }}:
- extraProperties: /p:DotNetSourceOnlyPublishArtifacts=true
+ extraProperties: ${{ leg.extraProperties }} /p:DotNetSourceOnlyPublishArtifacts=true
+ ${{ else }}:
+ extraProperties: ${{ leg.extraProperties }}
- ${{ if and(parameters.isBuiltFromVmr, ne(variables['Build.Reason'], 'PullRequest'), eq(parameters.useMicrosoftBuildAssetsForTests, true)) }}:
- stage: VMR_SourceOnly_Validation
@@ -130,12 +162,14 @@ stages:
container:
name: ${{ variables.centOSStreamContainerName }}
image: ${{ variables.centOSStreamContainerImage }}
+ artifactsRid: ${{ variables.centOSStreamX64Rid }}
# Fedora
${{ elseif eq(leg.distro, 'fedora') }}:
buildName: ${{ format(leg.buildNameFormat, variables.fedoraName) }}_Validation
container:
name: ${{ variables.fedoraContainerName }}
image: ${{ variables.fedoraContainerImage }}
+ artifactsRid: ${{ variables.fedoraX64Rid }}
# Ubuntu
${{ elseif eq(leg.distro, 'ubuntu') }}:
buildName: ${{ format(leg.buildNameFormat, variables.ubuntuName) }}_Validation
@@ -143,16 +177,19 @@ stages:
container:
name: ${{ variables.ubuntuArmContainerName }}
image: ${{ variables.ubuntuArmContainerImage }}
+ artifactsRid: ${{ variables.ubuntuArm64Rid }}
${{ else }}:
container:
name: ${{ variables.ubuntuContainerName }}
image: ${{ variables.ubuntuContainerImage }}
+ artifactsRid: ${{ variables.ubuntuX64Rid }}
# AlmaLinux
${{ elseif eq(leg.distro, 'almalinux') }}:
buildName: ${{ format(leg.buildNameFormat, variables.almaLinuxName) }}_Validation
container:
name: ${{ variables.almaLinuxContainerName }}
image: ${{ variables.almaLinuxContainerImage }}
+ artifactsRid: ${{ variables.almaLinuxX64Rid }}
targetRid: ${{ variables.almaLinuxX64Rid }}
# Alpine
${{ elseif eq(leg.distro, 'alpine') }}:
@@ -160,6 +197,7 @@ stages:
container:
name: ${{ variables.alpineContainerName }}
image: ${{ variables.alpineContainerImage }}
+ artifactsRid: ${{ variables.alpineX64Rid }}
targetRid: ${{ variables.alpineX64Rid }}
targetArchitecture: ${{ leg.targetArchitecture }}
@@ -174,9 +212,11 @@ stages:
enablePoison: ${{ leg.enablePoison }}
skipBuild: true
extraProperties: >
+ ${{ leg.extraProperties }}
/p:DotNetSourceOnlyTestOnly=true
/p:ExtraRestoreSourcePath=$(Pipeline.Workspace)/msft-pkgs
/p:RestoreAdditionalProjectSources=$(Pipeline.Workspace)/msft-pkgs
+ excludeRuntimeDependentJobs: ${{ parameters.excludeRuntimeDependentJobs }}
testInitSteps:
# Ensure the artifacts staging directory exists so that even if no files get placed there, it won't fail
@@ -199,13 +239,14 @@ stages:
downloadFilePatterns: packages/Release/Shipping/**
copyDestination: $(Pipeline.Workspace)/msft-pkgs
flattenDirs: true
- - template: ../steps/download-artifacts.yml
- parameters:
- artifactDescription: Microsoft WASM Packages
- artifactName: Browser_Shortstack_wasm_Artifacts
- downloadFilePatterns: packages/Release/Shipping/**
- copyDestination: $(Pipeline.Workspace)/msft-pkgs
- flattenDirs: true
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+ - template: ../steps/download-artifacts.yml
+ parameters:
+ artifactDescription: Microsoft WASM Packages
+ artifactName: Browser_Shortstack_wasm_Artifacts
+ downloadFilePatterns: packages/Release/Shipping/**
+ copyDestination: $(Pipeline.Workspace)/msft-pkgs
+ flattenDirs: true
- template: ../steps/download-artifacts.yml
parameters:
artifactDescription: Microsoft Windows Packages
diff --git a/eng/pipelines/templates/stages/source-build-sdk-diff-tests.yml b/eng/pipelines/templates/stages/source-build-sdk-diff-tests.yml
index ed0c074c3e14..1f89f15fbfad 100644
--- a/eng/pipelines/templates/stages/source-build-sdk-diff-tests.yml
+++ b/eng/pipelines/templates/stages/source-build-sdk-diff-tests.yml
@@ -13,7 +13,7 @@ stages:
jobs:
- template: /eng/pipelines/templates/jobs/sdk-diff-tests.yml@self
parameters:
- sbJobName: ${{ format('{0}_Offline_MsftSdk', variables.centOSStreamName) }}
+ sbJobName: ${{ format('SB_{0}_Offline_MsftSdk', variables.centOSStreamName) }}
msftJobName: AzureLinux_x64_Cross
sbTargetRid: ${{ variables.centOSStreamX64Rid }}
msftTargetRid: ${{ variables.linuxX64Rid }}
@@ -23,7 +23,7 @@ stages:
- template: /eng/pipelines/templates/jobs/sdk-diff-tests.yml@self
parameters:
- sbJobName: ${{ format('{0}_Offline_MsftSdk', variables.almaLinuxName) }}
+ sbJobName: ${{ format('SB_{0}_Offline_MsftSdk', variables.almaLinuxName) }}
msftJobName: AzureLinux_x64_Cross
sbTargetRid: ${{ variables.almaLinuxX64Rid }}
msftTargetRid: ${{ variables.linuxX64Rid }}
@@ -32,7 +32,7 @@ stages:
- template: /eng/pipelines/templates/jobs/sdk-diff-tests.yml@self
parameters:
- sbJobName: ${{ format('{0}_Offline_MsftSdk', variables.alpineName) }}
+ sbJobName: ${{ format('SB_{0}_Offline_MsftSdk', variables.alpineName) }}
msftJobName: AzureLinux_x64_Cross_Alpine
sbTargetRid: ${{ variables.alpineX64Rid }}
msftTargetRid: ${{ variables.linuxMuslX64Rid }}
@@ -41,7 +41,7 @@ stages:
- template: /eng/pipelines/templates/jobs/sdk-diff-tests.yml@self
parameters:
- sbJobName: ${{ format('{0}_Offline_MsftSdk', variables.fedoraName) }}
+ sbJobName: ${{ format('SB_{0}_Offline_MsftSdk', variables.fedoraName) }}
msftJobName: AzureLinux_x64_Cross
sbTargetRid: ${{ variables.fedoraX64Rid }}
msftTargetRid: ${{ variables.linuxX64Rid }}
@@ -50,7 +50,7 @@ stages:
- template: /eng/pipelines/templates/jobs/sdk-diff-tests.yml@self
parameters:
- sbJobName: ${{ format('{0}_Offline_MsftSdk', variables.ubuntuName) }}
+ sbJobName: ${{ format('SB_{0}_Offline_MsftSdk', variables.ubuntuName) }}
msftJobName: AzureLinux_x64_Cross
sbTargetRid: ${{ variables.ubuntuX64Rid }}
msftTargetRid: ${{ variables.linuxX64Rid }}
@@ -59,7 +59,7 @@ stages:
- template: /eng/pipelines/templates/jobs/sdk-diff-tests.yml@self
parameters:
- sbJobName: ${{ format('{0}Arm64_Offline_MsftSdk', variables.ubuntuName) }}
+ sbJobName: ${{ format('SB_{0}Arm64_Offline_MsftSdk', variables.ubuntuName) }}
msftJobName: AzureLinux_x64_Cross
sbTargetRid: ${{ variables.ubuntuArm64Rid }}
msftTargetRid: ${{ variables.linuxArm64Rid }}
diff --git a/eng/pipelines/templates/stages/source-build-stages.yml b/eng/pipelines/templates/stages/source-build-stages.yml
index c4a22870fd8c..70141d02aad7 100644
--- a/eng/pipelines/templates/stages/source-build-stages.yml
+++ b/eng/pipelines/templates/stages/source-build-stages.yml
@@ -16,6 +16,8 @@ parameters:
- lite
# run everything
- full
+ # run source build outer loop (Mono jobs)
+ - source-build-outer-loop
- name: useMicrosoftBuildAssetsForTests
type: boolean
@@ -26,6 +28,15 @@ parameters:
type: boolean
default: true
+# True when the build is a build run from the production pipeline
+- name: isOfficialBuild
+ type: boolean
+ default: false
+
+- name: desiredSigning
+ type: string
+ default: ''
+
- name: desiredFinalVersionKind
type: string
default: ''
@@ -35,6 +46,11 @@ parameters:
type: object
default: []
+# Indicates whether runtime dependent jobs are excluded.
+- name: excludeRuntimeDependentJobs
+ type: boolean
+ default: false
+
stages:
- ${{ if or(in(parameters.scope, 'full') , contains(join(';', parameters.verifications), 'source-build-')) }}:
- template: source-build-and-validate.yml
@@ -43,7 +59,10 @@ stages:
pool_LinuxArm64: ${{ parameters.pool_LinuxArm64 }}
useMicrosoftBuildAssetsForTests: ${{ parameters.useMicrosoftBuildAssetsForTests }}
isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ isOfficialBuild: ${{ parameters.isOfficialBuild }}
+ desiredSigning: ${{ parameters.desiredSigning }}
desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
+ excludeRuntimeDependentJobs: ${{ parameters.excludeRuntimeDependentJobs }}
# Description of the source build legs to run.
# This is described here as a parameter to allow two separate stages to be produced from this list (one for building
@@ -53,99 +72,28 @@ stages:
# to determine which variable to use for determining the various parameter values which are based on variables.
#
# Changing the build name requires updating the referenced name in the source-build-sdk-diff-tests.yml pipeline
+ # Changing the `disableSigning` parameter requires adding or removing the build name and source-built artifact
+ # patterns in the ../steps/vmr-validate-signing.yml file.
legs:
### Source-build verification legs ###
- # Stage 1 leg is built in full scope, or lite when any of the `source-build-` verifications are requested.
- - buildNameFormat: '{0}_Online_MsftSdk'
- distro: centos
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- runOnline: true # ✅
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
-
- - ${{ if containsValue(parameters.verifications, 'source-build-stage2') }}:
-
- - buildNameFormat: '{0}_Offline_CurrentSourceBuiltSdk'
- distro: centos
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
- reuseBuildArtifactsFrom: '{0}_Online_MsftSdk_x64'
-
- ### Additional legs for full build ###
- - ${{ if in(parameters.scope, 'full') }}:
-
- - buildNameFormat: '{0}_Offline_MsftSdk'
- distro: ubuntu
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- excludeOmniSharpTests: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
-
- - buildNameFormat: '{0}_Offline_PreviousSourceBuiltSdk'
- distro: centos
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: true # ✅
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: true # ✅
-
- - buildNameFormat: '{0}_Offline_MsftSdk'
- distro: almalinux
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
-
- - buildNameFormat: '{0}_Offline_MsftSdk'
- distro: alpine
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
+ - ${{ if in(parameters.scope, 'source-build-outer-loop') }}:
- - buildNameFormat: '{0}_Offline_MsftSdk'
+ - buildNameFormat: 'SB_{0}_Mono_Offline_MsftSdk'
distro: centos
targetArchitecture: x64
buildFromArchive: true # ✅
enablePoison: false # 🚫
runOnline: false # 🚫
- useMonoRuntime: false # 🚫
+ useMonoRuntime: true # ✅
useSystemLibraries: false # 🚫
withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+ extraProperties: /p:DotNetSkipTestsRequiringMicrosoftArtifacts=true
- - buildNameFormat: '{0}_Online_PreviousSourceBuiltSdk'
- distro: centos
- targetArchitecture: x64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- runOnline: true # ✅
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: true # ✅
-
- - buildNameFormat: '{0}_Mono_Offline_MsftSdk'
+ - buildNameFormat: 'SB_{0}_Mono_Offline_CurrentSourceBuiltSdk'
distro: centos
targetArchitecture: x64
buildFromArchive: true # ✅
@@ -154,47 +102,154 @@ stages:
useMonoRuntime: true # ✅
useSystemLibraries: false # 🚫
withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+ reuseBuildArtifactsFrom: 'SB_{0}_Mono_Offline_MsftSdk_x64'
+ extraProperties: /p:DotNetSkipTestsRequiringMicrosoftArtifacts=true
- - buildNameFormat: '{0}_Offline_MsftSdk'
- distro: fedora
- targetArchitecture: x64
- buildFromArchive: true # ✅
- enablePoison: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: true # ✅
- withPreviousSDK: false # 🚫
- enableCoreDumpGeneration: true # ✅
-
- - buildNameFormat: '{0}Arm64_Offline_MsftSdk'
- distro: ubuntu
- targetArchitecture: arm64
- buildFromArchive: false # 🚫
- enablePoison: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: false # 🚫
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
+ - ${{ else }}:
- - buildNameFormat: '{0}_Offline_CurrentSourceBuiltSdk'
- distro: fedora
+ # Stage 1 leg is built in full scope, or lite when any of the `source-build-` verifications are requested.
+ - buildNameFormat: 'SB_{0}_Online_MsftSdk'
+ distro: centos
targetArchitecture: x64
buildFromArchive: false # 🚫
enablePoison: false # 🚫
- runOnline: false # 🚫
+ runOnline: true # ✅
useMonoRuntime: false # 🚫
useSystemLibraries: false # 🚫
withPreviousSDK: false # 🚫
- enableCoreDumpGeneration: true # ✅
- reuseBuildArtifactsFrom: '{0}_Offline_MsftSdk_x64'
-
- - buildNameFormat: '{0}_Mono_Offline_CurrentSourceBuiltSdk'
- distro: centos
- targetArchitecture: x64
- buildFromArchive: true # ✅
- enablePoison: false # 🚫
- runOnline: false # 🚫
- useMonoRuntime: true # ✅
- useSystemLibraries: false # 🚫
- withPreviousSDK: false # 🚫
- reuseBuildArtifactsFrom: '{0}_Mono_Offline_MsftSdk_x64'
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+ ${{ if in(parameters.scope, 'lite') }}:
+ extraProperties: /p:DotNetSkipTestsRequiringMicrosoftArtifacts=true
+
+ - ${{ if containsValue(parameters.verifications, 'source-build-stage2') }}:
+
+ - buildNameFormat: 'SB_{0}_Offline_CurrentSourceBuiltSdk'
+ distro: centos
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+ reuseBuildArtifactsFrom: 'SB_{0}_Online_MsftSdk_x64'
+ ${{ if in(parameters.scope, 'lite') }}:
+ extraProperties: /p:DotNetSkipTestsRequiringMicrosoftArtifacts=true
+
+ ### Additional legs for full build ###
+ - ${{ if in(parameters.scope, 'full') }}:
+
+ - buildNameFormat: 'SB_{0}_Offline_MsftSdk'
+ distro: ubuntu
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ excludeOmniSharpTests: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}_Offline_PreviousSourceBuiltSdk'
+ distro: centos
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: true # ✅
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: true # ✅
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}_Offline_MsftSdk'
+ distro: almalinux
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}_Offline_MsftSdk'
+ distro: alpine
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}_Offline_MsftSdk'
+ distro: centos
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: false # 🚫
+ createSourceArtifact: true # ✅
+
+ - buildNameFormat: 'SB_{0}_Online_PreviousSourceBuiltSdk'
+ distro: centos
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: true # ✅
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: true # ✅
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}_Offline_MsftSdk'
+ distro: fedora
+ targetArchitecture: x64
+ buildFromArchive: true # ✅
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: true # ✅
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}Arm64_Offline_MsftSdk'
+ distro: ubuntu
+ targetArchitecture: arm64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+
+ - buildNameFormat: 'SB_{0}_Offline_CurrentSourceBuiltSdk'
+ distro: fedora
+ targetArchitecture: x64
+ buildFromArchive: false # 🚫
+ enablePoison: false # 🚫
+ runOnline: false # 🚫
+ useMonoRuntime: false # 🚫
+ useSystemLibraries: false # 🚫
+ withPreviousSDK: false # 🚫
+ disableSigning: true # ✅
+ createSourceArtifact: false # 🚫
+ reuseBuildArtifactsFrom: 'SB_{0}_Offline_MsftSdk_x64'
diff --git a/eng/pipelines/templates/stages/vmr-build.yml b/eng/pipelines/templates/stages/vmr-build.yml
index 166fabe3437e..04f5b6c3a514 100644
--- a/eng/pipelines/templates/stages/vmr-build.yml
+++ b/eng/pipelines/templates/stages/vmr-build.yml
@@ -24,12 +24,15 @@ parameters:
- lite
# run everything
- full
+ # run source build outer loop (Mono jobs)
+ - source-build-outer-loop
# True when build is running from dotnet/dotnet directly
- name: isBuiltFromVmr
type: boolean
default: true
+# True when the build is a build run from the production pipeline
- name: isOfficialBuild
type: boolean
default: false
@@ -90,16 +93,24 @@ parameters:
demands: ImageOverride -equals $(poolImage_Linux)
os: linux
+# Indicates whether to exclude runtime dependent jobs.
+# This is used to skip building the cross-OS DACs and other runtime dependent jobs in non-1xx branches.
+- name: excludeRuntimeDependentJobs
+ type: boolean
+ default: false
+
stages:
-- template: vmr-verticals.yml
- parameters:
- desiredSigning: ${{ parameters.desiredSigning }}
- isOfficialBuild: ${{ parameters.isOfficialBuild }}
- desiredIbc: ${{ parameters.desiredIbc }}
- desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- scope: ${{ parameters.scope }}
- verifications: ${{ parameters.verifications }}
+- ${{ if notin(parameters.scope, 'source-build-outer-loop') }}:
+ - template: vmr-verticals.yml
+ parameters:
+ desiredSigning: ${{ parameters.desiredSigning }}
+ isOfficialBuild: ${{ parameters.isOfficialBuild }}
+ desiredIbc: ${{ parameters.desiredIbc }}
+ desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ scope: ${{ parameters.scope }}
+ verifications: ${{ parameters.verifications }}
+ excludeRuntimeDependentJobs: ${{ parameters.excludeRuntimeDependentJobs }}
- ${{ if and(parameters.isBuiltFromVmr, eq(parameters.isOfficialBuild, true)) }}:
- stage: Publish_Build_Assets
@@ -120,6 +131,7 @@ stages:
**/manifests/**/*.xml
!*Sdk_*_Artifacts/**/VerticalManifest.xml
+- ${{ if and(ne(variables['System.TeamProject'], 'public'), in(parameters.scope, 'full')) }}:
- template: vmr-validation.yml
parameters:
desiredSigning: ${{ parameters.desiredSigning }}
@@ -132,6 +144,8 @@ stages:
pool_LinuxArm64: ${{ parameters.pool_LinuxArm64 }}
scope: ${{ parameters.scope }}
isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ isOfficialBuild: ${{ parameters.isOfficialBuild }}
+ desiredSigning: ${{ parameters.desiredSigning }}
desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
verifications: ${{ parameters.verifications }}
${{ if ne(parameters.scope, 'full') }}:
@@ -139,3 +153,4 @@ stages:
# are available from the subset of jobs that get build in PRs compared to the full build. Instead, we run
# the tests in the same job as the build and filter out some of the tests that can't be executed in this state.
useMicrosoftBuildAssetsForTests: false
+ excludeRuntimeDependentJobs: ${{ parameters.excludeRuntimeDependentJobs }}
diff --git a/eng/pipelines/templates/stages/vmr-license-scan.yml b/eng/pipelines/templates/stages/vmr-license-scan.yml
index 692144409142..9373404d2689 100644
--- a/eng/pipelines/templates/stages/vmr-license-scan.yml
+++ b/eng/pipelines/templates/stages/vmr-license-scan.yml
@@ -118,6 +118,7 @@ stages:
- script: |
source ./eng/common/tools.sh
InitializeDotNetCli true
+ echo "##vso[task.setvariable variable=DotNetPath]$_InitializeDotNetCli"
displayName: Install .NET SDK
workingDirectory: $(Build.SourcesDirectory)
@@ -135,6 +136,7 @@ stages:
- template: /eng/pipelines/templates/steps/create-baseline-update-pr.yml@self
parameters:
+ dotnetPath: $(DotNetPath)
pipeline: license
repo: dotnet/dotnet
originalFilesDirectory: test/Microsoft.DotNet.SourceBuild.Tests/assets/LicenseScanTests
diff --git a/eng/pipelines/templates/stages/vmr-scan.yml b/eng/pipelines/templates/stages/vmr-scan.yml
index 92c676432cbf..bd5ee5ff91c1 100644
--- a/eng/pipelines/templates/stages/vmr-scan.yml
+++ b/eng/pipelines/templates/stages/vmr-scan.yml
@@ -7,7 +7,7 @@ stages:
displayName: Tag & Scan
pool:
name: $(DncEngInternalBuildPool)
- image: 1es-ubuntu-2004
+ image: 1es-ubuntu-2204
os: linux
steps:
@@ -16,11 +16,15 @@ stages:
- script: |
source ./eng/common/tools.sh
InitializeDotNetCli true
- .dotnet/dotnet tool restore
- displayName: Initialize tooling
+ echo "##vso[task.setvariable variable=DotNetPath]$_InitializeDotNetCli"
+ displayName: Install .NET CLI
+
+ - script: |
+ $(DotNetPath)/dotnet tool restore
+ displayName: Restore tools
- script: >
- .dotnet/dotnet darc vmr scan-cloaked-files
+ $(DotNetPath)/dotnet darc vmr scan-cloaked-files
--vmr "$(Build.SourcesDirectory)"
--tmp "$(Agent.TempDirectory)"
|| (echo '##[error]Found cloaked files in the VMR' && exit 1)
diff --git a/eng/pipelines/templates/stages/vmr-validation.yml b/eng/pipelines/templates/stages/vmr-validation.yml
index 31e683a25fa2..83aa408574a3 100644
--- a/eng/pipelines/templates/stages/vmr-validation.yml
+++ b/eng/pipelines/templates/stages/vmr-validation.yml
@@ -53,6 +53,7 @@ stages:
displayName: VMR Validation
dependsOn:
- VMR_Vertical_Build
+ - VMR_SourceOnly_Build
variables:
- template: ../variables/vmr-build.yml
parameters:
@@ -65,7 +66,7 @@ stages:
jobs:
- job: ValidateInstallers_Linux_x64
pool: ${{ parameters.pool_Linux }}
- timeoutInMinutes: 30
+ timeoutInMinutes: 60
steps:
- template: ../steps/vmr-validate-installers.yml
parameters:
@@ -85,7 +86,7 @@ stages:
reuseBuildArtifactsFrom:
- Windows_x64
- AzureLinux_x64_Cross_arm64
- - ${{ if eq(variables.signEnabled, 'true') }}:
+ - ${{ if eq(variables.signType, 'real') }}:
- job: ValidateSigning_Windows
displayName: Validate Signing - Windows
pool: ${{ parameters.pool_Windows }}
diff --git a/eng/pipelines/templates/stages/vmr-verticals.yml b/eng/pipelines/templates/stages/vmr-verticals.yml
index 0687b344b6d1..4a77a2091ce7 100644
--- a/eng/pipelines/templates/stages/vmr-verticals.yml
+++ b/eng/pipelines/templates/stages/vmr-verticals.yml
@@ -82,6 +82,12 @@ parameters:
demands: ImageOverride -equals $(poolImage_Linux)
os: linux
+# Indicates whether to exclude runtime dependent jobs.
+# This is used to skip building the cross-OS DACs and other runtime dependent jobs in non-1xx branches.
+- name: excludeRuntimeDependentJobs
+ type: boolean
+ default: false
+
stages:
#### VERTICAL BUILD (Validation) ####
@@ -162,225 +168,229 @@ stages:
targetOS: windows
targetArchitecture: x86
- - ${{ if containsValue(parameters.verifications, 'unified-build-android-arm64') }}:
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Android_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.androidCrossContainerName }}
- image: ${{ variables.androidCrossContainerImage }}
- targetOS: android
- targetArchitecture: arm64
-
- - ${{ if containsValue(parameters.verifications, 'unified-build-browser-wasm') }}:
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Browser_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.browserCrossContainerName }}
- image: ${{ variables.browserCrossContainerImage }}
- crossRootFs: '/crossrootfs/x64'
- targetOS: browser
- targetArchitecture: wasm
-
- - ${{ if containsValue(parameters.verifications, 'unified-build-iossimulator-arm64') }}:
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: iOSSimulator_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: iossimulator
- targetArchitecture: arm64
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+
+ - ${{ if containsValue(parameters.verifications, 'unified-build-android-arm64') }}:
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Android_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.androidCrossContainerName }}
+ image: ${{ variables.androidCrossContainerImage }}
+ targetOS: android
+ targetArchitecture: arm64
+
+ - ${{ if containsValue(parameters.verifications, 'unified-build-browser-wasm') }}:
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Browser_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.browserCrossContainerName }}
+ image: ${{ variables.browserCrossContainerImage }}
+ crossRootFs: '/crossrootfs/x64'
+ targetOS: browser
+ targetArchitecture: wasm
+
+ - ${{ if containsValue(parameters.verifications, 'unified-build-iossimulator-arm64') }}:
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: iOSSimulator_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: iossimulator
+ targetArchitecture: arm64
### Additional jobs for full build ###
- ${{ if in(parameters.scope, 'full') }}:
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Android_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.androidCrossContainerName }}
- image: ${{ variables.androidCrossContainerImage }}
- targetOS: android
- targetArchitecture: arm
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Android_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.androidCrossContainerName }}
- image: ${{ variables.androidCrossContainerImage }}
- targetOS: android
- targetArchitecture: x64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Android_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.androidCrossContainerName }}
- image: ${{ variables.androidCrossContainerImage }}
- targetOS: android
- targetArchitecture: x86
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Browser_Multithreaded_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.browserCrossContainerName }}
- image: ${{ variables.browserCrossContainerImage }}
- crossRootFs: '/crossrootfs/x64'
- targetOS: browser
- targetArchitecture: wasm
- extraProperties: /p:WasmEnableThreads=true
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: LinuxBionic_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.linuxBionicCrossContainerName }}
- image: ${{ variables.linuxBionicCrossContainerImage }}
- targetOS: linux-bionic
- targetArchitecture: arm64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: LinuxBionic_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.linuxBionicCrossContainerName }}
- image: ${{ variables.linuxBionicCrossContainerImage }}
- targetOS: linux-bionic
- targetArchitecture: arm
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: LinuxBionic_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.linuxBionicCrossContainerName }}
- image: ${{ variables.linuxBionicCrossContainerImage }}
- targetOS: linux-bionic
- targetArchitecture: x64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: iOS_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: ios
- targetArchitecture: arm64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: iOSSimulator_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: iossimulator
- targetArchitecture: x64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: MacCatalyst_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: maccatalyst
- targetArchitecture: arm64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: MacCatalyst_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: maccatalyst
- targetArchitecture: x64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: tvOS_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: tvos
- targetArchitecture: arm64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: tvOSSimulator_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: tvossimulator
- targetArchitecture: arm64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: tvOSSimulator_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- targetOS: tvossimulator
- targetArchitecture: x64
-
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Wasi_Shortstack
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.wasiCrossContainerName }}
- image: ${{ variables.wasiCrossContainerImage }}
- crossRootFs: '/crossrootfs/x64'
- targetOS: wasi
- targetArchitecture: wasm
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Android_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.androidCrossContainerName }}
+ image: ${{ variables.androidCrossContainerImage }}
+ targetOS: android
+ targetArchitecture: arm
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Android_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.androidCrossContainerName }}
+ image: ${{ variables.androidCrossContainerImage }}
+ targetOS: android
+ targetArchitecture: x64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Android_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.androidCrossContainerName }}
+ image: ${{ variables.androidCrossContainerImage }}
+ targetOS: android
+ targetArchitecture: x86
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Browser_Multithreaded_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.browserCrossContainerName }}
+ image: ${{ variables.browserCrossContainerImage }}
+ crossRootFs: '/crossrootfs/x64'
+ targetOS: browser
+ targetArchitecture: wasm
+ extraProperties: /p:WasmEnableThreads=true
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: LinuxBionic_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.linuxBionicCrossContainerName }}
+ image: ${{ variables.linuxBionicCrossContainerImage }}
+ targetOS: linux-bionic
+ targetArchitecture: arm64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: LinuxBionic_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.linuxBionicCrossContainerName }}
+ image: ${{ variables.linuxBionicCrossContainerImage }}
+ targetOS: linux-bionic
+ targetArchitecture: arm
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: LinuxBionic_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.linuxBionicCrossContainerName }}
+ image: ${{ variables.linuxBionicCrossContainerImage }}
+ targetOS: linux-bionic
+ targetArchitecture: x64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: iOS_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: ios
+ targetArchitecture: arm64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: iOSSimulator_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: iossimulator
+ targetArchitecture: x64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: MacCatalyst_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: maccatalyst
+ targetArchitecture: arm64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: MacCatalyst_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: maccatalyst
+ targetArchitecture: x64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: tvOS_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: tvos
+ targetArchitecture: arm64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: tvOSSimulator_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: tvossimulator
+ targetArchitecture: arm64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: tvOSSimulator_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ targetOS: tvossimulator
+ targetArchitecture: x64
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Wasi_Shortstack
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.wasiCrossContainerName }}
+ image: ${{ variables.wasiCrossContainerImage }}
+ crossRootFs: '/crossrootfs/x64'
+ targetOS: wasi
+ targetArchitecture: wasm
- template: ../jobs/vmr-build.yml
parameters:
@@ -392,17 +402,19 @@ stages:
targetOS: osx
targetArchitecture: x64
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: OSX_Shortstack_Mono_LLVMAOT
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Mac }}
- useMonoRuntime: true
- targetOS: osx
- targetArchitecture: x64
- extraProperties: /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: OSX_Shortstack_Mono_LLVMAOT
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Mac }}
+ useMonoRuntime: true
+ targetOS: osx
+ targetArchitecture: x64
+ extraProperties: /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true
- template: ../jobs/vmr-build.yml
parameters:
@@ -432,21 +444,23 @@ stages:
targetArchitecture: x64
extraProperties: /p:PgoInstrument=true
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: AzureLinux_x64_Cross_Shortstack_Mono_LLVMAOT
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.azurelinuxX64CrossContainerName }}
- image: ${{ variables.azurelinuxX64CrossContainerImage }}
- crossRootFs: '/crossrootfs/x64'
- useMonoRuntime: true
- targetOS: linux
- targetArchitecture: x64
- extraProperties: /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: AzureLinux_x64_Cross_Shortstack_Mono_LLVMAOT
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.azurelinuxX64CrossContainerName }}
+ image: ${{ variables.azurelinuxX64CrossContainerImage }}
+ crossRootFs: '/crossrootfs/x64'
+ useMonoRuntime: true
+ targetOS: linux
+ targetArchitecture: x64
+ extraProperties: /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true
- template: ../jobs/vmr-build.yml
parameters:
@@ -535,21 +549,22 @@ stages:
targetArchitecture: arm64
targetRid: ${{ variables.linuxMuslArm64Rid }}
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: AzureLinux_x64_Cross_Shortstack_Mono_LLVMAOT
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- pool: ${{ parameters.pool_Linux_Shortstack }}
- container:
- name: ${{ variables.azurelinuxArm64CrossContainerName }}
- image: ${{ variables.azurelinuxArm64CrossContainerImage }}
- crossRootFs: '/crossrootfs/arm64'
- useMonoRuntime: true
- targetOS: linux
- targetArchitecture: arm64
- extraProperties: /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: AzureLinux_x64_Cross_Shortstack_Mono_LLVMAOT
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ pool: ${{ parameters.pool_Linux_Shortstack }}
+ container:
+ name: ${{ variables.azurelinuxArm64CrossContainerName }}
+ image: ${{ variables.azurelinuxArm64CrossContainerImage }}
+ crossRootFs: '/crossrootfs/arm64'
+ useMonoRuntime: true
+ targetOS: linux
+ targetArchitecture: arm64
+ extraProperties: /p:MonoEnableLLVM=true /p:MonoAOTEnableLLVM=true /p:MonoBundleLLVMOptimizer=true
- template: ../jobs/vmr-build.yml
parameters:
@@ -606,25 +621,27 @@ stages:
## Build Pass 2 verticals
- # build the cross-OS DACs
- - template: ../jobs/vmr-build.yml
- parameters:
- buildName: Windows
- isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
- sign: ${{ variables.signEnabled }}
- signType: ${{ variables.signType }}
- signDac: ${{ variables.signDacEnabled }}
- pool: ${{ parameters.pool_Windows }}
- targetOS: windows
- targetArchitecture: x86
- buildPass: 2
- reuseBuildArtifactsFrom:
- - AzureLinux_x64_Cross_x64
- - AzureLinux_x64_Cross_Alpine_x64
- - AzureLinux_x64_Cross_arm64
- - AzureLinux_x64_Cross_Alpine_arm64
- - AzureLinux_x64_Cross_arm
- - AzureLinux_x64_Cross_Alpine_arm
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+
+ # build the cross-OS DACs
+ - template: ../jobs/vmr-build.yml
+ parameters:
+ buildName: Windows
+ isBuiltFromVmr: ${{ parameters.isBuiltFromVmr }}
+ sign: ${{ variables.signEnabled }}
+ signType: ${{ variables.signType }}
+ signDac: ${{ variables.signDacEnabled }}
+ pool: ${{ parameters.pool_Windows }}
+ targetOS: windows
+ targetArchitecture: x86
+ buildPass: 2
+ reuseBuildArtifactsFrom:
+ - AzureLinux_x64_Cross_x64
+ - AzureLinux_x64_Cross_Alpine_x64
+ - AzureLinux_x64_Cross_arm64
+ - AzureLinux_x64_Cross_Alpine_arm64
+ - AzureLinux_x64_Cross_arm
+ - AzureLinux_x64_Cross_Alpine_arm
# build the ASP.NET Core hosting bundle and VS components
- template: ../jobs/vmr-build.yml
@@ -658,21 +675,22 @@ stages:
- Windows_x64
- Windows_x86
- Windows_arm64
- - Browser_Shortstack_wasm
- - Browser_Multithreaded_Shortstack_wasm
- - Wasi_Shortstack_wasm
- - Android_Shortstack_arm64
- - Android_Shortstack_arm
- - Android_Shortstack_x64
- - Android_Shortstack_x86
- - iOS_Shortstack_arm64
- - iOSSimulator_Shortstack_arm64
- - iOSSimulator_Shortstack_x64
- - tvOS_Shortstack_arm64
- - tvOSSimulator_Shortstack_arm64
- - tvOSSimulator_Shortstack_x64
- - MacCatalyst_Shortstack_arm64
- - MacCatalyst_Shortstack_x64
+ - ${{ if not(parameters.excludeRuntimeDependentJobs) }}:
+ - Browser_Shortstack_wasm
+ - Browser_Multithreaded_Shortstack_wasm
+ - Wasi_Shortstack_wasm
+ - Android_Shortstack_arm64
+ - Android_Shortstack_arm
+ - Android_Shortstack_x64
+ - Android_Shortstack_x86
+ - iOS_Shortstack_arm64
+ - iOSSimulator_Shortstack_arm64
+ - iOSSimulator_Shortstack_x64
+ - tvOS_Shortstack_arm64
+ - tvOSSimulator_Shortstack_arm64
+ - tvOSSimulator_Shortstack_x64
+ - MacCatalyst_Shortstack_arm64
+ - MacCatalyst_Shortstack_x64
## Build Pass 3 verticals
diff --git a/eng/pipelines/templates/steps/create-baseline-update-pr.yml b/eng/pipelines/templates/steps/create-baseline-update-pr.yml
index 442c59013d4c..0332a9fbc45b 100644
--- a/eng/pipelines/templates/steps/create-baseline-update-pr.yml
+++ b/eng/pipelines/templates/steps/create-baseline-update-pr.yml
@@ -1,4 +1,8 @@
parameters:
+- name: dotnetPath
+ type: string
+ default: '$(Build.SourcesDirectory)/.dotnet'
+
# The pipeline that is being run
# Used to determine the correct baseline update tool to run
# Currently only supports "sdk" and "license"
@@ -31,7 +35,7 @@ steps:
branchName=$(echo "$(Build.SourceBranch)" | sed 's/refs\/heads\///g')
- .dotnet/dotnet run \
+ ${{ parameters.dotnetPath }}/dotnet run \
--project eng/tools/CreateBaselineUpdatePR/ \
--property:RestoreSources="$restoreSources" \
"${{ parameters.pipeline }}" \
diff --git a/eng/pipelines/templates/steps/vmr-validate-installers.yml b/eng/pipelines/templates/steps/vmr-validate-installers.yml
index ed2bdff78a20..8e46f54d9694 100644
--- a/eng/pipelines/templates/steps/vmr-validate-installers.yml
+++ b/eng/pipelines/templates/steps/vmr-validate-installers.yml
@@ -15,6 +15,11 @@ parameters:
default: ''
steps:
+- ${{ if eq(parameters.OS, 'Darwin') }}:
+ - script: |
+ xcrun simctl runtime delete all
+ displayName: Reclaim disk space from unused simulator runtimes
+
- ${{ if ne(parameters.reuseBuildArtifactsFrom,'') }}:
- ${{ each reuseBuildArtifacts in parameters.reuseBuildArtifactsFrom }}:
- task: DownloadPipelineArtifact@2
diff --git a/eng/pipelines/templates/steps/vmr-validate-signing.yml b/eng/pipelines/templates/steps/vmr-validate-signing.yml
index 0d6b3cb14261..dd6f4991e729 100644
--- a/eng/pipelines/templates/steps/vmr-validate-signing.yml
+++ b/eng/pipelines/templates/steps/vmr-validate-signing.yml
@@ -28,6 +28,13 @@ parameters:
default: '$(Build.ArtifactStagingDirectory)/SigningValidation'
steps:
+- ${{ if eq(parameters.OS, 'Darwin') }}:
+ - script: |
+ xcrun simctl runtime delete all
+ displayName: Reclaim disk space from unused simulator runtimes
+
+# Include "**SB_CentOSStream*_Offline_MsftSdk_x64_Artifacts/**/Release/source-build/dotnet-source-*"
+# once https://github.com/dotnet/arcade/issues/16034 has been resolved.
- task: DownloadPipelineArtifact@2
displayName: Download Vertical Build Artifacts
continueOnError: ${{ parameters.continueOnError }}
@@ -38,6 +45,8 @@ steps:
**AzureLinux*_Artifacts/**
**OSX_*_Artifacts/**
**Windows_*_Artifacts/**
+ **SB_CentOSStream*_Offline_MsftSdk_x64_Artifacts/**/Release/source-build/dotnet-sdk-*.tar.gz
+ **SB_CentOSStream*_Offline_MsftSdk_x64_Artifacts/**/Release/source-build/Private.SourceBuilt.Artifacts.*.tar.gz
downloadPath: '${{ parameters.signCheckFilesDirectory }}'
# This is necessary whenever we want to publish/restore to an AzDO private feed
@@ -58,7 +67,8 @@ steps:
/p:ArtifactDownloadDirectory=${{ parameters.signCheckFilesDirectory }} `
/p:SourceBranch='$(Build.SourceBranch)' `
/p:DotNetRootDirectory=$(Build.SourcesDirectory) `
- /p:OutputLogsDirectory=${{ parameters.outputDirectory }}
+ /p:OutputLogsDirectory=${{ parameters.outputDirectory }} `
+ /bl:${{ parameters.outputDirectory }}/outer-signing-validation.binlog
displayName: Validate Signing
continueOnError: ${{ parameters.continueOnError }}
@@ -75,7 +85,8 @@ steps:
/p:ArtifactDownloadDirectory=${{ parameters.signCheckFilesDirectory }} \
/p:SourceBranch='$(Build.SourceBranch)' \
/p:DotNetRootDirectory=$(Build.SourcesDirectory) \
- /p:OutputLogsDirectory=${{ parameters.outputDirectory }}
+ /p:OutputLogsDirectory=${{ parameters.outputDirectory }} \
+ /bl:${{ parameters.outputDirectory }}/outer-signing-validation.binlog
displayName: Validate Signing
continueOnError: ${{ parameters.continueOnError }}
diff --git a/eng/pipelines/templates/variables/vmr-build.yml b/eng/pipelines/templates/variables/vmr-build.yml
index f570a7579f0c..13f3fb918837 100644
--- a/eng/pipelines/templates/variables/vmr-build.yml
+++ b/eng/pipelines/templates/variables/vmr-build.yml
@@ -41,8 +41,8 @@ variables:
- name: ibcEnabled
value: false
- ${{ elseif or(startsWith(parameters.desiredIBC, 'Default'), eq(parameters.desiredIBC, '')) }}:
- # Enable IBC on the internal project if the, branch is a release branch
- - ${{ if and(eq(parameters.isOfficialBuild, true), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))) }}:
+ # Enable IBC on the internal project if this is an official build of a release branch and is not a source-only build.
+ - ${{ if and(eq(parameters.isOfficialBuild, true), ne(parameters.buildSourceOnly, true), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))) }}:
- name: ibcEnabled
value: true
# No IBC otherwise.
@@ -53,18 +53,21 @@ variables:
- name: ibcEnabled
value: false
-- ${{ if eq(parameters.desiredFinalVersionKind, 'Default (repo specifies)') }}:
+- ${{ if eq(parameters.desiredFinalVersionKind, 'Repo default (uses the repo branding defaults)') }}:
- name: brandingType
- value: 'default'
-- ${{ elseif eq(parameters.desiredFinalVersionKind, 'Stable Preview') }}:
+ value: 'repodefault'
+- ${{ elseif eq(parameters.desiredFinalVersionKind, 'Unstable (produces assets with the repo specified branding suffix)') }}:
+ - name: brandingType
+ value: 'unstable'
+- ${{ elseif eq(parameters.desiredFinalVersionKind, 'Preview (produces assets with a .final branding suffix)') }}:
- name: brandingType
value: 'preview'
-- ${{ elseif eq(parameters.desiredFinalVersionKind, 'Stable Final') }}:
+- ${{ elseif eq(parameters.desiredFinalVersionKind, 'Release (produces assets without a branding suffix)') }}:
- name: brandingType
- value: 'rtm'
+ value: 'release'
- ${{ else }}:
- name: brandingType
- value: 'default'
+ value: ''
## Do not set this when building source only to avoid including telemetry in the bootstrap artifacts
## handed off to distro partners.
@@ -75,15 +78,13 @@ variables:
- name: officialBuildProperties
value: ''
-- ${{ if eq(parameters.buildSourceOnly, true) }}:
- - name: signEnabled
- value: false
-- ${{ elseif eq(parameters.desiredSigning, 'Signed (Real)') }}:
+- ${{ if eq(parameters.desiredSigning, 'Signed (Real)') }}:
- name: signEnabled
value: true
- name: signType
- value: Real
- - ${{ if and(eq(parameters.isOfficialBuild, true), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))) }}:
+ value: real
+ # Only sign DACs if this is an official build of a release branch and is not a source-only build.
+ - ${{ if and(eq(parameters.isOfficialBuild, true), ne(parameters.buildSourceOnly, true), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))) }}:
- name: signDacEnabled
value: true
- ${{ else }}:
@@ -93,7 +94,7 @@ variables:
- name: signEnabled
value: true
- name: signType
- value: Test
+ value: test
- name: signDacEnabled
value: false
- ${{ elseif eq(parameters.desiredSigning, 'Signed (Dry Run)') }}:
@@ -123,8 +124,13 @@ variables:
value: true
- name: signType
value: real
- - name: signDacEnabled
- value: true
+ # Only sign DACs if this is not a source-only build.
+ - ${{ if ne(parameters.buildSourceOnly, true) }}:
+ - name: signDacEnabled
+ value: true
+ - ${{ else }}:
+ - name: signDacEnabled
+ value: false
# Do not sign otherwise.
- ${{ else }}:
- name: signEnabled
@@ -145,7 +151,7 @@ variables:
- name: alpineContainerName
value: alpineContainer
- name: alpineContainerImage
- value: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.21-amd64
+ value: mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-amd64
- name: centOSStreamContainerName
value: centOSStreamContainer
@@ -155,7 +161,7 @@ variables:
- name: fedoraContainerName
value: fedoraContainer
- name: fedoraContainerImage
- value: mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-41
+ value: mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-43-amd64
- name: ubuntuContainerName
value: ubuntuContainer
@@ -220,11 +226,11 @@ variables:
- name: almaLinuxName
value: AlmaLinux8
- name: alpineName
- value: Alpine321
+ value: Alpine323
- name: centOSStreamName
value: CentOSStream10
- name: fedoraName
- value: Fedora41
+ value: Fedora43
- name: ubuntuName
value: Ubuntu2404
@@ -241,11 +247,11 @@ variables:
- name: linuxMuslArm64Rid
value: linux-musl-arm64
- name: alpineX64Rid
- value: alpine.3.21-x64
+ value: alpine.3.23-x64
- name: centOSStreamX64Rid
value: centos.10-x64
- name: fedoraX64Rid
- value: fedora.41-x64
+ value: fedora.43-x64
- name: ubuntux64Rid
value: ubuntu.24.04-x64
- name: ubuntuArm64Rid
@@ -263,13 +269,13 @@ variables:
- name: poolName_LinuxArm64
value: Docker-Linux-Arm-Public
- name: poolImage_Mac
- value: macos-13
+ value: macos-14
- ${{ if eq(parameters.isScoutingJob, true) }}:
- name: poolImage_Windows
- value: windows.vs2022preview.scout.amd64.open
+ value: windows.vs2022.scout.amd64.open
- ${{ else }}:
- name: poolImage_Windows
- value: windows.vs2022preview.amd64.open
+ value: windows.vs2022.amd64.open
- ${{ else }}:
- name: defaultPoolName
value: NetCore1ESPool-Internal
@@ -278,11 +284,10 @@ variables:
- name: poolImage_Linux
value: build.ubuntu.2204.amd64
- name: poolImage_LinuxArm64
- value: Mariner-2-Docker-ARM64
+ value: Azure-Linux-3-Arm64
- name: poolName_LinuxArm64
value: Docker-Linux-Arm-Internal
- name: poolImage_Mac
value: macos-latest-internal
- name: poolImage_Windows
- value: windows.vs2022preview.amd64
-
+ value: windows.vs2022.amd64
diff --git a/eng/pipelines/unofficial.yml b/eng/pipelines/unofficial.yml
index 32bb1d509042..d25e87cdd39e 100644
--- a/eng/pipelines/unofficial.yml
+++ b/eng/pipelines/unofficial.yml
@@ -133,3 +133,6 @@ extends:
desiredFinalVersionKind: ${{ parameters.desiredFinalVersionKind }}
scope: ${{ parameters.buildScope }}
isOfficialBuild: false
+ # Exclude runtime dependent jobs for any branch not producing a 1xx version since runtime-related repos aren't built in that context
+ # This is enabled for all branches except main and 1xx
+ excludeRuntimeDependentJobs: false
diff --git a/eng/pipelines/vmr-license-scan.yml b/eng/pipelines/vmr-license-scan.yml
index d0dda14d0db3..350dcb203439 100644
--- a/eng/pipelines/vmr-license-scan.yml
+++ b/eng/pipelines/vmr-license-scan.yml
@@ -6,9 +6,14 @@ schedules:
branches:
# For releases branches only run on internal/release branches because that's where dependencies flow.
# Previews don't have internal/release branches so they must be run from non-internal release branches.
+ # The 2xx, 3xx, 4xx triggers exist to cover the feature band pre-release time periods.
+ # They can be removed once released as the triggers below will handle the branches after release.
include:
- main
- release/*.0.1xx-preview*
+ - release/*.0.2xx*
+ - release/*.0.3xx*
+ - release/*.0.4xx*
- internal/release/*.0.1xx*
pr: none
@@ -16,10 +21,15 @@ pr: none
# Always trigger a run when changes are made to the license test implementation or baselines
trigger:
branches:
+ # The 2xx, 3xx, 4xx triggers exist to cover the feature band pre-release time periods.
+ # They can be removed once released as the internal/release trigger will handle the branches after release.
include:
- main
- release/*.0.1xx-preview*
- - internal/release/*.0.1xx*
+ - release/*.0.2xx*
+ - release/*.0.3xx*
+ - release/*.0.4xx*
+ - internal/release/*.0.?xx*
paths:
include:
- test/Microsoft.DotNet.SourceBuild.Tests/LicenseScanTests.cs
diff --git a/eng/shared-source-only.targets b/eng/shared-source-only.targets
new file mode 100644
index 000000000000..18271f472fe3
--- /dev/null
+++ b/eng/shared-source-only.targets
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ BootstrapOnly
+ BootstrapRepoDepsOnly
+ NonToolingOnly
+ NonToolingAndBootstrapOnly
+ ToolingOnly
+
+
+
+
+
+ <_VersionDetailsXml Condition="'$(PackageVersionPropsFlowType)' == 'DependenciesOnly'">$(ProjectDirectory)eng/Version.Details.xml
+
+
+
+
+
+
+ ;@(SharedRepositoryReference);
+ <_BootstrapRepoDepsString>;@(_BootstrapRepoDeps);
+ $(SharedComponentFilter_NonToolingAndBootstrapOnly)
+
+
+
+
+
+
+
+
+ <_ItemsToRemove Include="@(SharedComponentFilteredPackages)"
+ Condition="!$(SharedRepositoryReferenceString.Contains(';%(RepoOrigin);')) and !$([System.String]::new(';$(BootstrapArcadeRepos);').Contains(';%(RepoOrigin);'))" />
+
+
+
+
+ <_ItemsToRemove Include="@(SharedComponentFilteredPackages)"
+ Condition="!$(SharedRepositoryReferenceString.Contains(';%(RepoOrigin);'))" />
+
+
+
+
+ <_ItemsToRemove Include="@(SharedComponentFilteredPackages)"
+ Condition="$(SharedRepositoryReferenceString.Contains(';%(RepoOrigin);')) or $([System.String]::new(';$(BootstrapArcadeRepos);').Contains(';%(RepoOrigin);'))" />
+
+
+
+
+ <_ItemsToRemove Include="@(SharedComponentFilteredPackages)"
+ Condition="!$([System.String]::new(';$(BootstrapArcadeRepos);').Contains(';%(RepoOrigin);'))" />
+
+
+
+
+ <_ItemsToRemove Include="@(SharedComponentFilteredPackages)"
+ Condition="!$([System.String]::new(';$(_BootstrapRepoDepsString);').Contains(';%(Identity);'))" />
+
+
+
+
+ <_ItemsToRemoveString>@(_ItemsToRemove->'%(Identity)::%(Version)', ';')
+
+
+
+
+
+
+ $(SharedComponentsArtifactsPath)$([System.IO.Path]::GetFileName('%(PipelineArtifactPath)'))
+
+
+
+
+
+
diff --git a/eng/sign-source-built-artifacts.proj b/eng/sign-source-built-artifacts.proj
new file mode 100644
index 000000000000..001cc2a96a0f
--- /dev/null
+++ b/eng/sign-source-built-artifacts.proj
@@ -0,0 +1,63 @@
+
+
+
+ $(NetCurrent)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(ArtifactsDir)/staging/
+ $(ArtifactsStagingDir)/artifacts
+ $(ArtifactsPublishStagingDir)/assets/$(Configuration)
+ $(SourceBuiltAssetsDir)/source-build
+
+
+
+ dotnet-sdk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/source-build-toolset-init.sh b/eng/source-build-toolset-init.sh
new file mode 100755
index 000000000000..dd5a1eb4d4c6
--- /dev/null
+++ b/eng/source-build-toolset-init.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+
+### This script provides shared functionality for initializing the source build toolset.
+### It handles custom SDK setup, MSBuild SDK resolver initialization, and toolset preparation.
+
+set -euo pipefail
+
+function source_only_toolset_init() {
+ local custom_sdk_dir="$1"
+ local custom_packages_dir="$2"
+ local binary_log="$3"
+ local is_running_tests="${4:-false}"
+ local properties=("${@:5}") # All remaining arguments are properties
+
+ echo "Initializing source-only toolset..."
+
+ # Determine the script directory and navigate up to the repository root
+ local script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ local repo_root="$( cd "${script_dir}/.." && pwd )"
+
+ # Set up custom SDK if specified
+ if [ -n "$custom_sdk_dir" ]; then
+ if [ ! -d "$custom_sdk_dir" ]; then
+ echo "ERROR: Custom SDK directory '$custom_sdk_dir' does not exist"
+ exit 1
+ fi
+ if [ ! -x "$custom_sdk_dir/dotnet" ]; then
+ echo "ERROR: Custom SDK '$custom_sdk_dir/dotnet' does not exist or is not executable"
+ exit 1
+ fi
+ export SDK_VERSION=$("$custom_sdk_dir/dotnet" --version)
+ export CLI_ROOT="$custom_sdk_dir"
+ echo "Using custom bootstrap SDK from '$CLI_ROOT', version '$SDK_VERSION'"
+ else
+ sdkLine=$(grep -m 1 'dotnet' "$repo_root/global.json")
+ sdkPattern="\"dotnet\" *: *\"(.*)\""
+ if [[ $sdkLine =~ $sdkPattern ]]; then
+ export SDK_VERSION=${BASH_REMATCH[1]}
+ export CLI_ROOT="$repo_root/.dotnet"
+ fi
+ fi
+
+ # Set _InitializeDotNetCli & DOTNET_INSTALL_DIR so that eng/common/tools.sh doesn't attempt to restore the SDK.
+ export _InitializeDotNetCli="$CLI_ROOT"
+ export DOTNET_INSTALL_DIR="$CLI_ROOT"
+
+ # Don't use the global nuget cache folder when building source-only which
+ # restores prebuilt packages that should never get into the global nuget cache.
+ export NUGET_PACKAGES="$repo_root/.packages/"
+
+ if [[ "$is_running_tests" == true ]]; then
+ # Use a custom package cache for tests to make prebuilt detection work.
+ export NUGET_PACKAGES="${NUGET_PACKAGES}tests/"
+ fi
+
+ echo "NuGet packages cache: '${NUGET_PACKAGES}'"
+
+ # Find the Arcade SDK version and set env vars for the msbuild sdk resolver
+ local packageVersionsPath=''
+ local packagesDir="$repo_root/prereqs/packages/"
+ local packagesArchiveDir="${packagesDir}archive/"
+ local packagesPreviouslySourceBuiltDir="${packagesDir}previously-source-built/"
+ local tempDir=""
+
+ if [[ "$custom_packages_dir" != "" && -f "$custom_packages_dir/PackageVersions.props" ]]; then
+ packageVersionsPath="$custom_packages_dir/PackageVersions.props"
+ elif [ -d "$packagesArchiveDir" ]; then
+ sourceBuiltArchive=$(find "$packagesArchiveDir" -maxdepth 1 -name 'Private.SourceBuilt.Artifacts*.tar.gz')
+ if [ -f "${packagesPreviouslySourceBuiltDir}PackageVersions.props" ]; then
+ packageVersionsPath=${packagesPreviouslySourceBuiltDir}PackageVersions.props
+ elif [ -f "$sourceBuiltArchive" ]; then
+ # Extract safely into a private temporary directory and ensure cleanup.
+ tempDir="$(mktemp -d)"
+ trap "rm -rf '${tempDir}'" EXIT # tempDir is local, use double quotes to expand.
+ tar -xzf "$sourceBuiltArchive" -C "$tempDir" PackageVersions.props
+ packageVersionsPath="$tempDir/PackageVersions.props"
+ fi
+ fi
+
+ if [ ! -f "$packageVersionsPath" ]; then
+ echo "Cannot find PackagesVersions.props. Debugging info:"
+ echo " Attempted custom PVP path: $custom_packages_dir/PackageVersions.props"
+ echo " Attempted previously-source-built path: ${packagesPreviouslySourceBuiltDir}PackageVersions.props"
+ echo " Attempted archive path: $packagesArchiveDir"
+ exit 1
+ fi
+
+ # Extract toolset packages
+
+ # Ensure that by default, the bootstrap version of the toolset SDK is used. Source-build infra
+ # projects use bootstrap toolset SDKs, and would fail to find it in the build. The repo
+ # projects overwrite this so that they use the source-built toolset SDK instad.
+
+ # 1. Microsoft.DotNet.Arcade.Sdk
+ arcadeSdkLine=$(grep -m 1 'MicrosoftDotNetArcadeSdkVersion' "$packageVersionsPath")
+ arcadeSdkPattern="(.*)"
+ if [[ $arcadeSdkLine =~ $arcadeSdkPattern ]]; then
+ export ARCADE_BOOTSTRAP_VERSION=${BASH_REMATCH[1]}
+
+ export SOURCE_BUILT_SDK_ID_ARCADE=Microsoft.DotNet.Arcade.Sdk
+ export SOURCE_BUILT_SDK_VERSION_ARCADE=$ARCADE_BOOTSTRAP_VERSION
+ export SOURCE_BUILT_SDK_DIR_ARCADE=${NUGET_PACKAGES}BootstrapPackages/microsoft.dotnet.arcade.sdk/$ARCADE_BOOTSTRAP_VERSION
+ fi
+
+ # 2. Microsoft.Build.NoTargets
+ notargetsSdkLine=$(grep -m 1 'Microsoft.Build.NoTargets' "$repo_root/global.json")
+ notargetsSdkPattern="\"Microsoft\\.Build\\.NoTargets\" *: *\"(.*)\""
+ if [[ $notargetsSdkLine =~ $notargetsSdkPattern ]]; then
+ export NOTARGETS_BOOTSTRAP_VERSION=${BASH_REMATCH[1]}
+
+ export SOURCE_BUILT_SDK_ID_NOTARGETS=Microsoft.Build.NoTargets
+ export SOURCE_BUILT_SDK_VERSION_NOTARGETS=$NOTARGETS_BOOTSTRAP_VERSION
+ export SOURCE_BUILT_SDK_DIR_NOTARGETS=${NUGET_PACKAGES}BootstrapPackages/microsoft.build.notargets/$NOTARGETS_BOOTSTRAP_VERSION
+ fi
+
+ # 3. Microsoft.Build.Traversal
+ traversalSdkLine=$(grep -m 1 'Microsoft.Build.Traversal' "$repo_root/global.json")
+ traversalSdkPattern="\"Microsoft\\.Build\\.Traversal\" *: *\"(.*)\""
+ if [[ $traversalSdkLine =~ $traversalSdkPattern ]]; then
+ export TRAVERSAL_BOOTSTRAP_VERSION=${BASH_REMATCH[1]}
+
+ export SOURCE_BUILT_SDK_ID_TRAVERSAL=Microsoft.Build.Traversal
+ export SOURCE_BUILT_SDK_VERSION_TRAVERSAL=$TRAVERSAL_BOOTSTRAP_VERSION
+ export SOURCE_BUILT_SDK_DIR_TRAVERSAL=${NUGET_PACKAGES}BootstrapPackages/microsoft.build.traversal/$TRAVERSAL_BOOTSTRAP_VERSION
+ fi
+
+ echo "Found bootstrap versions: SDK $SDK_VERSION, Arcade $ARCADE_BOOTSTRAP_VERSION, NoTargets $NOTARGETS_BOOTSTRAP_VERSION and Traversal $TRAVERSAL_BOOTSTRAP_VERSION"
+
+ # toolset prep steps
+ source "$repo_root/eng/common/tools.sh"
+ InitializeBuildTool
+
+ initSourceOnlyBinaryLog=""
+ if [[ "$binary_log" == true ]]; then
+ initSourceOnlyBinaryLog="/bl:\"$log_dir/init-source-only.binlog\""
+ fi
+
+ "$_InitializeBuildTool" build-server shutdown --msbuild
+ MSBuild-Core "$repo_root/eng/init-source-only.proj" $initSourceOnlyBinaryLog "${properties[@]}"
+ # kill off the MSBuild server so that on future invocations we pick up our custom SDK Resolver
+ "$_InitializeBuildTool" build-server shutdown --msbuild
+
+ local bootstrapArcadeDir=$(cat "$repo_root/artifacts/toolset/bootstrap-sdks.txt" | grep "microsoft.dotnet.arcade.sdk")
+ local arcadeBuildStepsDir="$bootstrapArcadeDir/tools/"
+
+ # Point MSBuild to the custom SDK resolvers folder, so it will pick up our custom SDK Resolver
+ export MSBUILDADDITIONALSDKRESOLVERSFOLDER="$repo_root/artifacts/toolset/VSSdkResolvers/"
+
+ # Set _InitializeToolset so that eng/common/tools.sh doesn't attempt to restore the arcade toolset again.
+ _InitializeToolset="${arcadeBuildStepsDir}/Build.proj"
+
+ echo "Source-only toolset initialization complete"
+}
diff --git a/eng/tools/BinaryToolKit/BinaryTool.cs b/eng/tools/BinaryToolKit/BinaryTool.cs
index a9343581883c..c17a0405d1b4 100644
--- a/eng/tools/BinaryToolKit/BinaryTool.cs
+++ b/eng/tools/BinaryToolKit/BinaryTool.cs
@@ -9,7 +9,7 @@ namespace BinaryToolKit;
public static class BinaryTool
{
- public static async Task ExecuteAsync(
+ public static void Execute(
TaskLoggingHelper log,
string targetDirectory,
string outputReportDirectory,
@@ -21,7 +21,7 @@ public static async Task ExecuteAsync(
log.LogMessage(MessageImportance.High, $"Starting binary tool at {startTime} in {mode} mode");
// Run the tooling
- var detectedBinaries = await DetectBinaries.ExecuteAsync(log, targetDirectory, outputReportDirectory, allowedBinariesFile);
+ var detectedBinaries = DetectBinaries.Execute(log, targetDirectory, outputReportDirectory, allowedBinariesFile);
if (mode == Modes.Validate)
{
diff --git a/eng/tools/BinaryToolKit/BinaryToolTask.cs b/eng/tools/BinaryToolKit/BinaryToolTask.cs
index e4ac9e2b11fc..df9d4ca81a87 100644
--- a/eng/tools/BinaryToolKit/BinaryToolTask.cs
+++ b/eng/tools/BinaryToolKit/BinaryToolTask.cs
@@ -37,14 +37,12 @@ public string Mode
private Modes _mode;
- public override bool Execute() => ExecuteAsync().GetAwaiter().GetResult();
-
- private async Task ExecuteAsync()
+ public override bool Execute()
{
try
{
ParseArgs();
- await BinaryTool.ExecuteAsync(Log, TargetDirectory, OutputReportDirectory, AllowedBinariesFile, _mode);
+ BinaryTool.Execute(Log, TargetDirectory, OutputReportDirectory, AllowedBinariesFile, _mode);
}
catch (Exception ex)
{
diff --git a/eng/tools/BinaryToolKit/DetectBinaries.cs b/eng/tools/BinaryToolKit/DetectBinaries.cs
index 4037a79ebb34..45b966bef12f 100644
--- a/eng/tools/BinaryToolKit/DetectBinaries.cs
+++ b/eng/tools/BinaryToolKit/DetectBinaries.cs
@@ -17,11 +17,9 @@ namespace BinaryToolKit;
public static class DetectBinaries
{
- private const string Utf16Marker = "UTF-16";
- private const int ChunkSize = 4096;
private static readonly Regex GitCleanRegex = new Regex(@"Would (remove|skip)( repository)? (.*)");
- public static async Task> ExecuteAsync(
+ public static IList Execute(
TaskLoggingHelper log,
string targetDirectory,
string outputReportDirectory,
@@ -40,33 +38,30 @@ public static async Task> ExecuteAsync(
return (pattern: p, matcher: m);
}).ToList();
- var parallelOptions = new ParallelOptions
+ foreach (var file in Directory.EnumerateFiles(targetDirectory, "*", new EnumerationOptions() { AttributesToSkip = FileAttributes.ReparsePoint, RecurseSubdirectories = true }))
{
- MaxDegreeOfParallelism = Environment.ProcessorCount * 2
- };
-
- await Parallel.ForEachAsync(Directory.EnumerateFiles(targetDirectory, "*", SearchOption.AllDirectories), parallelOptions, async (file, _) =>
- {
- bool matched = false;
-
- foreach (var (pattern, matcher) in patternMatchers)
+ // This code is meant for finding binaries in source code repositories.
+ // Most files will be non-binary. We want to avoid checking each of those against the patternMatchers [O(N*M)], so we first check if the file is binary.
+ if (IsBinary(file))
{
- if (matcher.Match(targetDirectory, file).HasMatches)
+ bool matched = false;
+
+ foreach (var (pattern, matcher) in patternMatchers)
{
- usedPatterns.Add(pattern);
- matched = true;
- break;
+ if (matcher.Match(targetDirectory, file).HasMatches)
+ {
+ usedPatterns.Add(pattern);
+ matched = true;
+ break;
+ }
}
- }
- if (!matched)
- {
- if (await IsBinaryAsync(log, file))
+ if (!matched)
{
newBinaries.Add(file.Substring(targetDirectory.Length + 1));
}
}
- });
+ }
var unusedPatterns = new HashSet(patterns.Except(usedPatterns));
UpdateAllowedBinariesFile(log, allowedBinariesFile, outputReportDirectory, unusedPatterns);
@@ -76,69 +71,23 @@ await Parallel.ForEachAsync(Directory.EnumerateFiles(targetDirectory, "*", Searc
return newBinaries.ToList();
}
- private static async Task IsBinaryAsync(TaskLoggingHelper log, string filePath)
+ private static bool IsBinary(string filePath)
{
// Using the GNU diff heuristic to determine if a file is binary or not.
// For more details, refer to the GNU diff manual:
// https://www.gnu.org/software/diffutils/manual/html_node/Binary.html
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
- using (BinaryReader br = new BinaryReader(fs))
{
- byte[] buffer = new byte[ChunkSize];
- int bytesRead = br.Read(buffer, 0, ChunkSize);
- for (int i = 0; i < bytesRead; i++)
- {
- if (buffer[i] == 0)
- {
- // Need to check that the file is not UTF-16 encoded
- // because heuristic can return false positives
- return await IsNotUTF16Async(log, filePath);
- }
- }
- }
- return false;
- }
+ Span buffer = stackalloc byte[4096];
+ int bytesRead = fs.Read(buffer);
+ buffer = buffer[..bytesRead];
- private static async Task IsNotUTF16Async(TaskLoggingHelper log, string file)
- {
- if (Environment.OSVersion.Platform == PlatformID.Unix)
- {
- string output = await ExecuteProcessAsync(log, "file", $"\"{file}\"");
- output = output.Split(":")[1].Trim();
-
- if (output.Contains(Utf16Marker))
- {
- return false;
- }
- }
- return true;
- }
-
- private static async Task ExecuteProcessAsync(TaskLoggingHelper log, string executable, string arguments)
- {
- ProcessStartInfo psi = new()
- {
- FileName = executable,
- Arguments = arguments,
- CreateNoWindow = true,
- RedirectStandardOutput = true,
- RedirectStandardError = true
- };
-
- var proc = Process.Start(psi)!;
-
- string output = await proc.StandardOutput.ReadToEndAsync();
- string error = await proc.StandardError.ReadToEndAsync();
+ bool hasZeroByte = buffer.IndexOf((byte)0) != -1;
+ bool hasUTF16ByteOrderMarker = buffer.StartsWith((ReadOnlySpan)[0xFE, 0xFF]) || buffer.StartsWith((ReadOnlySpan)[0xFF, 0xFE]);
- await proc.WaitForExitAsync();
-
- if (!string.IsNullOrEmpty(error))
- {
- log.LogError(error);
+ return hasZeroByte && !hasUTF16ByteOrderMarker;
}
-
- return output;
}
private static IEnumerable ParseAllowedBinariesFile(TaskLoggingHelper log, string file, List? knownFiles = null)
diff --git a/eng/tools/BuildComparer/BuildComparer.cs b/eng/tools/BuildComparer/BuildComparer.cs
index 6dad7fddd5cc..efc0e0ad2e12 100644
--- a/eng/tools/BuildComparer/BuildComparer.cs
+++ b/eng/tools/BuildComparer/BuildComparer.cs
@@ -3,54 +3,60 @@
using Microsoft.Arcade.Common;
using Microsoft.DotNet.Build.Manifest;
-using NuGet.Packaging;
using System.Collections.Concurrent;
using System.Collections.Immutable;
-using System.CommandLine;
-using System.Formats.Tar;
-using System.IO.Compression;
-using System.Reflection;
-using System.Reflection.Metadata;
-using System.Reflection.PortableExecutable;
using System.Xml.Linq;
public abstract class BuildComparer
{
+ private readonly HashSet _includedRepositories =
+ [
+ "arcade",
+ "deployment-tools",
+ "diagnostics",
+ "fsharp",
+ "msbuild",
+ "nuget-client",
+ "razor",
+ "roslyn",
+ "vstest"
+ ];
+
///
/// Type of asset being processed in the build comparison tool.
///
protected AssetType? _assetType;
-
+
///
/// Base path for VMR build assets.
///
protected string _vmrBuildAssetBasePath;
-
+
///
/// Base path for Microsoft build assets.
///
protected string _baseBuildAssetBasePath;
-
+
///
/// Path where the comparison report for issues will be saved.
///
private string _issuesReportPath;
-
+
///
/// Path where the comparison report for no issues will be saved.
///
private string _noIssuesReportPath;
-
+
///
/// Semaphore used to control parallel processing.
///
protected SemaphoreSlim _throttle;
-
+
///
/// Report containing the results of the comparison.
///
protected ComparisonReport _comparisonReport = new ComparisonReport();
-
+
///
/// List of all asset mappings between base and VMR builds.
///
@@ -168,33 +174,19 @@ protected void GenerateAssetMappings()
// Walk the top-level directories of the asset base path, and find the MergedManifest under each
// one. The MergedManifest.xml contains the list of outputs produced by the repo.
-
- foreach (var baseDirectory in Directory.GetDirectories(_baseBuildAssetBasePath, "*", SearchOption.TopDirectoryOnly))
+ foreach (string includedRepository in _includedRepositories)
{
// Find the merged manifest underneath this directory
- // (e.g. /arcade/nonshipping/>/MergedManifest.xml)
+ // (e.g. /arcade/nonshipping//MergedManifest.xml)
+ string repoBaseAssetsDirectory = Path.Combine(_baseBuildAssetBasePath, includedRepository);
- string repoMergedManifestPath = Directory.GetFiles(baseDirectory,
+ string repoMergedManifestPath = Directory.GetFiles(repoBaseAssetsDirectory,
"MergedManifest.xml", SearchOption.AllDirectories)
- .FirstOrDefault();
-
- if (repoMergedManifestPath == null)
- {
- // These repos don't publish assets, so we skip them
- if (baseDirectory.EndsWith("scenario-tests")
- || baseDirectory.EndsWith("source-build-reference-packages")
- || baseDirectory.EndsWith("runtime")
- || baseDirectory.EndsWith("sdk"))
- {
- continue;
- }
-
- throw new FileNotFoundException($"MergedManifest.xml not found in {baseDirectory}");
- }
+ .FirstOrDefault() ?? throw new FileNotFoundException($"MergedManifest.xml not found in {repoBaseAssetsDirectory}");
_assetMappings.AddRange(MapFilesForRepoManifest(
vmrManifests,
- baseDirectory,
+ repoBaseAssetsDirectory,
_vmrBuildAssetBasePath,
repoMergedManifestPath));
}
diff --git a/eng/tools/BuildComparer/BuildComparer.csproj b/eng/tools/BuildComparer/BuildComparer.csproj
index 0dbe36eb7ee6..8874541b8068 100644
--- a/eng/tools/BuildComparer/BuildComparer.csproj
+++ b/eng/tools/BuildComparer/BuildComparer.csproj
@@ -1,7 +1,8 @@
+
- Exe
$(NetCurrent)
+ Exe
enable
disable
@@ -10,4 +11,5 @@
+
diff --git a/eng/tools/ChangeValidation/ChangeValidation.csproj b/eng/tools/ChangeValidation/ChangeValidation.csproj
new file mode 100644
index 000000000000..f9975de051f7
--- /dev/null
+++ b/eng/tools/ChangeValidation/ChangeValidation.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ $(NetCurrent)
+ enable
+ enable
+
+ $(NoWarn);CS8002
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/tools/ChangeValidation/ExclusionFileValidation.cs b/eng/tools/ChangeValidation/ExclusionFileValidation.cs
new file mode 100644
index 000000000000..390a2cd9026e
--- /dev/null
+++ b/eng/tools/ChangeValidation/ExclusionFileValidation.cs
@@ -0,0 +1,151 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.FileSystemGlobbing;
+using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
+using Microsoft.DotNet.DarcLib;
+using Microsoft.DotNet.DarcLib.VirtualMonoRepo;
+using Microsoft.DotNet.DarcLib.Models.VirtualMonoRepo;
+using System.Linq;
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using Microsoft.DotNet.DarcLib.Helpers;
+using static ChangeValidation.Validation;
+
+namespace ChangeValidation;
+
+internal class ExclusionFileValidation : IValidationStep
+{
+ private static readonly int maxDisplayedFiles = 20;
+ private readonly IVmrDependencyTracker _dependencyTracker;
+ private readonly IProcessManager _processManager;
+ private readonly IVmrInfo _vmrInfo;
+ private readonly ILocalGitRepoFactory _localGitRepoFactory;
+
+ public ExclusionFileValidation(
+ IVmrDependencyTracker dependencyTracker,
+ IProcessManager processManager,
+ ILocalGitRepoFactory localGitRepoFactory,
+ IVmrInfo vmrInfo)
+ {
+ _dependencyTracker = dependencyTracker;
+ _processManager = processManager;
+ _localGitRepoFactory = localGitRepoFactory;
+ _vmrInfo = vmrInfo;
+ }
+
+ public string DisplayName => "Exclusion File Validation";
+
+ public async Task Validate(PrInfo prInfo)
+ {
+ ILocalGitRepo vmr = _localGitRepoFactory.Create(_vmrInfo.VmrPath);
+
+ var newExclusionRules = await GetExclusionPatterns(); // We are already checked to the PR Head commit, just parse exclusions from file
+ var originalExclusionRules = await GetExclusionPatternsFromBranch(vmr, prInfo.TargetBranch);
+
+ var newExcludedFiles = FindMatchingFiles(newExclusionRules);
+ var originalExcludedFiles = FindMatchingFiles(originalExclusionRules);
+
+ var excludedFilesInPr = prInfo.ChangedFiles
+ .Where(file => newExcludedFiles.Contains(NormalizePath(file)))
+ .ToList();
+
+ var filesMatchingNewExclusionRules = newExcludedFiles
+ .Where(file => !originalExcludedFiles.Contains(NormalizePath(file)) && !prInfo.ChangedFiles.Contains(NormalizePath(file)))
+ .ToList();
+
+ foreach (var file in excludedFilesInPr.Take(maxDisplayedFiles).ToList())
+ {
+ LogError($"This PR modifies the file `{file}`, which is part of the excluded files" +
+ $" defined in {VmrInfo.DefaultRelativeSourceMappingsPath}. If these changes are" +
+ $" necessary, please contact @dotnet/product-construction.");
+ }
+
+ if (excludedFilesInPr.Count > maxDisplayedFiles)
+ {
+ LogError($"... {excludedFilesInPr.Count - maxDisplayedFiles} more excluded files detected" +
+ $" in the PR (only showing the first {maxDisplayedFiles} files).");
+ }
+
+ foreach (var file in filesMatchingNewExclusionRules.Take(maxDisplayedFiles).ToList())
+ {
+ LogError($"The new exclusion rules defined in {VmrInfo.DefaultRelativeSourceMappingsPath} " +
+ $"include the VMR file `{file}`. If this file is not needed in the VMR, consider " +
+ $"deleting it as part of the PR.");
+ }
+
+ if (filesMatchingNewExclusionRules.Count > maxDisplayedFiles)
+ {
+ LogError($"... {filesMatchingNewExclusionRules.Count - maxDisplayedFiles} more VMR files " +
+ $"match the new exclusion rules (only showing the first {maxDisplayedFiles} files). " +
+ "Please review the modifications made to exclusion rules");
+ }
+
+ return !excludedFilesInPr.Any() && !filesMatchingNewExclusionRules.Any();
+ }
+
+ private async Task> GetExclusionPatternsFromBranch(ILocalGitRepo vmr, string branchName)
+ {
+ string originalRef = await vmr.GetCheckedOutBranchAsync();
+ try
+ {
+ LogInfo($"Checking out branch {branchName} to get exclusion patterns.");
+ await vmr.CheckoutAsync(branchName);
+ return await GetExclusionPatterns();
+ }
+ finally
+ {
+ await vmr.CheckoutAsync(originalRef);
+ }
+ }
+
+ private async Task> GetExclusionPatterns()
+ {
+ await _dependencyTracker.RefreshMetadataAsync();
+
+ var sourceMappings = _dependencyTracker.Mappings;
+
+ var exclusionPatterns = sourceMappings.SelectMany(mapping => GetVmrGlobFromSourceMapping(mapping))
+ .Distinct()
+ .ToList();
+
+ LogInfo("Successfully parsed exclusion patterns...");
+ LogInfo(string.Join(Environment.NewLine, exclusionPatterns));
+
+ return exclusionPatterns;
+ }
+
+ private List GetVmrGlobFromSourceMapping(SourceMapping mapping)
+ {
+ return mapping.Exclude.Select(exclusion => "src/" + mapping.Name + "/" + NormalizePath(exclusion)).ToList();
+ }
+
+ private HashSet FindMatchingFiles(List globPatterns)
+ {
+ var matcher = new Matcher();
+
+ foreach (var pattern in globPatterns)
+ {
+ matcher.AddInclude(pattern);
+ }
+
+ var directoryInfo = new DirectoryInfo(_vmrInfo.VmrPath);
+ var directoryWrapper = new DirectoryInfoWrapper(directoryInfo);
+ var result = matcher.Execute(directoryWrapper);
+
+ var res = result.Files
+ .Select(file => file.Path)
+ .ToHashSet();
+
+ return res;
+ }
+
+ internal static string NormalizePath(string path)
+ {
+ return path.Replace('\\', '/');
+ }
+}
diff --git a/eng/tools/ChangeValidation/IValidationStep.cs b/eng/tools/ChangeValidation/IValidationStep.cs
new file mode 100644
index 000000000000..6a09f03d3f83
--- /dev/null
+++ b/eng/tools/ChangeValidation/IValidationStep.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace ChangeValidation;
+
+internal interface IValidationStep
+{
+ ///
+ /// Executes the validation step with the provided file names.
+ ///
+ /// List of file names to validate.
+ /// boolean determining the success of the validation step
+ Task Validate(PrInfo prInfo);
+
+ ///
+ /// Gets the display name of the validation step.
+ ///
+ string DisplayName { get; }
+}
diff --git a/eng/tools/ChangeValidation/PrInfo.cs b/eng/tools/ChangeValidation/PrInfo.cs
new file mode 100644
index 000000000000..c8407edfe55c
--- /dev/null
+++ b/eng/tools/ChangeValidation/PrInfo.cs
@@ -0,0 +1,12 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Immutable;
+using System.Linq;
+
+namespace ChangeValidation;
+
+internal record PrInfo(
+ string TargetBranch,
+ ImmutableList ChangedFiles);
diff --git a/eng/tools/ChangeValidation/SubmoduleValidation.cs b/eng/tools/ChangeValidation/SubmoduleValidation.cs
new file mode 100644
index 000000000000..5431093ac9d7
--- /dev/null
+++ b/eng/tools/ChangeValidation/SubmoduleValidation.cs
@@ -0,0 +1,81 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Linq;
+using System.Text;
+using Microsoft.Extensions.FileSystemGlobbing;
+using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.DotNet.DarcLib;
+using Microsoft.DotNet.DarcLib.Helpers;
+using Microsoft.DotNet.DarcLib.VirtualMonoRepo;
+using Microsoft.DotNet.DarcLib.Models.VirtualMonoRepo;
+using static ChangeValidation.Validation;
+
+namespace ChangeValidation;
+
+internal class SubmoduleValidation : IValidationStep
+{
+ private static readonly int maxDisplayedFiles = 20;
+ private readonly IVmrDependencyTracker _dependencyTracker;
+ private readonly IProcessManager _processManager;
+
+ public string DisplayName => "Submodule Validation";
+
+ private static string ConvertSubmodulePathToVmrGlob(string submodulePath) =>
+ "src/" + submodulePath.Replace('\\', '/').TrimStart('/').TrimEnd('/') + "/**";
+
+ public SubmoduleValidation(
+ IVmrDependencyTracker vmrDependencyTracker,
+ IProcessManager processManager)
+ {
+ _dependencyTracker = vmrDependencyTracker;
+ _processManager = processManager;
+ }
+
+ public async Task Validate(PrInfo prInfo)
+ {
+ var repoRoot = _processManager.FindGitRoot(AppContext.BaseDirectory);
+ var sourceManifest = await GetSourceManifestFromBranch("HEAD", repoRoot);
+
+ LogInfo("Reading submodule paths and converting to glob patterns...");
+
+ var submoduleGlobPatterns = sourceManifest.Submodules.Select(submodule => submodule.Path)
+ .Select(pattern => ConvertSubmodulePathToVmrGlob(pattern))
+ .ToList();
+
+ LogInfo(string.Join(Environment.NewLine, submoduleGlobPatterns));
+
+ var matcher = new Matcher();
+ foreach (var pattern in submoduleGlobPatterns)
+ {
+ matcher.AddInclude(pattern);
+ }
+
+ var directory = new InMemoryDirectoryInfo("/", prInfo.ChangedFiles);
+
+ var result = matcher.Execute(directory);
+
+ var modifiedSubmoduleFiles = result.Files.Select(f => f.Path).ToList();
+
+ foreach(var file in modifiedSubmoduleFiles.Take(maxDisplayedFiles).ToList())
+ {
+ LogError($"This PR modifies the submodule file `{file}`, which is not allowed. Submodule files are managed by the repository maintainers and should not be modified directly.");
+ }
+
+ if (modifiedSubmoduleFiles.Count > maxDisplayedFiles)
+ {
+ LogError($"... {modifiedSubmoduleFiles.Count - maxDisplayedFiles} more submodule files detected in the PR. Only showing the first {maxDisplayedFiles} files.");
+ }
+
+ return !modifiedSubmoduleFiles.Any();
+ }
+
+ private async Task GetSourceManifestFromBranch(string branchName, string repoRoot)
+ {
+ var sourceManifestContent = await _processManager.ExecuteGit(repoRoot, ["show", $"{branchName}:{VmrInfo.DefaultRelativeSourceManifestPath}"]);
+ var sourceManifest = SourceManifest.FromJson(sourceManifestContent.StandardOutput);
+ return sourceManifest;
+ }
+}
diff --git a/eng/tools/ChangeValidation/ToolingFilesValidation.cs b/eng/tools/ChangeValidation/ToolingFilesValidation.cs
new file mode 100644
index 000000000000..6a3c250a8265
--- /dev/null
+++ b/eng/tools/ChangeValidation/ToolingFilesValidation.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Text;
+using System.Text.RegularExpressions;
+using static ChangeValidation.Validation;
+
+namespace ChangeValidation;
+
+internal class ToolingFilesValidation : IValidationStep
+{
+ public string DisplayName => "Tooling Files Validation";
+
+ private static readonly string[] ToolingFilePatterns = new[]
+ {
+ "^eng/Version\\.Details\\.xml$",
+ "^src/source-manifest\\.json$",
+ "^eng/Version\\.props$",
+ "^eng/Version\\.Details\\.props$",
+ "^global\\.json$",
+ "^eng/common/.*"
+ };
+
+ private static readonly List ToolingFilesRegexes = ToolingFilePatterns
+ .Select(pattern => new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled))
+ .ToList();
+
+ public Task Validate(PrInfo prInfo)
+ {
+ var syncToolingChanges = prInfo.ChangedFiles
+ .Where(f => ToolingFilesRegexes.Any(regex => regex.IsMatch(f)))
+ .ToList();
+
+ if (syncToolingChanges.Any())
+ {
+ foreach (var file in syncToolingChanges)
+ {
+ LogError($"The file `{file}` is a tooling file reserved for automated processes. Modifying this file is not permitted.");
+ }
+ return Task.FromResult(false);
+ }
+ else
+ {
+ return Task.FromResult(true);
+ }
+ }
+}
diff --git a/eng/tools/ChangeValidation/Validation.cs b/eng/tools/ChangeValidation/Validation.cs
new file mode 100644
index 000000000000..1b5a01551202
--- /dev/null
+++ b/eng/tools/ChangeValidation/Validation.cs
@@ -0,0 +1,126 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections.Immutable;
+using Maestro.Common;
+using Microsoft.DotNet.DarcLib.Helpers;
+using Microsoft.DotNet.DarcLib.VirtualMonoRepo;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging.Abstractions;
+
+
+namespace ChangeValidation;
+
+internal static class Validation
+{
+ internal static void LogInfo(string message) => Console.WriteLine(message);
+ internal static void LogWarning(string message) => Console.WriteLine($"##vso[task.logissue type=warning] {message}");
+ internal static void LogError(string message) => Console.WriteLine($"##vso[task.logissue type=error] {message}");
+
+ internal static async Task Main(string[] args)
+ {
+ var pm = new ProcessManager(NullLogger.Instance, "git");
+
+ var repoRoot = pm.FindGitRoot(AppContext.BaseDirectory);
+
+ var serviceProvider = RegisterServices(repoRoot);
+
+ List validationSteps = CreateValidationSteps(serviceProvider);
+
+ PrInfo prInfo = await SetupPrInfo(pm, repoRoot);
+
+ return await RunValidationSteps(validationSteps, prInfo) ? 0 : 1;
+ }
+
+ private static async Task RunValidationSteps(List validationSteps, PrInfo prInfo)
+ {
+ int stepCounter = 0;
+ int failedSteps = 0;
+
+ foreach (var validationStep in validationSteps)
+ {
+ stepCounter++;
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine($"{stepCounter}. Starting {validationStep.DisplayName}");
+ bool validationSuccess = false;
+ try
+ {
+ validationSuccess = await validationStep.Validate(prInfo);
+ }
+ catch (Exception)
+ {
+ LogError($"{validationStep.DisplayName} was interrupted with an unexpected error.");
+ }
+ if (validationSuccess)
+ {
+ LogInfo($"{validationStep.DisplayName} succeeded.");
+ }
+ else
+ {
+ failedSteps++;
+ Console.WriteLine($"{validationStep.DisplayName} failed.");
+ }
+ }
+ if (failedSteps > 0)
+ {
+ Console.WriteLine();
+ Console.WriteLine();
+ LogError($"{failedSteps} out of {validationSteps.Count} validation steps have failed.");
+ return false;
+ }
+ else
+ {
+ LogInfo("All validation steps succeeded!");
+ return true;
+ }
+ }
+
+ private static async Task SetupPrInfo(IProcessManager pm, string repoPath)
+ {
+ string? targetBranch = $"origin/{Environment.GetEnvironmentVariable("SYSTEM_PULLREQUEST_TARGETBRANCH")}";
+ string? prNumber = Environment.GetEnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER");
+
+ if (string.IsNullOrEmpty(targetBranch))
+ {
+ throw new ArgumentException("Cannot determine PR target branch.");
+ }
+
+ // Create a git reference to the original branching-off point of the PR branch from the target branch
+ await pm.ExecuteGit(repoPath, "fetch", "origin", $"refs/pull/{prNumber}/merge:pr-merge");
+
+ var diffOutput = (await pm.ExecuteGit(repoPath, ["diff", "--name-only", targetBranch, "pr-merge"])).StandardOutput.Trim();
+
+ var changedFiles = diffOutput
+ .Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)
+ .Select(f => f.Replace('\\', '/').Trim())
+ .ToImmutableList();
+
+ Console.WriteLine($"Found modifications to {changedFiles.Count} file(s) in PR head branch");
+
+ return new PrInfo(targetBranch, changedFiles);
+ }
+
+ private static ServiceProvider RegisterServices(string repoRoot)
+ {
+ return new ServiceCollection()
+ .AddCodeflow("tmp", vmrPath: repoRoot)
+ .AddSingleton()
+ .BuildServiceProvider();
+ }
+
+ private static List CreateValidationSteps(IServiceProvider serviceProvider)
+ {
+ return [
+ ActivatorUtilities.CreateInstance(serviceProvider),
+ ActivatorUtilities.CreateInstance(serviceProvider),
+ ActivatorUtilities.CreateInstance(serviceProvider)
+ ];
+ }
+
+ private class NullRemoteTokenProvider : IRemoteTokenProvider
+ {
+ public string? GetTokenForRepository(string repoUri) => null;
+ public Task GetTokenForRepositoryAsync(string repoUri) => Task.FromResult(null);
+ }
+}
diff --git a/eng/tools/CreateBaselineUpdatePR/PRCreator.cs b/eng/tools/CreateBaselineUpdatePR/PRCreator.cs
index 1189d8084868..83b29c8bd0ee 100644
--- a/eng/tools/CreateBaselineUpdatePR/PRCreator.cs
+++ b/eng/tools/CreateBaselineUpdatePR/PRCreator.cs
@@ -17,6 +17,7 @@ public class PRCreator
private const string BuildLink = "https://dev.azure.com/dnceng/internal/_build/results?buildId=";
private const string DefaultLicenseBaselineContent = "{\n \"files\": []\n}";
private const string TreeMode = "040000";
+ private const string UpdatedFilePrefix = "updated";
private const int MaxRetries = 10;
public PRCreator(string repo, string gitHubToken)
{
@@ -105,10 +106,11 @@ await Parallel.ForEachAsync(treeResponse.Tree, async (item, cancellationToken) =
}
// Return a dictionary using the filename without the
- // "Updated" prefix and anything after the first '.' as the key
+ // "updated" prefix (case-insensitive) and anything after the first '.' as the key
private Dictionary> GetUpdatedFiles(string updatedFilesDirectory) =>
Directory
- .GetFiles(updatedFilesDirectory, "Updated*", SearchOption.AllDirectories)
+ .GetFiles(updatedFilesDirectory, "*", SearchOption.AllDirectories)
+ .Where(file => Path.GetFileName(file).StartsWith(UpdatedFilePrefix, StringComparison.OrdinalIgnoreCase))
.GroupBy(updatedTestsFile => ParseUpdatedFileName(updatedTestsFile).Split('.')[0])
.ToDictionary(
group => group.Key,
@@ -255,7 +257,15 @@ private async Task CreateBlobAsync(string content)
return await ApiRequestWithRetries(() => _client.Git.Blob.Create(_repoOwner, _repoName, blob));
}
- private string ParseUpdatedFileName(string updatedFile) => updatedFile.Split("Updated")[1];
+ private string ParseUpdatedFileName(string updatedFile)
+ {
+ string fileName = Path.GetFileName(updatedFile);
+ if (fileName.StartsWith(UpdatedFilePrefix, StringComparison.OrdinalIgnoreCase))
+ {
+ return fileName.Substring(UpdatedFilePrefix.Length);
+ }
+ throw new ArgumentException($"File name '{fileName}' does not start with '{UpdatedFilePrefix}' prefix.", nameof(updatedFile));
+ }
private async Task CreateTreeFromItemsAsync(List items, string path = "")
{
diff --git a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogFileEntry.cs b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogFileEntry.cs
index 67fb52b29221..aa66622dc613 100644
--- a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogFileEntry.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogFileEntry.cs
@@ -15,12 +15,10 @@ internal class CatalogFileEntry
const string ElementName = "File";
internal string Path { get; set; }
- internal byte[] OriginalHash { get; set; }
internal byte[] PoisonedHash { get; set; }
public XElement ToXml() => new XElement(ElementName,
new XAttribute(nameof(Path), Path),
- new XAttribute(nameof(OriginalHash), OriginalHash.ToHexString()),
PoisonedHash == null ? null : new XAttribute(nameof(PoisonedHash), PoisonedHash.ToHexString())
);
}
diff --git a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogPackageEntry.cs b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogPackageEntry.cs
index 99e334a0012b..654762f2eb8e 100644
--- a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogPackageEntry.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CatalogPackageEntry.cs
@@ -18,7 +18,6 @@ internal class CatalogPackageEntry
internal string Path { get; set; }
internal string Id { get; set; }
internal string Version { get; set; }
- internal byte[] OriginalHash { get; set; }
internal byte[] PoisonedHash { get; set; }
internal List Files { get; }
@@ -31,7 +30,6 @@ public CatalogPackageEntry()
new XAttribute(nameof(Path), Path),
new XAttribute(nameof(Id), Id),
new XAttribute(nameof(Version), Version),
- new XAttribute(nameof(OriginalHash), OriginalHash.ToHexString()),
PoisonedHash == null ? null : new XAttribute(nameof(PoisonedHash), PoisonedHash.ToHexString()),
Files.Select(f => f.ToXml())
);
diff --git a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CheckForPoison.cs b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CheckForPoison.cs
index 61e21fec9125..cbf852f1b31b 100644
--- a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CheckForPoison.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/CheckForPoison.cs
@@ -47,16 +47,16 @@ public class CheckForPoison : Task
public string PoisonReportOutputFilePath { get; set; }
///
- /// The path of a previously-generated file hash catalog, if
+ /// The paths of previously-generated file hash catalogs, if
/// hash checked is desired. If not, only assembly attributes
- /// and package marker file checked will be done.
+ /// and package marker files checks will be done.
///
- public string HashCatalogFilePath { get; set; }
+ public ITaskItem[] HashCatalogFilePaths { get; set; }
///
- /// The marker file name to check for in poisoned nupkg files.
+ /// The marker file names to check for in poisoned nupkg files.
///
- public string MarkerFileName { get; set; }
+ public ITaskItem[] MarkerFileNames { get; set; }
///
/// If true, fails the build if any poisoned files are found.
@@ -86,66 +86,6 @@ public class CheckForPoison : Task
".tar.gz",
};
- private static readonly string[] FileNamesToSkip =
- {
- "_._",
- "-.-",
- ".bowerrc",
- ".gitignore",
- ".gitkeep",
- ".rels",
- "LICENSE",
- "prefercliruntime",
- "RunCsc",
- "RunVbc",
- };
-
- private static readonly string[] FileExtensionsToSkip =
- {
- ".config",
- ".cs",
- ".cshtml",
- ".csproj",
- ".css",
- ".db",
- ".editorconfig",
- ".eot",
- ".fs",
- ".fsproj",
- ".h",
- ".html",
- ".ico",
- ".js",
- ".json",
- ".map",
- ".md",
- ".nuspec",
- ".otf",
- ".png",
- ".props",
- ".proto",
- ".proj",
- ".psmdcp",
- ".pubxml",
- ".razor",
- ".rtf",
- ".scss",
- ".sln",
- ".svg",
- ".targets",
- ".transform",
- ".ts",
- ".ttf",
- ".txt",
- ".vb",
- ".vbproj",
- ".win32manifest",
- ".woff",
- ".woff2",
- ".xaml",
- ".xml",
- };
-
private const string PoisonMarker = "POISONED";
private const string SbrpAttributeType = "System.Reflection.AssemblyMetadataAttribute";
@@ -156,7 +96,7 @@ private record CandidateFileEntry(string ExtractedPath, string DisplayPath, bool
public override bool Execute()
{
- IEnumerable poisons = GetPoisonedFiles(FilesToCheck, HashCatalogFilePath, MarkerFileName);
+ IEnumerable poisons = GetPoisonedFiles(FilesToCheck, HashCatalogFilePaths, MarkerFileNames);
// if we should write out the poison report, do that
if (!string.IsNullOrWhiteSpace(PoisonReportOutputFilePath))
@@ -181,12 +121,12 @@ public override bool Execute()
/// Internal helper to allow other tasks to check for poisoned files.
///
/// Initial queue of candidate files (will be cleared when done)
- /// File path to the file hash catalog
- /// Marker file name to check for in poisoned nupkgs
+ /// File paths to the file hash catalog
+ /// Marker file names to check for in poisoned nupkgs
/// List of poisoned packages and files found and reasons for each
- internal IEnumerable GetPoisonedFiles(IEnumerable initialCandidates, string catalogedPackagesFilePath, string markerFileName)
+ internal IEnumerable GetPoisonedFiles(IEnumerable initialCandidates, IEnumerable catalogedPackagesFilePaths, IEnumerable markerFileNames)
{
- IEnumerable catalogedPackages = ReadCatalog(catalogedPackagesFilePath);
+ IEnumerable catalogedPackages = catalogedPackagesFilePaths.SelectMany(file => ReadCatalog(file.ItemSpec));
var poisons = new List();
var candidateQueue = new Queue(initialCandidates.Select(candidate =>
new CandidateFileEntry(candidate.ItemSpec,
@@ -211,7 +151,7 @@ internal IEnumerable GetPoisonedFiles(IEnumerable
Log.LogMessage($"Zip or NuPkg file to check: {candidate.ExtractedPath}");
var tempCheckingDir = Path.Combine(tempDir.FullName, Path.GetFileNameWithoutExtension(candidate.ExtractedPath));
- PoisonedFileEntry result = ExtractAndCheckZipFileOnly(catalogedPackages, candidate, markerFileName, tempCheckingDir, candidateQueue);
+ PoisonedFileEntry result = ExtractAndCheckZipFileOnly(catalogedPackages, candidate, markerFileNames, tempCheckingDir, candidateQueue);
if (result != null)
{
poisons.Add(result);
@@ -232,19 +172,12 @@ internal IEnumerable GetPoisonedFiles(IEnumerable
return poisons;
}
- private static PoisonedFileEntry CheckSingleFile(IEnumerable catalogedPackages, CandidateFileEntry candidate)
+ private PoisonedFileEntry CheckSingleFile(IEnumerable catalogedPackages, CandidateFileEntry candidate)
{
// skip some common files that get copied verbatim from nupkgs - LICENSE, _._, etc as well as
// file types that we never care about - text files, .gitconfig, etc.
var fileToCheck = candidate.ExtractedPath;
- if (FileNamesToSkip.Any(f => Path.GetFileName(fileToCheck).ToLowerInvariant() == f.ToLowerInvariant()) ||
- FileExtensionsToSkip.Any(e => Path.GetExtension(fileToCheck).ToLowerInvariant() == e.ToLowerInvariant()) ||
- (new FileInfo(fileToCheck).Length == 0))
- {
- return null;
- }
-
var poisonEntry = new PoisonedFileEntry();
poisonEntry.Path = candidate.DisplayPath;
@@ -264,15 +197,13 @@ private static PoisonedFileEntry CheckSingleFile(IEnumerable f.OriginalHash.SequenceEqual(poisonEntry.Hash) || (f.PoisonedHash?.SequenceEqual(poisonEntry.Hash) ?? false)))
+ foreach (var matchingCatalogedFile in p.Files.Where(f => f.PoisonedHash?.SequenceEqual(poisonEntry.Hash) ?? false))
{
poisonEntry.Type |= PoisonType.Hash;
var match = new PoisonMatch
{
File = matchingCatalogedFile.Path,
- Package = p.Path,
+ Package = Utility.MakeRelativePath(p.Path, ProjectDirPath),
PackageId = p.Id,
PackageVersion = p.Version,
};
@@ -373,7 +304,7 @@ private static bool IsAttributeSbrp(MetadataReader reader, CustomAttribute attr)
return false;
}
- private static PoisonedFileEntry ExtractAndCheckZipFileOnly(IEnumerable catalogedPackages, CandidateFileEntry candidate, string markerFileName, string tempDir, Queue futureFilesToCheck)
+ private static PoisonedFileEntry ExtractAndCheckZipFileOnly(IEnumerable catalogedPackages, CandidateFileEntry candidate, IEnumerable markerFileNames, string tempDir, Queue futureFilesToCheck)
{
var poisonEntry = new PoisonedFileEntry();
var zipToCheck = candidate.ExtractedPath;
@@ -385,10 +316,8 @@ private static PoisonedFileEntry ExtractAndCheckZipFileOnly(IEnumerable c.OriginalHash.SequenceEqual(poisonEntry.Hash) || (c.PoisonedHash?.SequenceEqual(poisonEntry.Hash) ?? false)))
+ // first check for a matching hash match
+ foreach (var matchingCatalogedPackage in catalogedPackages.Where(c => c.PoisonedHash?.SequenceEqual(poisonEntry.Hash) ?? false))
{
poisonEntry.Type |= PoisonType.Hash;
var match = new PoisonMatch
@@ -422,7 +351,7 @@ private static PoisonedFileEntry ExtractAndCheckZipFileOnly(IEnumerable HasMarkerFile(tempDir, markerFileName.ItemSpec)))
{
poisonEntry.Type |= PoisonType.NupkgFile;
}
@@ -458,7 +387,6 @@ private static IEnumerable ReadCatalog(string hashCatalogFi
{
Id = p.Attributes["Id"].Value,
Version = p.Attributes["Version"].Value,
- OriginalHash = p.Attributes["OriginalHash"].Value.ToBytes(),
PoisonedHash = p.Attributes["PoisonedHash"]?.Value?.ToBytes(),
Path = p.Attributes["Path"].Value,
};
@@ -467,7 +395,6 @@ private static IEnumerable ReadCatalog(string hashCatalogFi
{
var fEntry = new CatalogFileEntry
{
- OriginalHash = f.Attributes["OriginalHash"].Value.ToBytes(),
PoisonedHash = f.Attributes["PoisonedHash"]?.Value?.ToBytes(),
Path = f.Attributes["Path"].Value,
};
@@ -476,5 +403,8 @@ private static IEnumerable ReadCatalog(string hashCatalogFi
}
return packages;
}
+
+ private static bool HasMarkerFile(string nugetPackageDir, string markerFileName)
+ => !string.IsNullOrWhiteSpace(markerFileName) && File.Exists(Path.Combine(nugetPackageDir, markerFileName));
}
}
diff --git a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/MarkAndCatalogPackages.cs b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/MarkAndCatalogPackages.cs
index 598bbd43661b..874269256fcd 100644
--- a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/MarkAndCatalogPackages.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/MarkAndCatalogPackages.cs
@@ -77,10 +77,6 @@ public override bool Execute()
var packageEntry = new CatalogPackageEntry();
packageEntries.Add(packageEntry);
packageEntry.Path = p.ItemSpec;
- using (var stream = File.OpenRead(p.ItemSpec))
- {
- packageEntry.OriginalHash = sha.ComputeHash(stream);
- }
var packageIdentity = ReadNuGetPackageInfos.ReadIdentity(p.ItemSpec);
packageEntry.Id = packageIdentity.Id;
packageEntry.Version = packageIdentity.Version.OriginalVersion;
@@ -96,29 +92,16 @@ public override bool Execute()
continue;
}
- var catalogFileEntry = new CatalogFileEntry();
- packageEntry.Files.Add(catalogFileEntry);
- catalogFileEntry.Path = Utility.MakeRelativePath(file, packageTempPath);
-
- // There seem to be some weird issues with using a file stream both for hashing and
- // assembly loading, even closing it in between. Use a MemoryStream to avoid issues.
- var memStream = new MemoryStream();
- using (var stream = File.OpenRead(file))
- {
- stream.CopyTo(memStream);
- }
-
- // First get the original hash of the file
- memStream.Seek(0, SeekOrigin.Begin);
- catalogFileEntry.OriginalHash = sha.ComputeHash(memStream);
-
// Add poison marker to assemblies
try
{
AssemblyName asm = AssemblyName.GetAssemblyName(file);
Poison(file);
- // then get the hash of the now-poisoned file
+ var catalogFileEntry = new CatalogFileEntry();
+ packageEntry.Files.Add(catalogFileEntry);
+ catalogFileEntry.Path = Utility.MakeRelativePath(file, packageTempPath);
+
using (var stream = File.OpenRead(file))
{
catalogFileEntry.PoisonedHash = sha.ComputeHash(stream);
diff --git a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/PoisonedFileEntry.cs b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/PoisonedFileEntry.cs
index 374105e3d1a7..09b06cab0561 100644
--- a/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/PoisonedFileEntry.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.SourceBuild.Tasks.LeakDetection/PoisonedFileEntry.cs
@@ -31,7 +31,11 @@ internal PoisonedFileEntry()
new XAttribute(nameof(Path), Path),
new XElement(nameof(Hash), Hash.ToHexString()),
new XElement(nameof(Type), Type.ToString()),
- Matches.Select(m => m.ToXml())
+ // Order matches to ensure the output is deterministic across runs
+ Matches
+ .OrderBy(m => m.Package)
+ .ThenBy(m => m.File)
+ .Select(m => m.ToXml())
);
}
}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Config.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Config.cs
new file mode 100644
index 000000000000..1c83da016fb2
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Config.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.Versioning;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks;
+
+internal static class Config
+{
+ private static readonly string _taskAssemblyLocation =
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ??
+ throw new InvalidOperationException("Unable to determine task assembly location.");
+
+ private static readonly string _staticDirectory = Path.Combine(_taskAssemblyLocation, "static");
+
+ private const string EmptyProjectFileName = "empty.proj";
+ public const string SigningPropsFileName = "Signing.props";
+
+ public static string EmptyProjectPath => Path.Combine(_staticDirectory, EmptyProjectFileName);
+ public static string SigningPropsPath => Path.Combine(_staticDirectory, SigningPropsFileName);
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/CreateSourceArtifact.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/CreateSourceArtifact.cs
new file mode 100644
index 000000000000..ad07a66b565d
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/CreateSourceArtifact.cs
@@ -0,0 +1,92 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.Build.Framework;
+using Microsoft.DotNet.UnifiedBuild.Tasks.Services;
+using BuildTask = Microsoft.Build.Utilities.Task;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks;
+
+public class CreateSourceArtifact : BuildTask
+{
+ ///
+ /// Commit SHA of the VMR source to download
+ ///
+ [Required]
+ public required string SourceCommit { get; init; }
+
+ ///
+ /// Name of the artifact to generate
+ ///
+ [Required]
+ public required string ArtifactName { get; init; }
+
+ ///
+ /// The stable sdk version
+ /// Should match the sdk tag associated with a release
+ /// Used for artifact prefixing
+ ///
+ [Required]
+ public required string SdkStableVersion { get; init; }
+
+ ///
+ /// The build/non-stable sdk version
+ /// Used for artifact versioning
+ ///
+ [Required]
+ public required string SdkNonStableVersion { get; init; }
+
+ ///
+ /// Path to the root of the repo
+ ///
+ [Required]
+ public required string RepoRoot { get; init; }
+
+ ///
+ /// Path to the directory to place the source artifacts in
+ ///
+ [Required]
+ public required string OutputDirectory { get; init; }
+
+ private const string GitHubRepoName = "dotnet";
+ private const string GitHubTimezone = "America/Los_Angeles"; // GitHub uses this timezone for commit timestamps in zip metadata
+ private const int GitArchiveTimeout = 5 * 60 * 1000; // 5 minutes
+ private const string TarExtension = "tar.gz";
+
+ public override bool Execute() => ExecuteAsync().GetAwaiter().GetResult();
+
+ private async Task ExecuteAsync()
+ {
+ var processService = new ProcessService(Log, GitArchiveTimeout);
+
+ string artifactFilePath = Path.Combine(OutputDirectory, $"{ArtifactName}-{SdkNonStableVersion}.{TarExtension}");
+
+ Log.LogMessage(MessageImportance.High, $"Creating {TarExtension} source artifact at: {artifactFilePath}");
+
+ try
+ {
+ ProcessResult result = await processService.RunProcessAsync(
+ "git",
+ $"-c \"tar.tar.gz.command=gzip -cn\" archive --format={TarExtension} --output \"{artifactFilePath}\" --prefix \"{GitHubRepoName}-{SdkStableVersion}/\" {SourceCommit}",
+ environmentVariables: new List { new ProcessEnvironmentVariable("TZ", GitHubTimezone) },
+ workingDirectory: RepoRoot
+ );
+
+ if (result.ExitCode != 0)
+ {
+ Log.LogError($"[{TarExtension}] Git exited with code {result.ExitCode}: {result.Error}");
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.LogError($"[{TarExtension}] Exception during artifact creation: {ex.Message}");
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/GetDependencyNamesFromVersionDetails.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/GetDependencyNamesFromVersionDetails.cs
new file mode 100644
index 000000000000..3f7d02bbc6b8
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/GetDependencyNamesFromVersionDetails.cs
@@ -0,0 +1,60 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks
+{
+ ///
+ /// Reads a Version.Details.xml file and returns the list of non-pinned dependency package names.
+ ///
+ public class GetDependencyNamesFromVersionDetails : Microsoft.Build.Utilities.Task
+ {
+ private const string PinnedAttributeName = "Pinned";
+ private const string DependencyAttributeName = "Dependency";
+ private const string NameAttributeName = "Name";
+
+ ///
+ /// Path to the Version.Details.xml file.
+ ///
+ [Required]
+ public string VersionDetailsPath { get; set; }
+
+ ///
+ /// Output: Array of dependency package names found in the Version.Details.xml file.
+ /// Excludes pinned dependencies.
+ ///
+ [Output]
+ public string[] DependencyNames { get; set; }
+
+ public override bool Execute()
+ {
+ if (string.IsNullOrEmpty(VersionDetailsPath) || !File.Exists(VersionDetailsPath))
+ {
+ Log.LogError($"The VersionDetailsPath must point to a valid Version.Details.xml file. " +
+ $"Provided file path '{VersionDetailsPath}' does not exist.");
+ return false;
+ }
+
+ HashSet dependencies = VersionDetailsHelper.GetDependencies(VersionDetailsPath, Log);
+
+ if (Log.HasLoggedErrors)
+ {
+ return false;
+ }
+
+ DependencyNames = dependencies
+ .OrderBy(name => name, StringComparer.OrdinalIgnoreCase)
+ .ToArray();
+
+ return true;
+ }
+ }
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Microsoft.DotNet.UnifiedBuild.Tasks.csproj b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Microsoft.DotNet.UnifiedBuild.Tasks.csproj
index a974280c841e..746c6282d69b 100644
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Microsoft.DotNet.UnifiedBuild.Tasks.csproj
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Microsoft.DotNet.UnifiedBuild.Tasks.csproj
@@ -13,4 +13,8 @@
+
+
+
+
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Services/ProcessService.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Services/ProcessService.cs
new file mode 100644
index 000000000000..6e2be154f290
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/Services/ProcessService.cs
@@ -0,0 +1,117 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Task = System.Threading.Tasks.Task;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks.Services;
+
+public record ProcessEnvironmentVariable(string Name, string Value);
+public record ProcessResult(string Output, string Error, int ExitCode);
+
+public class ProcessService(TaskLoggingHelper log, int timeout = 10 * 1000)
+{
+ private TaskLoggingHelper Log { get; } = log;
+ private TimeSpan Timeout { get; } = TimeSpan.FromMilliseconds(timeout);
+
+ public async Task RunProcessAsync(
+ string command,
+ string arguments,
+ List? environmentVariables = null,
+ string workingDirectory = "",
+ bool printOutput = false)
+ {
+ var processInfo = new ProcessStartInfo
+ {
+ FileName = command,
+ Arguments = arguments,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ WorkingDirectory = workingDirectory
+ };
+
+ if (environmentVariables != null)
+ {
+ foreach (ProcessEnvironmentVariable env in environmentVariables)
+ {
+ processInfo.EnvironmentVariables[env.Name] = env.Value;
+ }
+ }
+
+ using var process = new Process { StartInfo = processInfo, EnableRaisingEvents = true };
+
+ var outputBuilder = new StringBuilder();
+ var errorBuilder = new StringBuilder();
+
+ var outputTcs = new TaskCompletionSource();
+ var errorTcs = new TaskCompletionSource();
+
+ process.OutputDataReceived += (s, e) =>
+ {
+ if (e.Data == null)
+ {
+ outputTcs.TrySetResult();
+ return;
+ }
+
+ outputBuilder.AppendLine(e.Data);
+ if (printOutput)
+ {
+ Log.LogMessage(MessageImportance.High, e.Data);
+ }
+ };
+
+ process.ErrorDataReceived += (s, e) =>
+ {
+ if (e.Data == null)
+ {
+ errorTcs.TrySetResult();
+ return;
+ }
+
+ errorBuilder.AppendLine(e.Data);
+ if (printOutput)
+ {
+ Log.LogMessage(MessageImportance.High, e.Data);
+ }
+ };
+
+ if (!process.Start())
+ {
+ throw new InvalidOperationException($"Failed to start process: {command} {arguments}");
+ }
+
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+
+ using var timeoutCts = new CancellationTokenSource(Timeout);
+
+ var exitedTask = Task.Run(() => process.WaitForExit(), timeoutCts.Token);
+
+ try
+ {
+ await exitedTask;
+ await Task.WhenAll(outputTcs.Task, errorTcs.Task);
+ }
+ catch (OperationCanceledException)
+ {
+ try { process.Kill(entireProcessTree: true); } catch { }
+ throw new TimeoutException($"Process timed out after {Timeout.TotalMilliseconds} ms");
+ }
+
+ return new ProcessResult(
+ Output: outputBuilder.ToString(),
+ Error: errorBuilder.ToString(),
+ ExitCode: process.ExitCode
+ );
+ }
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SignSourceBuiltArtifacts.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SignSourceBuiltArtifacts.cs
new file mode 100644
index 000000000000..ba21f1489870
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SignSourceBuiltArtifacts.cs
@@ -0,0 +1,143 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using Microsoft.Build.Framework;
+using Microsoft.DotNet.UnifiedBuild.Tasks.Services;
+using BuildTask = Microsoft.Build.Utilities.Task;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks;
+
+public class SignSourceBuiltArtifacts : BuildTask
+{
+ ///
+ /// List of source-built assets to sign
+ ///
+ [Required]
+ public required ITaskItem[] SignableSourceBuiltAssets { get; init; }
+
+ ///
+ /// Path to the eng directory
+ ///
+ [Required]
+ public required string DotNetEngDirectory { get; init; }
+
+ ///
+ /// Path to the logs directory
+ ///
+ [Required]
+ public required string LogsDirectory { get; init; }
+
+ ///
+ /// Sign-specific properties to pass to the signing process
+ ///
+ public string SignProperties { get; init; } = string.Empty;
+
+ ///
+ /// The official build ID
+ ///
+ public string OfficialBuildId { get; init; } = string.Empty;
+
+ private string SigningPropsTargetPath => Path.Combine(DotNetEngDirectory, Config.SigningPropsFileName);
+ private const string SignBinlogFileName = "sign-source-built-artifacts.binlog";
+ private const int SigningTimeout = 60 * 60 * 1000 * 2; // 2 hours
+
+ public override bool Execute() => ExecuteAsync().GetAwaiter().GetResult();
+
+ private async Task ExecuteAsync()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ Log.LogError("Windows is not supported for signing.");
+ return false;
+ }
+
+ try
+ {
+ PrepareForSigning();
+ await RunSigningAsync();
+ Log.LogMessage(MessageImportance.High, "Signing complete.");
+ }
+ catch (Exception ex)
+ {
+ Log.LogError($"Signing failed: {ex.Message}");
+ }
+ finally
+ {
+ CleanupSigning();
+ }
+
+ return !Log.HasLoggedErrors;
+ }
+
+ private void PrepareForSigning()
+ {
+ if (!Directory.Exists(LogsDirectory))
+ {
+ Directory.CreateDirectory(LogsDirectory);
+ }
+
+ // Place the Signing.props file into the repo's eng directory for
+ // Arcade's signing infra to find
+ File.Copy(Config.SigningPropsPath, SigningPropsTargetPath, overwrite: true);
+ }
+
+ private void CleanupSigning()
+ {
+ if (File.Exists(SigningPropsTargetPath))
+ {
+ File.Delete(SigningPropsTargetPath);
+ }
+ }
+
+ ///
+ /// Runs the signing process
+ ///
+ private async Task RunSigningAsync()
+ {
+ (string command, string arguments) = GetSigningCommandAndArguments();
+ Log.LogMessage(MessageImportance.High, $"Running signing command: {command} {arguments}");
+
+ var processService = new ProcessService(Log, timeout: SigningTimeout);
+ ProcessResult result = await processService.RunProcessAsync(
+ command,
+ arguments,
+ environmentVariables: new List { new ProcessEnvironmentVariable("OPENSSL_ENABLE_SHA1_SIGNATURES", "1") },
+ printOutput: true);
+
+ if (result.ExitCode != 0)
+ {
+ Log.LogError($"Signing failed with exit code {result.ExitCode}");
+ }
+ }
+
+ ///
+ /// Gets the command and arguments to run signing
+ ///
+ private (string command, string arguments) GetSigningCommandAndArguments()
+ {
+ string buildScript = Path.Combine(DotNetEngDirectory, "common", "build.sh");
+ string binlog = Path.Combine(LogsDirectory, SignBinlogFileName);
+ string signableAssets = string.Join(';', SignableSourceBuiltAssets.Select(a => a.ItemSpec));
+
+ string arguments =
+ $"--ci " +
+ $"--configuration Release " +
+ $"--restore " +
+ $"--projects {Config.EmptyProjectPath} " +
+ $"--sign " +
+ $"--excludecibinarylog " +
+ $"/bl:{binlog} " +
+ $"/p:OfficialBuildId={OfficialBuildId} " +
+ $"/p:SignableSourceBuiltAssets=\\\"{signableAssets}\\\" " +
+ $"{SignProperties}";
+
+ return (buildScript, arguments);
+ }
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SigningValidation.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SigningValidation.cs
index 84b1e4a1acd1..cc1ee51326e1 100644
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SigningValidation.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/SigningValidation.cs
@@ -12,12 +12,14 @@
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
+using System.Threading.Tasks;
using System.Xml.Linq;
-using Task = System.Threading.Tasks.Task;
+using Microsoft.DotNet.UnifiedBuild.Tasks.Services;
+using BuildTask = Microsoft.Build.Utilities.Task;
namespace Microsoft.DotNet.UnifiedBuild.Tasks;
-public class SigningValidation : Microsoft.Build.Utilities.Task
+public class SigningValidation : BuildTask
{
///
/// Directory where the blobs and packages were downloaded to
@@ -58,13 +60,16 @@ public class SigningValidation : Microsoft.Build.Utilities.Task
///
private static readonly string _signCheckFilesDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(), "SignCheckFiles");
+ private const string _signCheckBinLogFileName = "signing-validation.binlog";
private const string _signCheckExclusionsFileName = "SignCheckExclusionsFile.txt";
private const string _signCheckStdoutLogFileName = "signcheck.log";
private const string _signCheckStderrLogFileName = "signcheck.error.log";
private const string _signCheckResultsXmlFileName = "signcheck.xml";
private const int _signCheckTimeout = 60 * 60 * 1000 * 2; // 2 hours
- public override bool Execute()
+ public override bool Execute() => ExecuteAsync().GetAwaiter().GetResult();
+
+ private async Task ExecuteAsync()
{
try
{
@@ -72,7 +77,7 @@ public override bool Execute()
PrepareFilesToSignCheck();
- RunSignCheck();
+ await RunSignCheckAsync();
ProcessSignCheckResults();
@@ -108,23 +113,33 @@ private void PrepareFilesToSignCheck()
var manifestsDir = Path.Combine(artifactDirectory, "manifests");
if (!Directory.Exists(manifestsDir))
{
- continue;
+ Log.LogMessage(MessageImportance.High,
+ $" No manifests in '{artifactDirectory}' to parse for files to sign check. " +
+ $"All files defined in the directory will be included...");
+ filesToSignCheck.AddRange(Directory.EnumerateFiles(artifactDirectory, "*", SearchOption.AllDirectories)
+ .Select(file => (artifactDirectory, Path.GetRelativePath(artifactDirectory, file))));
}
- foreach (string manifest in Directory.EnumerateFiles(manifestsDir, "*.xml", SearchOption.AllDirectories))
+ else
{
- using (Stream xmlStream = File.OpenRead(manifest))
+ Log.LogMessage(MessageImportance.High,
+ $" Parsing manifests in '{manifestsDir}' for files to sign check. " +
+ $"All blobs and packages defined in the manifests will be included...");
+ foreach (string manifest in Directory.EnumerateFiles(manifestsDir, "*.xml", SearchOption.AllDirectories))
{
- XDocument doc = XDocument.Load(xmlStream);
-
- // Extract blobs
- filesToSignCheck.AddRange(doc.Descendants("Blob")
- .Where(blob => IsReleaseShipping(blob) && IsExternallyVisible(blob))
- .Select(blob => (artifactDirectory, ExtractAttribute(blob, "PipelineArtifactPath"))));
-
- // Extract packages
- filesToSignCheck.AddRange(doc.Descendants("Package")
- .Where(pkg => IsReleaseShipping(pkg) && IsExternallyVisible(pkg))
- .Select(pkg => (artifactDirectory, ExtractAttribute(pkg, "PipelineArtifactPath"))));
+ using (Stream xmlStream = File.OpenRead(manifest))
+ {
+ XDocument doc = XDocument.Load(xmlStream);
+
+ // Extract blobs
+ filesToSignCheck.AddRange(doc.Descendants("Blob")
+ .Where(blob => IsReleaseShipping(blob) && IsExternallyVisible(blob))
+ .Select(blob => (artifactDirectory, ExtractAttribute(blob, "PipelineArtifactPath"))));
+
+ // Extract packages
+ filesToSignCheck.AddRange(doc.Descendants("Package")
+ .Where(pkg => IsReleaseShipping(pkg) && IsExternallyVisible(pkg))
+ .Select(pkg => (artifactDirectory, ExtractAttribute(pkg, "PipelineArtifactPath"))));
+ }
}
}
}
@@ -174,56 +189,33 @@ private void PrepareFilesToSignCheck()
///
/// Runs the signcheck task on the specified package base path
///
- private void RunSignCheck()
+ private async Task RunSignCheckAsync()
{
- using (var process = new Process())
+ (string command, string arguments) = GetSignCheckCommandAndArguments();
+ Log.LogMessage(MessageImportance.High, $"Running SignCheck...");
+
+ var processService = new ProcessService(Log, timeout: _signCheckTimeout);
+ ProcessResult result = await processService.RunProcessAsync(
+ command,
+ arguments,
+ printOutput: false);
+
+ string errorLog = GetLogPath(_signCheckStderrLogFileName);
+ string errorLogContent = File.Exists(errorLog) ? File.ReadAllText(errorLog).Trim() : string.Empty;
+ if (result.ExitCode != 0 || !string.IsNullOrWhiteSpace(errorLogContent))
{
- (string command, string arguments) = GetSignCheckCommandAndArguments();
-
- process.StartInfo = new ProcessStartInfo()
- {
- FileName = command,
- Arguments = arguments,
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- };
-
- // SignCheck writes console output to log files and the output stream.
- // To avoid cluttering the console, redirect the output to empty handlers.
- process.OutputDataReceived += (sender, args) => { };
- process.ErrorDataReceived += (sender, args) => { };
-
- Log.LogMessage(MessageImportance.High, $"Running SignCheck...");
-
- process.Start();
-
- process.BeginOutputReadLine();
- process.BeginErrorReadLine();
-
- bool hasExited = process.WaitForExit(_signCheckTimeout);
- if (!hasExited)
- {
- throw new TimeoutException($"SignCheck timed out after {_signCheckTimeout / 1000} seconds.");
- }
-
- string errorLog = GetLogPath(_signCheckStderrLogFileName);
- string errorLogContent = File.Exists(errorLog) ? File.ReadAllText(errorLog).Trim() : string.Empty;
- if (process.ExitCode != 0 || !string.IsNullOrWhiteSpace(errorLogContent))
- {
- // We don't want to throw here because SignCheck will fail for unsigned files
- Log.LogError($"SignCheck failed with exit code {process.ExitCode}: {errorLogContent}");
- }
-
- string stdoutLog = GetLogPath(_signCheckStdoutLogFileName);
- string stdoutLogContent = File.Exists(stdoutLog) ? File.ReadAllText(stdoutLog).Trim() : string.Empty;
- if (!string.IsNullOrWhiteSpace(stdoutLogContent) && stdoutLogContent.Contains("No files were processed"))
- {
- Log.LogError("SignCheck did not process any files.");
- }
+ // We don't want to throw here because SignCheck will fail for unsigned files
+ Log.LogError($"SignCheck failed with exit code {result.ExitCode}: {errorLogContent}");
+ }
- Log.LogMessage(MessageImportance.High, $"SignCheck completed.");
+ string stdoutLog = GetLogPath(_signCheckStdoutLogFileName);
+ string stdoutLogContent = File.Exists(stdoutLog) ? File.ReadAllText(stdoutLog).Trim() : string.Empty;
+ if (!string.IsNullOrWhiteSpace(stdoutLogContent) && stdoutLogContent.Contains("No files were processed"))
+ {
+ Log.LogError("SignCheck did not process any files.");
}
+
+ Log.LogMessage(MessageImportance.High, $"SignCheck completed.");
}
private void ProcessSignCheckResults()
@@ -299,7 +291,9 @@ private bool LogAndCheckResults(IEnumerable results, string issueType)
///
private (string command, string arguments) GetSignCheckCommandAndArguments()
{
- string sdkTaskScript = Path.Combine(DotNetRootDirectory, "eng", "common", "sdk-task");
+ // Target sdk-task scripts from Arcade to catch and fix issues with the scripts between releases
+ // This reduces our exposure to known issues in the local VMR copy and improves build reliability during the VMR bootstrap window.
+ string sdkTaskScript = Path.Combine(DotNetRootDirectory, "src", "arcade", "eng", "common", "sdk-task");
string argumentsTemplate =
$"'{sdkTaskScript}.$scriptExtension$' " +
@@ -312,6 +306,7 @@ private bool LogAndCheckResults(IEnumerable results, string issueType)
$"/p:SignCheckErrorLog='{GetLogPath(_signCheckStderrLogFileName)}' " +
$"/p:SignCheckResultsXmlFile='{GetLogPath(_signCheckResultsXmlFileName)}' " +
$"/p:SignCheckExclusionsFile='{GetSignCheckExclusionsFile()}' " +
+ $"/bl:{GetLogPath(_signCheckBinLogFileName)} " +
$"$additionalArgs$";
string command = string.Empty;
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/ValidateUsageAgainstBaseline.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/ValidateUsageAgainstBaseline.cs
deleted file mode 100644
index ea30a676c37b..000000000000
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/ValidateUsageAgainstBaseline.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#nullable disable
-
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
-using NuGet.Packaging.Core;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Xml.Linq;
-
-namespace Microsoft.DotNet.UnifiedBuild.Tasks.UsageReport
-{
- public class ValidateUsageAgainstBaseline : Task
- {
- [Required]
- public string DataFile { get; set; }
-
- [Required]
- public string OutputBaselineFile { get; set; }
-
- [Required]
- public string OutputReportFile { get; set; }
-
- public bool AllowTestProjectUsage { get; set; }
-
- public string BaselineDataFile { get; set; }
-
- public override bool Execute()
- {
- var used = UsageData.Parse(XElement.Parse(File.ReadAllText(DataFile)));
-
- IEnumerable baselineUsages;
- if (File.Exists(BaselineDataFile))
- {
- baselineUsages = UsageData.Parse(XElement.Parse(File.ReadAllText(BaselineDataFile))).Usages;
- }
- else
- {
- baselineUsages = Enumerable.Empty();
- }
-
- Comparison diff = Compare(
- used.Usages.Select(u => u.GetIdentityWithoutRid()).Distinct(),
- baselineUsages.Select(u => u.GetIdentityWithoutRid()).Distinct());
-
- var report = new XElement("BaselineComparison");
-
- bool tellUserToUpdateBaseline = false;
-
- if (diff.Added.Any())
- {
- tellUserToUpdateBaseline = true;
- Log.LogError(
- $"{diff.Added.Length} new packages used not in baseline! See report " +
- $"at {OutputReportFile} for more information. Package IDs are:\n" +
- string.Join("\n", diff.Added.Select(u => u.ToString())));
-
- // In the report, list full usage info, not only identity.
- report.Add(
- new XElement(
- "New",
- used.Usages
- .Where(u => diff.Added.Contains(u.GetIdentityWithoutRid()))
- .Select(u => u.ToXml())));
- }
- if (diff.Removed.Any())
- {
- tellUserToUpdateBaseline = true;
- Log.LogMessage(
- MessageImportance.High,
- $"{diff.Removed.Length} packages in baseline weren't used!");
-
- report.Add(new XElement("Removed", diff.Removed.Select(id => id.ToXElement())));
- }
- if (diff.Unchanged.Any())
- {
- Log.LogMessage(
- MessageImportance.High,
- $"{diff.Unchanged.Length} packages used as expected in the baseline.");
- }
-
- if (!AllowTestProjectUsage)
- {
- Usage[] testProjectUsages = used.Usages
- .Where(WriteUsageReports.IsTestUsageByHeuristic)
- .ToArray();
-
- if (testProjectUsages.Any())
- {
- string[] projects = testProjectUsages
- .Select(u => u.AssetsFile)
- .Distinct()
- .ToArray();
-
- Log.LogError(
- $"{testProjectUsages.Length} forbidden test usages found in " +
- $"{projects.Length} projects:\n" +
- string.Join("\n", projects));
- }
- }
-
- // Simplify the used data to what is necessary for a baseline, to reduce file size.
- foreach (var usage in used.Usages)
- {
- usage.AssetsFile = null;
- }
- used.Usages = used.Usages.Distinct().ToArray();
-
- Directory.CreateDirectory(Path.GetDirectoryName(OutputBaselineFile));
- File.WriteAllText(OutputBaselineFile, used.ToXml().ToString());
-
- Directory.CreateDirectory(Path.GetDirectoryName(OutputReportFile));
- File.WriteAllText(OutputReportFile, report.ToString());
-
- if (tellUserToUpdateBaseline)
- {
- Log.LogWarning(
- "Prebuilt usages are different from the baseline. If detected changes are " +
- "acceptable, update baseline with:\n" +
- $"cp '{OutputBaselineFile}' '{BaselineDataFile}'");
- }
-
- return !Log.HasLoggedErrors;
- }
-
- private static Comparison Compare(IEnumerable actual, IEnumerable baseline)
- {
- return new Comparison(actual.ToArray(), baseline.ToArray());
- }
-
- private class Comparison
- {
- public T[] Added { get; }
- public T[] Removed { get; }
- public T[] Unchanged { get; }
-
- public Comparison(
- IEnumerable actual,
- IEnumerable baseline)
- {
- Added = actual.Except(baseline).ToArray();
- Removed = baseline.Except(actual).ToArray();
- Unchanged = actual.Intersect(baseline).ToArray();
- }
- }
- }
-}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteAnnotatedUsageReport.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteAnnotatedUsageReport.cs
new file mode 100644
index 000000000000..f9396eb0df1b
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteAnnotatedUsageReport.cs
@@ -0,0 +1,256 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#nullable disable
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks.UsageReport
+{
+ public class WriteAnnotatedUsageReport : Task
+ {
+ private const string SnapshotPrefix = "PackageVersions.";
+ private const string SnapshotSuffix = ".Snapshot.props";
+
+ ///
+ /// Source usage data JSON file.
+ ///
+ [Required]
+ public string DataFile { get; set; }
+
+ ///
+ /// Suffix to use for the version property name.
+ ///
+ [Required]
+ public string VersionPropertySuffix { get; set; }
+
+ ///
+ /// A set of "PackageVersions.{repo}.Snapshot.props" files. They are analyzed to find
+ /// packages built during source-build, and which repo built them. This info is added to the
+ /// report. New packages are associated to a repo by going through each PVP in ascending
+ /// file modification order.
+ ///
+ public ITaskItem[] PackageVersionPropsSnapshots { get; set; }
+
+ ///
+ /// File containing the results of poisoning the prebuilts. Example format:
+ ///
+ /// MATCH: output built\dotnet-sdk-...\System.Collections.dll(hash 4b...31) matches one of:
+ /// intermediate\netstandard.library.2.0.1.nupkg\build\...\System.Collections.dll
+ ///
+ /// The usage report reads this file, looking for 'intermediate\*.nupkg' to annotate.
+ ///
+ public string PoisonedReportFile { get; set; }
+
+ ///
+ /// Path to write the prebuilt annotated usage report file.
+ ///
+ [Required]
+ public string PrebuiltAnnotatedUsageReportFile { get; set; }
+
+ public override bool Execute()
+ {
+ UsageData data = UsageData.Parse(XElement.Parse(File.ReadAllText(DataFile)));
+ IEnumerable sourceBuildRepoOutputs = GetSourceBuildRepoOutputs();
+
+ var poisonNupkgFilenames = new HashSet(StringComparer.OrdinalIgnoreCase);
+
+ if (File.Exists(PoisonedReportFile))
+ {
+ foreach (string line in File.ReadAllLines(PoisonedReportFile))
+ {
+ string[] segments = line.Split('\\');
+ if (segments.Length > 2 &&
+ segments[0].Trim() == "intermediate" &&
+ segments[1].EndsWith(".nupkg"))
+ {
+ poisonNupkgFilenames.Add(Path.GetFileNameWithoutExtension(segments[1]));
+ }
+ }
+ }
+
+ var report = new XElement("AnnotatedUsages");
+
+ var annotatedUsages = data.Usages.NullAsEmpty()
+ .Select(usage =>
+ {
+ string id = usage.PackageIdentity.Id;
+ string version = usage.PackageIdentity.Version.OriginalVersion;
+
+ string pvpIdent = WritePackageVersionsProps.GetPropertyName(id, VersionPropertySuffix);
+
+ var sourceBuildCreator = new StringBuilder();
+ foreach (RepoOutput output in sourceBuildRepoOutputs)
+ {
+ foreach (PackageVersionPropsElement p in output.Built)
+ {
+ if (p.Name.Equals(pvpIdent, StringComparison.OrdinalIgnoreCase))
+ {
+ if (sourceBuildCreator.Length != 0)
+ {
+ sourceBuildCreator.Append(" ");
+ }
+ sourceBuildCreator.Append(output.Repo);
+ sourceBuildCreator.Append(" ");
+ sourceBuildCreator.Append(p.Name);
+ sourceBuildCreator.Append("/");
+ sourceBuildCreator.Append(p.Version);
+ }
+ }
+ }
+
+ return new AnnotatedUsage
+ {
+ Usage = usage,
+
+ Project = data.ProjectDirectories
+ ?.FirstOrDefault(p => usage.AssetsFile?.StartsWith(p) ?? false),
+
+ SourceBuildPackageIdCreator = sourceBuildCreator.Length == 0
+ ? null
+ : sourceBuildCreator.ToString(),
+
+ TestProjectByHeuristic = IsTestUsageByHeuristic(usage),
+
+ EndsUpInOutput = poisonNupkgFilenames.Contains($"{id}.{version}")
+ };
+ })
+ .ToArray();
+
+ foreach (var onlyTestProjectUsage in annotatedUsages
+ .GroupBy(u => u.Usage.PackageIdentity)
+ .Where(g => g.All(u => u.TestProjectByHeuristic))
+ .SelectMany(g => g))
+ {
+ onlyTestProjectUsage.TestProjectOnlyByHeuristic = true;
+ }
+
+ report.Add(annotatedUsages.Select(u => u.ToXml()));
+
+ Directory.CreateDirectory(Path.GetDirectoryName(PrebuiltAnnotatedUsageReportFile));
+ File.WriteAllText(PrebuiltAnnotatedUsageReportFile, report.ToString());
+
+ return !Log.HasLoggedErrors;
+ }
+
+ private RepoOutput[] GetSourceBuildRepoOutputs()
+ {
+ var pvpSnapshotFiles = PackageVersionPropsSnapshots.NullAsEmpty()
+ .Select(item =>
+ {
+ var content = File.ReadAllText(item.ItemSpec);
+ return new
+ {
+ Path = item.ItemSpec,
+ Content = content,
+ Xml = XElement.Parse(content)
+ };
+ })
+ .OrderBy(snapshot =>
+ {
+ // Get the embedded creation time if possible: the file's original metadata may
+ // have been destroyed by copying, zipping, etc.
+ string creationTime = snapshot.Xml
+ // Get all elements
+ .Elements()
+ // Select all the subelements
+ .SelectMany(e => e.Elements())
+ // Find all that match the creation time property name
+ .Where(e => e.Name == snapshot.Xml.GetDefaultNamespace().GetName(WritePackageVersionsProps.CreationTimePropertyName))
+ // There should be only one or zero
+ .SingleOrDefault()?.Value;
+
+ if (string.IsNullOrEmpty(creationTime))
+ {
+ Log.LogError($"No creation time property found in snapshot {snapshot.Path}");
+ return default(DateTime);
+ }
+
+ return new DateTime(long.Parse(creationTime));
+ })
+ .Select(snapshot =>
+ {
+ string filename = Path.GetFileName(snapshot.Path);
+ return new
+ {
+ Repo = filename.Substring(
+ SnapshotPrefix.Length,
+ filename.Length - SnapshotPrefix.Length - SnapshotSuffix.Length),
+ PackageVersionProp = PackageVersionPropsElement.Parse(snapshot.Xml)
+ };
+ })
+ .ToArray();
+
+ return pvpSnapshotFiles.Skip(1)
+ .Zip(pvpSnapshotFiles, (pvp, prev) => new RepoOutput
+ {
+ Repo = prev.Repo,
+ Built = pvp.PackageVersionProp.Except(prev.PackageVersionProp).ToArray()
+ })
+ .ToArray();
+ }
+
+ public static bool IsTestUsageByHeuristic(Usage usage)
+ {
+ string[] assetsFileParts = usage.AssetsFile?.Split('/', '\\');
+
+ // If the dir name ends in Test(s), it's probably a test project.
+ // Ignore the first two segments to avoid classifying everything in "src/vstest".
+ // This also catches "test" dirs that contain many test projects.
+ if (assetsFileParts?.Skip(2).Any(p =>
+ p.EndsWith("Tests", StringComparison.OrdinalIgnoreCase) ||
+ p.EndsWith("Test", StringComparison.OrdinalIgnoreCase)) == true)
+ {
+ return true;
+ }
+
+ // CoreFX restores test dependencies during this sync project.
+ if (assetsFileParts?.Contains("XUnit.Runtime") == true)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private class RepoOutput
+ {
+ public string Repo { get; set; }
+ public PackageVersionPropsElement[] Built { get; set; }
+ }
+
+ private struct PackageVersionPropsElement
+ {
+ public static PackageVersionPropsElement[] Parse(XElement xml)
+ {
+ return xml
+ // Get the first PropertyGroup. The second PropertyGroup is 'extra properties', and the third group is the creation time.
+ // Only select the first because the extra properties are not built packages.
+ .Elements()
+ .First()
+ // Get all *PackageVersion property elements.
+ .Elements()
+ .Select(x => new PackageVersionPropsElement(
+ x.Name.LocalName,
+ x.Nodes().OfType().First().Value))
+ .ToArray();
+ }
+
+ public string Name { get; }
+ public string Version { get; }
+
+ public PackageVersionPropsElement(string name, string version)
+ {
+ Name = name;
+ Version = version;
+ }
+ }
+ }
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WritePackageUsageData.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WritePackageUsageData.cs
index 36b317f380d3..b5d44e139e4e 100644
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WritePackageUsageData.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WritePackageUsageData.cs
@@ -83,6 +83,13 @@ public class WritePackageUsageData : Task
///
public string ProjectAssetsJsonArchiveFile { get; set; }
+ ///
+ /// Output: List of prebuilt packages detected.
+ /// Each item has PackageId and PackageVersion metadata.
+ ///
+ [Output]
+ public ITaskItem[] PrebuiltPackages { get; set; }
+
public override bool Execute()
{
DateTime startTime = DateTime.Now;
@@ -256,6 +263,16 @@ public override bool Execute()
Directory.CreateDirectory(Path.GetDirectoryName(DataFile));
File.WriteAllText(DataFile, data.ToXml().ToString());
+ PrebuiltPackages = prebuilt
+ .Select(p => new Microsoft.Build.Utilities.TaskItem(
+ p.ToString(),
+ new Dictionary
+ {
+ { "PackageId", p.Id },
+ { "PackageVersion", p.Version.ToNormalizedString() }
+ }))
+ .ToArray();
+
Log.LogMessage(MessageImportance.Normal, $"Writing package usage data... done. Took {DateTime.Now - startTime}");
return !Log.HasLoggedErrors;
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteUsageBurndownData.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteUsageBurndownData.cs
deleted file mode 100644
index 6fc172538a96..000000000000
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteUsageBurndownData.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#nullable disable
-
-using Microsoft.Build.Framework;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using NuGet.Packaging.Core;
-using NuGet.Versioning;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using System.Xml.Linq;
-using Task = Microsoft.Build.Utilities.Task;
-
-namespace Microsoft.DotNet.UnifiedBuild.Tasks.UsageReport
-{
- public class WriteUsageBurndownData : Task
- {
- ///
- /// Specifies the root directory for git.
- /// Note: Requires a trailing "/" when specifying the directory.
- ///
- [Required]
- public string RootDirectory { get; set; }
-
- ///
- /// Specifies the path to the prebuilt baseline file
- /// to be used to generate the burndown.
- ///
- [Required]
- public string PrebuiltBaselineFile { get; set; }
-
- ///
- /// Output data CSV file.
- ///
- [Required]
- public string OutputFilePath { get; set; }
-
- ///
- /// Sends HTTP requests and receives HTTP responses.
- ///
- private readonly HttpClient client = new();
-
- public override bool Execute() => ExecuteAsync().GetAwaiter().GetResult();
-
- private async Task ExecuteAsync()
- {
- string baselineRelativeFileName = PrebuiltBaselineFile.Replace(RootDirectory, "");
- string gitLogCommand = $"log --first-parent --pretty=format:%H,%f,%ci -- {PrebuiltBaselineFile}";
-
- DateTime startTime = DateTime.Now;
- Log.LogMessage(MessageImportance.High, "Generating summary usage burndown data...");
-
-
- IEnumerable> getCommitTasks = ExecuteGitCommand(RootDirectory, gitLogCommand)
- .Select(async commitLine =>
- {
- var splitLine = commitLine.Split(',');
- var commit = new Commit()
- {
- Sha = splitLine[0],
- Title = splitLine[1],
- CommitDate = DateTime.Parse(splitLine[2])
- };
- string fileContents = await GetFileContentsAsync(baselineRelativeFileName, commit.Sha);
- Usage[] usages = UsageData.Parse(XElement.Parse(fileContents)).Usages.NullAsEmpty().ToArray();
- commit.PackageVersionCount = usages.Count();
- commit.PackageCount = usages.GroupBy(i => i.PackageIdentity.Id).Select(grp => grp.First()).Count();
- return commit;
- });
-
- Commit[] commits = await System.Threading.Tasks.Task.WhenAll(getCommitTasks);
- IEnumerable data = commits.Select(c => c.ToString());
-
- Directory.CreateDirectory(Path.GetDirectoryName(OutputFilePath));
-
- File.WriteAllLines(OutputFilePath, data);
-
- Log.LogMessage(
- MessageImportance.High,
- $"Generating summary usage burndown data at {OutputFilePath} done. Took {DateTime.Now - startTime}");
-
- return !Log.HasLoggedErrors;
- }
-
- ///
- /// Get the contents of a git file based on the commit sha.
- ///
- /// The relative path (from the git root) to the file.
- /// The commit sha for the version of the file to get.
- /// The contents of the specified file.
- private Task GetFileContentsAsync(string relativeFilePath, string commitSha) =>
- client.GetStringAsync($"https://raw.githubusercontent.com/dotnet/source-build/{commitSha}/{relativeFilePath.Replace('\\', '/')}");
-
- ///
- /// Executes a git command and returns the result.
- ///
- /// The working directory for the git command.
- /// The git command to execute.
- /// An array of the output lines of the git command.
- private string[] ExecuteGitCommand(string workingDirectory, string command)
- {
- string[] returnData;
- Process _process = new Process();
- _process.StartInfo.FileName = "git";
- _process.StartInfo.Arguments = command;
- _process.StartInfo.WorkingDirectory = workingDirectory;
- _process.StartInfo.RedirectStandardOutput = true;
- _process.StartInfo.UseShellExecute = false;
- _process.Start();
- returnData = _process.StandardOutput.ReadToEnd().Split('\n');
- _process.WaitForExit();
- return returnData;
- }
-
- private class Commit
- {
- public string Sha { get; set; }
- public string Title { get; set; }
- public DateTime CommitDate { get; set; }
- public int PackageVersionCount { get; set; }
- public int PackageCount { get; set; }
-
- public override string ToString()
- {
- return $"{Sha}, {Title}, {CommitDate}, {PackageVersionCount}, {PackageCount}";
- }
- }
- }
-}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteUsageReports.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteUsageReports.cs
deleted file mode 100644
index 1d0f53f7e91a..000000000000
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/UsageReport/WriteUsageReports.cs
+++ /dev/null
@@ -1,256 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#nullable disable
-
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Xml.Linq;
-
-namespace Microsoft.DotNet.UnifiedBuild.Tasks.UsageReport
-{
- public class WriteUsageReports : Task
- {
- private const string SnapshotPrefix = "PackageVersions.";
- private const string SnapshotSuffix = ".Snapshot.props";
-
- ///
- /// Source usage data JSON file.
- ///
- [Required]
- public string DataFile { get; set; }
-
- ///
- /// Suffix to use for the version property name.
- ///
- [Required]
- public string VersionPropertySuffix { get; set; }
-
- ///
- /// A set of "PackageVersions.{repo}.Snapshot.props" files. They are analyzed to find
- /// packages built during source-build, and which repo built them. This info is added to the
- /// report. New packages are associated to a repo by going through each PVP in ascending
- /// file modification order.
- ///
- public ITaskItem[] PackageVersionPropsSnapshots { get; set; }
-
- ///
- /// File containing the results of poisoning the prebuilts. Example format:
- ///
- /// MATCH: output built\dotnet-sdk-...\System.Collections.dll(hash 4b...31) matches one of:
- /// intermediate\netstandard.library.2.0.1.nupkg\build\...\System.Collections.dll
- ///
- /// The usage report reads this file, looking for 'intermediate\*.nupkg' to annotate.
- ///
- public string PoisonedReportFile { get; set; }
-
- [Required]
- public string OutputDirectory { get; set; }
-
- public override bool Execute()
- {
- UsageData data = UsageData.Parse(XElement.Parse(File.ReadAllText(DataFile)));
- IEnumerable sourceBuildRepoOutputs = GetSourceBuildRepoOutputs();
-
- var poisonNupkgFilenames = new HashSet(StringComparer.OrdinalIgnoreCase);
-
- if (File.Exists(PoisonedReportFile))
- {
- foreach (string line in File.ReadAllLines(PoisonedReportFile))
- {
- string[] segments = line.Split('\\');
- if (segments.Length > 2 &&
- segments[0].Trim() == "intermediate" &&
- segments[1].EndsWith(".nupkg"))
- {
- poisonNupkgFilenames.Add(Path.GetFileNameWithoutExtension(segments[1]));
- }
- }
- }
-
- var report = new XElement("AnnotatedUsages");
-
- var annotatedUsages = data.Usages.NullAsEmpty()
- .Select(usage =>
- {
- string id = usage.PackageIdentity.Id;
- string version = usage.PackageIdentity.Version.OriginalVersion;
-
- string pvpIdent = WritePackageVersionsProps.GetPropertyName(id, VersionPropertySuffix);
-
- var sourceBuildCreator = new StringBuilder();
- foreach (RepoOutput output in sourceBuildRepoOutputs)
- {
- foreach (PackageVersionPropsElement p in output.Built)
- {
- if (p.Name.Equals(pvpIdent, StringComparison.OrdinalIgnoreCase))
- {
- if (sourceBuildCreator.Length != 0)
- {
- sourceBuildCreator.Append(" ");
- }
- sourceBuildCreator.Append(output.Repo);
- sourceBuildCreator.Append(" ");
- sourceBuildCreator.Append(p.Name);
- sourceBuildCreator.Append("/");
- sourceBuildCreator.Append(p.Version);
- }
- }
- }
-
- return new AnnotatedUsage
- {
- Usage = usage,
-
- Project = data.ProjectDirectories
- ?.FirstOrDefault(p => usage.AssetsFile?.StartsWith(p) ?? false),
-
- SourceBuildPackageIdCreator = sourceBuildCreator.Length == 0
- ? null
- : sourceBuildCreator.ToString(),
-
- TestProjectByHeuristic = IsTestUsageByHeuristic(usage),
-
- EndsUpInOutput = poisonNupkgFilenames.Contains($"{id}.{version}")
- };
- })
- .ToArray();
-
- foreach (var onlyTestProjectUsage in annotatedUsages
- .GroupBy(u => u.Usage.PackageIdentity)
- .Where(g => g.All(u => u.TestProjectByHeuristic))
- .SelectMany(g => g))
- {
- onlyTestProjectUsage.TestProjectOnlyByHeuristic = true;
- }
-
- report.Add(annotatedUsages.Select(u => u.ToXml()));
-
- Directory.CreateDirectory(OutputDirectory);
-
- File.WriteAllText(
- Path.Combine(OutputDirectory, "annotated-usage.xml"),
- report.ToString());
-
- return !Log.HasLoggedErrors;
- }
-
- private RepoOutput[] GetSourceBuildRepoOutputs()
- {
- var pvpSnapshotFiles = PackageVersionPropsSnapshots.NullAsEmpty()
- .Select(item =>
- {
- var content = File.ReadAllText(item.ItemSpec);
- return new
- {
- Path = item.ItemSpec,
- Content = content,
- Xml = XElement.Parse(content)
- };
- })
- .OrderBy(snapshot =>
- {
- // Get the embedded creation time if possible: the file's original metadata may
- // have been destroyed by copying, zipping, etc.
- string creationTime = snapshot.Xml
- // Get all elements
- .Elements()
- // Select all the subelements
- .SelectMany(e => e.Elements())
- // Find all that match the creation time property name
- .Where(e => e.Name == snapshot.Xml.GetDefaultNamespace().GetName(WritePackageVersionsProps.CreationTimePropertyName))
- // There should be only one or zero
- .SingleOrDefault()?.Value;
-
- if (string.IsNullOrEmpty(creationTime))
- {
- Log.LogError($"No creation time property found in snapshot {snapshot.Path}");
- return default(DateTime);
- }
-
- return new DateTime(long.Parse(creationTime));
- })
- .Select(snapshot =>
- {
- string filename = Path.GetFileName(snapshot.Path);
- return new
- {
- Repo = filename.Substring(
- SnapshotPrefix.Length,
- filename.Length - SnapshotPrefix.Length - SnapshotSuffix.Length),
- PackageVersionProp = PackageVersionPropsElement.Parse(snapshot.Xml)
- };
- })
- .ToArray();
-
- return pvpSnapshotFiles.Skip(1)
- .Zip(pvpSnapshotFiles, (pvp, prev) => new RepoOutput
- {
- Repo = prev.Repo,
- Built = pvp.PackageVersionProp.Except(prev.PackageVersionProp).ToArray()
- })
- .ToArray();
- }
-
- public static bool IsTestUsageByHeuristic(Usage usage)
- {
- string[] assetsFileParts = usage.AssetsFile?.Split('/', '\\');
-
- // If the dir name ends in Test(s), it's probably a test project.
- // Ignore the first two segments to avoid classifying everything in "src/vstest".
- // This also catches "test" dirs that contain many test projects.
- if (assetsFileParts?.Skip(2).Any(p =>
- p.EndsWith("Tests", StringComparison.OrdinalIgnoreCase) ||
- p.EndsWith("Test", StringComparison.OrdinalIgnoreCase)) == true)
- {
- return true;
- }
-
- // CoreFX restores test dependencies during this sync project.
- if (assetsFileParts?.Contains("XUnit.Runtime") == true)
- {
- return true;
- }
-
- return false;
- }
-
- private class RepoOutput
- {
- public string Repo { get; set; }
- public PackageVersionPropsElement[] Built { get; set; }
- }
-
- private struct PackageVersionPropsElement
- {
- public static PackageVersionPropsElement[] Parse(XElement xml)
- {
- return xml
- // Get the first PropertyGroup. The second PropertyGroup is 'extra properties', and the third group is the creation time.
- // Only select the first because the extra properties are not built packages.
- .Elements()
- .First()
- // Get all *PackageVersion property elements.
- .Elements()
- .Select(x => new PackageVersionPropsElement(
- x.Name.LocalName,
- x.Nodes().OfType().First().Value))
- .ToArray();
- }
-
- public string Name { get; }
- public string Version { get; }
-
- public PackageVersionPropsElement(string name, string version)
- {
- Name = name;
- Version = version;
- }
- }
- }
-}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/VersionDetailsHelper.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/VersionDetailsHelper.cs
new file mode 100644
index 000000000000..37d68bed2ee4
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/VersionDetailsHelper.cs
@@ -0,0 +1,82 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using Microsoft.Build.Utilities;
+
+namespace Microsoft.DotNet.UnifiedBuild.Tasks
+{
+ ///
+ /// Helper class for reading dependency information from Version.Details.xml files.
+ ///
+ internal static class VersionDetailsHelper
+ {
+ private const string PinnedAttributeName = "Pinned";
+ private const string DependencyAttributeName = "Dependency";
+ private const string NameAttributeName = "Name";
+
+ ///
+ /// Retrieve the set of non-pinned dependencies from a Version.Details.xml file.
+ ///
+ /// Path to the Version.Details.xml file.
+ /// TaskLoggingHelper for logging errors.
+ /// Hash set of dependency names, or null if an error occurred.
+ public static HashSet GetDependencies(string versionDetailsPath, TaskLoggingHelper log)
+ {
+ XmlDocument document = new XmlDocument();
+
+ try
+ {
+ document.Load(versionDetailsPath);
+ }
+ catch (Exception e)
+ {
+ log.LogErrorFromException(e);
+ return null;
+ }
+
+ HashSet dependencyNames = new HashSet(StringComparer.OrdinalIgnoreCase);
+
+ // Load the nodes and filter those that are pinned
+ XmlNodeList dependencyNodes = document.DocumentElement.SelectNodes($"//{DependencyAttributeName}");
+
+ foreach (XmlNode dependency in dependencyNodes)
+ {
+ if (dependency.NodeType == XmlNodeType.Comment || dependency.NodeType == XmlNodeType.Whitespace)
+ {
+ continue;
+ }
+
+ bool isPinned = false;
+ XmlAttribute pinnedAttribute = dependency.Attributes[PinnedAttributeName];
+ if (pinnedAttribute != null && !bool.TryParse(pinnedAttribute.Value, out isPinned))
+ {
+ log.LogError($"The '{PinnedAttributeName}' attribute is set but the value " +
+ $"'{pinnedAttribute.Value}' is not a valid boolean.");
+ return null;
+ }
+
+ if (isPinned)
+ {
+ continue;
+ }
+
+ var name = dependency.Attributes[NameAttributeName]?.Value?.Trim();
+
+ if (string.IsNullOrEmpty(name))
+ {
+ log.LogError($"The '{NameAttributeName}' attribute must be specified.");
+ return null;
+ }
+
+ dependencyNames.Add(name);
+ }
+
+ return dependencyNames;
+ }
+ }
+}
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WritePackageVersionsProps.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WritePackageVersionsProps.cs
index 89be96e23fc4..27eb63530804 100644
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WritePackageVersionsProps.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WritePackageVersionsProps.cs
@@ -98,56 +98,7 @@ public class WritePackageVersionsProps : Microsoft.Build.Utilities.Task
/// Hash set of dependency names.
private HashSet GetDependences()
{
- XmlDocument document = new XmlDocument();
-
- try
- {
- document.Load(VersionDetails);
- }
- catch (Exception e)
- {
- Log.LogErrorFromException(e);
- return null;
- }
-
- HashSet dependencyNames = new HashSet(StringComparer.OrdinalIgnoreCase);
-
- // Load the nodes, filter those that are not pinned, and
- XmlNodeList dependencyNodes = document.DocumentElement.SelectNodes($"//{DependencyAttributeName}");
-
- foreach (XmlNode dependency in dependencyNodes)
- {
- if (dependency.NodeType == XmlNodeType.Comment || dependency.NodeType == XmlNodeType.Whitespace)
- {
- continue;
- }
-
- bool isPinned = false;
- XmlAttribute pinnedAttribute = dependency.Attributes[PinnedAttributeName];
- if (pinnedAttribute != null && !bool.TryParse(pinnedAttribute.Value, out isPinned))
- {
- Log.LogError($"The '{PinnedAttributeName}' attribute is set but the value " +
- $"'{pinnedAttribute.Value}' is not a valid boolean...");
- return null;
- }
-
- if (isPinned)
- {
- continue;
- }
-
- var name = dependency.Attributes[NameAttributeName]?.Value?.Trim();
-
- if (string.IsNullOrEmpty(name))
- {
- Log.LogError($"The '{NameAttributeName}' attribute must be specified.");
- return null;
- }
-
- dependencyNames.Add(name);
- }
-
- return dependencyNames;
+ return VersionDetailsHelper.GetDependencies(VersionDetails, Log);
}
///
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WriteSbrpUsageReport.cs b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WriteSbrpUsageReport.cs
index ea02dd5118d6..31aa6df459b9 100644
--- a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WriteSbrpUsageReport.cs
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/WriteSbrpUsageReport.cs
@@ -215,6 +215,25 @@ private void ScanProjectReferences()
TrackPackageReference(lockFile.Path, downloadDep.Name, downloadDep.VersionRange.MinVersion?.ToString(), Enumerable.Empty());
}
+ // Track framework references (e.g., Microsoft.NETCore.App, Microsoft.AspNetCore.App)
+ // These correspond to targeting packs like Microsoft.NETCore.App.Ref.6.0.0
+ foreach (var targetFramework in lockFile.PackageSpec.TargetFrameworks)
+ {
+ foreach (var frameworkRef in targetFramework.FrameworkReferences)
+ {
+ string? targetingPackVersion = InferTargetingPackVersion(targetFramework.FrameworkName.GetShortFolderName());
+ if (targetingPackVersion != null)
+ {
+ string targetingPackName = $"{frameworkRef.Name}.Ref";
+ TrackPackageReference(
+ lockFile.Path,
+ targetingPackName,
+ targetingPackVersion,
+ [ targetFramework.FrameworkName.GetShortFolderName() ]);
+ }
+ }
+ }
+
if (lockFile.PackageSpec.RestoreMetadata.ProjectPath.Contains(SbrpRepoName))
{
// For SBRP projects, we need to track the project references as well. While project references are included in the targets
@@ -241,6 +260,25 @@ private void ScanProjectReferences()
}
}
+ // Match patterns like net6.0, net7.0, net8.0, net9.0, net10.0, etc.
+ [GeneratedRegex(@"^net(\d+\.\d+)$")]
+ private static partial Regex GetTargetingPackVersionRegex();
+
+ ///
+ /// Infers the targeting pack version from a target framework moniker.
+ /// For source-build, we map net6.0 -> 6.0.0, net7.0 -> 7.0.0, etc.
+ ///
+ private static string? InferTargetingPackVersion(string tfm)
+ {
+ var match = GetTargetingPackVersionRegex().Match(tfm);
+ if (match.Success)
+ {
+ return $"{match.Groups[1].Value}.0";
+ }
+
+ return null;
+ }
+
private void TrackPackageReference(string lockFilePath, string? name, string? version, IEnumerable tfms)
{
string id = PackageInfo.GetId(name, version);
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/static/Signing.props b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/static/Signing.props
new file mode 100644
index 000000000000..70fd9258a16f
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/static/Signing.props
@@ -0,0 +1,45 @@
+
+
+
+ 3PartySHA2
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/static/empty.proj b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/static/empty.proj
new file mode 100644
index 000000000000..0d2eaa148745
--- /dev/null
+++ b/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/static/empty.proj
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/eng/tools/tools.proj b/eng/tools/tools.proj
new file mode 100644
index 000000000000..1cf3fdcd1a46
--- /dev/null
+++ b/eng/tools/tools.proj
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/vs-workaround.targets b/eng/vs-workaround.targets
new file mode 100644
index 000000000000..e53cb5e68895
--- /dev/null
+++ b/eng/vs-workaround.targets
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/es-metadata.yml b/es-metadata.yml
new file mode 100644
index 000000000000..972dbca33d9e
--- /dev/null
+++ b/es-metadata.yml
@@ -0,0 +1,8 @@
+schemaVersion: 0.0.1
+isProduction: true
+accountableOwners:
+ service: 8d20dc36-68f2-41f9-94fe-c3cd15ce04bd
+routing:
+ defaultAreaPath:
+ org: devdiv
+ path: DevDiv\.NET Shared\VMR
diff --git a/global.json b/global.json
index b00fc4e0f22a..d33e0de0c8d8 100644
--- a/global.json
+++ b/global.json
@@ -1,10 +1,10 @@
{
"tools": {
- "dotnet": "10.0.100-rc.1.25411.109"
+ "dotnet": "11.0.100-alpha.1.25618.104"
},
"msbuild-sdks": {
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.4.0",
- "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25411.109"
+ "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.25618.104"
}
}
diff --git a/prep-source-build.sh b/prep-source-build.sh
index 1a52284bb54c..125fb9ea9548 100755
--- a/prep-source-build.sh
+++ b/prep-source-build.sh
@@ -7,6 +7,8 @@
### and detecting binaries and removing any non-SB allowed binaries.
###
### Options:
+### --configuration Build configuration: 'Debug' or 'Release' (short: -c)
+### Default is Release
### --no-artifacts Exclude the download of the previously source-built artifacts archive
### --no-bootstrap Don't replace portable packages in the download source-built artifacts
### --no-prebuilts Exclude the download of the prebuilts archive
@@ -32,17 +34,23 @@ IFS=$'\n\t'
source="${BASH_SOURCE[0]}"
REPO_ROOT="$( cd -P "$( dirname "$0" )" && pwd )"
+# Load common helper functions
+source "$REPO_ROOT/eng/download-source-built-archive.sh"
+source "$REPO_ROOT/eng/source-build-toolset-init.sh"
+
function print_help () {
sed -n '/^### /,/^$/p' "$source" | cut -b 5-
}
packagesDir="$REPO_ROOT/prereqs/packages"
+# Common settings
+configuration='Release'
+
# SB prep default arguments
defaultArtifactsRid='centos.10-x64'
# Binary Tooling default arguments
-defaultDotnetSdk="$REPO_ROOT/.dotnet"
defaultPsbDir="$packagesDir/previously-source-built"
# SB prep arguments
@@ -57,15 +65,12 @@ runtime_source_feed='' # IBM requested these to support s390x scenarios
runtime_source_feed_key='' # IBM requested these to support s390x scenarios
# Binary Tooling arguments
-dotnetSdk=$defaultDotnetSdk
+customSdkDir=''
psbDir=$defaultPsbDir
artifactsBaseFileName="Private.SourceBuilt.Artifacts"
artifactsTarballPattern="$artifactsBaseFileName.*.tar.gz"
-sharedComponentsBaseFileName="Private.SourceBuilt.SharedComponents"
-sharedComponentsTarballPattern="$sharedComponentsBaseFileName.*.tar.gz"
-
prebuiltsBaseFileName="Private.SourceBuilt.Prebuilts"
prebuiltsTarballPattern="$prebuiltsBaseFileName.*.tar.gz"
@@ -80,6 +85,10 @@ while :; do
print_help
exit 0
;;
+ --configuration|-c)
+ configuration=$2
+ shift
+ ;;
--no-bootstrap)
buildBootstrap=false
;;
@@ -112,11 +121,15 @@ while :; do
removeBinaries=false
;;
--with-sdk)
- dotnetSdk=$2
+ customSdkDir="$(cd -P "$2" && pwd)"
shift
;;
--with-packages)
- psbDir=$2
+ psbDir="$(cd -P "$2" && pwd)"
+ if [ ! -d "$psbDir" ]; then
+ echo "Custom previously built packages directory '$psbDir' does not exist"
+ exit 1
+ fi
shift
;;
*)
@@ -127,137 +140,11 @@ while :; do
shift
done
-# Attempting to bootstrap without an SDK will fail. So either the --no-sdk flag must be passed
-# or a pre-existing .dotnet SDK directory must exist.
-if [ "$buildBootstrap" == true ] && [ "$installDotnet" == false ] && [ ! -d "$REPO_ROOT/.dotnet" ]; then
- echo " ERROR: --no-sdk requires --no-bootstrap or a pre-existing .dotnet SDK directory. Exiting..."
- exit 1
-fi
-
-# Check to make sure curl exists to download the archive files
-if ! command -v curl &> /dev/null
-then
- echo " ERROR: curl not found. Exiting..."
- exit 1
-fi
-
-# Check if Private.SourceBuilt artifacts archive exists
-downloadPsbArtifacts=$downloadArtifacts
-packagesArchiveDir="$packagesDir/archive/"
-if [ "$downloadArtifacts" == true ] && [ -f ${packagesArchiveDir}${artifactsTarballPattern} ]; then
- echo " $artifactsTarballPattern exists in $packagesArchiveDir...it will not be downloaded"
- downloadPsbArtifacts=false
-fi
-
-# Check if shared components archive exists
-downloadSharedComponentsArtifacts=$downloadArtifacts
-if [ "$downloadArtifacts" == true ] && [ -f ${packagesArchiveDir}${sharedComponentsTarballPattern} ]; then
- echo " $sharedComponentsTarballPattern exists in $packagesArchiveDir...it will not be downloaded"
- downloadSharedComponentsArtifacts=false
-fi
+source "$REPO_ROOT/eng/common/tools.sh"
-# Check if Private.SourceBuilt prebuilts archive exists
-if [ "$downloadPrebuilts" == true ] && [ -f ${packagesArchiveDir}${prebuiltsTarballPattern} ]; then
- echo " $prebuiltsTarballPattern exists in $packagesArchiveDir...it will not be downloaded"
- downloadPrebuilts=false
-fi
-
-# Check if dotnet is installed
-if [ "$installDotnet" == true ] && [ -d "$REPO_ROOT/.dotnet" ]; then
- echo " ./.dotnet SDK directory exists...it will not be installed"
- installDotnet=false;
-fi
-
-# Helper to extract a property value from an XML file
-function GetXmlPropertyValue {
- local propName="$1"
- local filePath="$2"
- local value=""
- local line pattern
- line=$(grep -m 1 "<$propName>" "$filePath" || :)
- pattern="<$propName>(.*)$propName>"
- if [[ $line =~ $pattern ]]; then
- value="${BASH_REMATCH[1]}"
- fi
- echo "$value"
-}
-
-# Helper to download a file with retries
-function DownloadWithRetries {
- local url="$1"
- local targetDir="$2"
- (
- cd "$targetDir" &&
- for i in {1..5}; do
- if curl -fL --retry 5 -O "$url"; then
- return 0
- else
- case $? in
- 18)
- sleep 3
- ;;
- *)
- return 1
- ;;
- esac
- fi
- done
- return 1
- )
-}
-
-function DownloadArchive {
- local label="$1"
- local propertyName="$2"
- local isRequired="$3"
- local artifactsRid="$4"
- local outputDir="$5"
- local destinationFilenamePrefix="${6:-}"
-
- local packageVersionsPath="$REPO_ROOT/eng/Versions.props"
- local notFoundMessage="No $label found to download..."
-
- local archiveVersion
- archiveVersion=$(GetXmlPropertyValue "$propertyName" "$packageVersionsPath")
- if [[ -z "$archiveVersion" ]]; then
- if [ "$isRequired" == true ]; then
- echo " ERROR: $notFoundMessage"
- exit 1
- else
- echo " $notFoundMessage"
- return
- fi
- fi
-
- local archiveUrl
- if [[ "$propertyName" == "MicrosoftNETSdkVersion" ]]; then
- archiveUrl="https://ci.dot.net/public/source-build/$artifactsBaseFileName.$archiveVersion.$artifactsRid.tar.gz"
- elif [[ "$propertyName" == *Prebuilts* ]]; then
- archiveUrl="https://builds.dotnet.microsoft.com/source-built-artifacts/assets/$prebuiltsBaseFileName.$archiveVersion.$defaultArtifactsRid.tar.gz"
- elif [[ "$propertyName" == *Artifacts* ]]; then
- archiveUrl="https://builds.dotnet.microsoft.com/source-built-artifacts/assets/$artifactsBaseFileName.$archiveVersion.$artifactsRid.tar.gz"
- else
- echo " ERROR: Unknown archive property name: $propertyName"
- exit 1
- fi
-
- echo " Downloading $label from $archiveUrl..."
- if ! DownloadWithRetries "$archiveUrl" "$outputDir"; then
- echo " ERROR: Failed to download $archiveUrl"
- exit 1
- fi
-
- # Rename the file if a destination filename prefix is provided
- if [[ -n "$destinationFilenamePrefix" ]]; then
- local downloadedFilename
- downloadedFilename=$(basename "$archiveUrl")
- # Extract the suffix from the downloaded filename
- local suffix="${downloadedFilename#$artifactsBaseFileName}"
- local newFilename="$destinationFilenamePrefix$suffix"
- mv "$outputDir/$downloadedFilename" "$outputDir/$newFilename"
- echo " Renamed $downloadedFilename to $newFilename"
- fi
-}
+# Default properties
+properties=( "/p:Configuration=$configuration" )
+properties+=( "/p:DotNetBuildSourceOnly=true" )
function BootstrapArtifacts {
DOTNET_SDK_PATH="$REPO_ROOT/.dotnet"
@@ -283,21 +170,60 @@ function BootstrapArtifacts {
# Copy NuGet.config from the sdk repo to have the right feeds
cp "$REPO_ROOT/src/sdk/NuGet.config" "$workingDir"
- properties=( "/p:ArchiveDir=$packagesArchiveDir" )
+ local bootstrapProperties=( "${properties[@]}" )
+ bootstrapProperties+=( "/p:ArchiveDir=$packagesArchiveDir" )
if [[ -n "$bootstrap_rid" ]]; then
- properties+=( "/p:PortableTargetRid=$bootstrap_rid" )
+ bootstrapProperties+=( "/p:PortableTargetRid=$bootstrap_rid" )
fi
# Run restore on project to initiate download of bootstrap packages
- "$DOTNET_SDK_PATH/dotnet" restore "$workingDir/buildBootstrapPreviouslySB.csproj" /bl:artifacts/log/prep-bootstrap.binlog /fileLoggerParameters:LogFile=artifacts/log/prep-bootstrap.log "${properties[@]}"
+ "$DOTNET_SDK_PATH/dotnet" restore "$workingDir/buildBootstrapPreviouslySB.csproj" /bl:$log_dir/prep-bootstrap.binlog /fileLoggerParameters:LogFile=$log_dir/prep-bootstrap.log "${bootstrapProperties[@]}"
# Remove working directory
rm -rf "$workingDir"
}
+# Attempting to bootstrap without an SDK will fail. So either the --no-sdk flag must be passed
+# or a pre-existing .dotnet SDK directory must exist.
+if [ "$buildBootstrap" == true ] && [ "$installDotnet" == false ] && [ ! -d "$REPO_ROOT/.dotnet" ]; then
+ echo " ERROR: --no-sdk requires --no-bootstrap or a pre-existing .dotnet SDK directory. Exiting..."
+ exit 1
+fi
+
+# Check to make sure curl exists to download the archive files
+if ! command -v curl &> /dev/null
+then
+ echo " ERROR: curl not found. Exiting..."
+ exit 1
+fi
+
+# Check if Private.SourceBuilt artifacts archive exists
+downloadPsbArtifacts=$downloadArtifacts
+packagesArchiveDir="$packagesDir/archive/"
+if [ "$downloadArtifacts" == true ] && [ -f ${packagesArchiveDir}${artifactsTarballPattern} ]; then
+ echo " $artifactsTarballPattern exists in $packagesArchiveDir...it will not be downloaded"
+ downloadPsbArtifacts=false
+fi
+
+# Check if Private.SourceBuilt prebuilts archive exists
+if [ "$downloadPrebuilts" == true ] && [ -f ${packagesArchiveDir}${prebuiltsTarballPattern} ]; then
+ echo " $prebuiltsTarballPattern exists in $packagesArchiveDir...it will not be downloaded"
+ downloadPrebuilts=false
+fi
+
+# Check if dotnet is installed
+expectedSdkVersion=$(GetXmlPropertyValue "PrivateSourceBuiltSdkVersion" "$REPO_ROOT/eng/Versions.props")
+if [ "$installDotnet" == true ] && [ -d "$REPO_ROOT/.dotnet" ]; then
+ installedVersions=$("$REPO_ROOT/.dotnet/dotnet" --list-sdks | awk '{print $1}')
+ if grep -qx "$expectedSdkVersion" <<< "${installedVersions[*]}"; then
+ echo " Skipping SDK installation - version $expectedSdkVersion detected"
+ installDotnet=false
+ fi
+fi
+
# Check for the version of dotnet to install
if [ "$installDotnet" == true ]; then
- echo " Installing dotnet..."
+ echo " Installing .NET SDK $expectedSdkVersion"
use_installed_dotnet_cli=false
(source ./eng/common/tools.sh && InitializeDotNetCli true)
fi
@@ -311,25 +237,19 @@ if [ "$downloadPsbArtifacts" == true ]; then
fi
fi
-if [ "$downloadSharedComponentsArtifacts" == true ]; then
- source $REPO_ROOT/eng/common/native/init-os-and-arch.sh
- source $REPO_ROOT/eng/common/native/init-distro-rid.sh
- initDistroRidGlobal "$os" "$arch" ""
-
- DownloadArchive "shared component artifacts" "MicrosoftNETSdkVersion" false "$__DistroRid" "$packagesArchiveDir" "$sharedComponentsBaseFileName"
-fi
-
if [ "$downloadPrebuilts" == true ]; then
-
DownloadArchive "prebuilts" "PrivateSourceBuiltPrebuiltsVersion" false "$artifactsRid" "$packagesArchiveDir"
fi
if [ "$removeBinaries" == true ]; then
originalPackagesDir=$packagesDir
- # Create working directory for extracking packages
+ # Create working directory for extracting packages
workingDir=$(mktemp -d)
+ toolsetInitProperties=( "${properties[@]}" )
+ toolsetInitProperties+=( "/p:DisableSharedComponentValidation=true" )
+
# If --with-packages is not passed, unpack PSB artifacts
if [[ $psbDir == $defaultPsbDir ]]; then
echo " Extracting previously source-built to $workingDir"
@@ -345,15 +265,23 @@ if [ "$removeBinaries" == true ]; then
tar -xzf "$sourceBuiltArchive" -C "$workingDir"
psbDir=$workingDir
+ else
+ echo " Using previously source-built packages from $psbDir"
+ toolsetInitProperties+=( "/p:CustomPreviouslySourceBuiltPackagesPath=$psbDir" )
fi
- "$dotnetSdk/dotnet" build \
+
+ # Initialize source-only toolset for binary detection (includes custom SDK setup, MSBuild resolver, and source-built resolver)
+ source_only_toolset_init "$customSdkDir" "$psbDir" "true" "" "${toolsetInitProperties[@]}"
+
+ "$_InitializeBuildTool" build \
"$REPO_ROOT/eng/init-detect-binaries.proj" \
+ "${properties[@]}" \
"/p:BinariesMode=Clean" \
"/p:AllowedBinariesFile=$REPO_ROOT/eng/allowed-sb-binaries.txt" \
"/p:BinariesPackagesDir=$psbDir" \
- "/bl:artifacts/log/prep-remove-binaries.binlog" \
- "/fileLoggerParameters:LogFile=artifacts/log/prep-remove-binaries.log" \
+ "/bl:$log_dir/prep-remove-binaries.binlog" \
+ "/fileLoggerParameters:LogFile=$log_dir/prep-remove-binaries.log" \
"${positional_args[@]}"
rm -rf "$workingDir"
diff --git a/repo-projects/Directory.Build.props b/repo-projects/Directory.Build.props
index b41783a5080b..aa112e54e2af 100644
--- a/repo-projects/Directory.Build.props
+++ b/repo-projects/Directory.Build.props
@@ -118,6 +118,8 @@
$(CommonArgs) /p:OfficialBuildId=$(OfficialBuildId)
$(CommonArgs) /p:OfficialBuilder="$(OfficialBuilder)"
$(CommonArgs) /p:ForceDryRunSigning=$(ForceDryRunSigning)
+ $(CommonArgs) /p:DotNetSignType=$(DotNetSignType)
+ $(CommonArgs) /p:KeepNativeSymbols=$(KeepNativeSymbols)
$(CommonArgs) /p:DotNetPackageVersionPropsPath=$(PackageVersionPropsPath)
@@ -219,7 +221,7 @@
Group="ARCADE"
Version="$(ArcadeBootstrapVersion)"
Location="$(BootstrapPackagesDir)microsoft.dotnet.arcade.sdk/$(ArcadeBootstrapVersion)" />
-
+
diff --git a/repo-projects/Directory.Build.targets b/repo-projects/Directory.Build.targets
index 53b9e9a78883..96a2e2392c62 100644
--- a/repo-projects/Directory.Build.targets
+++ b/repo-projects/Directory.Build.targets
@@ -28,7 +28,13 @@
$(CommonArgs) /p:PortableBuild=$(PortableBuild)
$(CommonArgs) /p:PortableTargetRid=$(PortableTargetRid)
$(CommonArgs) /p:DefaultArtifactVisibility=$(DefaultArtifactVisibility)
- $(CommonArgs) /p:DotNetFinalVersionKind=$(DotNetFinalVersionKind)
+
+
+
+ /p:DotNetFinalVersionKind=""
+ /p:DotNetFinalVersionKind=prerelease
+ /p:DotNetFinalVersionKind=release
+ $(CommonArgs) $(RepoDotNetFinalVersionKindArg)
$(CommonArgs) /p:DotNetBuildTests=true
@@ -36,7 +42,6 @@
$(BuildArgs) /p:EnableDefaultRidSpecificArtifacts=$(EnableDefaultRidSpecificArtifacts)
$(BuildArgs) /p:AllowEmptySignList=true
-
@@ -145,8 +150,14 @@
-
+
+
+
+
-
-
-
-
-
ExtraSources
@@ -174,6 +176,7 @@
previously-source-built
shared-components
reference-packages
+ extra-test-dependencies
true
false
@@ -182,6 +185,7 @@
<_CommonBuildSources Include="@(DependentRepoSourceName)" />
<_CommonBuildSources Include="$(ExtraSourcesNuGetSourceName)" Condition="'$(ExtraRestoreSourcePath)' != ''" />
+ <_CommonBuildSources Include="$(ExtraTestDependenciesNuGetSourceName)" Condition="Exists('$(ExtraTestDependenciesRestoreSourcePath)')" />
@@ -241,6 +245,11 @@
SourcePath="$(ExtraRestoreSourcePath)"
Condition="'$(ExtraRestoreSourcePath)' != ''" />
+
+
+
+ <_SharedComponentFilterMode>$(SharedComponentFilter_NonToolingOnly)
+ <_SharedComponentFilterMode Condition="$([System.String]::new(';$(BootstrapArcadeRepos);').Contains(';$(RepositoryName);'))">$(SharedComponentFilter_BootstrapRepoDepsOnly)
+
+
+ Properties="SharedComponentFilterMode=$(_SharedComponentFilterMode)">
@@ -535,6 +549,17 @@
+
+
+ @(_DependencyProducedPackage->WithMetadataValue('Identity', 'Microsoft.NETCore.App.Ref')->Metadata('Version'))
+
+
+
-
$(BuildArgs) /p:EnablePackageValidation=false
+
+ $(BuildArgs) /p:AfterMicrosoftNETSdkTargets=$(RepositoryEngineeringDir)vs-workaround.targets
+
true
@@ -56,6 +59,9 @@
+
+
-
+
-
+
+
diff --git a/repo-projects/nuget-client.proj b/repo-projects/nuget-client.proj
index b66a1c13b3e4..4f90e9049807 100644
--- a/repo-projects/nuget-client.proj
+++ b/repo-projects/nuget-client.proj
@@ -7,6 +7,11 @@
$([MSBuild]::NormalizePath('$(ProjectDirectory)', 'eng', 'dotnet-build', 'build$(ShellExtension)'))
$(BuildArgs) /p:GenerateResourceUsePreserializedResources=true
+
+
+ $(BuildArgs) /p:NetCurrent=$(NetCurrent)
+ $(BuildArgs) /p:NetPrevious=$(NetPrevious)
+ $(BuildArgs) /p:NetMinimum=$(NetMinimum)
diff --git a/repo-projects/roslyn-analyzers.proj b/repo-projects/roslyn-analyzers.proj
deleted file mode 100644
index 3bae3c296103..000000000000
--- a/repo-projects/roslyn-analyzers.proj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
- $(BuildArgs) $(FlagParameterPrefix)warnAsError $(ArcadeFalseBoolBuildArg)
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/repo-projects/roslyn.proj b/repo-projects/roslyn.proj
index be68563daa5e..30d118be522b 100644
--- a/repo-projects/roslyn.proj
+++ b/repo-projects/roslyn.proj
@@ -33,7 +33,6 @@
-
diff --git a/repo-projects/runtime.proj b/repo-projects/runtime.proj
index e295703ab58c..c7ca094258ce 100644
--- a/repo-projects/runtime.proj
+++ b/repo-projects/runtime.proj
@@ -27,10 +27,17 @@
true
- $(BuildArgs) $(FlagParameterPrefix)cross
+ $(BuildArgs) $(FlagParameterPrefix)cross
-
- $(BuildArgs) --bootstrap
+
+ true
+ false
+ false
+ $(BuildArgs) $(FlagParameterPrefix)bootstrap
$(BuildArgs) /p:DotNetBuildAllRuntimePacks=true
@@ -49,7 +56,6 @@
$(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_BROTLI=true
$(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=true
-
$(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_RAPIDJSON=true
$(BuildArgs) --cmakeargs -DCLR_CMAKE_USE_SYSTEM_ZLIB=true
$(BuildArgs) /p:FeatureXplatEventSource=false
diff --git a/repo-projects/scenario-tests.proj b/repo-projects/scenario-tests.proj
index f272b133313b..9c0c6c1b7187 100644
--- a/repo-projects/scenario-tests.proj
+++ b/repo-projects/scenario-tests.proj
@@ -47,7 +47,9 @@
$(ScenarioTestsResultsDir)$([System.DateTime]::Now.ToString("yyyy-MM-dd_HH_mm_ss")).xml
--xml $(TestXmlOutputPath) --target-rid $(TargetRid) --portable-rid $(PortableTargetRid) --no-cleanup --no-traits Category=MultiTFM
$(ScenarioTestsAdditionalArgs) --no-traits Category=RequiresNonTargetRidPackages
+ $(ScenarioTestsAdditionalArgs) --no-traits Category=RequiresPortableAssets
$(ScenarioTestsAdditionalArgs) --no-traits SkipIfBuild=SourceOnlyUnofficialBuild
+ $(ScenarioTestsAdditionalArgs) --no-traits SkipIfBuild=SourceOnly
diff --git a/repo-projects/sdk.proj b/repo-projects/sdk.proj
index 6e2e0db05e70..741cde9370aa 100644
--- a/repo-projects/sdk.proj
+++ b/repo-projects/sdk.proj
@@ -33,14 +33,13 @@
-
-
+
diff --git a/repo-projects/source-build-reference-packages.proj b/repo-projects/source-build-reference-packages.proj
index ce6da2771436..2ab299a1c826 100644
--- a/repo-projects/source-build-reference-packages.proj
+++ b/repo-projects/source-build-reference-packages.proj
@@ -12,9 +12,9 @@
+ Returns="@(ReferenceOnlyPackage)">
- <_ReferenceOnlyPackages Include="$(RepoArtifactsDir)packages\$(Configuration)\ReferenceOnly\*" />
+
@@ -22,18 +22,20 @@
-
+
-
-
-
+
-
+
+
+
+
+
+
diff --git a/repo-projects/sourcelink.proj b/repo-projects/sourcelink.proj
index 82a553312e8e..2ddfa6a13dd7 100644
--- a/repo-projects/sourcelink.proj
+++ b/repo-projects/sourcelink.proj
@@ -1,8 +1,14 @@
+
+
+ true
+
+
+
diff --git a/repo-projects/symreader.proj b/repo-projects/symreader.proj
index 9deac728bc91..23a52690490f 100644
--- a/repo-projects/symreader.proj
+++ b/repo-projects/symreader.proj
@@ -1,5 +1,10 @@
+
+
+ true
+
+
diff --git a/repo-projects/winforms.proj b/repo-projects/winforms.proj
index 93a79216bb8d..b66ed44eec11 100644
--- a/repo-projects/winforms.proj
+++ b/repo-projects/winforms.proj
@@ -1,7 +1,7 @@
- $(BuildArgs) $(FlagParameterPrefix)NativeToolsOnMachine
+ $(BuildArgs) $(FlagParameterPrefix)NativeToolsOnMachine
true
@@ -9,7 +9,7 @@
-
+
diff --git a/repo-projects/wpf.proj b/repo-projects/wpf.proj
index f77b34f28978..0d8e37d25c2a 100644
--- a/repo-projects/wpf.proj
+++ b/repo-projects/wpf.proj
@@ -6,6 +6,9 @@
$(BuildArgs) /p:Platform=$(TargetArchitecture)
$(BuildArgs) /p:BuildWithNetFrameworkHostedCompiler=true
+
+
+ $(BuildArgs) /p:AfterMicrosoftNETSdkTargets=$(RepositoryEngineeringDir)vs-workaround.targets
@@ -13,4 +16,8 @@
+
+
+
+
diff --git a/repo-projects/xdt.proj b/repo-projects/xdt.proj
index b17ec80adf3d..0a7edcedbfe1 100644
--- a/repo-projects/xdt.proj
+++ b/repo-projects/xdt.proj
@@ -1,5 +1,10 @@
+
+
+ true
+
+
diff --git a/src/arcade/.azuredevops/dependabot.yml b/src/arcade/.azuredevops/dependabot.yml
new file mode 100644
index 000000000000..f18e60565a42
--- /dev/null
+++ b/src/arcade/.azuredevops/dependabot.yml
@@ -0,0 +1,5 @@
+version: 2
+
+# Disabling dependabot on Azure DevOps as this is a mirrored repo. Updates should go through github.
+enable-campaigned-updates: false
+enable-security-updates: false
diff --git a/src/arcade/.config/dotnet-tools.json b/src/arcade/.config/dotnet-tools.json
index 9feb133fc414..170a9e381796 100644
--- a/src/arcade/.config/dotnet-tools.json
+++ b/src/arcade/.config/dotnet-tools.json
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"microsoft.dnceng.secretmanager": {
- "version": "1.1.0-beta.25381.1",
+ "version": "1.1.0-beta.25564.1",
"commands": [
"secret-manager"
]
diff --git a/src/arcade/.github/workflows/backport-base.yml b/src/arcade/.github/workflows/backport-base.yml
index 22b1aaa16091..913b646e0fa4 100644
--- a/src/arcade/.github/workflows/backport-base.yml
+++ b/src/arcade/.github/workflows/backport-base.yml
@@ -19,6 +19,19 @@ on:
required: false
type: string
default: 'dotnet,microsoft'
+ additional_git_am_switches:
+ description: 'Additional switches to pass to git am command (e.g., "--exclude=docs/release-notes/* --whitespace=fix"). Useful for excluding files that differ between branches or fixing whitespace conflicts.'
+ required: false
+ type: string
+ default: ''
+ conflict_resolution_command:
+ description: >-
+ Optional shell command to attempt automatic conflict resolution after a failed git am.
+ If the command eliminates merge conflicts, the backport proceeds automatically.
+ Do not run git commands from this parameter as they might have unintended side effects.
+ DO NOT PASS UNTRUSTED INPUT TO THIS PARAMETER.
+ required: false
+ type: string
jobs:
cleanup:
@@ -64,7 +77,8 @@ jobs:
with:
script: |
const target_branch = '${{ steps.target-branch-extractor.outputs.result }}';
- const backport_start_body = `Started backporting to _${target_branch}_: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
+ const workflow_run_url = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
+ const backport_start_body = `Started backporting to \`${target_branch}\` ([link to workflow run](${workflow_run_url}))`;
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
@@ -80,6 +94,8 @@ jobs:
env:
BACKPORT_PR_TITLE_TEMPLATE: ${{ inputs.pr_title_template }}
BACKPORT_PR_DESCRIPTION_TEMPLATE: ${{ inputs.pr_description_template }}
+ ADDITIONAL_GIT_AM_SWITCHES: ${{ inputs.additional_git_am_switches }}
+ CONFLICT_RESOLUTION_COMMAND: ${{ inputs.conflict_resolution_command }}
with:
script: |
const target_branch = '${{ steps.target-branch-extractor.outputs.result }}';
@@ -87,19 +103,40 @@ jobs:
const repo_name = context.payload.repository.name;
const pr_number = context.payload.issue.number;
const comment_user = context.payload.comment.user.login;
+ const workflow_run_url = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
+
+ const wrap_in_code_block = (language, content) => `\`\`\`${language}\n${content}\n\`\`\``;
+ const wrap_in_details_block = (summary, content) => `\n${summary}
\n\n${content}\n `;
+
+ // Post a comment on the PR and return the comment URL
+ async function postComment(body) {
+ const { data: comment } = await github.rest.issues.createComment({
+ owner: repo_owner,
+ repo: repo_name,
+ issue_number: pr_number,
+ body
+ });
+ return comment.html_url;
+ }
try {
- // verify the comment user is a repo collaborator
+ // verify the comment user has write access to the repo
try {
- await github.rest.repos.checkCollaborator({
+ const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: repo_owner,
repo: repo_name,
username: comment_user
});
- console.log(`Verified ${comment_user} is a repo collaborator.`);
+
+ const writePermissions = ['admin', 'write'];
+ if (!writePermissions.includes(permission.permission)) {
+ throw new Error(`Insufficient permissions: ${permission.permission}`);
+ }
+
+ console.log(`Verified ${comment_user} has ${permission.permission} access to the repo.`);
} catch (error) {
console.log(error);
- throw new Error(`Error: @${comment_user} is not a repo collaborator, backporting is not allowed. If you're a collaborator please make sure your ${repo_owner} team membership visibility is set to Public on https://github.com/orgs/${repo_owner}/people?query=${comment_user}`);
+ throw new Error(`Error: @${comment_user} does not have write access to this repo, backporting is not allowed. Required permissions: write or admin.`);
}
try { await exec.exec(`git ls-remote --exit-code --heads origin ${target_branch}`) } catch { throw new Error(`Error: The specified backport target branch "${target_branch}" wasn't found in the repo.`); }
@@ -127,9 +164,14 @@ jobs:
} catch { }
// download and apply patch
- await exec.exec(`curl -sSL "${context.payload.issue.pull_request.patch_url}" --output changes.patch`);
+ const patch_file = 'changes.patch';
+ await exec.exec(`curl -sSL "${context.payload.issue.pull_request.patch_url}" --output ${patch_file}`);
- const git_am_command = "git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch";
+ const additional_switches = process.env.ADDITIONAL_GIT_AM_SWITCHES?.trim() || '';
+ const base_switches = '--3way --empty=keep --ignore-whitespace --keep-non-patch';
+ const git_am_command = additional_switches
+ ? `git am ${base_switches} ${additional_switches} ${patch_file}`
+ : `git am ${base_switches} ${patch_file}`;
let git_am_output = `$ ${git_am_command}\n\n`;
let git_am_failed = false;
try {
@@ -145,21 +187,52 @@ jobs:
}
if (git_am_failed) {
- const git_am_failed_body = `@${context.payload.comment.user.login} backporting to "${target_branch}" failed, the patch most likely resulted in conflicts:\n\n\`\`\`shell\n${git_am_output}\n\`\`\`\n\nPlease backport manually!`;
- await github.rest.issues.createComment({
- owner: repo_owner,
- repo: repo_name,
- issue_number: pr_number,
- body: git_am_failed_body
- });
- core.setFailed("Error: git am failed, most likely due to a merge conflict.");
- return;
- }
- else {
- // push the temp branch to the repository
- await exec.exec(`git push --force --set-upstream origin HEAD:${temp_branch}`);
+ const resolution_command = process.env.CONFLICT_RESOLUTION_COMMAND || '';
+
+ // If no resolution command supplied, fail immediately
+ if (resolution_command.trim().length === 0) {
+ const details = `${wrap_in_code_block('console', git_am_output)}\n[Link to workflow output](${workflow_run_url})`;
+ const git_am_failed_body = `@${comment_user} backporting to \`${target_branch}\` failed, the patch most likely resulted in conflicts. Please backport manually!\n${wrap_in_details_block('git am output', details)}`;
+ postComment(git_am_failed_body);
+ core.setFailed("git am failed, most likely due to a merge conflict.");
+ return;
+ }
+
+ console.log(`git am failed; attempting in-session conflict resolution via provided command: ${resolution_command}`);
+
+ // Run user-provided resolution command
+ // Ignore return code to capture stdout/stderr
+ const resolution_result = await exec.getExecOutput(`bash -c "${resolution_command}"`, [], { ignoreReturnCode: true });
+ if (resolution_result.exitCode !== 0) {
+ const details = `\`${resolution_command}\` stderr:\n${wrap_in_code_block('console', resolution_result.stderr)}\n[Link to workflow output](${workflow_run_url})`;
+ const resolution_failed_body = `@${comment_user} backporting to \`${target_branch}\` failed during automated conflict resolution. Please backport manually!\n${wrap_in_details_block('Error details', details)}`;
+ postComment(resolution_failed_body);
+ core.setFailed(`Automated conflict resolution command exited with code ${resolution_result.exitCode}`);
+ return;
+ }
+
+ // Stage changes (excluding patch file)
+ await exec.exec(`git add -A`);
+ await exec.exec(`git reset HEAD ${patch_file}`);
+
+ // Check for remaining conflicts
+ const diff_command = 'git diff --name-only --diff-filter=U';
+ const diff_result = await exec.getExecOutput(diff_command);
+ if (diff_result.stdout.trim().length !== 0) {
+ const details = `${wrap_in_code_block('console', diff_result.stdout)}\n[Link to workflow output](${workflow_run_url})`;
+ const conflicts_body = `@${comment_user} backporting to \`${target_branch}\` failed. Automated conflict resolution did not resolve all conflicts. Please backport manually!\n${wrap_in_details_block(`${diff_command} output`, details)}`;
+ postComment(conflicts_body);
+ core.setFailed(`Automated conflict resolution did not resolve all conflicts.`);
+ return;
+ }
+
+ console.log('Automated conflict resolution resolved all merge conflicts. Continuing.');
+ await exec.exec('git am --continue');
}
+ // push the temp branch to the repository
+ await exec.exec(`git push --force --set-upstream origin HEAD:${temp_branch}`);
+
if (!should_open_pull_request) {
console.log("Backport temp branch already exists, skipping opening a PR.");
return;
@@ -200,19 +273,12 @@ jobs:
console.log("Successfully opened the GitHub PR.");
} catch (error) {
-
+ const body = `@${comment_user} an error occurred while backporting to \`${target_branch}\`. See the [workflow output](${workflow_run_url}) for details.`;
+ const comment_url = await postComment(body);
+ console.log(`Posted comment: ${comment_url}`);
core.setFailed(error);
-
- // post failure to GitHub comment
- const unknown_error_body = `@${comment_user} an error occurred while backporting to "${target_branch}", please check the run log for details!\n\n${error.message}`;
- await github.rest.issues.createComment({
- owner: repo_owner,
- repo: repo_name,
- issue_number: pr_number,
- body: unknown_error_body
- });
}
-
+
- name: Re-lock PR comments
uses: actions/github-script@v7
if: ${{ github.event.issue.locked == true && (success() || failure()) }}
diff --git a/src/arcade/.github/workflows/inter-branch-merge-base.yml b/src/arcade/.github/workflows/inter-branch-merge-base.yml
index 19ada5b48883..dee843a51b86 100644
--- a/src/arcade/.github/workflows/inter-branch-merge-base.yml
+++ b/src/arcade/.github/workflows/inter-branch-merge-base.yml
@@ -71,7 +71,7 @@ jobs:
if: steps.extract-configuration-values.outputs.configurationFound != 'true'
name: Read configuration status
- - run: ${{ github.workspace }}\arcade-repository\.github\workflows\scripts\inter-branch-merge.ps1 -RepoName ${{ steps.fetch-repo-name.outputs.repository_name }} -RepoOwner ${{ github.repository_owner }} -MergeFromBranch $env:GITHUB_REF_NAME -MergeToBranch ${{ steps.extract-configuration-values.outputs.mergeToBranch }} ${{ steps.extract-configuration-values.outputs.mergeSwitchArguments }}
+ - run: ${{ github.workspace }}\arcade-repository\.github\workflows\scripts\inter-branch-merge.ps1 -RepoName ${{ steps.fetch-repo-name.outputs.repository_name }} -RepoOwner ${{ github.repository_owner }} -MergeFromBranch $env:GITHUB_REF_NAME -MergeToBranch ${{ steps.extract-configuration-values.outputs.mergeToBranch }} -ResetToTargetPaths "${{ steps.extract-configuration-values.outputs.resetToTargetPaths }}" ${{ steps.extract-configuration-values.outputs.mergeSwitchArguments }}
if: steps.extract-configuration-values.outputs.configurationFound == 'true'
name: Merge branches
working-directory: ${{ github.workspace }}/repository
diff --git a/src/arcade/.github/workflows/scripts/inter-branch-merge.ps1 b/src/arcade/.github/workflows/scripts/inter-branch-merge.ps1
index d1e251e09d64..c05c2c87895d 100644
--- a/src/arcade/.github/workflows/scripts/inter-branch-merge.ps1
+++ b/src/arcade/.github/workflows/scripts/inter-branch-merge.ps1
@@ -15,6 +15,10 @@ The current branch
Create a PR even if the only commits are from dotnet-maestro[bot]
.PARAMETER QuietComments
Do not tag commiters, do not comment on PR updates. Reduces GitHub notifications
+.PARAMETER ResetToTargetPaths
+Semicolon-separated list of glob patterns for files to reset to the target branch version.
+After the merge branch is created, files matching these patterns will be checked out from
+the target branch and committed, resolving potential merge conflicts for these files.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
@@ -36,7 +40,10 @@ param(
[switch]$AllowAutomatedCommits,
- [switch]$QuietComments
+ [switch]$QuietComments,
+
+ [Alias('r')]
+ [string]$ResetToTargetPaths = ""
)
$ErrorActionPreference = 'stop'
@@ -105,6 +112,70 @@ function GetCommitterGitHubName($sha) {
return $null
}
+function ResetFilesToTargetBranch($patterns, $targetBranch) {
+ if (-not $patterns -or $patterns.Count -eq 0) {
+ return
+ }
+
+ Write-Host "Resetting files to $targetBranch for patterns: $($patterns -join ', ')"
+
+ # Verify the target branch exists
+ $branchExists = & git rev-parse --verify "origin/$targetBranch" 2>&1
+ if ($LASTEXITCODE -ne 0) {
+ Write-Warning "Target branch 'origin/$targetBranch' does not exist. Skipping file reset."
+ return
+ }
+
+ # Configure git user for the commit
+ # Use GitHub Actions bot identity
+ Invoke-Block { & git config user.name "github-actions[bot]" }
+ Invoke-Block { & git config user.email "41898282+github-actions[bot]@users.noreply.github.com" }
+
+ # Track which patterns had changes
+ $processedPatterns = @()
+
+ foreach ($pattern in $patterns) {
+ $pattern = $pattern.Trim()
+ if (-not $pattern) {
+ continue
+ }
+
+ Write-Host "Processing pattern: $pattern"
+
+ # Use git checkout to reset files matching the pattern to the target branch
+ # The -- is needed to separate the revision from the pathspec
+ # Just attempt to checkout the pattern directly - git will handle whether files exist
+ try {
+ & git checkout "origin/$targetBranch" -- $pattern 2>&1 | Write-Host
+ if ($LASTEXITCODE -eq 0) {
+ Write-Host -f Green "Checked out pattern '$pattern' from $targetBranch"
+ $processedPatterns += $pattern
+ } else {
+ Write-Host -f Yellow "Pattern '$pattern' did not match any files in $targetBranch"
+ }
+ }
+ catch {
+ Write-Warning "Failed to checkout pattern '$pattern' from $targetBranch. Error: $_"
+ }
+ }
+
+ # Check if there are any changes to commit after processing all patterns
+ $status = & git status --porcelain
+ if ($status -and $processedPatterns.Count -gt 0) {
+ # Add all changes (the checkout already modified the specific files)
+ Invoke-Block { & git add -A }
+
+ # Create a commit message listing all patterns that were reset
+ $patternsList = $processedPatterns -join "`n- "
+ $commitMessage = "Reset files to $targetBranch`n`nReset patterns:`n- $patternsList"
+
+ Invoke-Block { & git commit -m $commitMessage }
+ Write-Host -f Green "Successfully reset files to $targetBranch for patterns: $patternsList"
+ } else {
+ Write-Host "No changes to commit after processing all patterns"
+ }
+}
+
# see https://git-scm.com/docs/pretty-formats
$formatString = '%h %cn <%ce>: %s (%cr)'
@@ -151,6 +222,12 @@ try {
$mergeBranchName = "merge/$MergeFromBranch-to-$MergeToBranch"
Invoke-Block { & git checkout -B $mergeBranchName }
+ # Reset specified files to target branch if ResetToTargetPaths is configured
+ if ($ResetToTargetPaths) {
+ $patterns = $ResetToTargetPaths -split ";"
+ ResetFilesToTargetBranch $patterns $MergeToBranch
+ }
+
$remoteName = 'origin'
$prOwnerName = $RepoOwner
$prRepoName = $RepoName
diff --git a/src/arcade/.github/workflows/scripts/read-configuration.ps1 b/src/arcade/.github/workflows/scripts/read-configuration.ps1
index 1aeae31238e8..73e72d7c37bd 100644
--- a/src/arcade/.github/workflows/scripts/read-configuration.ps1
+++ b/src/arcade/.github/workflows/scripts/read-configuration.ps1
@@ -53,7 +53,7 @@ function GetConfiguration {
Write-Host "Fetching configuration file from $urlToConfigurationFile"
try{
- $response = Invoke-WebRequest -Method GET -MaximumRetryCount 3 -Headers $headers `
+ $response = Invoke-WebRequest -UseBasicParsing -Method GET -MaximumRetryCount 3 -Headers $headers `
$urlToConfigurationFile
$mergeFlowConfig = ConvertFrom-Json -InputObject $response.Content -AsHashTable
@@ -98,8 +98,15 @@ if ($configuration -ne $null) {
$ExtraSwitches = $configuration['ExtraSwitches']
}
+ $ResetToTargetPaths = "";
+ if($configuration.ContainsKey('ResetToTargetPaths')){
+ # Convert array to semicolon-separated string for output
+ $ResetToTargetPaths = $configuration['ResetToTargetPaths'] -join ";"
+ }
+
"mergeSwitchArguments=$ExtraSwitches" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"mergeToBranch=$MergeToBranch" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
+ "resetToTargetPaths=$ResetToTargetPaths" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
"configurationFound=$true" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
}
diff --git a/src/arcade/Arcade.slnx b/src/arcade/Arcade.slnx
index cc381104afc9..337ee9c22791 100644
--- a/src/arcade/Arcade.slnx
+++ b/src/arcade/Arcade.slnx
@@ -29,6 +29,7 @@
+
@@ -45,6 +46,7 @@
+
@@ -71,7 +73,6 @@
-
diff --git a/src/arcade/Directory.Build.targets b/src/arcade/Directory.Build.targets
index 994499260938..1b8d3519ede2 100644
--- a/src/arcade/Directory.Build.targets
+++ b/src/arcade/Directory.Build.targets
@@ -4,4 +4,9 @@
+
+
+ true
+
+
diff --git a/src/arcade/Directory.Packages.props b/src/arcade/Directory.Packages.props
index 3dc1678af592..a093ae1c0a59 100644
--- a/src/arcade/Directory.Packages.props
+++ b/src/arcade/Directory.Packages.props
@@ -11,11 +11,11 @@
5.8.4
3.14.1-9323.2545153
- 5.0.2-dotnet.2737382
+ 5.0.2-dotnet.2811440
2.9.3
- 3.0.0
+ 3.1.0
1.22.0
$(XUnitVersion)
3.1.3
@@ -77,11 +77,11 @@
-
-
+
+
-
+
@@ -91,7 +91,7 @@
-
+
diff --git a/src/arcade/Documentation/ArcadeSdk.md b/src/arcade/Documentation/ArcadeSdk.md
index 5ff86313be40..a5df38e66b25 100644
--- a/src/arcade/Documentation/ArcadeSdk.md
+++ b/src/arcade/Documentation/ArcadeSdk.md
@@ -702,7 +702,7 @@ The following task restores tools that are only available from internal feeds.
feedsToUse: config
restoreSolution: 'eng\common\internal\Tools.csproj'
nugetConfigPath: 'eng\common\internal\NuGet.config'
- restoreDirectory: '$(Build.SourcesDirectory)\.packages'
+ restoreDirectory: '$(System.DefaultWorkingDirectory)\.packages'
```
[The tools](https://github.com/dotnet/arcade/blob/master/eng/common/internal/Tools.csproj) are restored conditionally based on which Arcade SDK features the repository uses (these are specified via `UsingToolXxx` properties).
@@ -745,7 +745,7 @@ The Build Pipeline needs to link the following variable group:
- task: PublishBuildArtifacts@1
displayName: Publish Logs
inputs:
- PathtoPublish: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)'
+ PathtoPublish: '$(System.DefaultWorkingDirectory)\artifacts\log\$(BuildConfiguration)'
ArtifactName: '$(OperatingSystemName) $(BuildConfiguration)'
continueOnError: true
condition: not(succeeded())
@@ -887,7 +887,7 @@ The following build definition steps are required for successful generation of a
inputs:
dropServiceURI: 'https://devdiv.artifacts.visualstudio.com'
buildNumber: 'ProfilingInputs/DevDiv/$(Build.Repository.Name)/$(Build.SourceBranchName)/$(Build.BuildNumber)'
- sourcePath: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data'
+ sourcePath: '$(System.DefaultWorkingDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data'
toLowerCase: false
usePat: false
displayName: 'OptProf - Publish to Artifact Services - ProfilingInputs'
@@ -900,7 +900,7 @@ The following build definition steps are required for successful generation of a
vsMajorVersion: $(VisualStudio.MajorVersion)
channelName: $(VisualStudio.ChannelName)
manifests: $(VisualStudio.SetupManifestList)
- outputFolder: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\Insertion'
+ outputFolder: '$(System.DefaultWorkingDirectory)\artifacts\VSSetup\$(BuildConfiguration)\Insertion'
displayName: 'OptProf - Build VS bootstrapper'
condition: succeeded()
diff --git a/src/arcade/Documentation/AzureDevOps/PhaseToJobSchemaChange.md b/src/arcade/Documentation/AzureDevOps/PhaseToJobSchemaChange.md
index 39cf0a9dde47..fbaec6a0c024 100644
--- a/src/arcade/Documentation/AzureDevOps/PhaseToJobSchemaChange.md
+++ b/src/arcade/Documentation/AzureDevOps/PhaseToJobSchemaChange.md
@@ -188,7 +188,7 @@ phases:
- task: PublishBuildArtifacts@1
displayName: Publish Logs to VSTS
inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)'
+ PathtoPublish: '$(System.DefaultWorkingDirectory)/artifacts/log/$(_BuildConfig)'
PublishLocation: Container
ArtifactName: $(Agent.Os)_$(Agent.JobName)
continueOnError: true
@@ -276,7 +276,7 @@ phases:
- task: PublishBuildArtifacts@1
displayName: Publish Logs to VSTS
inputs:
- PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)'
+ PathtoPublish: '$(System.DefaultWorkingDirectory)/artifacts/log/$(_BuildConfig)'
PublishLocation: Container
ArtifactName: $(Agent.Os)_$(Agent.JobName)
continueOnError: true
diff --git a/src/arcade/Documentation/AzureDevOps/SendingJobsToHelix.md b/src/arcade/Documentation/AzureDevOps/SendingJobsToHelix.md
index bb39c2a9dc51..6b93e46321ac 100644
--- a/src/arcade/Documentation/AzureDevOps/SendingJobsToHelix.md
+++ b/src/arcade/Documentation/AzureDevOps/SendingJobsToHelix.md
@@ -100,7 +100,7 @@ The list of available Helix queues can be found on the [Helix homepage](https://
# HelixConfiguration: '' -- any property that you would like to attached to a job
# HelixPreCommands: '' -- any commands that you would like to run prior to running your job
# HelixPostCommands: '' -- any commands that you would like to run after running your job
- XUnitProjects: $(Build.SourcesDirectory)/HelloTests/HelloTests.csproj # specify your xUnit projects (semicolon delimited) here!
+ XUnitProjects: $(System.DefaultWorkingDirectory)/HelloTests/HelloTests.csproj # specify your xUnit projects (semicolon delimited) here!
# XUnitWorkItemTimeout: '00:05:00' -- a timeout (specified as a System.TimeSpan string) for all work items created from XUnitProjects
XUnitPublishTargetFramework: netcoreapp3.1 # specify your publish target framework here
XUnitRuntimeTargetFramework: netcoreapp2.0 # specify the framework you want to use for the xUnit runner
diff --git a/src/arcade/Documentation/DependencyFlowOnboardingWithoutArcade.md b/src/arcade/Documentation/DependencyFlowOnboardingWithoutArcade.md
index 1f31150624d0..7212c4ea9e37 100644
--- a/src/arcade/Documentation/DependencyFlowOnboardingWithoutArcade.md
+++ b/src/arcade/Documentation/DependencyFlowOnboardingWithoutArcade.md
@@ -78,7 +78,7 @@ If you only have one Azure DevOps job that publishes assets, then you can add th
azureSubscription: "Darc: Maestro Production"
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/sdk-task.ps1
arguments: -task PublishBuildAssets
-restore
-msbuildEngine dotnet
diff --git a/src/arcade/Documentation/HowToAddPerfTestingToPipeline.md b/src/arcade/Documentation/HowToAddPerfTestingToPipeline.md
index ec8c55009f0e..cb3155519e8d 100644
--- a/src/arcade/Documentation/HowToAddPerfTestingToPipeline.md
+++ b/src/arcade/Documentation/HowToAddPerfTestingToPipeline.md
@@ -103,7 +103,7 @@ Performance testing has been fully tested in coreclr. Coreclr, corefx and other
# Test job depends on the corresponding build job
dependsOn: build_Windows_NT_x64_Release
- extraSetupParameters: -CoreRootDirectory $(Build.SourcesDirectory)\bin\tests\Windows_NT.x64.Release\Tests\Core_Root -Architecture x64
+ extraSetupParameters: -CoreRootDirectory $(System.DefaultWorkingDirectory)\bin\tests\Windows_NT.x64.Release\Tests\Core_Root -Architecture x64
steps:
# Download product build
@@ -121,7 +121,7 @@ Performance testing has been fully tested in coreclr. Coreclr, corefx and other
inputs:
sourceFolder: $(System.ArtifactsDirectory)/Windows_NT_x64_Release_build
contents: '**'
- targetFolder: $(Build.SourcesDirectory)/bin/Product/Windows_NT.x64.Release
+ targetFolder: $(System.DefaultWorkingDirectory)/bin/Product/Windows_NT.x64.Release
# Create Core_Root
- script: build-test.cmd Release x64 skipmanaged skipnative
diff --git a/src/arcade/Documentation/OneLocBuild.md b/src/arcade/Documentation/OneLocBuild.md
index 404e47f2ae9d..c217dd48f1b3 100644
--- a/src/arcade/Documentation/OneLocBuild.md
+++ b/src/arcade/Documentation/OneLocBuild.md
@@ -182,7 +182,7 @@ The parameters that can be passed to the template are as follows:
| **Parameter** | **Default Value** | **Notes** |
|:-:|:-:|-|
| `RepoType` | `'gitHub'` | Should be set to `'gitHub'` for GitHub-based repositories and `'azureDevOps'` for Azure DevOps-based ones. |
-| `SourcesDirectory` | `$(Build.SourcesDirectory)` | This is the root directory for your repository source code. |
+| `SourcesDirectory` | `$(System.DefaultWorkingDirectory)` | This is the root directory for your repository source code. |
| `CreatePr` | `true` | When set to `true`, instructs the OneLocBuild task to make a PR back to the source repository containing the localized files. |
| `AutoCompletePr` | `false` | When set to `true`, instructs the OneLocBuild task to autocomplete the created PR. Requires permissions to bypass any checks on the main branch. |
| `ReusePr` | `true` | When set to `true`, instructs the OneLocBuild task to update an existing PR (if one exists) rather than open a new one to reduce PR noise. |
diff --git a/src/arcade/Documentation/Policy/PowershellBestPractices.md b/src/arcade/Documentation/Policy/PowershellBestPractices.md
index ff25d5a91ecc..27a9c9abe059 100644
--- a/src/arcade/Documentation/Policy/PowershellBestPractices.md
+++ b/src/arcade/Documentation/Policy/PowershellBestPractices.md
@@ -169,3 +169,7 @@ will force this behavior.
Was this helpful? [](https://helix.dot.net/f/p/5?p=Documentation%5CPolicy%5CPowershellBestPractices.md) [](https://helix.dot.net/f/n/5?p=Documentation%5CPolicy%5CPowershellBestPractices.md)
+
+## Always pass -UseBasicParsing to Invoke-WebRequest
+
+To prevent blocking execution on older versions of PowerShell after the [KB5074596](https://support.microsoft.com/help/5074596) security update.
diff --git a/src/arcade/Documentation/Projects/Build Analysis/BuildRetryOnboard.md b/src/arcade/Documentation/Projects/Build Analysis/BuildRetryOnboard.md
index 906873208140..8ed320140698 100644
--- a/src/arcade/Documentation/Projects/Build Analysis/BuildRetryOnboard.md
+++ b/src/arcade/Documentation/Projects/Build Analysis/BuildRetryOnboard.md
@@ -21,7 +21,7 @@ Ex. \eng\BuildConfiguration\build-configuration.json
```
- task: PublishPipelineArtifact@1
inputs:
- targetPath: $(Build.SourcesDirectory)\eng\BuildConfiguration
+ targetPath: $(System.DefaultWorkingDirectory)\eng\BuildConfiguration
artifactName: BuildConfiguration
```
diff --git a/src/arcade/Documentation/SBOMGenerationGuidance.md b/src/arcade/Documentation/SBOMGenerationGuidance.md
index 9e9b5e28057b..f65f816cd3d2 100644
--- a/src/arcade/Documentation/SBOMGenerationGuidance.md
+++ b/src/arcade/Documentation/SBOMGenerationGuidance.md
@@ -78,7 +78,7 @@ Arcade configurations. The template allows customization of behavior via the fol
- `ManifestDirPath`: Determines where in the build agent the SBOM will be generated to, defaults to
`$(Build.ArtifactStagingDirectory)/sbom`
- `BuildDropPath` : Determines the directory that the SBOM tooling will use to find build outputs.
- Defaults to $`(Build.SourcesDirectory)/artifacts` to match Arcade's convention.
+ Defaults to $`(System.DefaultWorkingDirectory)/artifacts` to match Arcade's convention.
- `sbomContinueOnError`: By default the tasks are set up to not break the build and instead continue
on error if anything goes wrong in the generation process.
@@ -246,7 +246,7 @@ for your release builds:
```
It means that your build outputs might not match with the expected location for Arcade:
- `$(Build.SourcesDirectory)/Artifacts`. In this case you should modify the `BuildDropPath`
+ `$(System.DefaultWorkingDirectory)/Artifacts`. In this case you should modify the `BuildDropPath`
parameter of the template to point to your build's output directory.
- For any other problems with the tasks or templates, you can reach out to the [.NET Engineering
diff --git a/src/arcade/NuGet.config b/src/arcade/NuGet.config
index 98d5bfbc2460..f0da823560cb 100644
--- a/src/arcade/NuGet.config
+++ b/src/arcade/NuGet.config
@@ -14,6 +14,8 @@
+
+
@@ -50,12 +52,15 @@
+
+
+
+
+
+
+
-
-
-
-
diff --git a/src/arcade/azure-pipelines-codeql.yml b/src/arcade/azure-pipelines-codeql.yml
index 75f9c91e35d5..6e609a45668c 100644
--- a/src/arcade/azure-pipelines-codeql.yml
+++ b/src/arcade/azure-pipelines-codeql.yml
@@ -33,9 +33,7 @@ schedules:
branches:
include:
- main
- - release/6.0
- - release/8.0
- - release/9.0
+ - release/*.0
always: true
jobs:
diff --git a/src/arcade/azure-pipelines-daily.yaml b/src/arcade/azure-pipelines-daily.yaml
index a537ee89627c..357cc81d4882 100644
--- a/src/arcade/azure-pipelines-daily.yaml
+++ b/src/arcade/azure-pipelines-daily.yaml
@@ -27,9 +27,9 @@ stages:
inputs:
packageType: runtime
version: 8.x
- installationPath: $(Build.SourcesDirectory)/.dotnet
+ installationPath: $(System.DefaultWorkingDirectory)/.dotnet
- - script: $(Build.SourcesDirectory)/.dotnet/dotnet.exe tool restore
+ - script: dotnet tool restore
displayName: Restore dotnet tools
- task: AzureCLI@2
diff --git a/src/arcade/azure-pipelines-pr.yml b/src/arcade/azure-pipelines-pr.yml
index 8b20b6d280ba..4f2a75102bfb 100644
--- a/src/arcade/azure-pipelines-pr.yml
+++ b/src/arcade/azure-pipelines-pr.yml
@@ -3,9 +3,7 @@ trigger:
branches:
include:
- main
- - release/6.0
- - release/8.0
- - release/9.0
+ - release/*.0
exclude:
- .github/*
- Documentation/*
@@ -20,9 +18,7 @@ pr:
branches:
include:
- main
- - release/6.0
- - release/8.0
- - release/9.0
+ - release/*.0
- templates
paths:
include:
@@ -164,7 +160,7 @@ stages:
/p:DotNetSymbolServerTokenSymWeb=DryRunPTA
/p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
- /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt'
+ /p:SymbolPublishingExclusionsFile='$(System.DefaultWorkingDirectory)/eng/SymbolPublishingExclusionsFile.txt'
/p:Configuration=Release
/p:PublishToMSDL=false
- powershell: eng\common\build.ps1
@@ -174,8 +170,8 @@ stages:
-restore
-test
-warnAsError $false
- -projects $(Build.SourcesDirectory)\tests\UnitTests.proj
- /bl:$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)\Helix.binlog
+ -projects $(System.DefaultWorkingDirectory)\tests\UnitTests.proj
+ /bl:$(System.DefaultWorkingDirectory)\artifacts\log\$(_BuildConfig)\Helix.binlog
/p:RestoreUsingNuGetTargets=false
displayName: Run Helix Tests
env:
@@ -204,8 +200,8 @@ stages:
--restore
--test
--warnAsError false
- --projects $(Build.SourcesDirectory)/tests/UnitTests.proj
- /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.binlog
+ --projects $(System.DefaultWorkingDirectory)/tests/UnitTests.proj
+ /bl:$(System.DefaultWorkingDirectory)/artifacts/log/$(_BuildConfig)/Helix.binlog
/p:RestoreUsingNuGetTargets=false
displayName: Run Helix Tests
env:
@@ -249,8 +245,8 @@ stages:
-restore
-test
-warnAsError false
- -projects $(Build.SourcesDirectory)/tests/XHarness.Apple.SimulatorTests.proj
- /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/XHarness.Apple.Simulator.Tests.binlog
+ -projects $(System.DefaultWorkingDirectory)/tests/XHarness.Apple.SimulatorTests.proj
+ /bl:$(System.DefaultWorkingDirectory)/artifacts/log/$(_BuildConfig)/XHarness.Apple.Simulator.Tests.binlog
/p:RestoreUsingNuGetTargets=false
displayName: XHarness Apple Simulator Helix Testing
env:
@@ -279,8 +275,8 @@ stages:
-restore
-test
-warnAsError false
- -projects $(Build.SourcesDirectory)/tests/XHarness.Apple.DeviceTests.proj
- /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Apple.Device.Tests.binlog
+ -projects $(System.DefaultWorkingDirectory)/tests/XHarness.Apple.DeviceTests.proj
+ /bl:$(System.DefaultWorkingDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Apple.Device.Tests.binlog
/p:RestoreUsingNuGetTargets=false
displayName: XHarness Apple Device Helix Testing
env:
@@ -309,8 +305,8 @@ stages:
-restore
-test
-warnAsError false
- -projects $(Build.SourcesDirectory)/tests/XHarness.Android.SimulatorTests.proj
- /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Android.Simulator.Tests.binlog
+ -projects $(System.DefaultWorkingDirectory)/tests/XHarness.Android.SimulatorTests.proj
+ /bl:$(System.DefaultWorkingDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Android.Simulator.Tests.binlog
/p:RestoreUsingNuGetTargets=false
displayName: XHarness Android Helix Testing (Linux)
env:
@@ -338,8 +334,8 @@ stages:
-restore
-test
-warnAsError $false
- -projects $(Build.SourcesDirectory)\tests\XHarness.Android.DeviceTests.proj
- /bl:$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)\Helix.XHarness.Android.Device.Tests.binlog
+ -projects $(System.DefaultWorkingDirectory)\tests\XHarness.Android.DeviceTests.proj
+ /bl:$(System.DefaultWorkingDirectory)\artifacts\log\$(_BuildConfig)\Helix.XHarness.Android.Device.Tests.binlog
/p:RestoreUsingNuGetTargets=false
displayName: XHarness Android Helix Testing (Windows)
env:
diff --git a/src/arcade/azure-pipelines-unofficial.yml b/src/arcade/azure-pipelines-unofficial.yml
new file mode 100644
index 000000000000..887f46d621d6
--- /dev/null
+++ b/src/arcade/azure-pipelines-unofficial.yml
@@ -0,0 +1,27 @@
+trigger: none
+
+variables:
+- template: /eng/common-variables.yml@self
+ parameters:
+ signType: test
+- template: /eng/common/templates-official/variables/pool-providers.yml@self
+
+resources:
+ containers:
+ - container: LinuxContainer
+ image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-net10.0-fpm-amd64
+ repositories:
+ - repository: 1ESPipelineTemplates
+ type: git
+ name: 1ESPipelineTemplates/1ESPipelineTemplates
+ ref: refs/tags/release
+extends:
+ template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates
+ parameters:
+ pool:
+ name: $(DncEngInternalBuildPool)
+ image: windows.vs2019.amd64
+ os: windows
+
+ stages:
+ - template: /eng/build.yml@self
diff --git a/src/arcade/azure-pipelines.yml b/src/arcade/azure-pipelines.yml
index ce915aaac72c..373ee74dd6b2 100644
--- a/src/arcade/azure-pipelines.yml
+++ b/src/arcade/azure-pipelines.yml
@@ -3,9 +3,7 @@ trigger:
branches:
include:
- main
- - release/6.0
- - release/8.0
- - release/9.0
+ - release/*.0
paths:
include:
- '*'
@@ -24,6 +22,8 @@ pr: none
variables:
- template: /eng/common-variables.yml@self
+ parameters:
+ signType: real
- template: /eng/common/templates-official/variables/pool-providers.yml@self
resources:
@@ -47,67 +47,13 @@ extends:
enabled: true
tsa:
enabled: true
+ binskim:
+ scanOutputDirectoryOnly: true
+ analyzeTargetGlob: +:f|**/artifacts/**/*.dll;+:f|**/artifacts/**/*.exe;-:f|**/*.Tests/**/*;-:f|**/wix/**/*;-:f|**/wix3/**/*;-:f|**/winterop.dll;
stages:
- - stage: build
- displayName: Build
- jobs:
- - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/main')) }}:
- - template: /eng/common/templates-official/job/onelocbuild.yml@self
- parameters:
- MirrorRepo: arcade
- LclSource: lclFilesFromPackage
- LclPackageId: 'LCL-JUNO-PROD-ARCADE'
- - template: /eng/common/templates-official/jobs/jobs.yml@self
- parameters:
- artifacts:
- publish:
- artifacts: true
- logs: true
- manifests: true
- enableMicrobuild: true
- enableSourceIndex: true
- enableSourceBuild: true
- workspace:
- clean: all
- jobs:
- - job: Windows_NT
- timeoutInMinutes: 90
- strategy:
- matrix:
- Build_Release:
- _BuildConfig: Release
- preSteps:
- - checkout: self
- fetchDepth: 0
- clean: true
- steps:
- - script: eng\common\cibuild.cmd
- -configuration $(_BuildConfig)
- -prepareMachine
- $(_InternalBuildArgs)
- /p:Test=false
- displayName: Windows Build / Publish
-
- - stage: ValidateSdk
- displayName: Validate Arcade SDK
- dependsOn: build
- jobs:
- - template: /eng/validate-sdk.yml@self
- parameters:
- buildArgs: -configuration $(_BuildConfig)
- -prepareMachine
- $(_InternalBuildArgs)
- /p:Test=false
-
- - template: /eng/common/templates-official/post-build/post-build.yml@self
+ - template: /eng/build.yml@self
parameters:
- publishingInfraVersion: 3
- # signing validation will not run, even if the below value is 'true', if the 'PostBuildSign' variable is set to 'true'
- enableSigningValidation: false
- # Sourcelink validation isn't passing for Arcade due to some regressions. This should be
- # enabled back once this issue is resolved: https://github.com/dotnet/arcade/issues/2912
- enableSourceLinkValidation: false
- publishDependsOn:
- - Validate
- - ValidateSdk
+ ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
+ oneLocEnabled: true
+ microbuildUseESRP: true
diff --git a/src/arcade/eng/BuildTask.Packages.props b/src/arcade/eng/BuildTask.Packages.props
index fd82c1e09415..d8f9f7900665 100644
--- a/src/arcade/eng/BuildTask.Packages.props
+++ b/src/arcade/eng/BuildTask.Packages.props
@@ -2,14 +2,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/arcade/eng/Version.Details.props b/src/arcade/eng/Version.Details.props
index b1b6069ef9b8..bbe1689181ee 100644
--- a/src/arcade/eng/Version.Details.props
+++ b/src/arcade/eng/Version.Details.props
@@ -1,4 +1,3 @@
-
10.0.100-preview.4.25220.1
- 10.0.0-beta.25401.2
- 10.0.0-beta.25401.2
+ 11.0.0-beta.25570.6
+ 11.0.0-beta.25570.6
- 1.1.0-beta.25404.2
- 1.1.0-beta.25404.2
+ 1.1.0-beta.25564.1
+ 1.1.0-beta.25564.1
- 10.0.0-prerelease.25381.1
+ 11.0.0-prerelease.25603.1
1.1.0-beta2-19575-01
1.1.0-beta2-19575-01
8.0.0-preview.24461.2
-
- 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
- 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
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
+ 9.0.0
2.0.0-preview.1.24305.1
@@ -51,12 +50,16 @@ This file should be imported by eng/Versions.props
2.0.0-beta5.25210.1
- 1.1.0-beta.25381.1
+ 1.1.0-beta.25564.1
- 17.12.36
- 17.12.36
- 17.12.36
- 17.12.36
+ 17.12.50
+ 17.12.50
+ 17.12.50
+ 17.12.50
+
+ 2.23.0
+
+ 13.0.3
@@ -81,7 +84,7 @@ This file should be imported by eng/Versions.props
$(MicrosoftDiaSymReaderPdb2PdbPackageVersion)
$(MicrosoftSymbolManifestGeneratorPackageVersion)
-
+
$(MicrosoftBclAsyncInterfacesPackageVersion)
$(MicrosoftExtensionsDependencyInjectionPackageVersion)
$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)
@@ -111,5 +114,9 @@ This file should be imported by eng/Versions.props
$(MicrosoftBuildFrameworkPackageVersion)
$(MicrosoftBuildTasksCorePackageVersion)
$(MicrosoftBuildUtilitiesCorePackageVersion)
+
+ $(MicrosoftApplicationInsightsPackageVersion)
+
+ $(NewtonsoftJsonPackageVersion)
diff --git a/src/arcade/eng/Version.Details.xml b/src/arcade/eng/Version.Details.xml
index d4781abff02a..e43556c0c4a9 100644
--- a/src/arcade/eng/Version.Details.xml
+++ b/src/arcade/eng/Version.Details.xml
@@ -1,6 +1,6 @@
-
+
@@ -20,25 +20,25 @@
https://github.com/dotnet/templating
43b5827697e501c442eb75ffff832cd4df2514fe
-
+
https://github.com/dotnet/arcade
- 40693ae2ee51e447f6ca96d07bc1ba779dcb9b9c
+ c1926cf647dd684194c2914f47f61ff534f030ac
-
+
https://github.com/dotnet/arcade
- 40693ae2ee51e447f6ca96d07bc1ba779dcb9b9c
+ c1926cf647dd684194c2914f47f61ff534f030ac
-
+
https://github.com/dotnet/arcade-services
- 412c9802fe722908764810f1b097dcc8307fc8ec
+ 526aa00e2a2533e0263e50f299d5525572c48c18
-
+
https://github.com/dotnet/arcade-services
- 412c9802fe722908764810f1b097dcc8307fc8ec
+ 526aa00e2a2533e0263e50f299d5525572c48c18
-
+
https://github.com/dotnet/xharness
- 889949a0c734be07795cedf04690f959b0cf00bc
+ 3df2923500447ee925d59f026c81720c7a9b4e4b
https://github.com/dotnet/roslyn
@@ -58,57 +58,57 @@
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
https://github.com/dotnet/deployment-tools
@@ -119,51 +119,59 @@
ef4c24166691977558e5312758df4313ab310dc0
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
https://github.com/dotnet/command-line-api
e9b0511d7f1128e2bc3be7a658a2a4ea977e602d
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
- https://dev.azure.com/dnceng/internal/_git/dotnet-runtime
- 990ebf52fc408ca45929fd176d2740675a67fab8
+
+ https://github.com/dotnet/runtime
+ d3981726bc8b0e179db50301daf9f22d42393096
-
+
https://github.com/dotnet/dnceng
- 9f9162ee769829503e3efb7b7ec688de558ff63b
+ 79d5ba9594a98c05483843e8bc018e312bc5817b
-
+
https://github.com/dotnet/msbuild
d1cce8d7cc03c23a4f1bad8e9240714fd9d199a3
-
+
https://github.com/dotnet/msbuild
d1cce8d7cc03c23a4f1bad8e9240714fd9d199a3
-
+
https://github.com/dotnet/msbuild
d1cce8d7cc03c23a4f1bad8e9240714fd9d199a3
-
+
https://github.com/dotnet/msbuild
d1cce8d7cc03c23a4f1bad8e9240714fd9d199a3
+
+ https://github.com/microsoft/ApplicationInsights-dotnet
+ 2faa7e8b157a431daa2e71785d68abd5fa817b53
+
+
+ https://github.com/JamesNK/Newtonsoft.Json
+ 0a2e291c0d9c0c7675d445703e51750363a549ef
+
diff --git a/src/arcade/eng/Versions.props b/src/arcade/eng/Versions.props
index 50fe1932967b..fff57b61fc41 100644
--- a/src/arcade/eng/Versions.props
+++ b/src/arcade/eng/Versions.props
@@ -1,14 +1,15 @@
-
+
+
+
-
- 10.0.0
+ 11.0.0
beta
-
+
+
false
-
- true
+
6.0.0
@@ -20,21 +21,20 @@
4.5.5
6.0.1
+
9.0.0-beta.24223.1
4.3.0
-
- 2.0.3
- 6.13.2
- 6.13.2
- 6.13.2
- 6.13.2
- 6.13.2
+ 6.14.0
+ 6.14.0
+ 6.14.0
+ 6.14.0
+ 6.14.0
5.0.0
6.0.4
@@ -53,4 +53,5 @@
17.5.0
+
diff --git a/src/arcade/eng/build.yml b/src/arcade/eng/build.yml
new file mode 100644
index 000000000000..2c7cb0452de5
--- /dev/null
+++ b/src/arcade/eng/build.yml
@@ -0,0 +1,73 @@
+parameters:
+- name: oneLocEnabled
+ default: false
+ type: boolean
+- name: microbuildUseESRP
+ default: false
+ type: boolean
+
+stages:
+- stage: build
+ displayName: Build
+ jobs:
+ - ${{ if eq(parameters.oneLocEnabled, true) }}:
+ - template: /eng/common/templates-official/job/onelocbuild.yml@self
+ parameters:
+ MirrorRepo: arcade
+ LclSource: lclFilesFromPackage
+ LclPackageId: 'LCL-JUNO-PROD-ARCADE'
+ - template: /eng/common/templates-official/jobs/jobs.yml@self
+ parameters:
+ artifacts:
+ publish:
+ artifacts: true
+ logs: true
+ manifests: true
+ enableMicrobuild: true
+ microbuildUseESRP: ${{ parameters.microbuildUseESRP }}
+ enableSourceIndex: true
+ enableSourceBuild: true
+ workspace:
+ clean: all
+ jobs:
+ - job: Windows_NT
+ timeoutInMinutes: 90
+ strategy:
+ matrix:
+ Build_Release:
+ _BuildConfig: Release
+ preSteps:
+ - checkout: self
+ fetchDepth: 0
+ clean: true
+ steps:
+ - script: eng\common\cibuild.cmd
+ -configuration $(_BuildConfig)
+ -prepareMachine
+ $(_InternalBuildArgs)
+ /p:Test=false
+ displayName: Windows Build / Publish
+
+- stage: ValidateSdk
+ displayName: Validate Arcade SDK
+ dependsOn: build
+ jobs:
+ - template: /eng/validate-sdk.yml@self
+ parameters:
+ microbuildUseESRP: ${{ parameters.microbuildUseESRP }}
+ buildArgs: -configuration $(_BuildConfig)
+ -prepareMachine
+ $(_InternalBuildArgs)
+ /p:Test=false
+
+- template: /eng/common/templates-official/post-build/post-build.yml@self
+ parameters:
+ publishingInfraVersion: 3
+ # signing validation will not run, even if the below value is 'true', if the 'PostBuildSign' variable is set to 'true'
+ enableSigningValidation: false
+ # Sourcelink validation isn't passing for Arcade due to some regressions. This should be
+ # enabled back once this issue is resolved: https://github.com/dotnet/arcade/issues/2912
+ enableSourceLinkValidation: false
+ publishDependsOn:
+ - Validate
+ - ValidateSdk
diff --git a/src/arcade/eng/common-variables.yml b/src/arcade/eng/common-variables.yml
index 32cbb325ac39..4892a24959cd 100644
--- a/src/arcade/eng/common-variables.yml
+++ b/src/arcade/eng/common-variables.yml
@@ -1,3 +1,8 @@
+parameters:
+- name: signType
+ default: Test
+ type: string
+
variables:
# Cannot use key:value syntax in root defined variables
- name: _TeamName
@@ -17,7 +22,7 @@ variables:
- name: _RunAsInternal
value: True
- name: _SignType
- value: real
+ value: ${{ parameters.signType }}
# Publish-Build-Assets provides: BotAccount-dotnet-maestro-bot-PAT
# DotNet-HelixApi-Access provides: HelixApiAccessToken
- group: Publish-Build-Assets
@@ -25,7 +30,7 @@ variables:
- group: SDL_Settings
# DotNetPublishUsingPipelines can be removed when Arcade itself consumes a new Arcade version.
- name: _InternalBuildArgs
- value: /p:DotNetSignType=$(_SignType)
+ value: /p:DotNetSignType=${{ parameters.signType }}
/p:TeamName=$(_TeamName)
/p:DotNetPublishUsingPipelines=true
/p:OfficialBuildId=$(BUILD.BUILDNUMBER)
diff --git a/src/arcade/eng/common/SetupNugetSources.ps1 b/src/arcade/eng/common/SetupNugetSources.ps1
index 5db4ad71ee2f..fc8d618014e0 100644
--- a/src/arcade/eng/common/SetupNugetSources.ps1
+++ b/src/arcade/eng/common/SetupNugetSources.ps1
@@ -7,11 +7,11 @@
# See example call for this script below.
#
# - task: PowerShell@2
-# displayName: Setup Private Feeds Credentials
+# displayName: Setup internal Feeds Credentials
# condition: eq(variables['Agent.OS'], 'Windows_NT')
# inputs:
-# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
-# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
+# filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+# arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token
# env:
# Token: $(dn-bot-dnceng-artifact-feeds-rw)
#
@@ -34,19 +34,28 @@ Set-StrictMode -Version 2.0
. $PSScriptRoot\tools.ps1
+# Adds or enables the package source with the given name
+function AddOrEnablePackageSource($sources, $disabledPackageSources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) {
+ if ($disabledPackageSources -eq $null -or -not (EnableInternalPackageSource -DisabledPackageSources $disabledPackageSources -Creds $creds -PackageSourceName $SourceName)) {
+ AddPackageSource -Sources $sources -SourceName $SourceName -SourceEndPoint $SourceEndPoint -Creds $creds -Username $userName -pwd $Password
+ }
+}
+
# Add source entry to PackageSources
function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) {
$packageSource = $sources.SelectSingleNode("add[@key='$SourceName']")
if ($packageSource -eq $null)
{
+ Write-Host "Adding package source $SourceName"
+
$packageSource = $doc.CreateElement("add")
$packageSource.SetAttribute("key", $SourceName)
$packageSource.SetAttribute("value", $SourceEndPoint)
$sources.AppendChild($packageSource) | Out-Null
}
else {
- Write-Host "Package source $SourceName already present."
+ Write-Host "Package source $SourceName already present and enabled."
}
AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd
@@ -59,6 +68,8 @@ function AddCredential($creds, $source, $username, $pwd) {
return;
}
+ Write-Host "Inserting credential for feed: " $source
+
# Looks for credential configuration for the given SourceName. Create it if none is found.
$sourceElement = $creds.SelectSingleNode($Source)
if ($sourceElement -eq $null)
@@ -91,24 +102,27 @@ function AddCredential($creds, $source, $username, $pwd) {
$passwordElement.SetAttribute("value", $pwd)
}
-function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) {
- $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]")
-
- Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds."
-
- ForEach ($PackageSource in $maestroPrivateSources) {
- Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key
- AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd
+# Enable all darc-int package sources.
+function EnableMaestroInternalPackageSources($DisabledPackageSources, $Creds) {
+ $maestroInternalSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]")
+ ForEach ($DisabledPackageSource in $maestroInternalSources) {
+ EnableInternalPackageSource -DisabledPackageSources $DisabledPackageSources -Creds $Creds -PackageSourceName $DisabledPackageSource.key
}
}
-function EnablePrivatePackageSources($DisabledPackageSources) {
- $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]")
- ForEach ($DisabledPackageSource in $maestroPrivateSources) {
- Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource"
+# Enables an internal package source by name, if found. Returns true if the package source was found and enabled, false otherwise.
+function EnableInternalPackageSource($DisabledPackageSources, $Creds, $PackageSourceName) {
+ $DisabledPackageSource = $DisabledPackageSources.SelectSingleNode("add[@key='$PackageSourceName']")
+ if ($DisabledPackageSource) {
+ Write-Host "Enabling internal source '$($DisabledPackageSource.key)'."
+
# Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries
$DisabledPackageSources.RemoveChild($DisabledPackageSource)
+
+ AddCredential -Creds $creds -Source $DisabledPackageSource.Key -Username $userName -pwd $Password
+ return $true
}
+ return $false
}
if (!(Test-Path $ConfigFile -PathType Leaf)) {
@@ -121,15 +135,17 @@ $doc = New-Object System.Xml.XmlDocument
$filename = (Get-Item $ConfigFile).FullName
$doc.Load($filename)
-# Get reference to or create one if none exist already
+# Get reference to - fail if none exist
$sources = $doc.DocumentElement.SelectSingleNode("packageSources")
if ($sources -eq $null) {
- $sources = $doc.CreateElement("packageSources")
- $doc.DocumentElement.AppendChild($sources) | Out-Null
+ Write-PipelineTelemetryError -Category 'Build' -Message "Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. NuGet config file must contain a packageSources section: $ConfigFile"
+ ExitWithExitCode 1
}
$creds = $null
+$feedSuffix = "v3/index.json"
if ($Password) {
+ $feedSuffix = "v2"
# Looks for a node. Create it if none is found.
$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials")
if ($creds -eq $null) {
@@ -138,33 +154,22 @@ if ($Password) {
}
}
+$userName = "dn-bot"
+
# Check for disabledPackageSources; we'll enable any darc-int ones we find there
$disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources")
if ($disabledSources -ne $null) {
Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node"
- EnablePrivatePackageSources -DisabledPackageSources $disabledSources
-}
-
-$userName = "dn-bot"
-
-# Insert credential nodes for Maestro's private feeds
-InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password
-
-# 3.1 uses a different feed url format so it's handled differently here
-$dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']")
-if ($dotnet31Source -ne $null) {
- AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password
- 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
+ EnableMaestroInternalPackageSources -DisabledPackageSources $disabledSources -Creds $creds
}
-
-$dotnetVersions = @('5','6','7','8','9')
+$dotnetVersions = @('5','6','7','8','9','10')
foreach ($dotnetVersion in $dotnetVersions) {
$feedPrefix = "dotnet" + $dotnetVersion;
$dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']")
if ($dotnetSource -ne $null) {
- AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password
- AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password
+ AddOrEnablePackageSource -Sources $sources -DisabledPackageSources $disabledSources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/$feedSuffix" -Creds $creds -Username $userName -pwd $Password
+ AddOrEnablePackageSource -Sources $sources -DisabledPackageSources $disabledSources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/$feedSuffix" -Creds $creds -Username $userName -pwd $Password
}
}
diff --git a/src/arcade/eng/common/SetupNugetSources.sh b/src/arcade/eng/common/SetupNugetSources.sh
index 4604b61b0323..b97cc536379d 100755
--- a/src/arcade/eng/common/SetupNugetSources.sh
+++ b/src/arcade/eng/common/SetupNugetSources.sh
@@ -11,8 +11,8 @@
# - task: Bash@3
# displayName: Setup Internal Feeds
# inputs:
-# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
-# arguments: $(Build.SourcesDirectory)/NuGet.config
+# filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.sh
+# arguments: $(System.DefaultWorkingDirectory)/NuGet.config
# condition: ne(variables['Agent.OS'], 'Windows_NT')
# - task: NuGetAuthenticate@1
#
@@ -52,78 +52,124 @@ if [[ `uname -s` == "Darwin" ]]; then
TB=''
fi
-# Ensure there is a ... section.
-grep -i "" $ConfigFile
-if [ "$?" != "0" ]; then
- echo "Adding ... section."
- ConfigNodeHeader=""
- PackageSourcesTemplate="${TB}${NL}${TB}"
+# Enables an internal package source by name, if found. Returns 0 if found and enabled, 1 if not found.
+EnableInternalPackageSource() {
+ local PackageSourceName="$1"
+
+ # Check if disabledPackageSources section exists
+ grep -i "" "$ConfigFile" > /dev/null
+ if [ "$?" != "0" ]; then
+ return 1 # No disabled sources section
+ fi
+
+ # Check if this source name is disabled
+ grep -i " /dev/null
+ if [ "$?" == "0" ]; then
+ echo "Enabling internal source '$PackageSourceName'."
+ # Remove the disabled entry (including any surrounding comments or whitespace on the same line)
+ sed -i.bak "//d" "$ConfigFile"
+
+ # Add the source name to PackageSources for credential handling
+ PackageSources+=("$PackageSourceName")
+ return 0 # Found and enabled
+ fi
+
+ return 1 # Not found in disabled sources
+}
+
+# Add source entry to PackageSources
+AddPackageSource() {
+ local SourceName="$1"
+ local SourceEndPoint="$2"
+
+ # Check if source already exists
+ grep -i " /dev/null
+ if [ "$?" == "0" ]; then
+ echo "Package source $SourceName already present and enabled."
+ PackageSources+=("$SourceName")
+ return
+ fi
+
+ echo "Adding package source $SourceName"
+ PackageSourcesNodeFooter=""
+ PackageSourceTemplate="${TB}"
+
+ sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" "$ConfigFile"
+ PackageSources+=("$SourceName")
+}
+
+# Adds or enables the package source with the given name
+AddOrEnablePackageSource() {
+ local SourceName="$1"
+ local SourceEndPoint="$2"
+
+ # Try to enable if disabled, if not found then add new source
+ EnableInternalPackageSource "$SourceName"
+ if [ "$?" != "0" ]; then
+ AddPackageSource "$SourceName" "$SourceEndPoint"
+ fi
+}
- sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" $ConfigFile
-fi
+# Enable all darc-int package sources
+EnableMaestroInternalPackageSources() {
+ # Check if disabledPackageSources section exists
+ grep -i "" "$ConfigFile" > /dev/null
+ if [ "$?" != "0" ]; then
+ return # No disabled sources section
+ fi
+
+ # Find all darc-int disabled sources
+ local DisabledDarcIntSources=()
+ DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' "$ConfigFile" | tr -d '"')
+
+ for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do
+ if [[ $DisabledSourceName == darc-int* ]]; then
+ EnableInternalPackageSource "$DisabledSourceName"
+ fi
+ done
+}
-# Ensure there is a ... section.
-grep -i "" $ConfigFile
+# Ensure there is a ... section.
+grep -i "" $ConfigFile
if [ "$?" != "0" ]; then
- echo "Adding ... section."
-
- PackageSourcesNodeFooter=""
- PackageSourceCredentialsTemplate="${TB}${NL}${TB}"
-
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile
+ Write-PipelineTelemetryError -Category 'Build' "Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. NuGet config file must contain a packageSources section: $ConfigFile"
+ ExitWithExitCode 1
fi
PackageSources=()
-# Ensure dotnet3.1-internal and dotnet3.1-internal-transport are in the packageSources if the public dotnet3.1 feeds are present
-grep -i "... section.
+ grep -i "" $ConfigFile
if [ "$?" != "0" ]; then
- echo "Adding dotnet3.1-internal to the packageSources."
- PackageSourcesNodeFooter=""
- PackageSourceTemplate="${TB}"
+ echo "Adding ... section."
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
- fi
- PackageSources+=('dotnet3.1-internal')
-
- grep -i "" $ConfigFile
- if [ "$?" != "0" ]; then
- echo "Adding dotnet3.1-internal-transport to the packageSources."
PackageSourcesNodeFooter=""
- PackageSourceTemplate="${TB}"
+ PackageSourceCredentialsTemplate="${TB}${NL}${TB}"
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
+ sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile
fi
- PackageSources+=('dotnet3.1-internal-transport')
fi
-DotNetVersions=('5' '6' '7' '8' '9')
+# Check for disabledPackageSources; we'll enable any darc-int ones we find there
+grep -i "" $ConfigFile > /dev/null
+if [ "$?" == "0" ]; then
+ echo "Checking for any darc-int disabled package sources in the disabledPackageSources node"
+ EnableMaestroInternalPackageSources
+fi
+
+DotNetVersions=('5' '6' '7' '8' '9' '10')
for DotNetVersion in ${DotNetVersions[@]} ; do
FeedPrefix="dotnet${DotNetVersion}";
- grep -i " /dev/null
if [ "$?" == "0" ]; then
- grep -i ""
-
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
- fi
- PackageSources+=("$FeedPrefix-internal")
-
- grep -i "" $ConfigFile
- if [ "$?" != "0" ]; then
- echo "Adding $FeedPrefix-internal-transport to the packageSources."
- PackageSourcesNodeFooter=""
- PackageSourceTemplate="${TB}"
-
- sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile
- fi
- PackageSources+=("$FeedPrefix-internal-transport")
+ AddOrEnablePackageSource "$FeedPrefix-internal" "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$FeedPrefix-internal/nuget/$FeedSuffix"
+ AddOrEnablePackageSource "$FeedPrefix-internal-transport" "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$FeedPrefix-internal-transport/nuget/$FeedSuffix"
fi
done
@@ -139,29 +185,12 @@ if [ "$CredToken" ]; then
# Check if there is no existing credential for this FeedName
grep -i "<$FeedName>" $ConfigFile
if [ "$?" != "0" ]; then
- echo "Adding credentials for $FeedName."
+ echo " Inserting credential for feed: $FeedName"
PackageSourceCredentialsNodeFooter=""
- NewCredential="${TB}${TB}<$FeedName>${NL}${NL}${NL}$FeedName>"
+ NewCredential="${TB}${TB}<$FeedName>${NL}${TB}${NL}${TB}${TB}${NL}${TB}${TB}$FeedName>"
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
-if [ "$?" == "0" ]; then
- DisabledDarcIntSources=()
- echo "Re-enabling any disabled \"darc-int\" package sources in $ConfigFile"
- DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' $ConfigFile | tr -d '"')
- for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do
- if [[ $DisabledSourceName == darc-int* ]]
- then
- OldDisableValue=""
- NewDisableValue=""
- sed -i.bak "s|$OldDisableValue|$NewDisableValue|" $ConfigFile
- echo "Neutralized disablePackageSources entry for '$DisabledSourceName'"
- fi
- done
-fi
diff --git a/src/arcade/eng/common/build.sh b/src/arcade/eng/common/build.sh
index 9767bb411a4f..ec3e80d189ea 100755
--- a/src/arcade/eng/common/build.sh
+++ b/src/arcade/eng/common/build.sh
@@ -92,7 +92,7 @@ runtime_source_feed=''
runtime_source_feed_key=''
properties=()
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
-help|-h)
diff --git a/src/arcade/eng/common/core-templates/job/job.yml b/src/arcade/eng/common/core-templates/job/job.yml
index d9013251542c..748c4f07a64d 100644
--- a/src/arcade/eng/common/core-templates/job/job.yml
+++ b/src/arcade/eng/common/core-templates/job/job.yml
@@ -19,6 +19,8 @@ parameters:
# publishing defaults
artifacts: ''
enableMicrobuild: false
+ enablePreviewMicrobuild: false
+ microbuildPluginVersion: 'latest'
enableMicrobuildForMacAndLinux: false
microbuildUseESRP: true
enablePublishBuildArtifacts: false
@@ -71,6 +73,8 @@ jobs:
templateContext: ${{ parameters.templateContext }}
variables:
+ - name: AllowPtrToDetectTestRunRetryFiles
+ value: true
- ${{ if ne(parameters.enableTelemetry, 'false') }}:
- name: DOTNET_CLI_TELEMETRY_PROFILE
value: '$(Build.Repository.Uri)'
@@ -128,6 +132,8 @@ jobs:
- template: /eng/common/core-templates/steps/install-microbuild.yml
parameters:
enableMicrobuild: ${{ parameters.enableMicrobuild }}
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildPluginVersion: ${{ parameters.microbuildPluginVersion }}
enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}
microbuildUseESRP: ${{ parameters.microbuildUseESRP }}
continueOnError: ${{ parameters.continueOnError }}
@@ -153,6 +159,8 @@ jobs:
- template: /eng/common/core-templates/steps/cleanup-microbuild.yml
parameters:
enableMicrobuild: ${{ parameters.enableMicrobuild }}
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildPluginVersion: ${{ parameters.microbuildPluginVersion }}
enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }}
continueOnError: ${{ parameters.continueOnError }}
@@ -163,7 +171,7 @@ jobs:
inputs:
testResultsFormat: 'xUnit'
testResultsFiles: '*.xml'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/TestResults/$(_BuildConfig)'
testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit
mergeTestResults: ${{ parameters.mergeTestResults }}
continueOnError: true
@@ -174,7 +182,7 @@ jobs:
inputs:
testResultsFormat: 'VSTest'
testResultsFiles: '*.trx'
- searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)'
+ searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/TestResults/$(_BuildConfig)'
testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx
mergeTestResults: ${{ parameters.mergeTestResults }}
continueOnError: true
@@ -218,7 +226,7 @@ jobs:
- task: CopyFiles@2
displayName: Gather buildconfiguration for build retry
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/eng/common/BuildConfiguration'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/eng/common/BuildConfiguration'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/eng/common/BuildConfiguration'
continueOnError: true
diff --git a/src/arcade/eng/common/core-templates/job/onelocbuild.yml b/src/arcade/eng/common/core-templates/job/onelocbuild.yml
index 8bf7d23355bc..c5788829a872 100644
--- a/src/arcade/eng/common/core-templates/job/onelocbuild.yml
+++ b/src/arcade/eng/common/core-templates/job/onelocbuild.yml
@@ -8,7 +8,7 @@ parameters:
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)
+ SourcesDirectory: $(System.DefaultWorkingDirectory)
CreatePr: true
AutoCompletePr: false
ReusePr: true
@@ -68,7 +68,7 @@ jobs:
- ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}:
- task: Powershell@2
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/generate-locproject.ps1
arguments: $(_GenerateLocProjectArguments)
displayName: Generate LocProject.json
condition: ${{ parameters.condition }}
@@ -103,7 +103,7 @@ jobs:
- task: CopyFiles@2
displayName: Copy LocProject.json
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/eng/Localize/'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/eng/Localize/'
Contents: 'LocProject.json'
TargetFolder: '$(Build.ArtifactStagingDirectory)/loc'
condition: ${{ parameters.condition }}
diff --git a/src/arcade/eng/common/core-templates/job/publish-build-assets.yml b/src/arcade/eng/common/core-templates/job/publish-build-assets.yml
index d5303229c97e..8b5c635fe807 100644
--- a/src/arcade/eng/common/core-templates/job/publish-build-assets.yml
+++ b/src/arcade/eng/common/core-templates/job/publish-build-assets.yml
@@ -38,6 +38,10 @@ parameters:
# Optional: A minimatch pattern for the asset manifests to publish to BAR
assetManifestsPattern: '*/manifests/**/*.xml'
+ repositoryAlias: self
+
+ officialBuildId: ''
+
jobs:
- job: Asset_Registry_Publish
@@ -60,6 +64,11 @@ jobs:
value: false
# unconditional - needed for logs publishing (redactor tool version)
- template: /eng/common/core-templates/post-build/common-variables.yml
+ - name: OfficialBuildId
+ ${{ if ne(parameters.officialBuildId, '') }}:
+ value: ${{ parameters.officialBuildId }}
+ ${{ else }}:
+ value: $(Build.BuildNumber)
pool:
# We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
@@ -78,12 +87,12 @@ jobs:
- '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
+ - checkout: ${{ parameters.repositoryAlias }}
fetchDepth: 3
clean: true
- - ${{ if eq(parameters.isAssetlessBuild, 'false') }}:
- - ${{ if eq(parameters.publishingVersion, 3) }}:
+ - ${{ if eq(parameters.isAssetlessBuild, 'false') }}:
+ - ${{ if eq(parameters.publishingVersion, 3) }}:
- task: DownloadPipelineArtifact@2
displayName: Download Asset Manifests
inputs:
@@ -108,24 +117,35 @@ jobs:
flattenFolders: true
condition: ${{ parameters.condition }}
continueOnError: ${{ parameters.continueOnError }}
-
+
- task: NuGetAuthenticate@1
+ # Populate internal runtime variables.
+ - template: /eng/common/templates/steps/enable-internal-sources.yml
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ parameters:
+ legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - template: /eng/common/templates/steps/enable-internal-runtimes.yml
+
- task: AzureCLI@2
displayName: Publish Build Assets
inputs:
azureSubscription: "Darc: Maestro Production"
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/sdk-task.ps1
arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet
/p:ManifestsPath='$(Build.StagingDirectory)/AssetManifests'
/p:IsAssetlessBuild=${{ parameters.isAssetlessBuild }}
/p:MaestroApiEndpoint=https://maestro.dot.net
- /p:OfficialBuildId=$(Build.BuildNumber)
+ /p:OfficialBuildId=$(OfficialBuildId)
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
+
condition: ${{ parameters.condition }}
continueOnError: ${{ parameters.continueOnError }}
-
+
- task: powershell@2
displayName: Create ReleaseConfigs Artifact
inputs:
@@ -137,7 +157,7 @@ jobs:
Add-Content -Path $filePath -Value "$(DefaultChannels)"
Add-Content -Path $filePath -Value $(IsStableBuild)
- $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt"
+ $symbolExclusionfile = "$(System.DefaultWorkingDirectory)/eng/SymbolPublishingExclusionsFile.txt"
if (Test-Path -Path $symbolExclusionfile)
{
Write-Host "SymbolExclusionFile exists"
@@ -153,7 +173,7 @@ jobs:
artifactName: AssetManifests
displayName: 'Publish Merged Manifest'
retryCountOnTaskFailure: 10 # for any logs being locked
- sbomEnabled: false # we don't need SBOM for logs
+ sbomEnabled: false # we don't need SBOM for logs
- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
parameters:
@@ -170,6 +190,11 @@ jobs:
BARBuildId: ${{ parameters.BARBuildId }}
PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ # Darc is targeting 8.0, so make sure it's installed
+ - task: UseDotNet@2
+ inputs:
+ version: 8.0.x
- task: AzureCLI@2
displayName: Publish Using Darc
@@ -177,7 +202,7 @@ jobs:
azureSubscription: "Darc: Maestro Production"
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1
arguments: >
-BuildId $(BARBuildId)
-PublishingInfraVersion 3
@@ -186,9 +211,11 @@ jobs:
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
-SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
-SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
- ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}:
- template: /eng/common/core-templates/steps/publish-logs.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
- JobLabel: 'Publish_Artifacts_Logs'
+ JobLabel: 'Publish_Artifacts_Logs'
diff --git a/src/arcade/eng/common/core-templates/job/source-build.yml b/src/arcade/eng/common/core-templates/job/source-build.yml
index d805d5faeb94..9d820f974211 100644
--- a/src/arcade/eng/common/core-templates/job/source-build.yml
+++ b/src/arcade/eng/common/core-templates/job/source-build.yml
@@ -60,10 +60,10 @@ jobs:
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
+ demands: ImageOverride -equals build.ubuntu.2204.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
+ image: 1es-azurelinux-3
os: linux
${{ else }}:
pool:
diff --git a/src/arcade/eng/common/core-templates/job/source-index-stage1.yml b/src/arcade/eng/common/core-templates/job/source-index-stage1.yml
index 30530359a5d6..76baf5c27258 100644
--- a/src/arcade/eng/common/core-templates/job/source-index-stage1.yml
+++ b/src/arcade/eng/common/core-templates/job/source-index-stage1.yml
@@ -3,7 +3,7 @@ parameters:
sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
preSteps: []
binlogPath: artifacts/log/Debug/Build.binlog
- condition: ''
+ condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
dependsOn: ''
pool: ''
is1ESPipeline: ''
@@ -25,10 +25,10 @@ jobs:
pool:
${{ if eq(variables['System.TeamProject'], 'public') }}:
name: $(DncEngPublicBuildPool)
- image: windows.vs2022.amd64.open
+ image: windows.vs2026preview.scout.amd64.open
${{ if eq(variables['System.TeamProject'], 'internal') }}:
name: $(DncEngInternalBuildPool)
- image: windows.vs2022.amd64
+ image: windows.vs2026preview.scout.amd64
steps:
- ${{ if eq(parameters.is1ESPipeline, '') }}:
@@ -41,4 +41,4 @@ jobs:
- template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
parameters:
- binLogPath: ${{ parameters.binLogPath }}
\ No newline at end of file
+ binLogPath: ${{ parameters.binLogPath }}
diff --git a/src/arcade/eng/common/core-templates/jobs/codeql-build.yml b/src/arcade/eng/common/core-templates/jobs/codeql-build.yml
index 693b00b37044..dbc14ac580a2 100644
--- a/src/arcade/eng/common/core-templates/jobs/codeql-build.yml
+++ b/src/arcade/eng/common/core-templates/jobs/codeql-build.yml
@@ -24,7 +24,7 @@ jobs:
- name: DefaultGuardianVersion
value: 0.109.0
- name: GuardianPackagesConfigFile
- value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
+ value: $(System.DefaultWorkingDirectory)\eng\common\sdl\packages.config
- name: GuardianVersion
value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
diff --git a/src/arcade/eng/common/core-templates/jobs/jobs.yml b/src/arcade/eng/common/core-templates/jobs/jobs.yml
index 2f992b2c6ecc..01ada7476651 100644
--- a/src/arcade/eng/common/core-templates/jobs/jobs.yml
+++ b/src/arcade/eng/common/core-templates/jobs/jobs.yml
@@ -43,6 +43,8 @@ parameters:
artifacts: {}
is1ESPipeline: ''
+ repositoryAlias: self
+ officialBuildId: ''
# 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.
@@ -114,3 +116,5 @@ jobs:
enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
+ repositoryAlias: ${{ parameters.repositoryAlias }}
+ officialBuildId: ${{ parameters.officialBuildId }}
diff --git a/src/arcade/eng/common/core-templates/post-build/post-build.yml b/src/arcade/eng/common/core-templates/post-build/post-build.yml
index a151fd811e3e..06864cd1feb8 100644
--- a/src/arcade/eng/common/core-templates/post-build/post-build.yml
+++ b/src/arcade/eng/common/core-templates/post-build/post-build.yml
@@ -1,106 +1,106 @@
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: requireDefaultChannels
- displayName: Fail the build if there are no default channel(s) registrations for the current build
- type: boolean
- default: false
-
- - name: SDLValidationParameters
- type: object
- default:
- enable: false
- publishGdn: false
- continueOnError: false
- params: ''
- artifactNames: ''
- downloadArtifacts: true
-
- - name: isAssetlessBuild
- type: boolean
- displayName: Is Assetless Build
- default: false
-
- # 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
+# 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: requireDefaultChannels
+ displayName: Fail the build if there are no default channel(s) registrations for the current build
+ type: boolean
+ default: false
+
+- name: SDLValidationParameters
+ type: object
+ default:
+ enable: false
+ publishGdn: false
+ continueOnError: false
+ params: ''
+ artifactNames: ''
+ downloadArtifacts: true
+
+- name: isAssetlessBuild
+ type: boolean
+ displayName: Is Assetless Build
+ default: false
+
+# 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')) }}:
@@ -108,10 +108,10 @@ stages:
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 }}
+ - 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
@@ -127,35 +127,35 @@ stages:
${{ else }}:
${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
- image: windows.vs2022.amd64
+ image: windows.vs2026preview.scout.amd64
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026preview.scout.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/
+ - 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: $(System.DefaultWorkingDirectory)/eng/common/post-build/nuget-validation.ps1
+ arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/
- job:
displayName: Signing Validation
@@ -169,54 +169,54 @@ stages:
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
image: 1es-windows-2022
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026preview.scout.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
-
- # 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)
+ - 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
+
+ # 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='$(System.DefaultWorkingDirectory)/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
@@ -230,41 +230,41 @@ stages:
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ ${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
image: 1es-windows-2022
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026preview.scout.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
+ - 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: $(System.DefaultWorkingDirectory)/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
@@ -274,10 +274,10 @@ stages:
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 }}
+ - 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
@@ -291,30 +291,41 @@ stages:
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
+ ${{ 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
+ 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: >
+ - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
+ parameters:
+ BARBuildId: ${{ parameters.BARBuildId }}
+ PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
+ is1ESPipeline: ${{ parameters.is1ESPipeline }}
+
+ - task: NuGetAuthenticate@1
+
+ # Populate internal runtime variables.
+ - template: /eng/common/templates/steps/enable-internal-sources.yml
+ parameters:
+ legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw)
+
+ - template: /eng/common/templates/steps/enable-internal-runtimes.yml
+
+ - task: UseDotNet@2
+ inputs:
+ version: 8.0.x
+
+ - task: AzureCLI@2
+ displayName: Publish Using Darc
+ inputs:
+ azureSubscription: "Darc: Maestro Production"
+ scriptType: ps
+ scriptLocation: scriptPath
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1
+ arguments: >
-BuildId $(BARBuildId)
-PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
-AzdoToken '$(System.AccessToken)'
@@ -323,3 +334,5 @@ stages:
-ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}'
-SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}'
-SkipAssetsPublishing '${{ parameters.isAssetlessBuild }}'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
diff --git a/src/arcade/eng/common/core-templates/post-build/setup-maestro-vars.yml b/src/arcade/eng/common/core-templates/post-build/setup-maestro-vars.yml
index f7602980dbe7..a7abd58c4bb6 100644
--- a/src/arcade/eng/common/core-templates/post-build/setup-maestro-vars.yml
+++ b/src/arcade/eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -36,7 +36,7 @@ steps:
$AzureDevOpsBuildId = $Env:Build_BuildId
}
else {
- . $(Build.SourcesDirectory)\eng\common\tools.ps1
+ . $(System.DefaultWorkingDirectory)\eng\common\tools.ps1
$darc = Get-Darc
$buildInfo = & $darc get-build `
--id ${{ parameters.BARBuildId }} `
diff --git a/src/arcade/eng/common/core-templates/steps/enable-internal-sources.yml b/src/arcade/eng/common/core-templates/steps/enable-internal-sources.yml
index 64f881bffc3c..4085512b6909 100644
--- a/src/arcade/eng/common/core-templates/steps/enable-internal-sources.yml
+++ b/src/arcade/eng/common/core-templates/steps/enable-internal-sources.yml
@@ -17,8 +17,8 @@ steps:
- task: PowerShell@2
displayName: Setup Internal Feeds
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
- arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config -Password $Env:Token
env:
Token: ${{ parameters.legacyCredential }}
# If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate.
@@ -29,8 +29,8 @@ steps:
- task: PowerShell@2
displayName: Setup Internal Feeds
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
- arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(System.DefaultWorkingDirectory)/NuGet.config
- ${{ else }}:
- template: /eng/common/templates/steps/get-federated-access-token.yml
parameters:
@@ -39,8 +39,8 @@ steps:
- 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)
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/SetupNugetSources.ps1
+ arguments: -ConfigFile $(System.DefaultWorkingDirectory)/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).
diff --git a/src/arcade/eng/common/core-templates/steps/generate-sbom.yml b/src/arcade/eng/common/core-templates/steps/generate-sbom.yml
index 44a9636cdff9..003f7eae0fa5 100644
--- a/src/arcade/eng/common/core-templates/steps/generate-sbom.yml
+++ b/src/arcade/eng/common/core-templates/steps/generate-sbom.yml
@@ -5,8 +5,8 @@
# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
parameters:
- PackageVersion: 10.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ PackageVersion: 11.0.0
+ BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
PackageName: '.NET'
ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
IgnoreDirectories: ''
diff --git a/src/arcade/eng/common/core-templates/steps/install-microbuild-impl.yml b/src/arcade/eng/common/core-templates/steps/install-microbuild-impl.yml
new file mode 100644
index 000000000000..da22beb3f60c
--- /dev/null
+++ b/src/arcade/eng/common/core-templates/steps/install-microbuild-impl.yml
@@ -0,0 +1,34 @@
+parameters:
+ - name: microbuildTaskInputs
+ type: object
+ default: {}
+
+ - name: microbuildEnv
+ type: object
+ default: {}
+
+ - name: enablePreviewMicrobuild
+ type: boolean
+ default: false
+
+ - name: condition
+ type: string
+
+ - name: continueOnError
+ type: boolean
+
+steps:
+- ${{ if eq(parameters.enablePreviewMicrobuild, true) }}:
+ - task: MicroBuildSigningPluginPreview@4
+ displayName: Install Preview MicroBuild plugin
+ inputs: ${{ parameters.microbuildTaskInputs }}
+ env: ${{ parameters.microbuildEnv }}
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: ${{ parameters.condition }}
+- ${{ else }}:
+ - task: MicroBuildSigningPlugin@4
+ displayName: Install MicroBuild plugin
+ inputs: ${{ parameters.microbuildTaskInputs }}
+ env: ${{ parameters.microbuildEnv }}
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: ${{ parameters.condition }}
diff --git a/src/arcade/eng/common/core-templates/steps/install-microbuild.yml b/src/arcade/eng/common/core-templates/steps/install-microbuild.yml
index da30e67bc34c..4f4b56ed2a6b 100644
--- a/src/arcade/eng/common/core-templates/steps/install-microbuild.yml
+++ b/src/arcade/eng/common/core-templates/steps/install-microbuild.yml
@@ -4,6 +4,8 @@ parameters:
# Enable install tasks for MicroBuild on Mac and Linux
# Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'
enableMicrobuildForMacAndLinux: false
+ # Enable preview version of MB signing plugin
+ enablePreviewMicrobuild: false
# Determines whether the ESRP service connection information should be passed to the signing plugin.
# This overlaps with _SignType to some degree. We only need the service connection for real signing.
# It's important that the service connection not be passed to the MicroBuildSigningPlugin task in this place.
@@ -11,8 +13,10 @@ parameters:
# Unfortunately, _SignType can't be used to exclude the use of the service connection in non-real sign scenarios. The
# variable is not available in template expression. _SignType has a very large proliferation across .NET, so replacing it is tough.
microbuildUseESRP: true
- # Location of the MicroBuild output folder
- microBuildOutputFolder: '$(Build.SourcesDirectory)'
+ # Microbuild installation directory
+ microBuildOutputFolder: $(Agent.TempDirectory)/MicroBuild
+ # Microbuild version
+ microbuildPluginVersion: 'latest'
continueOnError: false
@@ -25,8 +29,27 @@ steps:
inputs:
packageType: sdk
version: 8.0.x
- installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet
- workingDirectory: ${{ parameters.microBuildOutputFolder }}
+ installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet-microbuild
+ condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
+
+ - script: |
+ set -euo pipefail
+
+ # UseDotNet@2 prepends the dotnet executable path to the PATH variable, so we can call dotnet directly
+ version=$(dotnet --version)
+ cat << 'EOF' > ${{ parameters.microBuildOutputFolder }}/global.json
+ {
+ "sdk": {
+ "version": "$version",
+ "paths": [
+ "${{ parameters.microBuildOutputFolder }}/.dotnet-microbuild"
+ ],
+ "errorMessage": "The .NET SDK version $version is required to install the MicroBuild signing plugin."
+ }
+ }
+ EOF
+ displayName: 'Add global.json to MicroBuild Installation path'
+ workingDirectory: ${{ parameters.microBuildOutputFolder }}
condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
- script: |
@@ -46,35 +69,50 @@ steps:
displayName: 'Validate ESRP usage (Non-Windows)'
condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
- - task: MicroBuildSigningPlugin@4
- displayName: Install MicroBuild plugin
- inputs:
- signType: $(_SignType)
- zipSources: false
- feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
- ${{ if eq(parameters.microbuildUseESRP, true) }}:
- ${{ if eq(parameters.enableMicrobuildForMacAndLinux, 'true') }}:
- azureSubscription: 'MicroBuild Signing Task (DevDiv)'
- useEsrpCli: true
- ${{ elseif eq(variables['System.TeamProject'], 'DevDiv') }}:
- ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea
- ${{ else }}:
- ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca
- env:
- TeamName: $(_TeamName)
- MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
- SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- continueOnError: ${{ parameters.continueOnError }}
- condition: and(
- succeeded(),
- or(
- and(
- eq(variables['Agent.Os'], 'Windows_NT'),
- in(variables['_SignType'], 'real', 'test')
- ),
- and(
- ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},
- ne(variables['Agent.Os'], 'Windows_NT'),
- eq(variables['_SignType'], 'real')
- )
- ))
+ # Two different MB install steps. This is due to not being able to use the agent OS during
+ # YAML expansion, and Windows vs. Linux/Mac uses different service connections. However,
+ # we can avoid including the MB install step if not enabled at all. This avoids a bunch of
+ # extra pipeline authorizations, since most pipelines do not sign on non-Windows.
+ - template: /eng/common/core-templates/steps/install-microbuild-impl.yml@self
+ parameters:
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildTaskInputs:
+ signType: $(_SignType)
+ zipSources: false
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ version: ${{ parameters.microbuildPluginVersion }}
+ ${{ if eq(parameters.microbuildUseESRP, true) }}:
+ ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)'
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea
+ ${{ else }}:
+ ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca
+ microbuildEnv:
+ TeamName: $(_TeamName)
+ MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test'))
+
+ - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, true) }}:
+ - template: /eng/common/core-templates/steps/install-microbuild-impl.yml@self
+ parameters:
+ enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }}
+ microbuildTaskInputs:
+ signType: $(_SignType)
+ zipSources: false
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ version: ${{ parameters.microbuildPluginVersion }}
+ workingDirectory: ${{ parameters.microBuildOutputFolder }}
+ ${{ if eq(parameters.microbuildUseESRP, true) }}:
+ ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)'
+ ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
+ ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39
+ ${{ else }}:
+ ConnectedPMEServiceName: c24de2a5-cc7a-493d-95e4-8e5ff5cad2bc
+ microbuildEnv:
+ TeamName: $(_TeamName)
+ MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ continueOnError: ${{ parameters.continueOnError }}
+ condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'), eq(variables['_SignType'], 'real'))
diff --git a/src/arcade/eng/common/core-templates/steps/publish-logs.yml b/src/arcade/eng/common/core-templates/steps/publish-logs.yml
index de24d0087c58..5a927b4c7bcb 100644
--- a/src/arcade/eng/common/core-templates/steps/publish-logs.yml
+++ b/src/arcade/eng/common/core-templates/steps/publish-logs.yml
@@ -12,22 +12,24 @@ steps:
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}}/
+ New-Item -ItemType Directory $(System.DefaultWorkingDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
+ Move-Item -Path $(System.DefaultWorkingDirectory)/artifacts/log/Debug/* $(System.DefaultWorkingDirectory)/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
+ filePath: $(System.DefaultWorkingDirectory)/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'
+ # Sensitive data can as well be added to $(System.DefaultWorkingDirectory)/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'
+ arguments: -InputPath '$(System.DefaultWorkingDirectory)/PostBuildLogs'
+ -BinlogToolVersion '${{parameters.BinlogToolVersion}}'
+ -TokensFilePath '$(System.DefaultWorkingDirectory)/eng/BinlogSecretsRedactionFile.txt'
+ -runtimeSourceFeed https://ci.dot.net/internal
+ -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)'
'$(publishing-dnceng-devdiv-code-r-build-re)'
'$(MaestroAccessToken)'
'$(dn-bot-all-orgs-artifact-feeds-rw)'
@@ -44,7 +46,7 @@ steps:
- task: CopyFiles@2
displayName: Gather post build logs
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/PostBuildLogs'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
condition: always()
diff --git a/src/arcade/eng/common/core-templates/steps/source-index-stage1-publish.yml b/src/arcade/eng/common/core-templates/steps/source-index-stage1-publish.yml
index c2917c1efc1c..3ad83b8c3075 100644
--- a/src/arcade/eng/common/core-templates/steps/source-index-stage1-publish.yml
+++ b/src/arcade/eng/common/core-templates/steps/source-index-stage1-publish.yml
@@ -1,6 +1,6 @@
parameters:
- sourceIndexUploadPackageVersion: 2.0.0-20250425.2
- sourceIndexProcessBinlogPackageVersion: 1.0.1-20250515.1
+ sourceIndexUploadPackageVersion: 2.0.0-20250906.1
+ sourceIndexProcessBinlogPackageVersion: 1.0.1-20250906.1
sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
binlogPath: artifacts/log/Debug/Build.binlog
@@ -14,13 +14,13 @@ steps:
workingDirectory: $(Agent.TempDirectory)
- script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.sourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.sourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
displayName: "Source Index: Download netsourceindex 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: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
+- script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(System.DefaultWorkingDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
displayName: "Source Index: Process Binlog into indexable sln"
- ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
diff --git a/src/arcade/eng/common/cross/build-rootfs.sh b/src/arcade/eng/common/cross/build-rootfs.sh
index 8abfb71f7275..9b7eede4e50f 100755
--- a/src/arcade/eng/common/cross/build-rootfs.sh
+++ b/src/arcade/eng/common/cross/build-rootfs.sh
@@ -72,7 +72,7 @@ __AlpinePackages+=" krb5-dev"
__AlpinePackages+=" openssl-dev"
__AlpinePackages+=" zlib-dev"
-__FreeBSDBase="13.4-RELEASE"
+__FreeBSDBase="13.5-RELEASE"
__FreeBSDPkg="1.21.3"
__FreeBSDABI="13"
__FreeBSDPackages="libunwind"
@@ -383,7 +383,7 @@ while :; do
;;
freebsd14)
__CodeName=freebsd
- __FreeBSDBase="14.2-RELEASE"
+ __FreeBSDBase="14.3-RELEASE"
__FreeBSDABI="14"
__SkipUnmount=1
;;
diff --git a/src/arcade/eng/common/darc-init.sh b/src/arcade/eng/common/darc-init.sh
index e889f439b8dc..9f5ad6b763b5 100755
--- a/src/arcade/eng/common/darc-init.sh
+++ b/src/arcade/eng/common/darc-init.sh
@@ -5,7 +5,7 @@ darcVersion=''
versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20'
verbosity='minimal'
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
--darcversion)
diff --git a/src/arcade/eng/common/dotnet-install.sh b/src/arcade/eng/common/dotnet-install.sh
index 7b9d97e3bd4d..61f302bb6775 100755
--- a/src/arcade/eng/common/dotnet-install.sh
+++ b/src/arcade/eng/common/dotnet-install.sh
@@ -18,7 +18,7 @@ architecture=''
runtime='dotnet'
runtimeSourceFeed=''
runtimeSourceFeedKey=''
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
-version|-v)
diff --git a/src/arcade/eng/common/dotnet.sh b/src/arcade/eng/common/dotnet.sh
index 2ef68235675f..f6d24871c1d4 100755
--- a/src/arcade/eng/common/dotnet.sh
+++ b/src/arcade/eng/common/dotnet.sh
@@ -19,7 +19,7 @@ source $scriptroot/tools.sh
InitializeDotNetCli true # install
# Invoke acquired SDK with args if they are provided
-if [[ $# > 0 ]]; then
+if [[ $# -gt 0 ]]; then
__dotnetDir=${_InitializeDotNetCli}
dotnetPath=${__dotnetDir}/dotnet
${dotnetPath} "$@"
diff --git a/src/arcade/eng/common/generate-locproject.ps1 b/src/arcade/eng/common/generate-locproject.ps1
index 524aaa57f2b7..fa1cdc2b3007 100644
--- a/src/arcade/eng/common/generate-locproject.ps1
+++ b/src/arcade/eng/common/generate-locproject.ps1
@@ -33,15 +33,27 @@ $jsonTemplateFiles | ForEach-Object {
$jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\\strings\.json" } # current winforms pattern
+$wxlFilesV3 = @()
+$wxlFilesV5 = @()
$wxlFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\.+\.wxl" -And -Not( $_.Directory.Name -Match "\d{4}" ) } # localized files live in four digit lang ID directories; this excludes them
if (-not $wxlFiles) {
$wxlEnFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\\1033\\.+\.wxl" } # pick up en files (1033 = en) specifically so we can copy them to use as the neutral xlf files
if ($wxlEnFiles) {
- $wxlFiles = @()
- $wxlEnFiles | ForEach-Object {
- $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)"
- $wxlFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru
- }
+ $wxlFiles = @()
+ $wxlEnFiles | ForEach-Object {
+ $destinationFile = "$($_.Directory.Parent.FullName)\$($_.Name)"
+ $content = Get-Content $_.FullName -Raw
+
+ # Split files on schema to select different parser settings in the generated project.
+ if ($content -like "*http://wixtoolset.org/schemas/v4/wxl*")
+ {
+ $wxlFilesV5 += Copy-Item $_.FullName -Destination $destinationFile -PassThru
+ }
+ elseif ($content -like "*http://schemas.microsoft.com/wix/2006/localization*")
+ {
+ $wxlFilesV3 += Copy-Item $_.FullName -Destination $destinationFile -PassThru
+ }
+ }
}
}
@@ -114,7 +126,32 @@ $locJson = @{
CloneLanguageSet = "WiX_CloneLanguages"
LssFiles = @( "wxl_loc.lss" )
LocItems = @(
- $wxlFiles | ForEach-Object {
+ $wxlFilesV3 | ForEach-Object {
+ $outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\"
+ $continue = $true
+ foreach ($exclusion in $exclusions.Exclusions) {
+ if ($_.FullName.Contains($exclusion)) {
+ $continue = $false
+ }
+ }
+ $sourceFile = ($_.FullName | Resolve-Path -Relative)
+ if ($continue)
+ {
+ return @{
+ SourceFile = $sourceFile
+ CopyOption = "LangIDOnPath"
+ OutputPath = $outputPath
+ }
+ }
+ }
+ )
+ },
+ @{
+ LanguageSet = $LanguageSet
+ CloneLanguageSet = "WiX_CloneLanguages"
+ LssFiles = @( "P210WxlSchemaV4.lss" )
+ LocItems = @(
+ $wxlFilesV5 | ForEach-Object {
$outputPath = "$($_.Directory.FullName | Resolve-Path -Relative)\"
$continue = $true
foreach ($exclusion in $exclusions.Exclusions) {
diff --git a/src/arcade/eng/common/generate-sbom-prep.sh b/src/arcade/eng/common/generate-sbom-prep.sh
old mode 100755
new mode 100644
diff --git a/src/arcade/eng/common/internal-feed-operations.ps1 b/src/arcade/eng/common/internal-feed-operations.ps1
index 92b77347d990..c282d3ae403a 100644
--- a/src/arcade/eng/common/internal-feed-operations.ps1
+++ b/src/arcade/eng/common/internal-feed-operations.ps1
@@ -26,7 +26,7 @@ function SetupCredProvider {
$url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1'
Write-Host "Writing the contents of 'installcredprovider.ps1' locally..."
- Invoke-WebRequest $url -OutFile installcredprovider.ps1
+ Invoke-WebRequest $url -UseBasicParsing -OutFile installcredprovider.ps1
Write-Host 'Installing plugin...'
.\installcredprovider.ps1 -Force
diff --git a/src/arcade/eng/common/internal-feed-operations.sh b/src/arcade/eng/common/internal-feed-operations.sh
index 9378223ba095..6299e7effd4c 100755
--- a/src/arcade/eng/common/internal-feed-operations.sh
+++ b/src/arcade/eng/common/internal-feed-operations.sh
@@ -100,7 +100,7 @@ operation=''
authToken=''
repoName=''
-while [[ $# > 0 ]]; do
+while [[ $# -gt 0 ]]; do
opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
case "$opt" in
--operation)
diff --git a/src/arcade/eng/common/native/install-dependencies.sh b/src/arcade/eng/common/native/install-dependencies.sh
index 477a44f335be..11f81cbd40d4 100755
--- a/src/arcade/eng/common/native/install-dependencies.sh
+++ b/src/arcade/eng/common/native/install-dependencies.sh
@@ -27,9 +27,11 @@ case "$os" in
libssl-dev libkrb5-dev pigz cpio
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
- elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then
+ elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos" ]; then
pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)"
$pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
+ elif [ "$ID" = "amzn" ]; then
+ dnf install -y cmake llvm lld lldb clang python libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
elif [ "$ID" = "alpine" ]; then
apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio
else
diff --git a/src/arcade/eng/common/post-build/nuget-verification.ps1 b/src/arcade/eng/common/post-build/nuget-verification.ps1
index a365194a9389..eea88e653c91 100644
--- a/src/arcade/eng/common/post-build/nuget-verification.ps1
+++ b/src/arcade/eng/common/post-build/nuget-verification.ps1
@@ -30,7 +30,7 @@
[CmdletBinding(PositionalBinding = $false)]
param(
[string]$NuGetExePath,
- [string]$PackageSource = "https://api.nuget.org/v3/index.json",
+ [string]$PackageSource = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json",
[string]$DownloadPath,
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$args
@@ -65,7 +65,7 @@ if ($NuGetExePath) {
Write-Host "Downloading nuget.exe from $nugetExeUrl..."
$ProgressPreference = 'SilentlyContinue'
try {
- Invoke-WebRequest $nugetExeUrl -OutFile $downloadedNuGetExe
+ Invoke-WebRequest $nugetExeUrl -UseBasicParsing -OutFile $downloadedNuGetExe
$ProgressPreference = 'Continue'
} catch {
$ProgressPreference = 'Continue'
diff --git a/src/arcade/eng/common/post-build/publish-using-darc.ps1 b/src/arcade/eng/common/post-build/publish-using-darc.ps1
index 1eda208a3bbf..48e55598bdd2 100644
--- a/src/arcade/eng/common/post-build/publish-using-darc.ps1
+++ b/src/arcade/eng/common/post-build/publish-using-darc.ps1
@@ -7,7 +7,9 @@ param(
[Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters,
[Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters,
[Parameter(Mandatory=$false)][string] $RequireDefaultChannels,
- [Parameter(Mandatory=$false)][string] $SkipAssetsPublishing
+ [Parameter(Mandatory=$false)][string] $SkipAssetsPublishing,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeed,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey
)
try {
diff --git a/src/arcade/eng/common/post-build/redact-logs.ps1 b/src/arcade/eng/common/post-build/redact-logs.ps1
index b7fc19591507..fc0218a013d1 100644
--- a/src/arcade/eng/common/post-build/redact-logs.ps1
+++ b/src/arcade/eng/common/post-build/redact-logs.ps1
@@ -7,7 +7,9 @@ param(
# 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
+ [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeed,
+ [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey
)
try {
diff --git a/src/arcade/eng/common/sdk-task.ps1 b/src/arcade/eng/common/sdk-task.ps1
index a9d2a2d26996..b64b66a6275b 100644
--- a/src/arcade/eng/common/sdk-task.ps1
+++ b/src/arcade/eng/common/sdk-task.ps1
@@ -7,13 +7,16 @@ Param(
[switch] $restore,
[switch] $prepareMachine,
[switch][Alias('nobl')]$excludeCIBinaryLog,
+ [switch]$noWarnAsError,
[switch] $help,
+ [string] $runtimeSourceFeed = '',
+ [string] $runtimeSourceFeedKey = '',
[Parameter(ValueFromRemainingArguments=$true)][String[]]$properties
)
$ci = $true
$binaryLog = if ($excludeCIBinaryLog) { $false } else { $true }
-$warnAsError = $true
+$warnAsError = if ($noWarnAsError) { $false } else { $true }
. $PSScriptRoot\tools.ps1
@@ -67,7 +70,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.13.0" -MemberType NoteProperty
+ $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "18.0.0" -MemberType NoteProperty
}
if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") {
$xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true
diff --git a/src/arcade/eng/common/sdk-task.sh b/src/arcade/eng/common/sdk-task.sh
index 2f83adc0269f..3270f83fa9a7 100755
--- a/src/arcade/eng/common/sdk-task.sh
+++ b/src/arcade/eng/common/sdk-task.sh
@@ -10,6 +10,7 @@ show_usage() {
echo "Advanced settings:"
echo " --excludeCIBinarylog Don't output binary log (short: -nobl)"
+ echo " --noWarnAsError Do not warn as error"
echo ""
echo "Command line arguments not listed above are passed thru to msbuild."
}
@@ -52,6 +53,7 @@ exclude_ci_binary_log=false
restore=false
help=false
properties=''
+warnAsError=true
while (($# > 0)); do
lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
@@ -73,6 +75,10 @@ while (($# > 0)); do
exclude_ci_binary_log=true
shift 1
;;
+ --noWarnAsError)
+ warnAsError=false
+ shift 1
+ ;;
--help)
help=true
shift 1
@@ -85,7 +91,6 @@ while (($# > 0)); do
done
ci=true
-warnAsError=true
if $help; then
show_usage
diff --git a/src/arcade/eng/common/template-guidance.md b/src/arcade/eng/common/template-guidance.md
index 98bbc1ded0ba..4bf4cf41bd7c 100644
--- a/src/arcade/eng/common/template-guidance.md
+++ b/src/arcade/eng/common/template-guidance.md
@@ -50,7 +50,7 @@ extends:
- task: CopyFiles@2
displayName: Gather build output
inputs:
- SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel'
+ SourceFolder: '$(System.DefaultWorkingDirectory)/artifacts/marvel'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel'
```
diff --git a/src/arcade/eng/common/templates-official/job/job.yml b/src/arcade/eng/common/templates-official/job/job.yml
index a8a943287458..92a0664f5647 100644
--- a/src/arcade/eng/common/templates-official/job/job.yml
+++ b/src/arcade/eng/common/templates-official/job/job.yml
@@ -3,7 +3,7 @@ parameters:
enableSbom: true
runAsPublic: false
PackageVersion: 9.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
jobs:
- template: /eng/common/core-templates/job/job.yml
diff --git a/src/arcade/eng/common/templates-official/variables/sdl-variables.yml b/src/arcade/eng/common/templates-official/variables/sdl-variables.yml
index dbdd66d4a4b3..f1311bbb1b33 100644
--- a/src/arcade/eng/common/templates-official/variables/sdl-variables.yml
+++ b/src/arcade/eng/common/templates-official/variables/sdl-variables.yml
@@ -4,4 +4,4 @@ variables:
- name: DefaultGuardianVersion
value: 0.109.0
- name: GuardianPackagesConfigFile
- value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
\ No newline at end of file
+ value: $(System.DefaultWorkingDirectory)\eng\common\sdl\packages.config
\ No newline at end of file
diff --git a/src/arcade/eng/common/templates/job/job.yml b/src/arcade/eng/common/templates/job/job.yml
index 7cbf668c22bc..238fa0818f7b 100644
--- a/src/arcade/eng/common/templates/job/job.yml
+++ b/src/arcade/eng/common/templates/job/job.yml
@@ -6,7 +6,7 @@ parameters:
enableSbom: true
runAsPublic: false
PackageVersion: 9.0.0
- BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
+ BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
jobs:
- template: /eng/common/core-templates/job/job.yml
@@ -77,7 +77,7 @@ jobs:
parameters:
is1ESPipeline: false
args:
- targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration'
+ targetPath: '$(System.DefaultWorkingDirectory)\eng\common\BuildConfiguration'
artifactName: 'BuildConfiguration'
displayName: 'Publish build retry configuration'
continueOnError: true
diff --git a/src/arcade/eng/common/tools.ps1 b/src/arcade/eng/common/tools.ps1
index d4cfd9ccd806..f6bde2683794 100644
--- a/src/arcade/eng/common/tools.ps1
+++ b/src/arcade/eng/common/tools.ps1
@@ -157,9 +157,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
return $global:_DotNetInstallDir
}
- # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism
- $env:DOTNET_MULTILEVEL_LOOKUP=0
-
# Disable first run since we do not need all ASP.NET packages restored.
$env:DOTNET_NOLOGO=1
@@ -225,7 +222,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
# Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build
Write-PipelinePrependPath -Path $dotnetRoot
- Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0'
Write-PipelineSetVariable -Name 'DOTNET_NOLOGO' -Value '1'
return $global:_DotNetInstallDir = $dotnetRoot
@@ -277,7 +273,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) {
Retry({
Write-Host "GET $uri"
- Invoke-WebRequest $uri -OutFile $installScript
+ Invoke-WebRequest $uri -UseBasicParsing -OutFile $installScript
})
}
@@ -394,8 +390,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
# If the version of msbuild is going to be xcopied,
# use this version. Version matches a package here:
- # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.13.0
- $defaultXCopyMSBuildVersion = '17.13.0'
+ # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/18.0.0
+ $defaultXCopyMSBuildVersion = '18.0.0'
if (!$vsRequirements) {
if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {
@@ -510,7 +506,7 @@ function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) {
Write-Host "Downloading $packageName $packageVersion"
$ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
Retry({
- Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -OutFile $packagePath
+ Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -UseBasicParsing -OutFile $packagePath
})
if (!(Test-Path $packagePath)) {
@@ -544,7 +540,8 @@ function LocateVisualStudio([object]$vsRequirements = $null){
if (Get-Member -InputObject $GlobalJson.tools -Name 'vswhere') {
$vswhereVersion = $GlobalJson.tools.vswhere
} else {
- $vswhereVersion = '2.5.2'
+ # keep this in sync with the VSWhereVersion in DefaultVersions.props
+ $vswhereVersion = '3.1.7'
}
$vsWhereDir = Join-Path $ToolsDir "vswhere\$vswhereVersion"
@@ -552,25 +549,33 @@ function LocateVisualStudio([object]$vsRequirements = $null){
if (!(Test-Path $vsWhereExe)) {
Create-Directory $vsWhereDir
- Write-Host 'Downloading vswhere'
+ Write-Host "Downloading vswhere $vswhereVersion"
+ $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
Retry({
- Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -OutFile $vswhereExe
+ Invoke-WebRequest "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/windows/vswhere/$vswhereVersion/vswhere.exe" -UseBasicParsing -OutFile $vswhereExe
})
}
- if (!$vsRequirements) { $vsRequirements = $GlobalJson.tools.vs }
+ if (!$vsRequirements) {
+ if (Get-Member -InputObject $GlobalJson.tools -Name 'vs' -ErrorAction SilentlyContinue) {
+ $vsRequirements = $GlobalJson.tools.vs
+ } else {
+ $vsRequirements = $null
+ }
+ }
+
$args = @('-latest', '-format', 'json', '-requires', 'Microsoft.Component.MSBuild', '-products', '*')
if (!$excludePrereleaseVS) {
$args += '-prerelease'
}
- if (Get-Member -InputObject $vsRequirements -Name 'version') {
+ if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'version' -ErrorAction SilentlyContinue)) {
$args += '-version'
$args += $vsRequirements.version
}
- if (Get-Member -InputObject $vsRequirements -Name 'components') {
+ if ($vsRequirements -and (Get-Member -InputObject $vsRequirements -Name 'components' -ErrorAction SilentlyContinue)) {
foreach ($component in $vsRequirements.components) {
$args += '-requires'
$args += $component
diff --git a/src/arcade/eng/common/tools.sh b/src/arcade/eng/common/tools.sh
index c1841c9dfd0f..6c121300ac7d 100755
--- a/src/arcade/eng/common/tools.sh
+++ b/src/arcade/eng/common/tools.sh
@@ -115,9 +115,6 @@ function InitializeDotNetCli {
local install=$1
- # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism
- export DOTNET_MULTILEVEL_LOOKUP=0
-
# Disable first run since we want to control all package sources
export DOTNET_NOLOGO=1
@@ -166,7 +163,6 @@ function InitializeDotNetCli {
# build steps from using anything other than what we've downloaded.
Write-PipelinePrependPath -path "$dotnet_root"
- Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0"
Write-PipelineSetVariable -name "DOTNET_NOLOGO" -value "1"
# return value
diff --git a/src/arcade/eng/publishing/v3/publish.yml b/src/arcade/eng/publishing/v3/publish.yml
index 2df2c31d0317..383ac1b8e5de 100644
--- a/src/arcade/eng/publishing/v3/publish.yml
+++ b/src/arcade/eng/publishing/v3/publish.yml
@@ -25,7 +25,7 @@ stages:
azureSubscription: "Darc: Maestro Production"
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/publishing/v3/validate-and-locate-build.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/publishing/v3/validate-and-locate-build.ps1
arguments: >
-BuildId ${{ parameters.BARBuildId }}
-PromoteToChannelIds ${{ parameters.PromoteToChannelIds }}
@@ -102,7 +102,7 @@ stages:
- task: PowerShell@2
displayName: Enable cross-org publishing
inputs:
- filePath: $(Build.SourcesDirectory)/eng/common/enable-cross-org-publishing.ps1
+ filePath: $(System.DefaultWorkingDirectory)/eng/common/enable-cross-org-publishing.ps1
arguments: -token $(dn-bot-all-orgs-artifact-feeds-rw)
- task: AzureCLI@2
@@ -136,9 +136,9 @@ stages:
azureSubscription: maestro-build-promotion
scriptType: ps
scriptLocation: scriptPath
- scriptPath: $(Build.SourcesDirectory)/eng/common/sdk-task.ps1
+ scriptPath: $(System.DefaultWorkingDirectory)/eng/common/sdk-task.ps1
arguments: >
- -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
+ -task PublishArtifactsInManifest -restore -msbuildEngine dotnet -noWarnAsError
/p:PublishingInfraVersion=3
/p:BARBuildId=${{ parameters.BARBuildId }}
/p:TargetChannels='${{ parameters.PromoteToChannelIds }}'
diff --git a/src/arcade/eng/validate-sdk.yml b/src/arcade/eng/validate-sdk.yml
index 30c12dea6954..5dd1a0e4d081 100644
--- a/src/arcade/eng/validate-sdk.yml
+++ b/src/arcade/eng/validate-sdk.yml
@@ -2,6 +2,8 @@ parameters:
buildArgs: ''
validateBlobFeedUrl: https://dotnetfeed.blob.core.windows.net/dotnet-core-test/index.json
buildConfig: Release
+ microbuildUseESRP: false
+
jobs:
- template: /eng/common/templates-official/job/job.yml@self
@@ -9,6 +11,7 @@ jobs:
name: ValidateArcadeSDK
displayName: Validate Arcade SDK
enableMicrobuild: true
+ microbuildUseESRP: ${{ parameters.microbuildUseESRP }}
artifacts:
download:
path: build_stage_artifacts
@@ -40,7 +43,7 @@ jobs:
inlineScript: >
.\eng\update-packagesource.ps1
-gitHubPat $(BotAccount-dotnet-maestro-bot-PAT)
- -packagesSource $(Build.SourcesDirectory)/build_stage_artifacts
+ -packagesSource $(System.DefaultWorkingDirectory)/build_stage_artifacts
- script: eng\common\cibuild.cmd
$(_BuildArgs)
displayName: Build / Validate
diff --git a/src/arcade/eng/xcopy-msbuild/install-visualstudiobuildtools.ps1 b/src/arcade/eng/xcopy-msbuild/install-visualstudiobuildtools.ps1
index 91bc94cf866e..766b683ed42f 100644
--- a/src/arcade/eng/xcopy-msbuild/install-visualstudiobuildtools.ps1
+++ b/src/arcade/eng/xcopy-msbuild/install-visualstudiobuildtools.ps1
@@ -21,14 +21,14 @@ if(-Not (Test-Path $destinationDir))
New-Item -ItemType 'Directory' -Path "$destinationDir" -Force | Out-Null
}
# Query the page to get the download link
-$response = Invoke-WebRequest $downloadUrl
+$response = Invoke-WebRequest $downloadUrl -UseBasicParsing
$regex = "downloadUrl: '(?[^']+)'"
$response.Content -Match $regex | Out-Null
$downloadLink = $Matches['downloadUrl']
Write-Host "download link: $downloadLink"
-$response = Invoke-WebRequest $downloadLink -OutFile "$installerPath"
+$response = Invoke-WebRequest $downloadLink -UseBasicParsing -OutFile "$installerPath"
if(-Not (Test-Path $outputDirectory))
{
diff --git a/src/arcade/es-metadata.yml b/src/arcade/es-metadata.yml
new file mode 100644
index 000000000000..76c257c77efd
--- /dev/null
+++ b/src/arcade/es-metadata.yml
@@ -0,0 +1,8 @@
+schemaVersion: 0.0.1
+isProduction: true
+accountableOwners:
+ service: b3bbd815-183a-4142-8056-3a676d687f71
+routing:
+ defaultAreaPath:
+ org: dnceng
+ path: internal\Dotnet-Core-Engineering
diff --git a/src/arcade/global.json b/src/arcade/global.json
index a5dd3101dde8..1bb09a938a29 100644
--- a/src/arcade/global.json
+++ b/src/arcade/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "10.0.100-preview.7.25372.107",
+ "version": "10.0.100",
"rollForward": "latestFeature",
"paths": [
".dotnet",
@@ -9,11 +9,11 @@
"errorMessage": "The required .NET SDK wasn't found. Please run ./eng/common/dotnet.cmd/sh to install it."
},
"tools": {
- "dotnet": "10.0.100-preview.7.25372.107"
+ "dotnet": "10.0.100"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25401.2",
- "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25401.2",
+ "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.25570.6",
+ "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.25570.6",
"Microsoft.Build.NoTargets": "3.7.0"
}
}
diff --git a/src/arcade/scripts/add-build-variables.ps1 b/src/arcade/scripts/add-build-variables.ps1
index cb0137303b0c..de1fcf2084a5 100644
--- a/src/arcade/scripts/add-build-variables.ps1
+++ b/src/arcade/scripts/add-build-variables.ps1
@@ -47,7 +47,7 @@ param (
function UpdatePipeline($id, $authHeaders)
{
$pipelineUri = "https://dev.azure.com/$Org/$Project/_apis/build/definitions/$($id)?api-version=6.1-preview.7"
- $existingPipeline = Invoke-WebRequest -Headers $authHeaders -Method Get -Uri $pipelineUri -ContentType 'application/json' | ConvertFrom-Json
+ $existingPipeline = Invoke-WebRequest -UseBasicParsing -Headers $authHeaders -Method Get -Uri $pipelineUri -ContentType 'application/json' | ConvertFrom-Json
Write-Host "Updating pipeline $Org/$Project/$($existingPipeline.name) (pipeline id: $id)"
# Update the variables with the new one if not already done. If variable value is null, remove
@@ -72,7 +72,7 @@ function UpdatePipeline($id, $authHeaders)
# Attempt the update
$bodyJson = $existingPipeline | ConvertTo-Json -Depth 10
- $updatedPipelineJson = Invoke-WebRequest -Headers $azdoAuthHeader -Method Put $pipelineUri -Body $bodyJson -ContentType 'application/json' | ConvertFrom-Json
+ $updatedPipelineJson = Invoke-WebRequest -UseBasicParsing -Headers $azdoAuthHeader -Method Put $pipelineUri -Body $bodyJson -ContentType 'application/json' | ConvertFrom-Json
}
$base64authinfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$AzDoPAT"))
@@ -81,7 +81,7 @@ $azdoAuthHeader = @{"Authorization"="Basic $base64authinfo"}
if ($PipelineId) {
UpdatePipeline $PipelineId $azdoAuthHeader
} else {
- $allPipelines = Invoke-WebRequest -ContentType 'application/json' -Method Get -Headers $azdoAuthHeader -Uri "https://dev.azure.com/$Org/$Project/_apis/build/definitions?api-version=6.1-preview.7" | ConvertFrom-Json
+ $allPipelines = Invoke-WebRequest -UseBasicParsing -ContentType 'application/json' -Method Get -Headers $azdoAuthHeader -Uri "https://dev.azure.com/$Org/$Project/_apis/build/definitions?api-version=6.1-preview.7" | ConvertFrom-Json
Write-Host "Updating $($allPipelines.count) pipelines"
foreach ($pipeline in $allPipelines.value) {
UpdatePipeline $pipeline.Id $azdoAuthHeader
diff --git a/src/arcade/scripts/cqb-utilities.ps1 b/src/arcade/scripts/cqb-utilities.ps1
index a792c7271bc6..c3e4ad35b969 100644
--- a/src/arcade/scripts/cqb-utilities.ps1
+++ b/src/arcade/scripts/cqb-utilities.ps1
@@ -48,7 +48,7 @@ Function Gen-Internal-Merge-PR
}
try {
- $resp = Invoke-WebRequest -Method Post -Body $($prBody | ConvertTo-Json) -Headers $header -Uri "https://dev.azure.com/$Org/$Project/_apis/git/repositories/$RepoName/pullrequests?api-version=7.0" -ContentType application/json
+ $resp = Invoke-WebRequest -UseBasicParsing -Method Post -Body $($prBody | ConvertTo-Json) -Headers $header -Uri "https://dev.azure.com/$Org/$Project/_apis/git/repositories/$RepoName/pullrequests?api-version=7.0" -ContentType application/json
$result = $resp | ConvertFrom-Json
Write-Host https://dev.azure.com/$Org/$Project/_git/$RepoName/pullrequest/$($result.pullRequestId)
} catch {
diff --git a/src/arcade/scripts/create-preview-flow.ps1 b/src/arcade/scripts/create-preview-flow.ps1
index 593562719bd8..cb122c6635a8 100644
--- a/src/arcade/scripts/create-preview-flow.ps1
+++ b/src/arcade/scripts/create-preview-flow.ps1
@@ -162,12 +162,11 @@ if ($AddInternalFlow) {
Write-Host "Making default channels for SDK repos"
MakeDefaultChannel https://github.com/dotnet/sdk $SdkBranch $SdkChannel
-MakeDefaultChannel https://github.com/dotnet/roslyn-analyzers $SdkBranch $SdkChannel
MakeDefaultChannel https://github.com/dotnet/templating $SdkBranch $SdkChannel
if ($AddInternalFlow) {
# Because of where internal fixes tend to be, we eliminate some leaves in the sdk graph
- # and flow them through the normal public channels: templating, roslyn-analyzers
+ # and flow them through the normal public channels: templating
Write-Host "Making default channels for SDK repos"
MakeDefaultChannel https://dev.azure.com/dnceng/internal/_git/dotnet-sdk $InternalSdkBranch $InternalSdkChannel
MakeDefaultChannel https://dev.azure.com/dnceng/internal/_git/dotnet-templating $InternalSdkBranch $InternalSdkChannel
@@ -190,7 +189,6 @@ if ($AddInternalFlow) {
Write-Host "Adding arcade flow to repos not building in the VMR"
AddArcadeFlow https://dev.azure.com/dnceng/internal/_git/dotnet-wpf-int $RuntimeBranch
-AddArcadeFlow https://github.com/dotnet/icu "dotnet/$RuntimeBranch"
Write-Host "Adding non-VMR runtime flow"
AddPackageOnlyFlow https://dev.azure.com/dnceng/internal/_git/dotnet-wpf-int $RuntimeChannel https://github.com/dotnet/wpf $RuntimeBranch EveryBuild
@@ -223,14 +221,12 @@ if ($AddInternalFlow) {
}
Write-Host "Add VMR sdk repo forward flow"
-AddForwardFlow https://github.com/dotnet/roslyn-analyzers $SdkChannel $publicVMR roslyn-analyzers $SdkBranch EveryBuild
AddForwardFlow https://github.com/dotnet/templating $SdkChannel $publicVMR templating $SdkBranch EveryBuild
# SDK is batched so that it batches alongside NuGet for a cohesive set of changes.
AddBatchedForwardFlow https://github.com/dotnet/sdk $SdkChannel $publicVMR sdk $SdkBranch EveryBuild
if ($AddInternalFlow) {
Write-Host "Adding internal VMR sdk repo forward flow"
- AddForwardFlow https://dev.azure.com/dnceng/internal/_git/dotnet-roslyn-analyzers $InternalSdkChannel $internalVMR roslyn-analyzers $InternalSdkBranch EveryBuild
AddForwardFlow https://dev.azure.com/dnceng/internal/_git/dotnet-sdk $InternalSdkChannel $internalVMR sdk $InternalSdkBranch EveryBuild
AddForwardFlow https://dev.azure.com/dnceng/internal/_git/dotnet-templating $InternalSdkChannel $internalVMR templating $InternalSdkBranch EveryBuild
@@ -239,15 +235,12 @@ if ($AddInternalFlow) {
}
Write-Host "Adding tooling repo VMR forward flow"
-# NuGet is special in that it flows into the SDK and then batched source into the VMR
-# Change to traditional flow when https://github.com/dotnet/arcade-services/issues/4665 is resolved
-AddPackageOnlyFlow https://github.com/nuget/nuget.client $VSChannel https://github.com/dotnet/sdk $SdkBranch EveryBuild
-AddBatchedForwardFlow https://github.com/nuget/nuget.client $VSChannel $publicVMR nuget-client $SdkBranch EveryBuild
+AddForwardFlow https://github.com/nuget/nuget.client $VSChannel $publicVMR nuget-client $SdkBranch EveryBuild
AddForwardFlow https://github.com/dotnet/roslyn $VSChannel $publicVMR roslyn $SdkBranch EveryBuild
AddForwardFlow https://github.com/dotnet/fsharp $VSChannel $publicVMR fsharp $SdkBranch EveryBuild
AddForwardFlow https://github.com/dotnet/msbuild $VSChannel $publicVMR msbuild $SdkBranch EveryBuild
AddForwardFlow https://github.com/dotnet/razor $VSChannel $publicVMR razor $SdkBranch EveryBuild
-AddForwardFlow https://github.com/dotnet/vstest $VSChannel $publicVMR vstest $SdkBranch EveryBuild
+AddForwardFlow https://github.com/microsoft/vstest $VSChannel $publicVMR vstest $SdkBranch EveryBuild
if ($AddInternalFlow) {
Write-Host "Adding internal VMR sdk repo forward flow"
@@ -255,6 +248,9 @@ if ($AddInternalFlow) {
throw "NYI"
}
+Write-Host "Adding VMR->repo package flow"
+AddPackageOnlyFlow https://github.com/dotnet/dotnet $SdkBranch https://github.com/dotnet/icu "dotnet/$RuntimeBranch" None
+
Write-Host "Adding VMR->repo backflow."
# Only repos that branch for a release get backflow
AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/runtime runtime $RuntimeBranch EveryBuild
@@ -264,7 +260,6 @@ AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/emsdk emsdk $R
AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/windowsdesktop windowsdesktop $RuntimeBranch EveryBuild
AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/winforms winforms $RuntimeBranch EveryBuild
AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/wpf wpf $RuntimeBranch EveryBuild
-AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/roslyn-analyzers templating $SdkBranch EveryBuild
AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/sdk sdk $SdkBranch EveryBuild
AddBackwardsFlow $publicVMR $SdkChannel https://github.com/dotnet/templating templating $SdkBranch EveryBuild
diff --git a/src/arcade/scripts/duplicate-feed.ps1 b/src/arcade/scripts/duplicate-feed.ps1
index 7a27caa6b7c6..fa67529d6ecd 100644
--- a/src/arcade/scripts/duplicate-feed.ps1
+++ b/src/arcade/scripts/duplicate-feed.ps1
@@ -48,11 +48,11 @@ function Get-Package-List($vstsAuthHeader, $account, $visibility, $feed) {
try {
$packageListUri = "https://feeds.dev.azure.com/$account/${visibility}_apis/packaging/Feeds/$feed/packages?api-version=5.1-preview.1"
Write-Host "Looking up packages on feed at: $packageListUri"
- $result = Invoke-WebRequest -Headers $vstsAuthHeader $packageListUri
+ $result = Invoke-WebRequest -UseBasicParsing -Headers $vstsAuthHeader $packageListUri
$resultJson = $result | ConvertFrom-Json
Write-Host "Feed $SourceFeedUri has $($resultJson.count) packages"
foreach ($package in $resultJson.value) {
- $versionsResult = Invoke-WebRequest -Headers $vstsAuthHeader $package._links.versions.href
+ $versionsResult = Invoke-WebRequest -UseBasicParsing -Headers $vstsAuthHeader $package._links.versions.href
$versionsResultJson = $versionsResult | ConvertFrom-Json
foreach ($version in $versionsResultJson.value) {
if (-not $version.isDeleted) {
@@ -118,7 +118,7 @@ foreach ($packageToCopy in $listOfSourcePackages) {
$packageContentUrl = "https://pkgs.dev.azure.com/$($sourceFeedInfo.account)/$($sourceFeedInfo.visibility)_apis/packaging/feeds/$($sourceFeedInfo.feed)/nuget/packages/$($packageToCopy.name)/versions/$($packageToCopy.version)/content";
Write-Host "Downloading package $($packageToCopy.name) @ $($packageToCopy.version) from $packageContentUrl"
$localPackagePath = Join-Path -Path $downloadRoot -ChildPath "$($packageToCopy.name).$($packageToCopy.version).nupkg"
- Invoke-WebRequest -Headers $vstsAuthHeader $packageContentUrl -OutFile $localPackagePath
+ Invoke-WebRequest -UseBasicParsing -Headers $vstsAuthHeader $packageContentUrl -OutFile $localPackagePath
& $NugetPath push -Source $TargetFeedUri -ApiKey AzureDevOps $localPackagePath -SkipDuplicate
} catch {
Write-Error $_
diff --git a/src/arcade/scripts/launch-mirrors.ps1 b/src/arcade/scripts/launch-mirrors.ps1
index 71c4ea59d8e4..4bc09eb66fd5 100644
--- a/src/arcade/scripts/launch-mirrors.ps1
+++ b/src/arcade/scripts/launch-mirrors.ps1
@@ -59,7 +59,7 @@ function LaunchMirrorBuild {
$bodyStr = ConvertTo-Json $body
$uri = "${AzDOInstance}/_apis/build/builds?api-version=5.1"
Write-Host "Launching $mirrorType build for $repo @ $branch"
- $queueResponse = Invoke-WebRequest -Method Post -ContentType "application/json" -Headers $AzDOAuthHeader -Uri "${AzDOInstance}/_apis/build/builds?api-version=5.1" -Body $bodyStr | ConvertFrom-Json
+ $queueResponse = Invoke-WebRequest -UseBasicParsing -Method Post -ContentType "application/json" -Headers $AzDOAuthHeader -Uri "${AzDOInstance}/_apis/build/builds?api-version=5.1" -Body $bodyStr | ConvertFrom-Json
$buildId = $queueResponse.id
Write-Host "Launched $AzDOInstance/_build/results?buildId=$buildId"
}
diff --git a/src/arcade/scripts/list-dotnet-install-versions.ps1 b/src/arcade/scripts/list-dotnet-install-versions.ps1
index b12ce62e1002..ea15a791e92b 100644
--- a/src/arcade/scripts/list-dotnet-install-versions.ps1
+++ b/src/arcade/scripts/list-dotnet-install-versions.ps1
@@ -62,7 +62,7 @@ $productVersions += $queries | ForEach-Object -Parallel {
}
try {
- $response = Invoke-WebRequest $versionStringUrl
+ $response = Invoke-WebRequest $versionStringUrl -UseBasicParsing
# It's difficult to tell whether the aka.ms link 404s or not, since it redirects in case of
# a not found.
diff --git a/src/arcade/scripts/m2m-dotnet.ps1 b/src/arcade/scripts/m2m-dotnet.ps1
deleted file mode 100644
index b8f8bb6562e6..000000000000
--- a/src/arcade/scripts/m2m-dotnet.ps1
+++ /dev/null
@@ -1,404 +0,0 @@
-<#
-.SYNOPSIS
-Prepares data for migration, disables subscriptions, migrates and verifies
-DARC subcriptions and default channels.
-
-.DESCRIPTION
-This script runs in 3 modes:
- 1. GenerateDataFile - creates json file which describes DARC migration.
- 2. DisableSubscriptions - disables targeting subscriptions for your repository and old branch.
- 3. Migration - using json file generated during Initializatin, this script removes default channels
- and targeting subscriptions for your repository and branch. Then it recreates them under
- a new branch.
- 4. Verification - Compares default channels and targeting subscriptions from json file against current
- state in DARC.
-
-.PARAMETER Repository
-Mandatory short name of GitHub repository (e.g. dotnet/runtime or dotnet/wpf). This short name is transformed to
-public and internal repository (e.g. for dotnet/runtime https://github.com/dotnet/runtime and
-https://dev.azure.com/dnceng/internal/_git/dotnet-runtime).
-
-.PARAMETER NewBranch
-Optional new name of branch, defaults to 'main'.
-
-.PARAMETER OldBranch
-Optional old name of branch, defaults to 'master'.
-
-.PARAMETER GenerateDataFile
-Switch to run in generate data file mode. Repository parameter is required and NewBranch, OldBranch are optional.
-
-.PARAMETER DisableSubscriptions
-Switch to run in disable subscriptions on old branch mode. DataFile parameter is required.
-
-.PARAMETER Migrate
-Switch to run in migration mode. DataFile parameter is required.
-
-.PARAMETER Verify
-Switch to run in verification mode. DataFile parameter is required.
-
-.PARAMETER DataFile
-json file path used for DARC validation.
-
-.PARAMETER DryRun
-When specified then no DARC updates are executed, but only logged.
-
-.EXAMPLE
-1. For initilization execute:
-./m2m-dotnet.ps1 -GenerateDataFile -Repository dotnet/m2m-renaming-test-1
-or you can additionaly specify branch names:
-./m2m-dotnet.ps1 -GenerateDataFile -Repository dotnet/m2m-renaming-test-1 -OldBranch master -NewBranch main
-
-This generates data file m2m-dotnet_[timestamp].json and disables all targeting subscriptions.
-
-2. To disable targeting subscriptions for your repository and old branch execute:
-.\m2m-dotnet.ps1 -DisableSubscriptions -DataFile m2m-dotnet_[timestamp].json
-
-3. For migration execute:
-.\m2m-dotnet.ps1 -Migrate -DataFile m2m-dotnet_[timestamp].json
-
-4. For verification execute:
-.\m2m-dotnet.ps1 -Verify -DataFile m2m-dotnet_[timestamp].json
-
-#>
-
-[CmdletBinding()]
-param (
-
- [Parameter(ParameterSetName = 'GenerateDataFile', Mandatory = $true)]
- [switch]$GenerateDataFile,
-
- [Parameter(ParameterSetName = 'DisableSubscriptions', Mandatory = $true)]
- [switch]$DisableSubscriptions,
-
- [Parameter(ParameterSetName = 'Migrate', Mandatory = $true)]
- [switch]$Migrate,
-
- [Parameter(ParameterSetName = 'Verify', Mandatory = $true)]
- [switch]$Verify,
-
- [Parameter(ParameterSetName = 'GenerateDataFile', Mandatory = $true)]
- [string]$Repository,
- [Parameter(ParameterSetName = 'GenerateDataFile')]
- [string]$NewBranch = "main",
- [Parameter(ParameterSetName = 'GenerateDataFile')]
- [string]$OldBranch = "master",
-
- [Parameter(ParameterSetName = 'Verify', Mandatory = $true)]
- [Parameter(ParameterSetName = 'Migrate', Mandatory = $true)]
- [Parameter(ParameterSetName = 'DisableSubscriptions', Mandatory = $true)]
- [string]$DataFile,
-
- [switch]$DryRun = $false
-)
-
-
-Class DarcExecutor {
- [bool]$DryRun = $false
-
- [string[]] ParseIgnoreChecks([string] $line) {
- $ignoreChecks = @()
- # Matches fragment like : ignoreChecks = [ "WIP", "license/cla" ]
- if ($line -match "ignoreChecks\s*=\s*\[\s*([^\]]+)\s*\]") {
- $ignoreChecksValuesMatches = [regex]::matches($matches[1], "`"([^`"]+)`"")
- ForEach ($check in $ignoreChecksValuesMatches) {
- $ignoreChecks += $check.Groups[1].Value
- }
- }
-
- return $ignoreChecks
- }
-
- [object[]] ParseMergePolicies([string] $line) {
- $line = $line -replace "ignoreChecks\s*=\s*\[\s*[^\]]*\s*\]", ""
- $policies = $line -split "\s+" | Where-Object { $_ }
- return $policies
- }
-
- [object[]] ParseSubscriptions([string] $output) {
- $darcOutputLines = $output.Split([Environment]::NewLine)
- $list = @()
- $processingMergePolicies = $false
- $batchable = $fromRepo = $fromChannel = $updateFrequency = $enabled = $mergePolicies = $null
- For ($i = 0; $i -le $darcOutputLines.Length; $i++) {
- $line = $darcOutputLines[$i]
- # Matches header like: https://github.com/dotnet/arcade (.NET Eng - Latest) ==> 'https://github.com/dotnet/m2m-renaming-test-1' ('main')
- if ($line -match "([^\s]+)\s+\(([^\)]+)\)\s+==>\s+'([^']+)'\s+\('([^\)]+)'\)") {
- if ($i -ne 0) {
- $list += @{fromRepo = $fromRepo; fromChannel = $fromChannel; updateFrequency = $updateFrequency; enabled = $enabled; batchable = $batchable; ignoreChecks = @($this.ParseIgnoreChecks($mergePolicies)); mergePolicies = @($this.ParseMergePolicies($mergePolicies)) };
- }
-
- $updateFrequency = $enabled = $batchable = $mergePolicies = ""
-
- $fromRepo = $matches[1]
- $fromChannel = $matches[2]
- continue
- }
- # Matches field like: - Update Frequency: EveryWeek
- if ($line -match "^\s+\-\s+([^:]+):\s*(.*)") {
- $processingMergePolicies = $false
- if ($matches[1] -eq "Update Frequency") {
- $updateFrequency = $matches[2]
- continue
- }
- if ($matches[1] -eq "Enabled") {
- $enabled = $matches[2]
- continue
- }
- if ($matches[1] -eq "Batchable") {
- $batchable = $matches[2]
- continue
- }
- if ($matches[1] -eq "Merge Policies") {
- $mergePolicies = $matches[2]
- $processingMergePolicies = $true
- continue
- }
- }
- if ($processingMergePolicies) {
- $mergePolicies += $line
- continue
- }
- }
-
- if ($null -ne $fromRepo) {
- $list += @{fromRepo = $fromRepo; fromChannel = $fromChannel; updateFrequency = $updateFrequency; enabled = $enabled; batchable = $batchable; ignoreChecks = @($this.ParseIgnoreChecks($mergePolicies)); mergePolicies = @($this.ParseMergePolicies($mergePolicies)) };
- }
-
- return $list
- }
-
- [object[]] GetSubscriptions([string]$repo, [string]$branch) {
- $arguments = @("get-subscriptions", "--exact", "--target-repo", $repo, "--target-branch", $branch)
- $output = $this.Execute($arguments, $false)
- $subscriptions = @($this.ParseSubscriptions($output))
- return $subscriptions
- }
-
-
- [void]AddSubscription($repo, $branch, $item) {
- $arguments = @("add-subscription", "--channel", $item.fromChannel, "--source-repo", $item.fromRepo, "--target-repo", $repo, "--update-frequency", $item.updateFrequency, "--target-branch", $branch, "--no-trigger", "-q")
- $policiesArguments = @("set-repository-policies", "--repo", $repo, "--branch", $branch, "-q")
- $targetArgumentsRef = [ref]$arguments
- if ($item.batchable -eq "True") {
- $arguments += "--batchable"
- $targetArgumentsRef = [ref]$policiesArguments
- }
- if ($item.mergePolicies -contains "Standard") {
- $targetArgumentsRef.value += "--standard-automerge"
- }
- if ($item.mergePolicies -like "NoRequestedChanges") {
- $targetArgumentsRef.value += "--no-requested-changes"
- }
- if ($item.mergePolicies -like "NoExtraCommits") {
- $targetArgumentsRef.value += "--no-extra-commits"
- }
- if ($item.mergePolicies -like "AllChecksSuccessful") {
- $targetArgumentsRef.value += "--all-checks-passed"
- }
- if ($item.ignoreChecks.length -gt 0) {
- $targetArgumentsRef.value += "--ignore-checks"
- $targetArgumentsRef.value += $item.ignoreChecks -join ","
- }
-
- if ($item.batchable -eq "True") {
- $this.Execute($policiesArguments, $true)
- }
-
- $output = $this.Execute($arguments, $true)
-
- if ($output -match "Successfully created new subscription with id '([^']+)'.") {
- $id = $matches[1]
- if ($item.enabled -eq [bool]::FalseString) {
- $this.DisableSubscription($id)
- }
- }
- else {
- Write-Error(" WARNING: {0}" -f $output)
- }
- }
-
- [void]DeleteSubscriptions($repo, $branch) {
- $arguments = @("get-subscriptions", "--exact", "--target-repo", $repo, "--target-branch", $branch)
- $output = $this.Execute($arguments, $false)
- if (-not ($output -match "^No subscriptions found matching the specified criteria.")) {
- Write-Host ("Deleting subscriptions for {0} {1}" -f $repo, $branch)
- $arguments = @("delete-subscriptions", "--exact", "--target-repo", $repo, "--target-branch", $branch, "-q")
- $this.Execute($arguments, $true)
- }
- }
-
- [void]CreateDefaultChannel($repo, $branch, $channel) {
- Write-Host ("Creating default channel {2} for branch {0} {1}" -f $repo, $branch, $channel)
- $arguments = @("add-default-channel", "--repo", $repo, "--branch", $branch, "--channel", $channel, "-q")
- $this.Execute($arguments, $true)
- }
-
- [void]DisableSubscription ([string] $id) {
- Write-Host ("Disabling subscription {0}" -f $id)
- $arguments = @("subscription-status", "--id", $id, "-d", "-q")
- $this.Execute($arguments, $true)
- }
-
- [string[]]GetTargetSubscriptionIds ([string] $repo, [string] $branch) {
- $arguments = @("get-subscriptions", "--exact", "--target-repo", $repo, "--target-branch", $branch)
- $ids = $this.Execute($arguments, $false) | Select-String -AllMatches -Pattern "\s+-\s+Id:\s+([^\s]+)" | ForEach-Object { $_.Matches } | Foreach-Object { $_.Groups[1].Value }
- return $ids
- }
-
- [void]DisableTargetSubscriptions ([string] $repo, [string] $branch) {
- Write-Host "Disabling targeting subscriptions for $repo ($branch)"
-
- $ids = $this.GetTargetSubscriptionIds($repo, $branch)
- ForEach ($id in $ids) {
- $this.DisableSubscription($id)
- }
- }
-
- [Hashtable[]]GetDefaultChannels ([string] $repo, [string] $branch) {
- $arguments = @("get-default-channels", "--source-repo", $repo, "--branch", $branch)
- $output = $this.Execute($arguments, $true)
- $records = @($output | Select-String -AllMatches -Pattern "\((\d+)\)\s+$repo\s+@\s+$branch\s+->\s+(.*)\b" | ForEach-Object { $_.Matches } | ForEach-Object { @{id = $_.Groups[1].Value; channel = $_.Groups[2].Value } })
- return $records
- }
-
- [void]DeleteDefaultChannel([string] $id) {
- Write-Host ("Deleting default channel {0}" -f $id)
- $arguments = @("delete-default-channel", "--id", $id)
- $this.Execute($arguments, $true)
- }
-
- [void]DeleteDefaultChannels([string] $repo, [string] $branch) {
- $channels = @($this.GetDefaultChannels($repo, $branch))
- ForEach ($item in $channels) {
- $this.DeleteDefaultChannel($item.id)
- }
- }
-
- [Hashtable]GetRepoConfig([string] $repo, [string] $newBranch, [string] $oldBranch) {
- $defaultChannels = @($this.GetDefaultChannels($repo, $oldBranch) | ForEach-Object { $_.channel })
- $subscriptions = @($this.GetSubscriptions($repo, $oldBranch))
- $config = @{repo = $repo; newBranch = $newBranch; oldBranch = $oldBranch; defaultChannels = $defaultChannels; subscriptions = $subscriptions; }
- return $config
- }
-
- [void]MigrateRepo([PSCustomObject]$config) {
- Write-Host (">>>Migrating repository {0} {1} ==> {2}..." -f $config.repo, $config.oldBranch, $config.newBranch)
-
- $this.DeleteDefaultChannels($config.repo, $config.oldBranch)
- ForEach ($channel in $config.defaultChannels) {
- $this.CreateDefaultChannel($config.repo, $config.newBranch, $channel)
- }
-
- $this.DeleteSubscriptions($config.repo, $config.oldBranch)
- $this.DeleteSubscriptions($config.repo, $config.newBranch)
-
- Write-Host ("Adding subscriptions")
- ForEach ($item in $config.subscriptions) {
- $this.AddSubscription($config.repo, $config.newBranch, $item)
- }
- }
-
- [void]VerifyRepo([PSCustomObject]$config) {
- Write-Host (">>>Verifying repository {0} {1} ==> {2}..." -f $config.repo, $config.oldBranch, $config.newBranch)
- if ($this.GetDefaultChannels($config.repo, $config.oldBranch).length -ne 0) {
- throw("Default channels for old branch haven't been removed.")
- }
- if ($this.GetTargetSubscriptionIds($config.repo, $config.oldBranch).length -ne 0) {
- throw("Subscriptions for old branch haven't been removed.")
- }
-
- $actualConfig = $this.GetRepoConfig($config.repo, $config.oldBranch, $config.newBranch)
- if ($actualConfig.defaultChannels.length -ne $config.defaultChannels.length) {
- throw("Subscriptions for old branch haven't been removed.")
- }
-
- $expectedDefaultChannels = ConvertTo-Json($actualConfig.defaultChannels | Sort-Object)
- $actualDefaultChannels = ConvertTo-Json($config.defaultChannels | Sort-Object)
- if ($expectedDefaultChannels -ne $actualDefaultChannels) {
- throw("Expected default channels {0} don't match actual {1}." -f $actualDefaultChannels, $actualDefaultChannels)
- }
-
- $actualSubscriptions = ConvertTo-Json($actualConfig.subscriptions | Sort-Object { $_.fromRepo })
- $expectedSubscriptions = ConvertTo-Json($config.subscriptions | Sort-Object { $_.fromRepo })
-
- if ($expectedSubscriptions -ne $actualSubscriptions) {
- throw("Expected subscriptions {0} don't match actual {1}." -f $expectedSubscriptions, $actualSubscriptions)
- }
-
- Write-Host ("Validation of {0} passed" -f $config.repo)
- }
-
- [string]Execute ([string[]] $arguments, [bool]$exitCodeCheck) {
- if ($this.DryRun -and ($arguments[0] -ne "get-default-channels") -and ($arguments[0] -ne "get-subscriptions")) {
- Write-Host (">>> darc {0}" -f ($arguments -join " "))
- return "Successfully created new subscription with id 'TEST_ID'."
- }
- else {
- $output = (&"darc" $arguments | Out-String)
- if ($exitCodeCheck -and $LASTEXITCODE -ne 0) {
- throw (" Error executing command ""darc {0}"" with status code {1}: {2}" -f ($arguments -join " "), $LASTEXITCODE, $output)
- }
- return $output
- }
- }
-}
-function InitializeDarc {
- param (
- [DarcExecutor] $darc
- )
- $configFile = "m2m-dotnet_{0:yyyyMMdd_HHmmss}.json" -f (get-date)
- $internalRepo = "https://dev.azure.com/dnceng/internal/_git/{0}" -f ($Repository -replace "/", "-")
- $publicRepo = "https://github.com/{0}" -f $Repository
-
- Write-Host ("Creating configuration for repository {0} {1} ==> {2}..." -f $publicRepo, $OldBranch, $NewBranch)
- $configPublic = $darc.GetRepoConfig($publicRepo, $NewBranch, $OldBranch)
-
- Write-Host ("Creating configuration for repository {0} {1} ==> {2}..." -f $internalRepo, $OldBranch, $NewBranch)
- $configInternal = $darc.GetRepoConfig($internalRepo, $NewBranch, $OldBranch)
-
- $configs = @($configPublic, $configInternal)
- ConvertTo-Json $configs -Depth 4 | Out-File -FilePath $configFile
- Write-Host ("Configuration has been saved as {0}" -f $configFile)
-}
-
-function DisableDarcSubscriptions {
- param (
- [DarcExecutor] $darc
- )
-
- $configs = Get-Content -Raw -Path $DataFile | ConvertFrom-Json
- ForEach ($config in $configs) {
- $darc.DisableTargetSubscriptions($config.repo, $config.oldBranch)
- }
-}
-function MigrateDarc {
- param (
- [DarcExecutor]$darc
- )
-
- $configs = Get-Content -Raw -Path $DataFile | ConvertFrom-Json
- ForEach ($config in $configs) {
- $darc.MigrateRepo($config)
- }
-}
-function VerifyDarc {
- param (
- [DarcExecutor]$darc
- )
-
- $configs = Get-Content -Raw -Path $DataFile | ConvertFrom-Json
- ForEach ($config in $configs) {
- $darc.VerifyRepo($config)
- }
-}
-
-$ErrorActionPreference = 'Stop'
-$darc = [DarcExecutor]::new()
-$darc.DryRun = $DryRun
-
-switch ($PSCmdlet.ParameterSetName) {
- "GenerateDataFile" { InitializeDarc -darc $darc }
- "DisableSubscriptions" { DisableDarcSubscriptions -darc $darc }
- "Migrate" { MigrateDarc -darc $darc }
- "Verify" { VerifyDarc -darc $darc }
-}
diff --git a/src/arcade/scripts/pause-all-pipelines.ps1 b/src/arcade/scripts/pause-all-pipelines.ps1
index e109d06e079c..47c0de52c6ad 100644
--- a/src/arcade/scripts/pause-all-pipelines.ps1
+++ b/src/arcade/scripts/pause-all-pipelines.ps1
@@ -26,7 +26,7 @@ param (
$base64authinfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$AzDOPat"))
$AzDOAuthHeader = @{"Authorization"="Basic $base64authinfo"}
-$allPipelines = Invoke-WebRequest -Uri "https://dev.azure.com/$Organization/$Project/_apis/build/definitions?api-version=6.0" -Headers $AzDOAuthHeader | ConvertFrom-Json
+$allPipelines = Invoke-WebRequest -UseBasicParsing -Uri "https://dev.azure.com/$Organization/$Project/_apis/build/definitions?api-version=6.0" -Headers $AzDOAuthHeader | ConvertFrom-Json
$queueStatusString = $null
$uxString = $null
@@ -48,13 +48,13 @@ foreach ($pipeline in $allPipelines.value) {
Write-Host -NoNewLine " $uxString '$($pipeline.name)' (id: $pipelineId)..."
$pipelineUri = "https://dev.azure.com/$Organization/$Project/_apis/build/definitions/$($pipelineId)?api-version=6.0"
- $pipelineInfo = Invoke-WebRequest -Uri $pipelineUri -Headers $AzDOAuthHeader | ConvertFrom-Json
+ $pipelineInfo = Invoke-WebRequest -UseBasicParsing -Uri $pipelineUri -Headers $AzDOAuthHeader | ConvertFrom-Json
# Update the pipeline
$pipelineInfo.queueStatus = $queueStatusString
#update the definition
- $result = Invoke-WebRequest -Uri $pipelineUri -Headers $AzDOAuthHeader -Method Put -Body (ConvertTo-Json $pipelineInfo -Depth 100) -ContentType "application/json"
+ $result = Invoke-WebRequest -UseBasicParsing -Uri $pipelineUri -Headers $AzDOAuthHeader -Method Put -Body (ConvertTo-Json $pipelineInfo -Depth 100) -ContentType "application/json"
if ($result.StatusCode -eq 200) {
Write-Host "done"
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs
index cd1a18098d22..9fe6fb49651e 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/src/DownloadFile.cs
@@ -215,11 +215,11 @@ private async Tasks.Task DownloadWithRetriesAsync(HttpClient httpClient, s
if (attempt > Retries)
{
Log.LogMessage($"Failed to download '{uri}' to '{DestinationPath}': {e.Message}");
+ Log.LogErrorFromException(e, true, true, null);
return false;
}
Log.LogMessage($"Retrying download of '{uri}' to '{DestinationPath}' due to failure: '{e.Message}' ({attempt}/{Retries})");
- Log.LogErrorFromException(e, true, true, null);
await Tasks.Task.Delay(RetryDelayMilliseconds).ConfigureAwait(false);
continue;
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props
index 3dd23f15f1c5..ed05aaf6bcd8 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/DefaultVersions.props
@@ -66,13 +66,13 @@
19.239.34923-buildid28260713
1.0.422
5.1.0-beta.21356.1
- 17.12.0
+ 18.0.1
16.9.1050
$(ArcadeSdkVersion)
$(ArcadeSdkVersion)
$(ArcadeSdkVersion)
$(ArcadeSdkVersion)
- 17.12.0
+ 18.0.1
2.9.3
@@ -80,17 +80,18 @@
$(XUnitVersion)
3.1.3
- 3.0.0
- 1.7.3
+ 3.1.0
+ 1.8.5
- 3.9.3
+ 4.0.2
$(MSTestVersion)
$(MSTestVersion)
$(ArcadeSdkVersion)
$(ArcadeSdkVersion)
3.12.0
3.15.1
- 2.6.7
+
+ 3.1.7
1.0.0
$(ArcadeSdkVersion)
$(ArcadeSdkVersion)
@@ -98,7 +99,7 @@
2.1.3
1.1.286
3.14.1-9323.2545153
- 5.0.2-dotnet.2737382
+ 5.0.2-dotnet.2811440
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Imports.targets b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Imports.targets
index 2bbcc1458651..1f53ba09b3f7 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Imports.targets
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Imports.targets
@@ -9,8 +9,11 @@
-
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.props b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.props
index 409f25e07e28..e443c179b2aa 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.props
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.props
@@ -20,6 +20,9 @@
Icon.png
$(MSBuildThisFileDirectory)Assets\DotNetPackageIcon.png
+
+ true
+
true
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.targets b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.targets
index 1dff8890440d..ff765c311416 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.targets
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/ProjectDefaults.targets
@@ -1,6 +1,11 @@
+
+
+ false
+
+
$(__DeployProjectOutput)
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj
index 603e337c4a4a..d0c77effc663 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/SdkTasks/PublishArtifactsInManifest.proj
@@ -77,6 +77,8 @@
$(NetToolCurrent)
Publish
+
+ false
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
index 9997e86b16a7..cf2a163077a6 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.proj
@@ -6,7 +6,7 @@
- https://github.com/dotnet/arcade/blob/master/Documentation/CorePackages/Signing.md
Optional variables:
- EnableDefaultArtifacts Includes *.nupkg, *.vsix and *.wixpack.zip under "/artifacts/packages/**" for sigining.
+ EnableDefaultArtifacts Includes *.nupkg, *.vsix and *.wixpack.zip under "/artifacts/packages/**" for signing.
Defaults to true.
EnableDefaultRidSpecificArtifacts Do not sign *.nupkg packages under "/artifacts/packages/**" that do not contain the current TargetRid.
DefaultArtifactVisibility The default visibility for Artifact items. Defaults to External.
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props
index ee62c8cf6fcd..d9f48837efb7 100644
--- a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Sign.props
@@ -30,6 +30,8 @@
+
+
+
+
+
+
- netstandard2.0%3bnetstandard2.1%3bnetcoreapp2.1%3bnetcoreapp3.1%3bnet5.0%3bnet6.0%3bnet7.0%3bnet8.0%3bnet9.0%3bnet10.0
+ netstandard2.0%3bnetstandard2.1%3bnetcoreapp2.1%3bnetcoreapp3.1%3bnet5.0%3bnet6.0%3bnet7.0%3bnet8.0%3bnet9.0%3bnet10.0%3b$(NetCurrent)
<_EnableTargetFrameworkFiltering>false
<_EnableTargetFrameworkFiltering Condition="'$(NoTargetFrameworkFiltering)' != 'true' and '$(DotNetTargetFrameworkFilter)' != ''">true
diff --git a/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/TargetingPacks.targets b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/TargetingPacks.targets
new file mode 100644
index 000000000000..7d4ce9b10d2a
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/TargetingPacks.targets
@@ -0,0 +1,109 @@
+
+
+
+
+
+ true
+ true
+
+ $(NetCurrent)
+ $(NetPrevious)
+ $(NetMinimum)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(KnownFrameworkReferenceMicrosoftNETCoreAppCurrentDefaultRuntimeFrameworkVersion)
+ $(KnownFrameworkReferenceMicrosoftNETCoreAppCurrentLatestRuntimeFrameworkVersion)
+ $(KnownFrameworkReferenceMicrosoftNETCoreAppCurrentTargetingPackVersion)
+
+
+
+ $(KnownRuntimePackMicrosoftNETCoreAppCurrentMonoLatestRuntimeFrameworkVersion)
+
+
+
+ $(KnownRuntimePackMicrosoftNETCoreAppCurrentNativeAOTLatestRuntimeFrameworkVersion)
+
+
+
+ $(KnownILCompilerPackCurrentVersion)
+
+
+
+ $(KnownCrossgen2PackCurrentVersion)
+
+
+
+ $(KnownAppHostPackCurrentVersion)
+
+
+
+ $(KnownILLinkPackCurrentVersion)
+
+
+
+
+
+
+ %(RuntimePackRuntimeIdentifiers);$(NETCoreSdkRuntimeIdentifier)
+
+
+ %(Crossgen2RuntimeIdentifiers);$(NETCoreSdkRuntimeIdentifier)
+
+
+
+
\ No newline at end of file
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/GeneralTests.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/GeneralTests.cs
index afa9d0642c17..c07a42262cda 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/GeneralTests.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/GeneralTests.cs
@@ -264,5 +264,28 @@ public void TargetChannelConfig_TargetFeeds_UnequalTest()
actualResult.Should().BeFalse();
}
+
+ [Theory]
+ [InlineData("https://dotnetcli.blob.core.windows.net/test", "https://builds.dotnet.microsoft.com/test")]
+ [InlineData("https://dotnetbuilds.blob.core.windows.net/internal", "https://ci.dot.net/internal")]
+ [InlineData("https://dotnetbuilds.blob.core.windows.net/public?sv=token", "https://ci.dot.net/public")]
+ [InlineData("https://unknown.blob.core.windows.net/test", "https://unknown.blob.core.windows.net/test")]
+ [InlineData("https://pkgs.dev.azure.com/dnceng/public/_packaging/feed/nuget/v3/index.json", "https://pkgs.dev.azure.com/dnceng/public/_packaging/feed/nuget/v3/index.json")]
+ public void TargetFeedConfig_SafeTargetURL_AppliesCdnSubstitution(string targetUrl, string expectedSafeUrl)
+ {
+ // Arrange
+ var feedConfig = new TargetFeedConfig(
+ contentType: TargetFeedContentType.Installer,
+ targetURL: targetUrl,
+ type: FeedType.AzureStorageContainer,
+ token: "dummyToken"
+ );
+
+ // Act
+ var actualSafeUrl = feedConfig.SafeTargetURL;
+
+ // Assert
+ actualSafeUrl.Should().Be(expectedSafeUrl);
+ }
}
}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/ProductionChannelValidatorTests.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/ProductionChannelValidatorTests.cs
new file mode 100644
index 000000000000..ece57d4bd3d7
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/ProductionChannelValidatorTests.cs
@@ -0,0 +1,704 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.DotNet.Build.Tasks.Feed.Model;
+using Microsoft.DotNet.Build.Manifest;
+using Microsoft.Extensions.Logging;
+using Moq;
+using Xunit;
+
+namespace Microsoft.DotNet.Build.Tasks.Feed.Tests
+{
+ public class ProductionChannelValidatorTests
+ {
+ private readonly Mock _mockAzureDevOpsService;
+ private readonly Mock _mockBranchClassificationService;
+ private readonly Mock> _mockLogger;
+
+ public ProductionChannelValidatorTests()
+ {
+ _mockAzureDevOpsService = new Mock();
+ _mockBranchClassificationService = new Mock();
+ _mockLogger = new Mock>();
+ }
+
+ private ProductionChannelValidator CreateValidator(ValidationMode validationMode)
+ {
+ return new ProductionChannelValidator(
+ _mockAzureDevOpsService.Object,
+ _mockBranchClassificationService.Object,
+ _mockLogger.Object,
+ validationMode);
+ }
+
+ private static ProductConstructionService.Client.Models.Build CreateTestBuild(
+ int id = 12345,
+ DateTimeOffset? dateProduced = null,
+ int staleness = 0,
+ bool released = false,
+ bool stable = false,
+ string commit = "abc123",
+ string azureDevOpsAccount = "dnceng",
+ string azureDevOpsProject = "internal",
+ int? azureDevOpsBuildId = 123456,
+ string azureDevOpsRepository = "https://dev.azure.com/dnceng/internal/_git/dotnet-runtime",
+ string azureDevOpsBranch = "refs/heads/main",
+ List channels = null,
+ List assets = null,
+ List dependencies = null,
+ List incoherencies = null)
+ {
+ var build = new ProductConstructionService.Client.Models.Build(
+ id: id,
+ dateProduced: dateProduced ?? DateTimeOffset.UtcNow,
+ staleness: staleness,
+ released: released,
+ stable: stable,
+ commit: commit,
+ channels: channels ?? new List(),
+ assets: assets ?? new List(),
+ dependencies: dependencies ?? new List(),
+ incoherencies: incoherencies ?? new List()
+ );
+
+ // Set the Azure DevOps properties using reflection since they might be read-only
+ // This is a test scenario, so it's acceptable to use reflection
+ build.AzureDevOpsAccount = azureDevOpsAccount;
+ build.AzureDevOpsProject = azureDevOpsProject;
+ build.AzureDevOpsBuildId = azureDevOpsBuildId;
+ build.AzureDevOpsRepository = azureDevOpsRepository;
+ build.AzureDevOpsBranch = azureDevOpsBranch;
+
+ return build;
+ }
+
+ private static TargetChannelConfig CreateProductionChannelConfig(int id = 1)
+ {
+ return new TargetChannelConfig(
+ id: id,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: null,
+ akaMSCreateLinkPatterns: null,
+ akaMSDoNotCreateLinkPatterns: null,
+ targetFeeds: new TargetFeedSpecification[0],
+ symbolTargetType: SymbolPublishVisibility.None,
+ flatten: true,
+ isProduction: true);
+ }
+
+ private static TargetChannelConfig CreateNonProductionChannelConfig(int id = 2)
+ {
+ return new TargetChannelConfig(
+ id: id,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: null,
+ akaMSCreateLinkPatterns: null,
+ akaMSDoNotCreateLinkPatterns: null,
+ targetFeeds: new TargetFeedSpecification[0],
+ symbolTargetType: SymbolPublishVisibility.None,
+ flatten: true,
+ isProduction: false);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce)]
+ [InlineData(ValidationMode.Audit)]
+ public async Task ValidateAsync_NullBuild_ThrowsArgumentNullException(ValidationMode validationMode)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var targetChannel = CreateProductionChannelConfig();
+
+ // Act & Assert
+ await Assert.ThrowsAsync(() =>
+ validator.ValidateAsync(null, targetChannel));
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce)]
+ [InlineData(ValidationMode.Audit)]
+ public async Task ValidateAsync_NonProductionChannel_ReturnsSuccess(ValidationMode validationMode)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateNonProductionChannelConfig();
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(TargetChannelValidationResult.Success);
+ _mockAzureDevOpsService.Verify(x => x.GetBuildInfoAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ _mockBranchClassificationService.Verify(x => x.GetBranchClassificationsAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce)]
+ [InlineData(ValidationMode.Audit)]
+ public async Task ValidateAsync_ProductionChannel_ValidBuild_ReturnsSuccess(ValidationMode validationMode)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official", "other-tag" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List
+ {
+ new BranchClassification { BranchName = "main", Classification = "production" },
+ new BranchClassification { BranchName = "release/*", Classification = "production" }
+ }
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(TargetChannelValidationResult.Success);
+ _mockAzureDevOpsService.Verify(x => x.GetBuildInfoAsync("dnceng", "internal", 123456), Times.Once);
+ _mockBranchClassificationService.Verify(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"), Times.Once);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_ProductionChannel_MissingRequiredTag_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "other-tag", "another-tag" }
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ _mockAzureDevOpsService.Verify(x => x.GetBuildInfoAsync("dnceng", "internal", 123456), Times.Once);
+ _mockBranchClassificationService.Verify(x => x.GetBranchClassificationsAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_ProductionChannel_NonProductionBranch_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild(azureDevOpsBranch: "refs/heads/feature/test");
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List
+ {
+ new BranchClassification { BranchName = "main", Classification = "production" },
+ new BranchClassification { BranchName = "release/*", Classification = "production" }
+ }
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_NonAzureDevOpsRepository_WithValidTags_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild(
+ azureDevOpsRepository: "https://github.com/dotnet/runtime",
+ azureDevOpsAccount: "dnceng",
+ azureDevOpsProject: "internal",
+ azureDevOpsBuildId: 123456
+ );
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "https://github.com/dotnet/runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ _mockAzureDevOpsService.Verify(x => x.GetBuildInfoAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once);
+ _mockBranchClassificationService.Verify(x => x.GetBranchClassificationsAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_ProductionChannel_MissingAzureDevOpsInfo_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange - Azure DevOps repository but missing Azure DevOps build metadata
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild(
+ azureDevOpsRepository: "https://dev.azure.com/dnceng/internal/_git/dotnet-runtime", // Azure DevOps repo
+ azureDevOpsAccount: null, // But missing metadata
+ azureDevOpsProject: null,
+ azureDevOpsBuildId: null
+ );
+ var targetChannel = CreateProductionChannelConfig();
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ _mockAzureDevOpsService.Verify(x => x.GetBuildInfoAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, "main", "main", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Enforce, "master", "master", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Enforce, "release/6.0", "release/*", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Enforce, "release/6.0.1", "release/*", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Enforce, "main", "~default", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Enforce, "master", "~default", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Enforce, "feature/test", "main", TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Enforce, "develop", "release/*", TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Enforce, "feature/test", "~default", TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, "main", "main", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Audit, "master", "master", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Audit, "release/6.0", "release/*", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Audit, "release/6.0.1", "release/*", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Audit, "main", "~default", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Audit, "master", "~default", TargetChannelValidationResult.Success)]
+ [InlineData(ValidationMode.Audit, "feature/test", "main", TargetChannelValidationResult.AuditOnlyFailure)]
+ [InlineData(ValidationMode.Audit, "develop", "release/*", TargetChannelValidationResult.AuditOnlyFailure)]
+ [InlineData(ValidationMode.Audit, "feature/test", "~default", TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_BranchPatternMatching_WorksCorrectly(ValidationMode validationMode, string branchName, string pattern, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild(azureDevOpsBranch: $"refs/heads/{branchName}");
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List
+ {
+ new BranchClassification { BranchName = pattern, Classification = "production" }
+ }
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_AzureDevOpsServiceThrows_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ThrowsAsync(new InvalidOperationException("API Error"));
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_BranchClassificationServiceThrows_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ThrowsAsync(new InvalidOperationException("API Error"));
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, LogLevel.Debug, LogLevel.Error)]
+ [InlineData(ValidationMode.Audit, LogLevel.Debug, LogLevel.Warning)]
+ public async Task ValidateAsync_BranchClassificationServiceThrows_LogsCorrectly(ValidationMode validationMode, LogLevel expectedDebugLevel, LogLevel expectedValidationLevel)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ThrowsAsync(new InvalidOperationException("API Error"));
+
+ // Act
+ await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ // Verify that debug logging is called for branch classification failures
+ _mockLogger.Verify(
+ x => x.Log(
+ expectedDebugLevel,
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Failed to fetch branch classifications for build")),
+ It.IsAny(),
+ It.IsAny>()),
+ Times.Once);
+
+ // Verify that validation mode appropriate logging is called
+ _mockLogger.Verify(
+ x => x.Log(
+ expectedValidationLevel,
+ It.IsAny(),
+ It.Is((v, t) => v.ToString().Contains("Error validating branch classification for build")),
+ It.IsAny(),
+ It.IsAny>()),
+ Times.Once);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce)]
+ [InlineData(ValidationMode.Audit)]
+ public async Task ValidateAsync_RepositoryUrlExtraction_WorksCorrectly(ValidationMode validationMode)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var repositoryUrl = "https://dev.azure.com/dnceng/internal/_git/dotnet-runtime";
+ var expectedRepoId = "dotnet-runtime";
+
+ var build = CreateTestBuild(azureDevOpsRepository: repositoryUrl);
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = expectedRepoId },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List
+ {
+ new BranchClassification { BranchName = "main", Classification = "production" }
+ }
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(TargetChannelValidationResult.Success);
+ }
+
+ [Theory]
+ [InlineData("refs/heads/main", "main")]
+ [InlineData("refs/heads/release/6.0", "release/6.0")]
+ [InlineData("main", "main")]
+ [InlineData("release/6.0", "release/6.0")]
+ public async Task ValidateAsync_BranchNameNormalization_WorksCorrectly(string inputBranch, string expectedNormalizedBranch)
+ {
+ // Arrange
+ var enforceValidator = CreateValidator(ValidationMode.Enforce);
+ var auditValidator = CreateValidator(ValidationMode.Audit);
+ var build = CreateTestBuild(azureDevOpsBranch: inputBranch);
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List
+ {
+ new BranchClassification { BranchName = expectedNormalizedBranch, Classification = "production" }
+ }
+ });
+
+ // Act - Test both validators for successful case
+ var enforceResult = await enforceValidator.ValidateAsync(build, targetChannel);
+ var auditResult = await auditValidator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ enforceResult.Should().Be(TargetChannelValidationResult.Success);
+ auditResult.Should().Be(TargetChannelValidationResult.Success);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_EmptyBranchClassifications_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List()
+ });
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_NullBranchClassificationResponse_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync((BranchClassificationResponse)null);
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Theory]
+ [InlineData(ValidationMode.Enforce, TargetChannelValidationResult.Fail)]
+ [InlineData(ValidationMode.Audit, TargetChannelValidationResult.AuditOnlyFailure)]
+ public async Task ValidateAsync_UnexpectedExceptionInValidation_ReturnsExpectedResult(ValidationMode validationMode, TargetChannelValidationResult expectedResult)
+ {
+ // Arrange
+ var validator = CreateValidator(validationMode);
+ var build = CreateTestBuild();
+ var targetChannel = CreateProductionChannelConfig();
+
+ // Mock the Azure DevOps service to throw when fetching build info
+ // This simulates an unexpected exception during validation
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ThrowsAsync(new HttpRequestException("Network error"));
+
+ // Act
+ var result = await validator.ValidateAsync(build, targetChannel);
+
+ // Assert
+ result.Should().Be(expectedResult);
+ }
+
+ [Fact]
+ public void AzureDevOpsService_GetBuildInfoAsync_CallsCorrectEndpoint()
+ {
+ // Arrange
+ var mockHttpClient = new Mock();
+ var mockLogger = new Mock>();
+ var service = new AzureDevOpsService(mockHttpClient.Object, mockLogger.Object);
+
+ // Note: This test would need to be expanded with proper HttpClient mocking
+ // which is more complex. For now, we're just verifying the interface structure.
+
+ // Act & Assert - Just verifying method signature exists
+ Assert.True(typeof(IProductionChannelValidatorBuildInfoService).GetMethod(nameof(IProductionChannelValidatorBuildInfoService.GetBuildInfoAsync)) != null);
+ }
+
+ [Fact]
+ public async Task ValidateAsync_ValidationMode_DefaultsToEnforce()
+ {
+ // Arrange - Create validator without specifying ValidationMode (should default to Enforce)
+ var defaultValidator = new ProductionChannelValidator(
+ _mockAzureDevOpsService.Object,
+ _mockBranchClassificationService.Object,
+ _mockLogger.Object);
+
+ var build = CreateTestBuild(azureDevOpsBranch: "refs/heads/feature/test");
+ var targetChannel = CreateProductionChannelConfig();
+
+ _mockAzureDevOpsService
+ .Setup(x => x.GetBuildInfoAsync("dnceng", "internal", 123456))
+ .ReturnsAsync(new AzureDevOpsBuildInfo
+ {
+ Project = new AzureDevOpsProject { Id = "project-guid-123", Name = "internal" },
+ Repository = new AzureDevOpsRepository { Id = "repo-guid-456", Name = "dotnet-runtime" },
+ Tags = new List { "1ES.PT.Official" }
+ });
+
+ _mockBranchClassificationService
+ .Setup(x => x.GetBranchClassificationsAsync("dnceng", "project-guid-123", "repo-guid-456"))
+ .ReturnsAsync(new BranchClassificationResponse
+ {
+ Status = "Success",
+ BranchClassifications = new List
+ {
+ new BranchClassification { BranchName = "main", Classification = "production" }
+ }
+ });
+
+ // Act
+ var result = await defaultValidator.ValidateAsync(build, targetChannel);
+
+ // Assert - Default should be Enforce mode, so non-production branch should return Fail
+ result.Should().Be(TargetChannelValidationResult.Fail);
+ }
+
+ [Fact]
+ public void PublishArtifactsInManifest_EnforceProduction_DefaultsToFalse()
+ {
+ // Arrange & Act
+ var task = new PublishArtifactsInManifest();
+
+ // Assert
+ task.EnforceProduction.Should().BeFalse();
+ }
+
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public void PublishArtifactsInManifest_EnforceProduction_AcceptsValidValues(bool enforceProduction)
+ {
+ // Arrange & Act
+ var task = new PublishArtifactsInManifest();
+ task.EnforceProduction = enforceProduction;
+
+ // Assert
+ task.EnforceProduction.Should().Be(enforceProduction);
+ }
+ }
+}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/PublishArtifactsInManifestTests.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/PublishArtifactsInManifestTests.cs
index 05c776ff704a..4b150806a7dc 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/PublishArtifactsInManifestTests.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed.Tests/PublishArtifactsInManifestTests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
@@ -16,6 +17,7 @@
using Microsoft.DotNet.Build.Tasks.Feed.Model;
using Microsoft.DotNet.Internal.DependencyInjection.Testing;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Xunit;
using static Microsoft.DotNet.Build.CloudTestTasks.AzureStorageUtils;
using static Microsoft.DotNet.Build.Tasks.Feed.PublishArtifactsInManifestBase;
@@ -30,6 +32,88 @@ public class PublishArtifactsInManifestTests
private const string AzDOFeedUrl = "https://pkgs.dev.azure.com/dnceng/public/_packaging/a-dotnet-feed/nuget/v3/index.json";
private const string StorageUrl = "https://dotnetstorageaccount.blob.core.windows.net/placewherethingsarepublished/index.json";
+ ///
+ /// Mock implementation of ITargetChannelValidator for testing negative scenarios.
+ ///
+ private class MockTargetChannelValidator : ITargetChannelValidator
+ {
+ private readonly TargetChannelValidationResult _validationResult;
+ private readonly bool _shouldValidate;
+
+ public MockTargetChannelValidator(TargetChannelValidationResult validationResult, bool shouldValidate = true)
+ {
+ _validationResult = validationResult;
+ _shouldValidate = shouldValidate;
+ }
+
+ public int ValidateCallCount { get; private set; }
+ public ProductConstructionService.Client.Models.Build LastBuild { get; private set; }
+ public TargetChannelConfig LastTargetChannel { get; private set; }
+
+ public Task ValidateAsync(ProductConstructionService.Client.Models.Build build, TargetChannelConfig targetChannel)
+ {
+ if (_shouldValidate)
+ {
+ ValidateCallCount++;
+ LastBuild = build;
+ LastTargetChannel = targetChannel;
+ }
+ return Task.FromResult(_validationResult);
+ }
+ }
+
+ ///
+ /// Test publishing task that exposes the ValidateTargetChannelAsync method for testing.
+ ///
+ private class TestablePublishArtifactsTask : PublishArtifactsInManifestBase
+ {
+ public TestablePublishArtifactsTask(ITargetChannelValidator validator = null)
+ : base(null, validator)
+ {
+ }
+
+ public override Task ExecuteAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+ public new async Task ValidateTargetChannelAsync(
+ ProductConstructionService.Client.Models.Build build,
+ TargetChannelConfig targetChannel)
+ {
+ return await base.ValidateTargetChannelAsync(build, targetChannel);
+ }
+ }
+
+ ///
+ /// Creates a test Build object with the required constructor parameters.
+ ///
+ private static ProductConstructionService.Client.Models.Build CreateTestBuild(
+ int id = 12345,
+ DateTimeOffset? dateProduced = null,
+ int staleness = 0,
+ bool released = false,
+ bool stable = false,
+ string commit = "abc123",
+ List channels = null,
+ List assets = null,
+ List dependencies = null,
+ List incoherencies = null)
+ {
+ return new ProductConstructionService.Client.Models.Build(
+ id: id,
+ dateProduced: dateProduced ?? DateTimeOffset.UtcNow,
+ staleness: staleness,
+ released: released,
+ stable: stable,
+ commit: commit,
+ channels: channels ?? new List(),
+ assets: assets ?? new List(),
+ dependencies: dependencies ?? new List(),
+ incoherencies: incoherencies ?? new List()
+ );
+ }
+
// This test should be refactored: https://github.com/dotnet/arcade/issues/6715
[Fact]
public void ConstructV3PublishingTask()
@@ -66,13 +150,31 @@ public void ConstructV4PublishingTask()
var task = new PublishArtifactsInManifest()
{
BuildEngine = buildEngine,
- TargetChannels = GeneralTestingChannelId
+ TargetChannels = GeneralTestingChannelId,
+ AzdoApiToken = "test-token" // Add test token for DI
};
// Dependency Injection setup
var collection = new ServiceCollection()
.AddSingleton()
- .AddSingleton();
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton(provider =>
+ {
+ var httpClient = provider.GetRequiredService();
+ var loggerFactory = provider.GetRequiredService();
+ var logger = loggerFactory.CreateLogger();
+ return new AzureDevOpsService(httpClient, logger, "test-token");
+ })
+ .AddSingleton(provider =>
+ {
+ var httpClient = provider.GetRequiredService();
+ var loggerFactory = provider.GetRequiredService();
+ var logger = loggerFactory.CreateLogger();
+ return new BranchClassificationService(httpClient, logger, "test-token");
+ })
+ .AddSingleton()
+ .AddLogging(); // Add logging services
task.ConfigureServices(collection);
using var provider = collection.BuildServiceProvider();
@@ -83,6 +185,68 @@ public void ConstructV4PublishingTask()
which.Should().BeOfType();
}
+ [Theory]
+ [InlineData(TargetChannelValidationResult.Success)]
+ [InlineData(TargetChannelValidationResult.Fail)]
+ public async Task ValidateTargetChannelAsync_ProductionChannelValidation_Works(TargetChannelValidationResult validationResult)
+ {
+ // Arrange
+ var mockValidator = new MockTargetChannelValidator(validationResult: validationResult);
+ var task = new TestablePublishArtifactsTask(mockValidator);
+ var buildEngine = new MockBuildEngine();
+ task.BuildEngine = buildEngine;
+
+ var build = CreateTestBuild(id: 12345, commit: "abc123");
+
+ var productionChannel = new TargetChannelConfig(
+ id: 1,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: null,
+ akaMSCreateLinkPatterns: null,
+ akaMSDoNotCreateLinkPatterns: null,
+ targetFeeds: new TargetFeedSpecification[0],
+ symbolTargetType: SymbolPublishVisibility.None,
+ flatten: true,
+ isProduction: true);
+
+ // Act
+ var result = await task.ValidateTargetChannelAsync(build, productionChannel);
+
+ // Assert
+ // For both Success and AuditOnlyFailure, the method returns true (allows publishing)
+ // Only Fail should return false
+ bool expectedResult = validationResult != TargetChannelValidationResult.Fail;
+ result.Should().Be(expectedResult);
+
+ mockValidator.ValidateCallCount.Should().Be(1);
+ mockValidator.LastBuild.Should().Be(build);
+ mockValidator.LastTargetChannel.Should().Be(productionChannel);
+
+ // Check that validation log message was written
+ buildEngine.BuildMessageEvents.Should().Contain(m =>
+ m.Importance == Microsoft.Build.Framework.MessageImportance.Normal &&
+ m.Message.Contains("Validating production channel 1"));
+
+ if (validationResult == TargetChannelValidationResult.Fail)
+ {
+ // Check that error was logged
+ buildEngine.BuildErrorEvents.Should().Contain(error =>
+ error.Message.Contains("Build validation failed for production channel 1"));
+ }
+ else if (validationResult == TargetChannelValidationResult.AuditOnlyFailure)
+ {
+ // Check that warning was logged for audit-only failure
+ buildEngine.BuildWarningEvents.Should().Contain(warning =>
+ warning.Message.Contains("Build validation audit failure for production channel 1"));
+ }
+ else
+ {
+ // Check that no error was logged for success
+ buildEngine.BuildErrorEvents.Should().BeEmpty();
+ }
+ }
+
[Theory]
[InlineData("https://pkgs.dev.azure.com/dnceng/public/_packaging/mmitche-test-transport/nuget/v3/index.json", "dnceng", "public/", "mmitche-test-transport")]
[InlineData("https://pkgs.dev.azure.com/DevDiv/public/_packaging/1234.5/nuget/v3/index.json", "DevDiv", "public/", "1234.5")]
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/Microsoft.DotNet.Build.Tasks.Feed.csproj b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/Microsoft.DotNet.Build.Tasks.Feed.csproj
index ff2898086e26..f3cb15a12eb7 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/Microsoft.DotNet.Build.Tasks.Feed.csproj
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/Microsoft.DotNet.Build.Tasks.Feed.csproj
@@ -11,6 +11,7 @@
+ true
$(DefineConstants);DOTNET_BUILD_SOURCE_ONLY
@@ -54,44 +55,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AssetPublisherFactory.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AssetPublisherFactory.cs
index f0af6a336cf0..7efed918fac1 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AssetPublisherFactory.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AssetPublisherFactory.cs
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-#if !NET472_OR_GREATER
using Azure;
using System;
using Microsoft.Build.Utilities;
@@ -53,4 +52,3 @@ private TokenCredential GetAzureTokenCredential(string managedIdentityClientId)
}
}
}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureDevOpsNugetFeedAssetPublisher.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureDevOpsNugetFeedAssetPublisher.cs
index 41fab2058271..235dd3a3a106 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureDevOpsNugetFeedAssetPublisher.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureDevOpsNugetFeedAssetPublisher.cs
@@ -9,7 +9,6 @@
using System.Threading;
using Microsoft.Build.Utilities;
using Microsoft.DotNet.Build.Tasks.Feed.Model;
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client.Models;
using NuGet.Packaging;
using NuGet.Packaging.Core;
@@ -94,9 +93,3 @@ public async Task PublishAssetAsync(string file, string blobPath, PushOptions op
}
}
}
-#else
-public class AzureDevOpsNugetFeedAssetPublisher : Task
-{
- public override bool Execute() => throw new NotSupportedException("AzureDevOpsNugetFeedAssetPublisher depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
-}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureStorageAssetPublisher.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureStorageAssetPublisher.cs
index b90c72114dac..686ec25d0127 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureStorageAssetPublisher.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/AzureStorageAssetPublisher.cs
@@ -7,14 +7,11 @@
using Azure.Storage.Blobs.Models;
using Microsoft.Build.Utilities;
using Microsoft.DotNet.Build.CloudTestTasks;
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client.Models;
-#endif
using Task = System.Threading.Tasks.Task;
namespace Microsoft.DotNet.Build.Tasks.Feed
{
-#if !NET472_OR_GREATER
public abstract class AzureStorageAssetPublisher : IAssetPublisher
{
private readonly TaskLoggingHelper _log;
@@ -67,19 +64,4 @@ public async Task PublishAssetAsync(string file, string blobPath, PushOptions op
}
}
}
-#else
- public abstract class AzureStorageAssetPublisher : IAssetPublisher
- {
- private readonly TaskLoggingHelper _log;
-
- protected AzureStorageAssetPublisher(TaskLoggingHelper log)
- {
- _log = log;
- }
-
- public abstract BlobClient CreateBlobClient(string blobPath);
-
- public Task PublishAssetAsync(string file, string blobPath, PushOptions options, SemaphoreSlim clientThrottle = null) => throw new NotImplementedException();
- }
-#endif
}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/IAssetPublisher.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/IAssetPublisher.cs
index 4c74e001bb48..0d21950b3329 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/IAssetPublisher.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/IAssetPublisher.cs
@@ -2,18 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Threading;
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client.Models;
-#endif
using Task = System.Threading.Tasks.Task;
namespace Microsoft.DotNet.Build.Tasks.Feed
{
public interface IAssetPublisher
{
-#if !NET472_OR_GREATER
LocationType LocationType { get; }
-#endif
Task PublishAssetAsync(string file, string blobPath, PushOptions options, SemaphoreSlim clientThrottle = null);
}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/ITargetChannelValidator.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/ITargetChannelValidator.cs
new file mode 100644
index 000000000000..7f2901c7c555
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/ITargetChannelValidator.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Threading.Tasks;
+using Microsoft.DotNet.Build.Tasks.Feed.Model;
+
+namespace Microsoft.DotNet.Build.Tasks.Feed
+{
+ public enum TargetChannelValidationResult
+ {
+ Success,
+ AuditOnlyFailure,
+ Fail
+ }
+
+ public enum ValidationMode
+ {
+ ///
+ /// In audit mode, validation failures are reported as AuditOnlyFailure instead of Fail.
+ /// This allows builds to be published but with warnings about validation issues.
+ ///
+ Audit,
+
+ ///
+ /// In enforce mode, validation failures are reported as Fail, preventing builds from being published.
+ ///
+ Enforce
+ }
+
+ ///
+ /// Interface for validating whether a build can be published to production channels.
+ ///
+ public interface ITargetChannelValidator
+ {
+ ///
+ /// Validates whether the build can be published to the specified target channel.
+ ///
+ /// The build information from BAR
+ /// The target channel the build will be published to
+ /// ValidationResult indicating the outcome of the validation
+ Task ValidateAsync(ProductConstructionService.Client.Models.Build build, TargetChannelConfig targetChannel);
+ }
+}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/ProductionChannelValidator.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/ProductionChannelValidator.cs
new file mode 100644
index 000000000000..55770683772a
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/ProductionChannelValidator.cs
@@ -0,0 +1,477 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.Json;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Microsoft.DotNet.Build.Tasks.Feed.Model;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.DotNet.Build.Tasks.Feed
+{
+ public class ProductionChannelValidator : ITargetChannelValidator
+ {
+ private const string RequiredAzureDevOpsTag = "1ES.PT.Official";
+
+ private readonly IProductionChannelValidatorBuildInfoService _productionChannelValidatorBuildInfoService;
+ private readonly IBranchClassificationService _branchClassificationService;
+ private readonly ILogger _logger;
+ private readonly ValidationMode _validationMode;
+
+ public ProductionChannelValidator(
+ IProductionChannelValidatorBuildInfoService productionChannelValidatorBuildInfoService,
+ IBranchClassificationService branchClassificationService,
+ ILogger logger,
+ ValidationMode validationMode = ValidationMode.Enforce)
+ {
+ _productionChannelValidatorBuildInfoService = productionChannelValidatorBuildInfoService ?? throw new ArgumentNullException(nameof(productionChannelValidatorBuildInfoService));
+ _branchClassificationService = branchClassificationService ?? throw new ArgumentNullException(nameof(branchClassificationService));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _validationMode = validationMode;
+ }
+
+ public async Task ValidateAsync(ProductConstructionService.Client.Models.Build build, TargetChannelConfig targetChannel)
+ {
+ if (build == null)
+ {
+ throw new ArgumentNullException(nameof(build));
+ }
+
+ // If the target channel is not a production channel, no validation is needed
+ if (!targetChannel.IsProduction)
+ {
+ _logger.LogInformation($"Target channel {targetChannel.Id} is not a production channel, skipping validation");
+ return TargetChannelValidationResult.Success;
+ }
+
+ _logger.LogInformation($"Validating build {build.Id} for production channel {targetChannel.Id}");
+
+ try
+ {
+ // Get build information from Azure DevOps which includes tags, project, and repository info
+ var buildInfo = await GetAzureDevOpsBuildInfoAsync(build);
+ if (buildInfo == null)
+ {
+ return ApplyValidationMode(TargetChannelValidationResult.Fail);
+ }
+
+ // Step 1: Validate Azure DevOps build has the required tag - always return Fail if tags don't validate
+ var tagValidationResult = ValidateAzureDevOpsTags(build, buildInfo.Tags);
+ if (tagValidationResult != TargetChannelValidationResult.Success)
+ {
+ return ApplyValidationMode(tagValidationResult); // This will be Fail for missing/invalid tags
+ }
+
+ // Step 2: Now that tags are validated, check if this is an Azure DevOps repository
+ if (!IsAzureDevOpsRepository(build.AzureDevOpsRepository))
+ {
+ LogValidationFailure($"Build {build.Id} repository '{build.AzureDevOpsRepository}' is not an Azure DevOps repository.");
+ return ApplyValidationMode(TargetChannelValidationResult.Fail);
+ }
+
+ // Step 3: Validate that the branch is a production branch
+ var branchValidationResult = await ValidateBranchIsProductionAsync(build, buildInfo);
+ if (branchValidationResult != TargetChannelValidationResult.Success)
+ {
+ return ApplyValidationMode(branchValidationResult);
+ }
+
+ _logger.LogInformation($"Build {build.Id} passed all production channel validations");
+ return TargetChannelValidationResult.Success;
+ }
+ catch (Exception ex)
+ {
+ LogValidationFailure(ex, $"Error validating build {build.Id} for production channel {targetChannel.Id}");
+ return ApplyValidationMode(TargetChannelValidationResult.Fail);
+ }
+ }
+
+ ///
+ /// Applies the validation mode to convert Fail results to AuditOnlyFailure when in Audit mode
+ ///
+ private TargetChannelValidationResult ApplyValidationMode(TargetChannelValidationResult result)
+ {
+ if (_validationMode == ValidationMode.Audit && result == TargetChannelValidationResult.Fail)
+ {
+ return TargetChannelValidationResult.AuditOnlyFailure;
+ }
+ return result;
+ }
+
+ ///
+ /// Logs a validation failure message based on the current validation mode.
+ /// In Audit mode, logs as a warning. In Enforce mode, logs as an error.
+ ///
+ private void LogValidationFailure(string message)
+ {
+ if (_validationMode == ValidationMode.Audit)
+ {
+ _logger.LogWarning(message);
+ }
+ else
+ {
+ _logger.LogError(message);
+ }
+ }
+
+ ///
+ /// Logs a validation failure message with exception based on the current validation mode.
+ /// In Audit mode, logs as a warning. In Enforce mode, logs as an error.
+ ///
+ private void LogValidationFailure(Exception exception, string message)
+ {
+ if (_validationMode == ValidationMode.Audit)
+ {
+ _logger.LogWarning(exception, message);
+ }
+ else
+ {
+ _logger.LogError(exception, message);
+ }
+ }
+
+ private static bool IsAzureDevOpsRepository(string repositoryUrl)
+ {
+ if (string.IsNullOrEmpty(repositoryUrl))
+ return false;
+
+ return repositoryUrl.Contains("dev.azure.com", StringComparison.OrdinalIgnoreCase) ||
+ repositoryUrl.Contains("visualstudio.com", StringComparison.OrdinalIgnoreCase);
+ }
+
+ private async Task GetAzureDevOpsBuildInfoAsync(ProductConstructionService.Client.Models.Build build)
+ {
+ // Extract Azure DevOps information from build
+ var azureDevOpsAccount = build.AzureDevOpsAccount;
+ var azureDevOpsProject = build.AzureDevOpsProject;
+ var azureDevOpsBuildId = build.AzureDevOpsBuildId;
+
+ if (string.IsNullOrEmpty(azureDevOpsAccount) ||
+ string.IsNullOrEmpty(azureDevOpsProject) ||
+ !azureDevOpsBuildId.HasValue)
+ {
+ LogValidationFailure($"Build {build.Id} missing Azure DevOps information for validation");
+ return null;
+ }
+
+ // Don't catch exceptions here - let them bubble up to the main catch block
+ // which will treat service communication failures as AuditOnlyFailure
+ return await _productionChannelValidatorBuildInfoService.GetBuildInfoAsync(azureDevOpsAccount, azureDevOpsProject, azureDevOpsBuildId.Value);
+ }
+
+ private TargetChannelValidationResult ValidateAzureDevOpsTags(ProductConstructionService.Client.Models.Build build, IReadOnlyList tags)
+ {
+ try
+ {
+ _logger.LogDebug($"Validating Azure DevOps tags for build {build.Id}");
+
+ if (tags == null)
+ {
+ LogValidationFailure($"Build {build.Id} has no tag information available");
+ return TargetChannelValidationResult.Fail;
+ }
+
+ bool hasRequiredTag = tags.Contains(RequiredAzureDevOpsTag, StringComparer.OrdinalIgnoreCase);
+
+ if (hasRequiredTag)
+ {
+ _logger.LogDebug($"Build {build.Id} has required tag '{RequiredAzureDevOpsTag}'");
+ return TargetChannelValidationResult.Success;
+ }
+ else
+ {
+ LogValidationFailure($"Build {build.Id} does not have required tag '{RequiredAzureDevOpsTag}'. Found tags: {string.Join(", ", tags)}");
+ return TargetChannelValidationResult.Fail;
+ }
+ }
+ catch (Exception ex)
+ {
+ LogValidationFailure(ex, $"Error validating Azure DevOps tags for build {build.Id}");
+ return TargetChannelValidationResult.Fail;
+ }
+ }
+
+ private async Task ValidateBranchIsProductionAsync(ProductConstructionService.Client.Models.Build build, AzureDevOpsBuildInfo buildInfo)
+ {
+ // Extract repository and branch information
+ var azureDevOpsAccount = build.AzureDevOpsAccount;
+ var azureDevOpsBranch = build.AzureDevOpsBranch;
+
+ if (string.IsNullOrEmpty(azureDevOpsAccount) ||
+ string.IsNullOrEmpty(azureDevOpsBranch))
+ {
+ LogValidationFailure($"Build {build.Id} missing repository information for branch validation");
+ return TargetChannelValidationResult.Fail;
+ }
+
+ string projectId = buildInfo?.Project?.Id;
+ string repositoryId = buildInfo?.Repository?.Id;
+
+ if (string.IsNullOrEmpty(projectId))
+ {
+ LogValidationFailure($"Build {build.Id}: Could not find project GUID from build info");
+ return TargetChannelValidationResult.Fail;
+ }
+
+ if (string.IsNullOrEmpty(repositoryId))
+ {
+ LogValidationFailure($"Build {build.Id}: Could not find repository GUID from build info");
+ return TargetChannelValidationResult.Fail;
+ }
+
+ // Normalize branch name (remove refs/heads/ prefix if present)
+ var branchName = NormalizeBranchName(azureDevOpsBranch);
+
+ _logger.LogDebug($"Checking branch classification for {azureDevOpsAccount}/{projectId}/{repositoryId}, branch: {branchName}");
+
+ try
+ {
+ var branchClassifications = await _branchClassificationService.GetBranchClassificationsAsync(
+ azureDevOpsAccount, projectId, repositoryId);
+
+ bool isProductionBranch = IsProductionBranch(branchName, branchClassifications);
+
+ if (isProductionBranch)
+ {
+ _logger.LogDebug($"Branch '{branchName}' is classified as a production branch");
+ return TargetChannelValidationResult.Success;
+ }
+ else
+ {
+ LogValidationFailure($"Branch '{branchName}' is not classified as a production branch");
+ return TargetChannelValidationResult.Fail;
+ }
+ }
+ catch (Exception ex)
+ {
+ // For branch classification service failures, always log as debug first
+ _logger.LogDebug(ex, $"Failed to fetch branch classifications for build {build.Id}");
+
+ // Then apply validation mode specific logging
+ LogValidationFailure(ex, $"Error validating branch classification for build {build.Id}");
+ return TargetChannelValidationResult.Fail;
+ }
+ }
+
+ private static string NormalizeBranchName(string branchName)
+ {
+ if (string.IsNullOrEmpty(branchName))
+ return branchName;
+
+ // Remove refs/heads/ prefix if present
+ if (branchName.StartsWith("refs/heads/", StringComparison.OrdinalIgnoreCase))
+ {
+ return branchName.Substring("refs/heads/".Length);
+ }
+
+ return branchName;
+ }
+
+ private static bool IsProductionBranch(string branchName, BranchClassificationResponse branchClassifications)
+ {
+ if (branchClassifications?.BranchClassifications == null)
+ return false;
+
+ foreach (var classification in branchClassifications.BranchClassifications)
+ {
+ if (classification.Classification.Equals("production", StringComparison.OrdinalIgnoreCase))
+ {
+ if (MatchesBranchPattern(branchName, classification.BranchName))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static bool MatchesBranchPattern(string branchName, string pattern)
+ {
+ if (string.IsNullOrEmpty(branchName) || string.IsNullOrEmpty(pattern))
+ return false;
+
+ // Handle exact match
+ if (pattern.Equals(branchName, StringComparison.OrdinalIgnoreCase))
+ return true;
+
+ // Handle wildcard patterns (e.g., "release/*")
+ if (pattern.EndsWith("/*"))
+ {
+ var prefix = pattern.Substring(0, pattern.Length - 2);
+ return branchName.StartsWith(prefix + "/", StringComparison.OrdinalIgnoreCase);
+ }
+
+ // Handle special ~default pattern
+ if (pattern.Equals("~default", StringComparison.OrdinalIgnoreCase))
+ {
+ // This would require additional logic to determine the default branch
+ // For now, treat common default branch names as matching
+ return branchName.Equals("main", StringComparison.OrdinalIgnoreCase) ||
+ branchName.Equals("master", StringComparison.OrdinalIgnoreCase);
+ }
+
+ return false;
+ }
+ }
+
+ // Interface definitions for dependency injection and testability
+ public interface IProductionChannelValidatorBuildInfoService
+ {
+ Task GetBuildInfoAsync(string account, string project, int buildId);
+ }
+
+ public interface IBranchClassificationService
+ {
+ Task GetBranchClassificationsAsync(string organizationName, string projectId, string repositoryId);
+ }
+
+ // Response models for Azure DevOps API
+ public class AzureDevOpsBuildInfo
+ {
+ public AzureDevOpsProject Project { get; set; }
+ public AzureDevOpsRepository Repository { get; set; }
+ public IReadOnlyList Tags { get; set; }
+ }
+
+ public class AzureDevOpsProject
+ {
+ public string Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ public class AzureDevOpsRepository
+ {
+ public string Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ // Response models for the branch classification API
+ public class BranchClassificationResponse
+ {
+ public IReadOnlyList BranchClassifications { get; set; }
+ public string Status { get; set; }
+ }
+
+ public class BranchClassification
+ {
+ public string BranchName { get; set; }
+ public string Classification { get; set; }
+ }
+
+ // Implementation classes
+ public class AzureDevOpsService : IProductionChannelValidatorBuildInfoService
+ {
+ private readonly HttpClient _httpClient;
+ private readonly ILogger _logger;
+ private readonly string _token;
+
+ public AzureDevOpsService(HttpClient httpClient, ILogger logger, string token = null)
+ {
+ _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _token = token;
+
+ // Configure authentication for Azure DevOps API using Basic authentication
+ if (!string.IsNullOrEmpty(_token))
+ {
+ _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
+ "Basic",
+ Convert.ToBase64String(Encoding.ASCII.GetBytes($":{_token}")));
+ }
+ }
+
+ public async Task GetBuildInfoAsync(string account, string project, int buildId)
+ {
+ try
+ {
+ var url = $"https://dev.azure.com/{account}/{project}/_apis/build/builds/{buildId}?api-version=6.0";
+ _logger.LogDebug($"Fetching build info from: {url}");
+
+ var response = await _httpClient.GetAsync(url);
+ response.EnsureSuccessStatusCode();
+
+ var content = await response.Content.ReadAsStringAsync();
+ var buildResponse = JsonSerializer.Deserialize(content, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ });
+
+ return new AzureDevOpsBuildInfo
+ {
+ Project = buildResponse?.Project,
+ Repository = buildResponse?.Repository,
+ Tags = buildResponse?.Tags ?? new List()
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogDebug(ex, $"Error fetching build info for {account}/{project}/{buildId}");
+ throw;
+ }
+ }
+
+ private class AzureDevOpsBuildInfoResponse
+ {
+ public AzureDevOpsProject Project { get; set; }
+ public AzureDevOpsRepository Repository { get; set; }
+ public List Tags { get; set; }
+ }
+ }
+
+ public class BranchClassificationService : IBranchClassificationService
+ {
+ private readonly HttpClient _httpClient;
+ private readonly ILogger _logger;
+ private readonly string _token;
+
+ public BranchClassificationService(HttpClient httpClient, ILogger logger, string token = null)
+ {
+ _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _token = token;
+ }
+
+ public async Task GetBranchClassificationsAsync(string organizationName, string projectId, string repositoryId)
+ {
+ try
+ {
+ var url = string.Format(CultureInfo.InvariantCulture,
+ "https://BranchClassification.app.prod.gitops.startclean.microsoft.com/api/getBranchClassifications/{0}/{1}/{2}",
+ organizationName, projectId, repositoryId);
+ _logger.LogDebug($"Fetching branch classifications from: {url}");
+
+ using var request = new HttpRequestMessage(HttpMethod.Get, url);
+
+ // Add Bearer token authentication for branch classification service
+ if (!string.IsNullOrEmpty(_token))
+ {
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
+ }
+
+ var response = await _httpClient.SendAsync(request);
+ response.EnsureSuccessStatusCode();
+
+ var content = await response.Content.ReadAsStringAsync();
+ var classification = JsonSerializer.Deserialize(content, new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true
+ });
+
+ return classification;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogDebug(ex, $"Error fetching branch classifications for {organizationName}/{projectId}/{repositoryId}");
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs
index c50fd0e6a941..480d59853956 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifest.cs
@@ -5,13 +5,14 @@
using Microsoft.Build.Framework;
using Microsoft.DotNet.Build.Tasks.Feed.Model;
using Microsoft.DotNet.Build.Manifest;
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Linq;
+using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
@@ -213,8 +214,17 @@ public string BuildQuality
public int NonStreamingPublishingMaxClients {get; set;}
+ ///
+ /// Whether to enforce production channel validation rules.
+ /// If true, validation failures prevent builds from being published (Fail).
+ /// If false, validation failures are reported as warnings but builds are allowed to be published (AuditOnlyFailure).
+ /// Default: false (audit mode)
+ ///
+ public bool EnforceProduction { get; set; } = false;
+
private IBuildModelFactory _buildModelFactory;
private IFileSystem _fileSystem;
+ private ITargetChannelValidator _targetChannelValidator;
private PublishingConstants.BuildQuality _buildQuality;
@@ -227,14 +237,53 @@ public override void ConfigureServices(IServiceCollection collection)
collection.TryAddSingleton();
collection.TryAddSingleton();
collection.TryAddSingleton();
+
+ // Register ProductionChannelValidator with the specified validation mode
+ collection.TryAddSingleton(provider =>
+ {
+ var buildInfoService = provider.GetRequiredService();
+ var branchClassificationService = provider.GetRequiredService();
+ var loggerFactory = provider.GetRequiredService();
+ var logger = loggerFactory.CreateLogger();
+
+ // Convert EnforceProduction boolean to ValidationMode enum
+ var validationMode = EnforceProduction ? ValidationMode.Enforce : ValidationMode.Audit;
+
+ return new ProductionChannelValidator(buildInfoService, branchClassificationService, logger, validationMode);
+ });
+
+ // Add logging services
+ collection.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Debug));
+
+ // Register AzureDevOpsService with proper authentication
+ collection.TryAddSingleton(provider =>
+ {
+ var httpClient = provider.GetRequiredService();
+ var loggerFactory = provider.GetRequiredService();
+ var logger = loggerFactory.CreateLogger();
+ return new AzureDevOpsService(httpClient, logger, AzdoApiToken);
+ });
+
+ // Register BranchClassificationService with proper authentication
+ collection.TryAddSingleton(provider =>
+ {
+ var httpClient = provider.GetRequiredService();
+ var loggerFactory = provider.GetRequiredService();
+ var logger = loggerFactory.CreateLogger();
+ return new BranchClassificationService(httpClient, logger, AzdoApiToken);
+ });
+
+ collection.TryAddSingleton();
collection.TryAddSingleton(Log);
}
public bool ExecuteTask(IBuildModelFactory buildModelFactory,
- IFileSystem fileSystem)
+ IFileSystem fileSystem,
+ ITargetChannelValidator targetChannelValidator)
{
_buildModelFactory = buildModelFactory;
_fileSystem = fileSystem;
+ _targetChannelValidator = targetChannelValidator;
return ExecuteAsync().GetAwaiter().GetResult();
}
@@ -358,7 +407,7 @@ internal PublishArtifactsInManifestBase ConstructPublishingV3Task(BuildModel bui
SymbolPublishingExclusionsFile = this.SymbolPublishingExclusionsFile,
PublishSpecialClrFiles = this.PublishSpecialClrFiles,
BuildQuality = this.BuildQuality,
- ArtifactsBasePath = this.ArtifactsBasePath,
+ ArtifactsBasePath = this.ArtifactsBasePath,
AzdoApiToken = this.AzdoApiToken,
BuildId = this.BuildId,
AzureDevOpsProject = this.AzureProject,
@@ -368,7 +417,9 @@ internal PublishArtifactsInManifestBase ConstructPublishingV3Task(BuildModel bui
SymbolRequestProject = this.SymbolRequestProject,
UseStreamingPublishing = this.UseStreamingPublishing,
StreamingPublishingMaxClients = this.StreamingPublishingMaxClients,
- NonStreamingPublishingMaxClients = this.NonStreamingPublishingMaxClients
+ NonStreamingPublishingMaxClients = this.NonStreamingPublishingMaxClients,
+ EnforceProduction = this.EnforceProduction,
+ TargetChannelValidator = _targetChannelValidator
};
}
@@ -416,14 +467,10 @@ internal PublishArtifactsInManifestBase ConstructPublishingV4Task(BuildModel bui
SymbolRequestProject = this.SymbolRequestProject,
UseStreamingPublishing = this.UseStreamingPublishing,
StreamingPublishingMaxClients = this.StreamingPublishingMaxClients,
- NonStreamingPublishingMaxClients = this.NonStreamingPublishingMaxClients
+ NonStreamingPublishingMaxClients = this.NonStreamingPublishingMaxClients,
+ EnforceProduction = this.EnforceProduction,
+ TargetChannelValidator = _targetChannelValidator
};
}
}
}
-#else
-public class PublishArtifactsInManifest : Microsoft.Build.Utilities.Task
-{
- public override bool Execute() => throw new System.NotSupportedException("PublishArtifactsInManifest depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
-}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs
index cc9f553f60f6..90f94d2cee92 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestBase.cs
@@ -22,13 +22,11 @@
using Microsoft.Arcade.Common;
using Microsoft.Build.Framework;
using Microsoft.DotNet.Build.Tasks.Feed.Model;
-#if !NET472_OR_GREATER
using Azure.Identity;
using Microsoft.DotNet.ProductConstructionService.Client;
using Microsoft.DotNet.ProductConstructionService.Client.Models;
using Microsoft.DotNet.Internal.SymbolHelper;
using Microsoft.DotNet.ArcadeAzureIntegration;
-#endif
using Microsoft.DotNet.Build.Manifest;
using Newtonsoft.Json;
using NuGet.Versioning;
@@ -39,7 +37,6 @@
namespace Microsoft.DotNet.Build.Tasks.Feed
{
-#if NET
///
/// The intended use of this task is to push artifacts described in
/// a build manifest to a static package feed.
@@ -48,6 +45,11 @@ public abstract class PublishArtifactsInManifestBase : Microsoft.Build.Utilities
{
public AssetPublisherFactory AssetPublisherFactory { get; }
+ ///
+ /// Production channel validator for validating builds before publishing to production channels.
+ ///
+ public ITargetChannelValidator TargetChannelValidator { get; set; }
+
///
/// Full path to the folder containing blob assets.
///
@@ -109,6 +111,14 @@ public abstract class PublishArtifactsInManifestBase : Microsoft.Build.Utilities
///
public int MaxClients { get { return UseStreamingPublishing ? StreamingPublishingMaxClients : NonStreamingPublishingMaxClients; } }
+ ///
+ /// Whether to enforce production channel validation rules.
+ /// If true, validation failures prevent builds from being published (Fail).
+ /// If false, validation failures are reported as warnings but builds are allowed to be published (AuditOnlyFailure).
+ /// Default: false (audit mode)
+ ///
+ public bool EnforceProduction { get; set; } = false;
+
///
/// Whether this build is internal or not. If true, extra checks are done to avoid accidental
/// publishing of assets to public feeds or storage accounts.
@@ -192,7 +202,7 @@ public abstract class PublishArtifactsInManifestBase : Microsoft.Build.Utilities
private ConcurrentDictionary _artifactUrlHelpers = new ConcurrentDictionary();
// Matches versions such as 1.0.0.1234
- private static readonly string FourPartVersionPattern = @"\d+\.\d+\.\d+\.\d+";
+ private static readonly string FourPartVersionPattern = @"\d+\.\d+\.\d+\.\d+";
private static Regex FourPartVersionRegex = new Regex(FourPartVersionPattern);
@@ -227,9 +237,11 @@ public abstract class PublishArtifactsInManifestBase : Microsoft.Build.Utilities
private int TimeoutInSeconds = 300;
- protected PublishArtifactsInManifestBase(AssetPublisherFactory assetPublisherFactory = null)
+ protected PublishArtifactsInManifestBase(AssetPublisherFactory assetPublisherFactory = null,
+ ITargetChannelValidator targetChannelValidator = null)
{
AssetPublisherFactory = assetPublisherFactory ?? new AssetPublisherFactory(Log);
+ TargetChannelValidator = targetChannelValidator;
}
public override bool Execute()
@@ -239,6 +251,47 @@ public override bool Execute()
public abstract Task ExecuteAsync();
+ ///
+ /// Validates whether the build can be published to a production channel.
+ /// This method uses the injected ITargetChannelValidator to perform the validation.
+ ///
+ /// The build information from BAR
+ /// The target channel the build will be published to
+ /// True if the build is allowed to be published to the target channel, false otherwise
+ protected async Task ValidateTargetChannelAsync(ProductConstructionService.Client.Models.Build build, TargetChannelConfig targetChannel)
+ {
+ if (targetChannel.IsProduction)
+ {
+ Log.LogMessage(MessageImportance.Normal, $"Validating production channel {targetChannel.Id}");
+ var validationResult = await TargetChannelValidator.ValidateAsync(build, targetChannel);
+
+ switch (validationResult)
+ {
+ case TargetChannelValidationResult.Success:
+ Log.LogMessage(MessageImportance.Normal, $"Build validation succeeded for production channel {targetChannel.Id}");
+ return true;
+
+ case TargetChannelValidationResult.AuditOnlyFailure:
+ Log.LogWarning($"Build validation audit failure for production channel {targetChannel.Id}. This is currently treated as a warning.");
+ return true; // For now, treat audit-only failures as success but log warning
+
+ case TargetChannelValidationResult.Fail:
+ Log.LogError($"Build validation failed for production channel {targetChannel.Id}");
+ return false;
+
+ default:
+ Log.LogError($"Unknown validation result '{validationResult}' for production channel {targetChannel.Id}");
+ return false;
+ }
+ }
+ else
+ {
+ Log.LogMessage(MessageImportance.Normal, $"Skipping validation for non-production channel {targetChannel.Id}");
+ }
+
+ return true;
+ }
+
///
/// Lookup an asset in the build asset dictionary by name and version
///
@@ -313,8 +366,8 @@ protected ReadOnlyDictionary CreateBuildAssetDictionary(ProductCo
/// True if that asset didn't have the informed location recorded already.
private bool TryAddAssetLocation(string assetId, string assetVersion, ReadOnlyDictionary buildAssets, TargetFeedConfig feedConfig, LocationType assetLocationType)
{
- Asset assetRecord = string.IsNullOrEmpty(assetVersion) ?
- LookupAsset(assetId, buildAssets) :
+ Asset assetRecord = string.IsNullOrEmpty(assetVersion) ?
+ LookupAsset(assetId, buildAssets) :
LookupAsset(assetId, assetVersion, buildAssets);
if (assetRecord == null)
@@ -701,7 +754,7 @@ FrozenSet LoadExclusions(string symbolPublishingExclusionsFile)
// These files tend to be short - load it all at once.
string[] files = File.ReadAllLines(symbolPublishingExclusionsFile);
- FrozenSet excludeFiles = files.Where(x => x is not null or "").ToFrozenSet();
+ FrozenSet excludeFiles = files.Where(x => !string.IsNullOrEmpty(x)).ToFrozenSet();
if (excludeFiles.Count > 0)
{
@@ -1312,7 +1365,7 @@ public async Task PushNugetPackagesAsync(
HashSet packagesToPublish,
TargetFeedConfig feedConfig,
int maxClients,
- Func packagePublishAction)
+ Func packagePublishAction)
{
if (!packagesToPublish.Any())
{
@@ -1443,6 +1496,7 @@ public async Task PushNugetPackageAsync(
// Using these callbacks we can mock up functionality when testing.
CompareLocalPackageToFeedPackageCallBack ??= CompareLocalPackageToFeedPackage;
AttemptPushPackageCallback ??= NuGetFeedUploadPackageAsync;
+
var packageStatus = PackageFeedStatus.Unknown;
try
@@ -1761,7 +1815,7 @@ await PushNugetPackageAsync(
}
///
- /// Create Temporary directory if it does not exists.
+ /// Creates a temporary directory if it does not exists.
///
///
public void EnsureTemporaryDirectoryExists(string temporaryLocation)
@@ -1883,32 +1937,3 @@ protected bool AnyMissingRequiredBaseProperties()
}
}
}
-#else
- public abstract class PublishArtifactsInManifestBase : Microsoft.Build.Utilities.Task
- {
- public override bool Execute() => throw new NotSupportedException("PublishArtifactsInManifestBase depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
-
- public abstract Task ExecuteAsync();
-
- public Task PushNugetPackagesAsync(
- HashSet packagesToPublish,
- TargetFeedConfig feedConfig,
- int maxClients,
- Func packagePublishAction)
- => throw new NotSupportedException("PublishArtifactsInManifestBase depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
-
- public Task PushNugetPackageAsync(
- TargetFeedConfig feedConfig,
- HttpClient client,
- string localPackageLocation,
- string id,
- string version,
- string feedAccount,
- string feedVisibility,
- string feedName,
- Func> CompareLocalPackageToFeedPackageCallBack = null,
- Func> RunProcessAndGetOutputsCallBack = null
- ) => throw new NotSupportedException("PublishArtifactsInManifestBase depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
- }
-}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs
index 3fb6f47440d1..71f032dddf54 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV3.cs
@@ -11,7 +11,6 @@
using System.Threading.Tasks;
using Microsoft.Build.Framework;
using Microsoft.DotNet.Build.Tasks.Feed.Model;
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client;
using Microsoft.DotNet.ProductConstructionService.Client.Models;
using Microsoft.DotNet.Build.Manifest;
@@ -126,6 +125,13 @@ public override async Task ExecuteAsync()
return false;
}
+ // Validate that the channel can be be used for this build
+ if (!await ValidateTargetChannelAsync(buildInformation, targetChannelConfig))
+ {
+ Log.LogError($"Channel with ID '{targetChannelId}' is not valid for this build.");
+ return false;
+ }
+
Log.LogMessage(MessageImportance.High, $"Publishing to this target channel: {targetChannelConfig}");
List shortLinkUrls = new List();
@@ -229,9 +235,3 @@ public PublishArtifactsInManifestV3(AssetPublisherFactory assetPublisherFactory
}
}
}
-#else
-public class PublishArtifactsInManifestV3 : Microsoft.Build.Utilities.Task
-{
- public override bool Execute() => throw new NotSupportedException("PublishArtifactsInManifestV3 depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
-}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV4.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV4.cs
index a0ff7f1b6ab4..7fee2b5e242a 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV4.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishArtifactsInManifestV4.cs
@@ -11,7 +11,6 @@
using System.Threading.Tasks;
using Microsoft.Build.Framework;
using Microsoft.DotNet.Build.Tasks.Feed.Model;
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client;
using Microsoft.DotNet.ProductConstructionService.Client.Models;
using Microsoft.DotNet.Build.Manifest;
@@ -122,6 +121,13 @@ public override async Task ExecuteAsync()
return false;
}
+ // Validate that the channel can be be used for this build
+ if (!await ValidateTargetChannelAsync(buildInformation, targetChannelConfig))
+ {
+ Log.LogError($"Channel with ID '{targetChannelId}' is not valid for this build.");
+ return false;
+ }
+
Log.LogMessage(MessageImportance.High, $"Publishing to this target channel: {targetChannelConfig}");
List shortLinkUrls = new List();
@@ -239,9 +245,3 @@ public PublishArtifactsInManifestV4(AssetPublisherFactory assetPublisherFactory
}
}
}
-#else
-public class PublishArtifactsInManifestV4 : Microsoft.Build.Utilities.Task
-{
- public override bool Execute() => throw new NotSupportedException("PublishArtifactsInManifestV4 depends on ProductConstructionService.Client, which has discontinued support for desktop frameworks.");
-}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishBuildToMaestro.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishBuildToMaestro.cs
index 7b284481ff26..80e05cb284a5 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishBuildToMaestro.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/PublishBuildToMaestro.cs
@@ -567,6 +567,13 @@ private void LookupForMatchingGitHubRepository(BuildIdentity buildIdentity)
break;
}
+ // Due to latency in receiving the response and calculating the value, we may have a negative timespan
+ TimeSpan minWait = TimeSpan.FromMilliseconds(100);
+ if (timeSpan < minWait)
+ {
+ timeSpan = minWait;
+ }
+
Log.LogMessage(MessageImportance.High,
$"API rate limit exceeded, retrying in {timeSpan.Value.TotalSeconds} seconds. Retry attempt: {retry}");
Thread.Sleep(timeSpan.Value);
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/TaskTracer.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/TaskTracer.cs
index 7ef4554334a0..bd5af0eb5662 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/TaskTracer.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/TaskTracer.cs
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-#if NET
using Microsoft.Build.Framework;
using MsBuildUtils = Microsoft.Build.Utilities;
@@ -68,4 +67,3 @@ public void Verbose(string format, params object[] arguments)
_log.LogMessage(_verbose ? MessageImportance.Normal : MessageImportance.Low, format, arguments);
}
}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/AssetComparer.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/AssetComparer.cs
index dc743d5e12fb..fef8e5d3c756 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/AssetComparer.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/AssetComparer.cs
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-#if !NET472_OR_GREATER
using Microsoft.DotNet.ProductConstructionService.Client.Models;
using System.Collections.Generic;
@@ -39,4 +38,3 @@ public int GetHashCode(Asset asset)
}
}
}
-#endif
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/LatestLinksManager.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/LatestLinksManager.cs
index d2e634874858..cf5a509ac587 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/LatestLinksManager.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/common/LatestLinksManager.cs
@@ -22,12 +22,6 @@ public class LatestLinksManager
private string _akaMSCreatedBy { get; }
private string _akaMSGroupOwner { get; }
- private static Dictionary AccountsWithCdns { get; } = new()
- {
- {"dotnetcli.blob.core.windows.net", "builds.dotnet.microsoft.com" },
- {"dotnetbuilds.blob.core.windows.net", "ci.dot.net" }
- };
-
public LatestLinksManager(
string akaMSClientId,
X509Certificate2 certificate,
@@ -106,14 +100,6 @@ public static string ComputeLatestLinkBase(TargetFeedConfig feedConfig)
{
feedBaseUrl += "/";
}
- var authority = new Uri(feedBaseUrl).Authority;
- if (AccountsWithCdns.TryGetValue(authority, out var replacementAuthority))
- {
- // The storage accounts are in a single datacenter in the US and thus download
- // times can be painful elsewhere. The CDN helps with this therefore we point the target
- // of the aka.ms links to the CDN.
- feedBaseUrl = feedBaseUrl.Replace(authority, replacementAuthority);
- }
return feedBaseUrl;
}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/PublishingConstants.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/PublishingConstants.cs
index 7811173aead4..b6c2fce2d68f 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/PublishingConstants.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/PublishingConstants.cs
@@ -13,13 +13,24 @@ public class PublishingConstants
{
public static readonly string ExpectedFeedUrlSuffix = "index.json";
+ ///
+ /// Mapping of Azure storage accounts to their corresponding CDN URLs.
+ /// Used to replace blob storage URLs with CDN URLs for both aka.ms links and asset locations.
+ ///
+ public static readonly Dictionary AccountsWithCdns = new()
+ {
+ {"dotnetcli.blob.core.windows.net", "builds.dotnet.microsoft.com" },
+ {"dotnetbuilds.blob.core.windows.net", "ci.dot.net" }
+ };
+
// Matches package feeds like
// https://pkgs.dev.azure.com/dnceng/public/_packaging/public-feed-name/nuget/v3/index.json
// or https://pkgs.dev.azure.com/dnceng/_packaging/internal-feed-name/nuget/v3/index.json
public static readonly string AzDoNuGetFeedPattern =
@"https://pkgs.dev.azure.com/(?[a-zA-Z0-9-]+)/(?[a-zA-Z0-9-]+/)?_packaging/(?.+)/nuget/v3/index.json";
- public static readonly TargetFeedContentType[] InstallersAndSymbols = {
+ public static readonly TargetFeedContentType[] InstallersAndSymbols =
+ [
TargetFeedContentType.OSX,
TargetFeedContentType.Deb,
TargetFeedContentType.Rpm,
@@ -31,9 +42,10 @@ public class PublishingConstants
TargetFeedContentType.Badge,
TargetFeedContentType.Symbols,
TargetFeedContentType.Other
- };
+ ];
- public static readonly TargetFeedContentType[] InstallersAndChecksums = {
+ public static readonly TargetFeedContentType[] InstallersAndChecksums =
+ [
TargetFeedContentType.OSX,
TargetFeedContentType.Deb,
TargetFeedContentType.Rpm,
@@ -45,15 +57,16 @@ public class PublishingConstants
TargetFeedContentType.Badge,
TargetFeedContentType.Checksum,
TargetFeedContentType.Other
- };
+ ];
- public static readonly TargetFeedContentType[] Packages = {
+ public static readonly TargetFeedContentType[] Packages =
+ [
TargetFeedContentType.Package,
TargetFeedContentType.CorePackage,
TargetFeedContentType.ToolingPackage,
TargetFeedContentType.InfrastructurePackage,
TargetFeedContentType.LibraryPackage,
- };
+ ];
public enum BuildQuality
{
@@ -80,7 +93,10 @@ public enum BuildQuality
public const string FeedStagingInternalForInstallers = "https://dotnetbuilds.blob.core.windows.net/internal";
public const string FeedStagingInternalForChecksums = "https://dotnetbuilds.blob.core.windows.net/internal-checksums";
- private const string FeedGeneralTesting = "https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json";
+ public const string FeedDevForInstallers = "https://dotnetbuilds.blob.core.windows.net/dev";
+ public const string FeedDevInternalForInstallers = "https://dotnetbuilds.blob.core.windows.net/dev-internal";
+
+ private const string FeedDev = "https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json";
private const string FeedDotNetExperimental = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json";
@@ -88,6 +104,8 @@ public enum BuildQuality
public const string FeedDotNetEng = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json";
+ private const string FeedDotNetEngInternal = "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-eng-internal/nuget/v3/index.json";
+
private const string FeedDotNetTools = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json";
private const string FeedDotNetToolsInternal = "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/v3/index.json";
@@ -125,6 +143,10 @@ public enum BuildQuality
private const string FeedDotNet10InternalShipping = "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet10-internal/nuget/v3/index.json";
private const string FeedDotNet10InternalTransport = "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet10-internal-transport/nuget/v3/index.json";
+ private const string FeedDotNet11Shipping = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json";
+ private const string FeedDotNet11Transport = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11-transport/nuget/v3/index.json";
+ private const string FeedDotNet11Workloads = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11-workloads/nuget/v3/index.json";
+
private const string FeedDotNetLibrariesShipping = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json";
private const string FeedDotNetLibrariesTransport = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries-transport/nuget/v3/index.json";
@@ -149,22 +171,6 @@ public enum BuildQuality
(TargetFeedContentType.Checksum, FeedStagingInternalForChecksums),
};
- private static TargetFeedSpecification[] DotNet7Feeds =
- {
- (Packages, FeedDotNet7Shipping, AssetSelection.ShippingOnly),
- (Packages, FeedDotNet7Transport, AssetSelection.NonShippingOnly),
- (InstallersAndSymbols, FeedStagingForInstallers),
- (TargetFeedContentType.Checksum, FeedStagingForChecksums),
- };
-
- private static TargetFeedSpecification[] DotNet7InternalFeeds =
- {
- (Packages, FeedDotNet7InternalShipping, AssetSelection.ShippingOnly),
- (Packages, FeedDotNet7InternalTransport, AssetSelection.NonShippingOnly),
- (InstallersAndSymbols, FeedStagingInternalForInstallers),
- (TargetFeedContentType.Checksum, FeedStagingInternalForChecksums),
- };
-
private static TargetFeedSpecification[] DotNet8Feeds =
{
(Packages, FeedDotNet8Shipping, AssetSelection.ShippingOnly),
@@ -231,8 +237,16 @@ public enum BuildQuality
private static TargetFeedSpecification[] DotNet10InternalFeeds =
{
- (Packages, FeedDotNet10InternalShipping, AssetSelection.ShippingOnly),
- (Packages, FeedDotNet10InternalTransport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.Package, FeedDotNet10InternalShipping, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.Package, FeedDotNet10InternalTransport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.InfrastructurePackage, FeedDotNetEngInternal, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.InfrastructurePackage, FeedDotNetEngInternal, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.CorePackage, FeedDotNet10InternalShipping, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.CorePackage, FeedDotNet10InternalTransport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.LibraryPackage, FeedDotNetLibrariesInternalShipping, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.LibraryPackage, FeedDotNetLibrariesInternalTransport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.ToolingPackage, FeedDotNetToolsInternal, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.ToolingPackage, FeedDotNetToolsInternal, AssetSelection.NonShippingOnly),
(InstallersAndSymbols, FeedStagingInternalForInstallers),
(TargetFeedContentType.Checksum, FeedStagingInternalForChecksums),
};
@@ -245,6 +259,30 @@ public enum BuildQuality
(TargetFeedContentType.Checksum, FeedStagingForChecksums),
};
+ private static TargetFeedSpecification[] DotNet11Feeds =
+ {
+ (TargetFeedContentType.Package, FeedDotNet11Shipping, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.Package, FeedDotNet11Transport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.InfrastructurePackage, FeedDotNetEng, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.InfrastructurePackage, FeedDotNetEng, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.CorePackage, FeedDotNet11Shipping, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.CorePackage, FeedDotNet11Transport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.LibraryPackage, FeedDotNetLibrariesShipping, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.LibraryPackage, FeedDotNetLibrariesTransport, AssetSelection.NonShippingOnly),
+ (TargetFeedContentType.ToolingPackage, FeedDotNetTools, AssetSelection.ShippingOnly),
+ (TargetFeedContentType.ToolingPackage, FeedDotNetTools, AssetSelection.NonShippingOnly),
+ (InstallersAndSymbols, FeedStagingForInstallers),
+ (TargetFeedContentType.Checksum, FeedStagingForChecksums),
+ };
+
+ private static TargetFeedSpecification[] DotNet11WorkloadFeeds =
+ {
+ (Packages, FeedDotNet11Workloads, AssetSelection.ShippingOnly),
+ (Packages, FeedDotNet11Workloads, AssetSelection.NonShippingOnly),
+ (InstallersAndSymbols, FeedStagingForInstallers),
+ (TargetFeedContentType.Checksum, FeedStagingForChecksums),
+ };
+
private static TargetFeedSpecification[] DotNetEngFeeds =
{
(Packages, FeedDotNetEng, AssetSelection.ShippingOnly),
@@ -303,22 +341,23 @@ public enum BuildQuality
private static TargetFeedSpecification[] GeneralTestingFeeds =
{
- (Packages, FeedGeneralTesting, AssetSelection.ShippingOnly),
- (Packages, FeedGeneralTesting, AssetSelection.NonShippingOnly),
- (InstallersAndSymbols, FeedStagingForInstallers),
- (TargetFeedContentType.Checksum, FeedStagingForChecksums),
+ (Packages, FeedDev, AssetSelection.ShippingOnly),
+ (Packages, FeedDev, AssetSelection.NonShippingOnly),
+ (InstallersAndSymbols, FeedDevForInstallers),
+ (TargetFeedContentType.Checksum, FeedDevForInstallers),
};
private static TargetFeedSpecification[] GeneralTestingInternalFeeds =
{
(Packages, FeedGeneralTestingInternal, AssetSelection.ShippingOnly),
(Packages, FeedGeneralTestingInternal, AssetSelection.NonShippingOnly),
- (InstallersAndSymbols, FeedStagingInternalForInstallers),
- (TargetFeedContentType.Checksum, FeedStagingInternalForChecksums),
+ (InstallersAndSymbols, FeedDevInternalForInstallers),
+ (TargetFeedContentType.Checksum, FeedDevInternalForInstallers),
};
#endregion
- public static readonly ImmutableList DefaultAkaMSCreateLinkPatterns = [
+ public static readonly ImmutableList DefaultAkaMSCreateLinkPatterns =
+ [
new Regex(@"\.rpm(\.sha512)?$", RegexOptions.IgnoreCase),
new Regex(@"\.zip(\.sha512)?$", RegexOptions.IgnoreCase),
new Regex(@"\.version(\.sha512)?$", RegexOptions.IgnoreCase),
@@ -335,17 +374,18 @@ public enum BuildQuality
new Regex(@"productversion", RegexOptions.IgnoreCase)
];
- public static readonly ImmutableList DefaultAkaMSDoNotCreateLinkPatterns = [
+ public static readonly ImmutableList DefaultAkaMSDoNotCreateLinkPatterns =
+ [
new Regex(@"wixpack", RegexOptions.IgnoreCase),
];
- private static readonly ImmutableList DotNet10AkaMSDoNotCreateLinkPatterns = [
+ private static readonly ImmutableList UnifiedBuildAkaMSDoNotCreateLinkPatterns =
+ [
..DefaultAkaMSDoNotCreateLinkPatterns,
new Regex(@"productversion", RegexOptions.IgnoreCase)
];
- #region Target Channel Configs
- public static readonly List ChannelInfos = new List() {
+ public static readonly List ChannelInfos = [
// How TO: Adding publishing for a new channel:
// 1. If not already complete, add desired using `darc add-channel`. Please using follow naming conventions from
@@ -366,6 +406,8 @@ public enum BuildQuality
// - symbolTargetType: List of symbol targets. Internal channels should use SymbolPublishVisibility.Internal and public channels should use SymbolPublishVisibility.Public
// - filenamesToExclude: Usually left as FilenamesToExclude.
+ #region .NET 6 Channels
+
// .NET 6,
new TargetChannelConfig(
id: 1296,
@@ -521,6 +563,10 @@ public enum BuildQuality
targetFeeds: DotNet6InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ #endregion
+
+ #region .NET 8 Channels
+
// .NET 8,
new TargetChannelConfig(
id: 3073,
@@ -588,6 +634,17 @@ public enum BuildQuality
targetFeeds: DotNet8InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 8 HotFix Internal,
+ new TargetChannelConfig(
+ id: 8624,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/8.0-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet8InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
// .NET 8.0.1xx SDK,
new TargetChannelConfig(
id: 3074,
@@ -610,6 +667,17 @@ public enum BuildQuality
targetFeeds: DotNet8InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 8.0.1xx SDK HotFix Internal,
+ new TargetChannelConfig(
+ id: 8625,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/8.0.1xx-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet8InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
// .NET 8.0.2xx SDK,
new TargetChannelConfig(
id: 4036,
@@ -654,6 +722,17 @@ public enum BuildQuality
targetFeeds: DotNet8InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 8.0.3xx SDK HotFix Internal,
+ new TargetChannelConfig(
+ id: 8627,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/8.0.3xx-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet8InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
// .NET 8.0.4xx SDK,
new TargetChannelConfig(
id: 4586,
@@ -676,6 +755,21 @@ public enum BuildQuality
targetFeeds: DotNet8InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 8.0.4xx SDK HotFix Internal,
+ new TargetChannelConfig(
+ id: 8628,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/8.0.4xx-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet8InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
+ #endregion
+
+ #region .NET 9 Channels
+
// .NET 9,
new TargetChannelConfig(
id: 3883,
@@ -732,6 +826,17 @@ public enum BuildQuality
targetFeeds: DotNet9InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 9 HotFix Internal,
+ new TargetChannelConfig(
+ id: 8629,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/9.0-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet9InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
// .NET 9 Workload Release,
new TargetChannelConfig(
id: 4611,
@@ -765,6 +870,17 @@ public enum BuildQuality
targetFeeds: DotNet9InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 9.0.1xx SDK HotFix Internal,
+ new TargetChannelConfig(
+ id: 8630,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/9.0.1xx-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet9InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
// .NET 9.0.2xx SDK,
new TargetChannelConfig(
id: 5286,
@@ -809,6 +925,21 @@ public enum BuildQuality
targetFeeds: DotNet9InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
+ // .NET 9.0.3xx SDK HotFix Internal,
+ new TargetChannelConfig(
+ id: 8632,
+ isInternal: true,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: ["internal/9.0.3xx-hotfix"],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet9InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
+
+ #endregion
+
+ #region .NET 10 Channels
+
// .NET 10,
new TargetChannelConfig(
id: 5172,
@@ -816,183 +947,173 @@ public enum BuildQuality
publishingInfraVersion: PublishingInfraVersion.Latest,
akaMSChannelNames: ["10.0"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 Workload Release,
+ // .NET 10 Internal,
new TargetChannelConfig(
- id: 5174,
- isInternal: false,
+ id: 5177,
+ isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: [ "10.0-workloads" ],
+ akaMSChannelNames: ["internal/10.0"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10WorkloadFeeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet10InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10.0.1xx SDK,
+ // .NET 10 Private,
new TargetChannelConfig(
- id: 5173,
- isInternal: false,
+ id: 8710,
+ isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: [ "10.0.1xx", "10.0" ],
+ akaMSChannelNames: ["internal/10.0-private"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet10InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10 UB,
+ // .NET 10 Eng,
new TargetChannelConfig(
- id: 5708,
+ id: 8394,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-ub", "10.0-ub"],
+ akaMSChannelNames: ["eng/net10"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetEngFeeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 Preview 1,
+ // .NET 10 Eng - Validation,
new TargetChannelConfig(
- id: 6545,
+ id: 8395,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview1"],
+ akaMSChannelNames: ["eng/net10validation"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetEngFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
- // .NET 10 Preview 2,
+ // .NET 10 Workload Release,
new TargetChannelConfig(
- id: 6547,
+ id: 5174,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview2"],
+ akaMSChannelNames: [ "10.0-workloads" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet10WorkloadFeeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 Preview 3,
+ // .NET 10.0.1xx SDK,
new TargetChannelConfig(
- id: 6549,
+ id: 5173,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview3"],
+ akaMSChannelNames: [ "10.0.1xx", "10.0" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 Preview 4,
+ // .NET 10.0.1xx SDK Release,
new TargetChannelConfig(
- id: 6551,
+ id: 8859,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview4"],
+ akaMSChannelNames: [ "10.0.1xx-release", "10.0-release" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 Preview 5,
+ // .NET 10.0.1xx SDK Internal,
new TargetChannelConfig(
- id: 6553,
- isInternal: false,
+ id: 5178,
+ isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview5"],
+ akaMSChannelNames: ["internal/10.0.1xx", "internal/10.0"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet10InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10 Preview 6,
+ // .NET 10.0.1xx SDK Release Internal,
new TargetChannelConfig(
- id: 6555,
- isInternal: false,
+ id: 8858,
+ isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview6"],
+ akaMSChannelNames: ["internal/10.0.1xx-release", "internal/10.0-release"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet10InternalFeeds,
+ symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10 Preview 7,
+ // .NET 10.0.2xx SDK,
new TargetChannelConfig(
- id: 6557,
+ id: 8856,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-preview7"],
+ akaMSChannelNames: [ "10.0.2xx", "10.0" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 RC 1,
+ // .NET 10.0.2xx SDK Release,
new TargetChannelConfig(
- id: 6494,
+ id: 8860,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-rc1"],
+ akaMSChannelNames: [ "10.0.2xx-release" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10 RC 1 Internal,
+ // .NET 10.0.2xx SDK Internal,
new TargetChannelConfig(
- id: 6496,
+ id: 8857,
isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["internal/10.0-rc1"],
+ akaMSChannelNames: ["internal/10.0.2xx"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10 RC 2,
+ // .NET 10.0.2xx SDK Internal,
new TargetChannelConfig(
- id: 6498,
- isInternal: false,
- publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0-rc2"],
- akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
-
- // .NET 10 RC 2 Internal,
- new TargetChannelConfig(
- id: 6500,
+ id: 8861,
isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["internal/10.0-rc2"],
+ akaMSChannelNames: ["internal/10.0.2xx-release"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10.0.1xx RC 1,
+ // .NET 10 RC 2,
new TargetChannelConfig(
- id: 6573,
+ id: 6498,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-rc1"],
+ akaMSChannelNames: ["10.0-rc2"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10.0.1xx RC 1 Internal,
+ // .NET 10 RC 2 Internal,
new TargetChannelConfig(
- id: 6575,
+ id: 6500,
isInternal: true,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["internal/10.0.1xx-rc1"],
+ akaMSChannelNames: ["internal/10.0-rc2"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
@@ -1003,7 +1124,7 @@ public enum BuildQuality
publishingInfraVersion: PublishingInfraVersion.Latest,
akaMSChannelNames: ["10.0.1xx-rc2"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
@@ -1014,86 +1135,50 @@ public enum BuildQuality
publishingInfraVersion: PublishingInfraVersion.Latest,
akaMSChannelNames: ["internal/10.0.1xx-rc2"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
targetFeeds: DotNet10InternalFeeds,
symbolTargetType: SymbolPublishVisibility.Internal),
- // .NET 10.0.1xx SDK Preview 1,
- new TargetChannelConfig(
- id: 6476,
- isInternal: false,
- publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview1"],
- akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ #endregion
- // .NET 10.0.1xx SDK Preview 2,
- new TargetChannelConfig(
- id: 6478,
- isInternal: false,
- publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview2"],
- akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ #region .NET 11 Channels
- // .NET 10.0.1xx SDK Preview 3,
+ // .NET 11,
new TargetChannelConfig(
- id: 6484,
+ id: 8297,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview3"],
+ akaMSChannelNames: ["11.0"],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet11Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10.0.1xx SDK Preview 4,
+ // .NET 11 Workload Release,
new TargetChannelConfig(
- id: 6486,
+ id: 8299,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview4"],
+ akaMSChannelNames: [ "11.0-workloads" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet11WorkloadFeeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10.0.1xx SDK Preview 5,
+ // .NET 11.0.1xx SDK,
new TargetChannelConfig(
- id: 6488,
+ id: 8298,
isInternal: false,
publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview5"],
+ akaMSChannelNames: [ "11.0.1xx", "11.0" ],
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
+ akaMSDoNotCreateLinkPatterns: UnifiedBuildAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNet11Feeds,
symbolTargetType: SymbolPublishVisibility.Public),
- // .NET 10.0.1xx SDK Preview 6,
- new TargetChannelConfig(
- id: 6490,
- isInternal: false,
- publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview6"],
- akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ #endregion
- // .NET 10.0.1xx SDK Preview 7,
- new TargetChannelConfig(
- id: 6492,
- isInternal: false,
- publishingInfraVersion: PublishingInfraVersion.Latest,
- akaMSChannelNames: ["10.0.1xx-preview7"],
- akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
- akaMSDoNotCreateLinkPatterns: DotNet10AkaMSDoNotCreateLinkPatterns,
- targetFeeds: DotNet10Feeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ #region Other .NET Channels
// .NET Core Experimental,
new TargetChannelConfig(
@@ -1305,7 +1390,8 @@ public enum BuildQuality
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
targetFeeds: GeneralTestingFeeds,
- symbolTargetType: SymbolPublishVisibility.Public),
+ symbolTargetType: SymbolPublishVisibility.Public,
+ isProduction: false),
// General Testing Internal,
new TargetChannelConfig(
@@ -1316,7 +1402,12 @@ public enum BuildQuality
akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
targetFeeds: GeneralTestingInternalFeeds,
- symbolTargetType: SymbolPublishVisibility.Internal),
+ symbolTargetType: SymbolPublishVisibility.Internal,
+ isProduction: false),
+
+ #endregion
+
+ #region VS Channels
// VS 16.6,
new TargetChannelConfig(
@@ -1473,6 +1564,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.7,
new TargetChannelConfig(
id: 3581,
@@ -1484,6 +1576,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.8,
new TargetChannelConfig(
id: 3582,
@@ -1495,6 +1588,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.9,
new TargetChannelConfig(
id: 4015,
@@ -1506,6 +1600,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.10
new TargetChannelConfig(
id: 4165,
@@ -1517,6 +1612,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.11
new TargetChannelConfig(
id: 4544,
@@ -1528,6 +1624,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.12
new TargetChannelConfig(
id: 4906,
@@ -1539,6 +1636,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.13
new TargetChannelConfig(
id: 5288,
@@ -1550,6 +1648,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.14
new TargetChannelConfig(
id: 6136,
@@ -1561,6 +1660,7 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
+
// VS 17.15
new TargetChannelConfig(
id: 6989,
@@ -1583,7 +1683,79 @@ public enum BuildQuality
targetFeeds: DotNetToolsFeeds,
symbolTargetType: SymbolPublishVisibility.Public,
flatten: false),
- };
- #endregion
+
+ // 18.1
+ new TargetChannelConfig(
+ id: 8703,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: [],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetToolsFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
+
+ // 18.2
+ new TargetChannelConfig(
+ id: 8704,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: [],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetToolsFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
+
+ // 18.3
+ new TargetChannelConfig(
+ id: 8705,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: [],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetToolsFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
+
+ // 18.4
+ new TargetChannelConfig(
+ id: 8706,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: [],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetToolsFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
+
+ // 18.5
+ new TargetChannelConfig(
+ id: 8707,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: [],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetToolsFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
+
+ // 18.6
+ new TargetChannelConfig(
+ id: 8708,
+ isInternal: false,
+ publishingInfraVersion: PublishingInfraVersion.Latest,
+ akaMSChannelNames: [],
+ akaMSCreateLinkPatterns: DefaultAkaMSCreateLinkPatterns,
+ akaMSDoNotCreateLinkPatterns: DefaultAkaMSDoNotCreateLinkPatterns,
+ targetFeeds: DotNetToolsFeeds,
+ symbolTargetType: SymbolPublishVisibility.Public,
+ flatten: false),
+ #endregion
+ ];
}
}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetChannelConfig.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetChannelConfig.cs
index 2942b8e1aff3..239261e471d2 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetChannelConfig.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetChannelConfig.cs
@@ -47,6 +47,12 @@ public struct TargetChannelConfig
public bool IsInternal { get; }
+ ///
+ /// Whether this channel is a production channel vs. a non-production channel.
+ /// Non-production channels are typically used for testing purposes.
+ ///
+ public bool IsProduction { get; }
+
public bool Flatten { get; }
public TargetChannelConfig(
@@ -58,7 +64,8 @@ public TargetChannelConfig(
ImmutableList akaMSDoNotCreateLinkPatterns,
IEnumerable targetFeeds,
SymbolPublishVisibility symbolTargetType,
- bool flatten = true)
+ bool flatten = true,
+ bool isProduction = true)
{
Id = id;
@@ -68,6 +75,7 @@ public TargetChannelConfig(
TargetFeeds = targetFeeds.ToImmutableList();
SymbolTargetType = symbolTargetType;
Flatten = flatten;
+ IsProduction = isProduction;
AkaMSCreateLinkPatterns = akaMSCreateLinkPatterns ?? ImmutableList.Empty;
AkaMSDoNotCreateLinkPatterns = akaMSDoNotCreateLinkPatterns ?? ImmutableList.Empty;
}
@@ -84,6 +92,7 @@ public override string ToString()
$"\n {string.Join("\n ", TargetFeeds.Select(f => $"{string.Join(", ", f.ContentTypes)} -> {f.FeedUrl}"))}" +
$"\n SymbolTargetType: '{SymbolTargetType}' " +
$"\n IsInternal: '{IsInternal}'" +
+ $"\n IsProduction: '{IsProduction}'" +
$"\n Flatten: '{Flatten}'";
}
@@ -97,6 +106,7 @@ public override bool Equals(object other)
PublishingInfraVersion == config.PublishingInfraVersion &&
Id == config.Id &&
IsInternal == config.IsInternal &&
+ IsProduction == config.IsProduction &&
Flatten == config.Flatten)
{
return true;
@@ -129,6 +139,7 @@ public override int GetHashCode()
hash.Add(PublishingInfraVersion);
hash.Add(Id);
hash.Add(IsInternal);
+ hash.Add(IsProduction);
foreach(var akaMSChannelName in AkaMSChannelNames)
{
hash.Add(akaMSChannelName);
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetFeedConfig.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetFeedConfig.cs
index b2f25c8fb4f2..fe3220c37395 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetFeedConfig.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Feed/src/model/TargetFeedConfig.cs
@@ -16,9 +16,25 @@ namespace Microsoft.DotNet.Build.Tasks.Feed.Model
public class TargetFeedConfig
{
///
- /// Returns the TargetURL stripped of SAS token so it can be used for logging purposes.
+ /// Returns the TargetURL stripped of SAS token and with CDN substitution applied
+ /// for known blob storage accounts. This is used for both logging purposes and
+ /// for storing asset locations in BAR that point to publicly accessible CDN URLs.
///
- public string SafeTargetURL => new UriBuilder(TargetURL) {Query = "", Fragment = ""}.Uri.AbsoluteUri;
+ public string SafeTargetURL
+ {
+ get
+ {
+ var uriBuilder = new UriBuilder(TargetURL) { Query = "", Fragment = "" };
+
+ // Apply CDN substitution for known storage accounts
+ if (PublishingConstants.AccountsWithCdns.TryGetValue(uriBuilder.Host, out var replacementHost))
+ {
+ uriBuilder.Host = replacementHost;
+ }
+
+ return uriBuilder.Uri.AbsoluteUri;
+ }
+ }
public TargetFeedContentType ContentType { get; }
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj
deleted file mode 100644
index c283a08255ed..000000000000
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/acquisition/acquire-nuget-exe/acquire-nuget-exe.proj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
- https://dist.nuget.org/win-x86-commandline/v3.5.0/nuget.exe
- $(BaseIntermediateOutputPath)nuget\
- $(NuGetExeToolDir)NuGet.exe
-
-
-
-
-
-
-
-
-
-
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets
index 7c6d934178df..b88ff9497152 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/bundle.targets
@@ -14,7 +14,8 @@
-
+
+
@@ -95,6 +96,29 @@
+
+
+ <_BundledComponentsPackageGroupWxsPath>$(IntermediateOutputPath)dotnetPackageGroup.wxs
+
+
+
+
+
+
+ @(_BundledComponents->'', '
+ ')
+
+
+
+]]>
+
+
+
+
-
- true
-
- false
-
-
-
- <_AzureLinuxVersionSuffix>azl
- <_InstallerBuildPartAzureLinux>$(Version)-$(_AzureLinuxVersionSuffix)-$(_InstallerArchSuffix)
- <_InstallerFileNameWithoutExtensionAzureLinux>$(InstallerName)-$(_InstallerBuildPartAzureLinux)$(CrossArchContentsBuildPart)
- <_InstallerFileAzureLinux>$(PackageOutputPath)$(_InstallerFileNameWithoutExtensionAzureLinux)$(InstallerExtension)
-
@@ -344,10 +325,24 @@
+
+ Condition="'$(PackageTargetOS)' == ''">
+
+ <_AzureLinuxVersionSuffix>azl
+ <_InstallerBuildPartAzureLinux>$(Version)-$(_AzureLinuxVersionSuffix)-$(_InstallerArchSuffix)
+ <_InstallerFileNameWithoutExtensionAzureLinux>$(InstallerName)-$(_InstallerBuildPartAzureLinux)$(CrossArchContentsBuildPart)
+ <_InstallerFileAzureLinux>$(PackageOutputPath)$(_InstallerFileNameWithoutExtensionAzureLinux)$(InstallerExtension)
+
+
+
+
+ <_NewKeyVersionSuffix>newkey
+ <_InstallerBuildPartNewKey>$(Version)-$(_NewKeyVersionSuffix)-$(_InstallerArchSuffix)
+ <_InstallerBuildPartNewKey Condition="'$(PackageTargetOS)' != ''">$(Version)-$(PackageTargetOS)-$(_NewKeyVersionSuffix)-$(_InstallerArchSuffix)
+ <_InstallerFileNameWithoutExtensionNewKey>$(InstallerName)-$(_InstallerBuildPartNewKey)$(CrossArchContentsBuildPart)
+ <_InstallerFileNewKey>$(PackageOutputPath)$(_InstallerFileNameWithoutExtensionNewKey)$(InstallerExtension)
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/DotNetLogo_256x.png b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/DotNetLogo_256x.png
new file mode 100644
index 000000000000..3ff052f8302a
Binary files /dev/null and b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/DotNetLogo_256x.png differ
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/dotnet.ico b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/dotnet.ico
new file mode 100644
index 000000000000..16c9148e8609
Binary files /dev/null and b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/resources/dotnet.ico differ
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/wix.targets b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/wix.targets
index b5006eb81308..08f5414e8969 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/wix.targets
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix/wix.targets
@@ -452,24 +452,10 @@
ComponentMsiFile=$(CrossArchMsiFile)" />
-
-
-
-
-
-
-
@@ -480,25 +466,12 @@
$(MSBuildThisFileDirectory)vs\VS.Redist.Common.Component.nuspec.txt
$(IntermediateOutputPath)vs\VS.Redist.Common.Component.nuspec
-
- $(PackProperties)COMPONENT_MSI=$(ComponentMsiFile);
- $(PackProperties)ARCH=$(MsiArch);
- $(PackProperties)COMPONENT_NAME=$(VSInsertionComponentName);
- $(PackProperties)FRIENDLY_NAME=$(ProductBrandName);
- $(PackProperties)PROJECT_URL=$(RepositoryUrl);
-
-
- $(PackArgs) $(VsInsertionNuspecFile)
- $(PackArgs) -Version $(Version)
- $(PackArgs) -OutputDirectory $(ArtifactsNonShippingPackagesDir)
- $(PackArgs) -NoDefaultExcludes
- $(PackArgs) -NoPackageAnalysis
- $(PackArgs) -Properties "$(PackProperties)"
+ COMPONENT_MSI=$(ComponentMsiFile);ARCH=$(MsiArch);COMPONENT_NAME=$(VSInsertionComponentName);FRIENDLY_NAME=$(ProductBrandName);PROJECT_URL=$(RepositoryUrl)
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/bundle/dummyEula.rtf b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/bundle/dummyEula.rtf
new file mode 100644
index 000000000000..ebcd5ac373f4
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/bundle/dummyEula.rtf
@@ -0,0 +1,237 @@
+{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}
+{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}
+{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f376\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f377\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\f379\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f380\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f381\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f382\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\f383\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f384\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f376\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f377\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\f379\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f380\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f381\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f382\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\f383\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f384\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f746\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f747\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}
+{\f749\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f750\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f751\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f752\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}
+{\f753\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f754\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
+{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
+{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
+{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}
+{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}
+{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
+{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
+{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
+{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
+{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
+{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}
+{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
+{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
+{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
+{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
+{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
+\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025
+\ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused
+Normal Table;}{\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \slink16 \sunhideused \styrsid10564401 header;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0
+\sbasedon10 \slink15 \slocked \styrsid10564401 Header Char;}{\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 \slink18 \sunhideused \styrsid10564401 footer;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0
+\sbasedon10 \slink17 \slocked \styrsid10564401 Footer Char;}}{\*\rsidtbl \rsid2163051\rsid10564401}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim0}{\info
+{\operator Rakesh Ranjan Singh}{\creatim\yr2017\mo5\dy30\hr17\min38}{\revtim\yr2017\mo5\dy30\hr17\min39}{\version2}{\edmins1}{\nofpages1}{\nofwords28}{\nofchars160}{\nofcharsws187}{\vern37}}{\*\userprops {\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85
+995028c_Enabled}\proptype30{\staticval True}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId}\proptype30{\staticval 72f988bf-86f1-41af-91ab-2d7cd011db47}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Ref}\proptype30
+{\staticval https://api.informationprotection.azure.com/api/72f988bf-86f1-41af-91ab-2d7cd011db47}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetBy}\proptype30{\staticval raksingh@microsoft.com}{\propname MSIP_Label_f42aa342-8706-4288-bd11-e
+bb85995028c_SetDate}\proptype30{\staticval 2017-05-30T17:39:57.6592568-07:00}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name}\proptype30{\staticval General}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Application}\proptype30
+{\staticval Microsoft Azure Information Protection}{\propname MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Extended_MSFT_Method}\proptype30{\staticval Automatic}{\propname Sensitivity}\proptype30{\staticval General}}{\*\xmlnstbl {\xmlns1 http://schemas
+.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect
+\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701
+\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot10564401 \nouicompat \fet0{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar
+\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {
+\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsep
+\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsepc
+\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsep
+\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051 \chftnsepc
+\par }}\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\headerl \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401
+\par }}{\headerr \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401
+\par }}{\footerl \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401
+\par }}{\footerr \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401
+\par }}{\headerf \ltrpar \pard\plain \ltrpar\s15\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401
+\par }}{\footerf \ltrpar \pard\plain \ltrpar\s17\ql \li0\ri0\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0
+\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid10564401
+\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}
+{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8
+\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa160\sl259\slmult1
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10564401 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1
+\af31507 \ltrch\fcs0 \insrsid10564401 \hich\af31506\dbch\af31505\loch\f31506 This is a dummy file for Eula as required by \hich\af31506\dbch\af31505\loch\f31506 B\hich\af31506\dbch\af31505\loch\f31506 urn bundle \hich\af31506\dbch\af31505\loch\f31506
+. The bal.WixStandardBootstrapperApplication element must hav a value for exactly one of the LicenseFile or LicenseUrl attributes.}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2163051\charrsid10564401
+\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
+9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
+5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
+b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0
+0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6
+a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f
+c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512
+0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462
+a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865
+6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b
+4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b
+4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100b6f4679893070000c9200000160000007468656d652f7468656d652f
+7468656d65312e786d6cec59cd8b1bc915bf07f23f347d97f5d5ad8fc1f2a24fcfda33b6b164873dd648a5eef2547789aad28cc56208de532e81c026e49085bd
+ed21842cecc22eb9e48f31d8249b3f22afaa5bdd5552c99e191c3061463074977eefd5afde7bf5de53d5ddcf5e26d4bbc05c1096f6fcfa9d9aefe174ce16248d
+7afeb3d9a4d2f13d2151ba4094a5b8e76fb0f03fbbf7eb5fdd454732c609f6403e1547a8e7c752ae8eaa5531876124eeb0154ee1bb25e30992f0caa3ea82a34b
+d09bd06aa3566b55134452df4b51026a1f2f97648ebd9952e9dfdb2a1f53784da5500373caa74a35b6243476715e5708b11143cabd0b447b3eccb3609733fc52
+fa1e4542c2173dbfa6fffceabdbb5574940b517940d6909be8bf5c2e17589c37f49c3c3a2b260d823068f50bfd1a40e53e6edc1eb7c6ad429f06a0f91c569a71
+b175b61bc320c71aa0ecd1a17bd41e35eb16ded0dfdce3dc0fd5c7c26b50a63fd8c34f2643b0a285d7a00c1feee1c3417730b2f56b50866fede1dbb5fe28685b
+fa3528a6243ddf43d7c25673b85d6d0159327aec8477c360d26ee4ca4b144443115d6a8a254be5a1584bd00bc6270050408a24493db959e1259a43140f112567
+9c7827248a21f056286502866b8ddaa4d684ffea13e827ed5174849121ad780113b137a4f87862cec94af6fc07a0d537206f7ffef9cdeb1fdfbcfee9cd575fbd
+79fdf77c6eadca923b466964cafdf2dd1ffef3cd6fbd7ffff0ed2f5fff319b7a172f4cfcbbbffdeedd3ffef93ef5b0e2d2146ffff4fdbb1fbf7ffbe7dfffebaf
+5f3bb4f7393a33e1339260e13dc297de5396c0021dfcf119bf9ec42c46c494e8a791402952b338f48f656ca11f6d10450edc00db767cce21d5b880f7d72f2cc2
+d398af2571687c182716f094313a60dc6985876a2ec3ccb3751ab927e76b13f714a10bd7dc43945a5e1eaf579063894be530c616cd2714a5124538c5d253dfb1
+738c1dabfb8210cbaea764ce99604be97d41bc01224e93ccc899154da5d03149c02f1b1741f0b7659bd3e7de8051d7aa47f8c246c2de40d4417e86a965c6fb68
+2d51e252394309350d7e8264ec2239ddf0b9891b0b099e8e3065de78818570c93ce6b05ec3e90f21cdb8dd7e4a37898de4929cbb749e20c64ce4889d0f6394ac
+5cd829496313fbb938871045de13265df05366ef10f50e7e40e941773f27d872f787b3c133c8b026a53240d4376beef0e57dccacf89d6ee8126157aae9f3c44a
+b17d4e9cd131584756689f604cd1255a60ec3dfbdcc160c05696cd4bd20f62c82ac7d815580f901dabea3dc5027a25d5dcece7c91322ac909de2881de073bad9
+493c1b9426881fd2fc08bc6eda7c0ca52e7105c0633a3f37818f08f480102f4ea33c16a0c308ee835a9fc4c82a60ea5db8e375c32dff5d658fc1be7c61d1b8c2
+be04197c6d1948eca6cc7b6d3343d49aa00c9819822ec3956e41c4727f29a28aab165b3be596f6a62ddd00dd91d5f42424fd6007b4d3fb84ffbbde073a8cb77f
+f9c6b10f3e4ebfe3566c25ab6b763a8792c9f14e7f7308b7dbd50c195f904fbfa919a175fa04431dd9cf58b73dcd6d4fe3ffdff73487f6f36d2773a8dfb8ed64
+7ce8306e3b99fc70e5e3743265f3027d8d3af0c80e7af4b14f72f0d46749289dca0dc527421ffc08f83db398c0a092d3279eb838055cc5f0a8ca1c4c60e1228e
+b48cc799fc0d91f134462b381daafb4a492472d591f0564cc0a1911e76ea5678ba4e4ed9223becacd7d5c16656590592e5782d2cc6e1a04a66e856bb3cc02bd4
+6bb6913e68dd1250b2d721614c6693683a48b4b783ca48fa58178ce620a157f65158741d2c3a4afdd6557b2c805ae115f8c1edc1cff49e1f06200242701e07cd
+f942f92973f5d6bbda991fd3d3878c69450034d8db08283ddd555c0f2e4fad2e0bb52b78da2261849b4d425b46377822869fc17974aad1abd0b8aeafbba54b2d
+7aca147a3e08ad9246bbf33e1637f535c8ede6069a9a9982a6de65cf6f35430899395af5fc251c1ac363b282d811ea3717a211dcbccc25cf36fc4d32cb8a0b39
+4222ce0cae934e960d122231f728497abe5a7ee1069aea1ca2b9d51b90103e59725d482b9f1a3970baed64bc5ce2b934dd6e8c284b67af90e1b35ce1fc568bdf
+1cac24d91adc3d8d1797de195df3a708422c6cd795011744c0dd413db3e682c0655891c8caf8db294c79da356fa3740c65e388ae62945714339967709dca0b3a
+faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca2aaa6abab39835c3b60cecd8f26645de60b53531e434b3c2
+67a97b37e576b7b96ea74f28aa0418bcb09fa3ea5ea12018d4cac92c6a8af17e1a56393b1fb56bc776811fa07695226164fdd656ed8edd8a1ae19c0e066f54f9
+416e376a6168b9ed2bb5a5f5adb979b1cdce5e40f2184197bba6526857c2c92e47d0104d754f92a50dd8222f65be35e0c95b73d2f3bfac85fd60d80887955a27
+1c57826650ab74c27eb3d20fc3667d1cd66ba341e31514161927f530bbb19fc00506dde4f7f67a7cefee3ed9ded1dc99b3a4caf4dd7c5513d777f7f5c6e1bb7b
+8f40d2f9b2d598749bdd41abd26df627956034e854bac3d6a0326a0ddba3c9681876ba9357be77a1c141bf390c5ae34ea5551f0e2b41aba6e877ba9576d068f4
+8376bf330efaaff23606569ea58fdc16605ecdebde7f010000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d65
+2f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d36
+3f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e
+3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d985
+0528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c020000130000000000000000000000
+0000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000
+000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c0000000000000000000000000019020000
+7468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100b6f4679893070000c92000001600000000000000
+000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000
+000000000000000000009d0a00007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000980b00000000}
+{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d
+617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
+6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
+656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
+{\*\latentstyles\lsdstimax375\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;
+\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;
+\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text;
+\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;
+\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;
+\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1;
+\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision;
+\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;
+\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1;
+\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;
+\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;
+\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;
+\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;
+\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;
+\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;
+\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;
+\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;
+\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;
+\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6;
+\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;
+\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;
+\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;
+\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography;
+\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4;
+\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4;
+\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1;
+\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1;
+\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2;
+\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2;
+\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3;
+\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4;
+\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4;
+\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5;
+\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5;
+\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6;
+\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6;
+\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark;
+\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1;
+\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1;
+\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2;
+\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3;
+\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3;
+\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4;
+\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4;
+\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
+\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
+\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
+\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
+\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;}}{\*\datastore 010500000200000018000000
+4d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
+d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000b00a
+ec6da6d9d201feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000105000000000000}}
\ No newline at end of file
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/eula.rtf b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/eula.rtf
new file mode 100644
index 000000000000..7f40e11a8ab6
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/eula.rtf
@@ -0,0 +1,97 @@
+{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Tahoma;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\froman\fprq2\fcharset0 Times New Roman;}{\f3\fswiss\fprq2\fcharset0 Calibri;}}
+{\colortbl ;\red0\green0\blue0;\red0\green0\blue255;}
+{\*\generator Riched20 10.0.10586}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1
+\pard\widctlpar\sb120\sa120\cf1\b\f0\fs24 MICROSOFT SOFTWARE LICENSE TERMS\fs28\par
+\fs24 MICROSOFT .NET LIBRARY\fs28\par
+\fs19 These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. Please read them. They apply to the software named above, which includes the media on which you received it, if any. The terms also apply to any Microsoft\par
+
+\pard\widctlpar\fi-363\li720\sb120\sa120\b0\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 updates,\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 supplements,\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 Internet-based services, and\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 support services\par
+
+\pard\widctlpar\sb120\sa120\b for this software, unless other terms accompany those items. If so, those terms apply.\par
+BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\par
+IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE PERPETUAL RIGHTS BELOW.\par
+
+\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\fs20 1.\b0\f2\fs14\~\~\~\~\b\f0\fs19 INSTALLATION AND USE RIGHTS.\par
+
+\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\fs20 a.\b0\f2\fs14\~\~\~\~\b\f0\fs19 Installation and Use.\b0\fs20\~You may install and use any number of copies of the software to design, develop and test your programs.\b\fs19\par
+\fs20 b.\b0\f2\fs14\~\~\~\~\b\f0\fs19 Third Party Programs.\b0\fs20\~The software may include third party programs that Microsoft, not the third party, licenses to you under this agreement. Notices, if any, for the third party program are included for your information only.\b\fs19\par
+
+\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\fs20 2.\b0\f2\fs14\~\~\~\~\b\f0\fs19 DATA.\~\kerning0\b0\fs20 The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may use this information to improve our products and services.\~You can learn more about data collection and use in the help documentation and the privacy statement at\~{\cf0\f3\fs24{\field{\*\fldinst{HYPERLINK "http://go.microsoft.com/fwlink/?LinkId=528096&clcid=0x409"}}{\fldrslt{\ul\cf2\cf2\ul\f0\fs20 http://go.microsoft.com/fwlink/?LinkId=528096}}}}\f0\fs20 . Your use of the software operates as your consent to these practices.\kerning36\b\fs19\par
+\fs20 3.\b0\f2\fs14\~\~\~\~\b\f0\fs20 ADDITIONAL LICENSING REQUIREMENTS AND/OR USE RIGHTS.\fs19\par
+
+\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\fs20 a.\b0\f2\fs14\~\~\~\~\b\f0\fs20 DISTRIBUTABLE CODE.\~\~\b0 The software is comprised of Distributable Code. \ldblquote Distributable Code\rdblquote is code that you are permitted to distribute in programs you develop if you comply with the terms below.\b\fs19\par
+
+\pard\widctlpar\fi-357\li1077\sb120\sa120\fs20 i.\b0\f2\fs14\~\~\~\~\~\~\b\f0\fs20 Right to Use and Distribute.\b0\fs19\par
+
+\pard\widctlpar\fi-357\li1434\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 You may copy and distribute the object code form of the software.\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as part of those programs.\fs19\par
+
+\pard\widctlpar\fi-357\li1077\sb120\sa120\b\fs20 ii.\b0\f2\fs14\~\~\~\~\b\f0\fs20 Distribution Requirements.\b0\~\b For any Distributable Code you distribute, you must\b0\fs19\par
+
+\pard\widctlpar\fi-357\li1434\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 add significant primary functionality to it in your programs;\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 require distributors and external end users to agree to terms that protect it at least as much as this agreement;\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 display your valid copyright notice on your programs; and\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 indemnify, defend, and hold harmless Microsoft from any claims, including attorneys\rquote fees, related to the distribution or use of your programs.\fs19\par
+
+\pard\widctlpar\fi-357\li1077\sb120\sa120\b\fs20 iii.\b0\f2\fs14\~\~\~\b\f0\fs20 Distribution Restrictions.\b0\~\b You may not\b0\fs19\par
+
+\pard\widctlpar\fi-357\li1434\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 alter any copyright, trademark or patent notice in the Distributable Code;\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 use Microsoft\rquote s trademarks in your programs\rquote names or in a way that suggests your programs come from or are endorsed by Microsoft;\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 include Distributable Code in malicious, deceptive or unlawful programs; or\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. An Excluded License is one that requires, as a condition of use, modification or distribution, that\fs19\par
+
+\pard\widctlpar\fi-358\li1792\sb120\sa120\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 the code be disclosed or distributed in source code form; or\fs19\par
+\f1\fs20\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs20 others have the right to modify it.\fs19\par
+
+\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b\fs20 4.\b0\f2\fs14\~\~\~\~\b\f0\fs19 SCOPE OF LICENSE.\~\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\b\par
+
+\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\b0\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 work around any technical limitations in the software;\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 publish the software for others to copy;\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 rent, lease or lend the software;\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 transfer the software or this agreement to any third party; or\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 use the software for commercial software hosting services.\par
+
+\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b\fs20 5.\b0\f2\fs14\~\~\~\~\b\f0\fs19 BACKUP COPY.\~\b0 You may make one backup copy of the software. You may use it only to reinstall the software.\b\par
+\fs20 6.\b0\f2\fs14\~\~\~\~\b\f0\fs19 DOCUMENTATION.\~\b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\b\par
+\fs20 7.\b0\f2\fs14\~\~\~\~\b\f0\fs19 EXPORT RESTRICTIONS.\~\b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see\~{\cf0\fs20{\field{\*\fldinst{HYPERLINK www.microsoft.com/exporting }}{\fldrslt{www.microsoft.com/exporting\ul0\cf0}}}}\f0\fs19 .\b\par
+\fs20 8.\b0\f2\fs14\~\~\~\~\b\f0\fs19 SUPPORT SERVICES.\~\b0 Because this software is \ldblquote as is,\rdblquote we may not provide support services for it.\b\par
+\fs20 9.\b0\f2\fs14\~\~\~\~\b\f0\fs19 ENTIRE AGREEMENT.\~\b0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\b\par
+\fs20 10.\b0\f2\fs14\~\~\~\b\f0\fs19 APPLICABLE LAW.\par
+
+\pard\widctlpar\fi-363\li720\sb120\sa120\kerning0\fs20 a.\b0\f2\fs14\~\~\~\~\b\f0\fs19 United States.\~\b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\b\par
+\fs20 b.\b0\f2\fs14\~\~\~\~\b\f0\fs19 Outside the United States. If you acquired the software in any other country, the laws of that country apply.\par
+
+\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\fs20 11.\b0\f2\fs14\~\~\b\f0\fs19 LEGAL EFFECT.\~\b0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\b\par
+\fs20 12.\b0\f2\fs14\~\~\b\f0\fs19 DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED \ldblquote AS-IS.\rdblquote YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS OR STATUTORY GUARANTEES UNDER YOUR LOCAL LAWS WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.\par
+
+\pard\widctlpar\li357\sb120\sa120\kerning0 FOR AUSTRALIA \endash YOU HAVE STATUTORY GUARANTEES UNDER THE AUSTRALIAN CONSUMER LAW AND NOTHING IN THESE TERMS IS INTENDED TO AFFECT THOSE RIGHTS.\b0\par
+
+\pard\widctlpar\fi-357\li357\sb120\sa120\kerning36\b\fs20 13.\b0\f2\fs14\~\~\b\f0\fs19 LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES.\par
+
+\pard\widctlpar\li357\sb120\sa120\kerning0\b0 This limitation applies to\par
+
+\pard\widctlpar\fi-363\li720\sb120\sa120\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\par
+\f1\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\par
+
+\pard\widctlpar\sb120\sa120 It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\par
+\lang9 Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\lang1033\par
+\lang9 Remarque : Ce logiciel \'e9tant distribu\'e9 au Qu\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\'e7ais.\lang1033\par
+\kerning36\b EXON\'c9RATION DE GARANTIE.\~\b0 Le logiciel vis\'e9 par une licence est offert \'ab tel quel \'bb. Toute utilisation de ce logiciel est \'e0 votre seule risque et p\'e9ril. Microsoft n\rquote accorde aucune autre garantie expresse. Vous pouvez b\'e9n\'e9ficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\'e9 marchande, d\rquote ad\'e9quation \'e0 un usage particulier et d\rquote absence de contrefa\'e7on sont exclues.\b\par
+LIMITATION DES DOMMAGES-INT\'c9R\'caTS ET EXCLUSION DE RESPONSABILIT\'c9 POUR LES DOMMAGES.\~\b0 Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\'e9tendre \'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\'e9ciaux, indirects ou accessoires et pertes de b\'e9n\'e9fices.\b\par
+\kerning0\b0\lang9 Cette limitation concerne :\lang1033\par
+
+\pard\widctlpar\li720\sb120\f1\lang9\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 tout ce qui est reli\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\lang1033\par
+
+\pard\widctlpar\li720\sa120\f1\lang9\'b7\f2\fs14\~\~\~\~\~\~\~\~\~\f0\fs19 les r\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\'e9 stricte, de n\'e9gligence ou d\rquote une autre faute dans la limite autoris\'e9e par la loi en vigueur.\lang1033\par
+
+\pard\widctlpar\sb120\sa120\lang9 Elle s\rquote applique \'e9galement, m\'eame si Microsoft connaissait ou devrait conna\'eetre l\rquote\'e9ventualit\'e9 d\rquote un tel dommage. Si votre pays n\rquote autorise pas l\rquote exclusion ou la limitation de responsabilit\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l\rquote exclusion ci-dessus ne s\rquote appliquera pas \'e0 votre \'e9gard.\lang1033\par
+\kerning36\b EFFET JURIDIQUE.\~\b0 Le pr\'e9sent contrat d\'e9crit certains droits juridiques. Vous pourriez avoir d\rquote autres droits pr\'e9vus par les lois de votre pays. Le pr\'e9sent contrat ne modifie pas les droits que vous conf\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\b\par
+\kerning0\fs20\lang1036\~\fs19\lang1033\par
+
+\pard\widctlpar\cf0\b0\f3\fs24\par
+}
+
\ No newline at end of file
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/breadcrumbstorefolder.wxs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/breadcrumbstorefolder.wxs
new file mode 100644
index 000000000000..fe71303fb322
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/breadcrumbstorefolder.wxs
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/product.common.wxi b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/product.common.wxi
new file mode 100644
index 000000000000..24a6a6c75a5f
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/product.common.wxi
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/product.wxs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/product.wxs
new file mode 100644
index 000000000000..3ffe84a15ed8
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/product.wxs
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/provider.wxs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/provider.wxs
new file mode 100644
index 000000000000..51f6bf4ba6b2
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/provider.wxs
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/registrykeys.wxs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/registrykeys.wxs
new file mode 100644
index 000000000000..ea54f57ddff1
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/registrykeys.wxs
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/werrelatedkeys.wxs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/werrelatedkeys.wxs
new file mode 100644
index 000000000000..d783a3012f9f
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/product/werrelatedkeys.wxs
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/variables.wxi b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/variables.wxi
new file mode 100644
index 000000000000..e446d14c1b8d
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/variables.wxi
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/vs/VS.Redist.Common.Component.nuspec.txt b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/vs/VS.Redist.Common.Component.nuspec.txt
new file mode 100644
index 000000000000..e9bb74c1aa46
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/vs/VS.Redist.Common.Component.nuspec.txt
@@ -0,0 +1,18 @@
+
+
+
+ $COMPONENT_NAME$
+ 1.0.0
+ $COMPONENT_NAME$
+ Microsoft
+ Microsoft
+ https://www.microsoft.com/net/dotnet_library_license.htm
+ $PROJECT_URL$
+ true
+ $FRIENDLY_NAME$ ($ARCH$) Windows Installer MSI as a .nupkg for internal Visual Studio build consumption
+ © Microsoft Corporation. All rights reserved.
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets
new file mode 100644
index 000000000000..131b6db1556d
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/build/wix5/wix.targets
@@ -0,0 +1,523 @@
+
+
+
+
+
+
+
+
+
+
+ $(IntermediateOutputPath)/wixpackcontents/
+
+
+
+ <_WixIntermediateOutputPath>$(BaseIntermediateOutputPath)wix
+
+
+
+ $(IntermediateOutputPath)/wix/
+ $(IntermediateOutputPath)/$(InstallerRuntimeIdentifier)/wix/
+ x86
+ $(InstallerTargetArchitecture)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(PkgMicrosoft_Wix)\tools\net6.0\any\
+ wixext5
+ $(PkgMicrosoft_WixToolset_UI_wixext)\$(WixExtensionsDir)\
+ $(PkgMicrosoft_WixToolset_Dependency_wixext)\$(WixExtensionsDir)\
+ $(PkgMicrosoft_WixToolset_Util_wixext)\$(WixExtensionsDir)\
+ $(PkgMicrosoft_WixToolset_Bal_wixext)\$(WixExtensionsDir)\
+
+
+
+
+
+ 5
+
+ 1996-04-01
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(BundleInstallerUpgradeCodeSeed) $(MajorVersion).$(MinorVersion) $(RuntimeIdentifier)
+
+
+
+
+
+
+
+
+
+
+
+ $(_OutInstallerFile)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_WixThemeIncludeLine Include="<?xml version="1.0"?>" />
+ <_WixThemeIncludeLine Include="<Include>" />
+ <_WixThemeIncludeLine Include="@(WixThemeVariable->'<Variable Name="%(Identity)" Value="%(Value)" />')"/>
+ <_WixThemeIncludeLine Include="</Include>" />
+
+
+
+ <_WixThemeFile>$(IntermediateOutputPath)wix/wixtheme.wxi
+
+
+
+
+
+
+ $(IntermediateOutputPath)o/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(MSBuildThisFileDirectory)..\resources\dotnet.ico
+ $(MSBuildThisFileDirectory)..\resources\DotNetLogo_256x.png
+ $(MSBuildThisFileDirectory)..\resources\dotnetlogo.bmp
+ Foundation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_OutInstallerFile>$(_InstallerFile)
+
+
+
+
+
+
+ <_OutInstallerFile Condition="'$(_OutInstallerFile)' == ''">$(_InstallerFile)
+
+
+
+ 500
+ 200
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(InstallerName.Replace('-', '_'))
+
+ -bcgg
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_wixArgs>
+ <_wixArgs>$(_wixArgs) -wx
+ <_wixArgs>$(_wixArgs) -nologo
+ <_wixArgs>$(_wixArgs) -culture en-us
+ <_wixArgs>$(_wixArgs) -arch $(MsiArch)
+ <_wixArgs>$(_wixArgs) -out "$(_OutInstallerFile)"
+
+ <_wixArgs>$(_wixArgs) @(WixExtensions -> '-ext %(Identity)', ' ')
+ <_wixArgs>$(_wixArgs) @(CandleVariables -> '-d %(Identity)="%(Value)"', ' ')
+ <_wixArgs>$(_wixArgs) @(WixSrcFile -> '"%(FullPath)"', ' ')
+
+ <_wixArgs>$(_wixArgs) $(AdditionalCandleArgs)
+ <_wixArgs>$(_wixArgs) $(AdditionalLightArgs)
+ <_wixArgs>$(_wixArgs) $(WixAdditionalOptions)
+
+ <_wixCommand>wix.exe build $(_wixArgs)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VS.Redist.Common.$(VSInsertionShortComponentName).$(InstallerTargetArchitecture)$(CrossArchContentsBuildPart).$(MajorVersion).$(MinorVersion)
+ $(ArtifactsNonShippingPackagesDir)$(VSInsertionComponentName).$(Version).nupkg
+
+
+ $(MSBuildThisFileDirectory)vs\VS.Redist.Common.Component.nuspec.txt
+ $(IntermediateOutputPath)vs\VS.Redist.Common.Component.nuspec
+
+ COMPONENT_MSI=$(ComponentMsiFile);ARCH=$(MsiArch);COMPONENT_NAME=$(VSInsertionComponentName);FRIENDLY_NAME=$(ProductBrandName);PROJECT_URL=$(RepositoryUrl)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/ArEntry.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/ArEntry.cs
index e7ba349668f2..93dfab25875e 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/ArEntry.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/ArEntry.cs
@@ -7,6 +7,8 @@ namespace Microsoft.DotNet.Build.Tasks.Installers
{
public sealed class ArEntry
{
+ public const uint FilePermissionMask = 0xFFF;
+
public ArEntry(string name, ulong timestamp, ulong ownerID, ulong groupID, uint mode, Stream dataStream)
{
Name = name;
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CpioEntry.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CpioEntry.cs
index aed27483c654..19377abf9ee6 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CpioEntry.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CpioEntry.cs
@@ -22,6 +22,8 @@ internal sealed class CpioEntry(ulong inode, string name, ulong timestamp, ulong
public const uint Directory = 0x4000;
+ public const uint FilePermissionMask = 0xFFF;
+
public ulong Inode { get; } = inode;
public string Name { get; } = name;
public ulong Timestamp { get; } = timestamp;
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateMD5SumsFile.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateMD5SumsFile.cs
index a454a7c61d2c..b877d72e75ce 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateMD5SumsFile.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateMD5SumsFile.cs
@@ -47,7 +47,7 @@ public override bool Execute()
#endif
}
- InstalledSize = installedSize.ToString();
+ InstalledSize = (installedSize / 1024).ToString();
return true;
}
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateWixBuildWixpack.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateWixBuildWixpack.cs
index c05d9c5d4981..c86b95e36842 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateWixBuildWixpack.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/CreateWixBuildWixpack.cs
@@ -28,6 +28,8 @@ namespace Microsoft.DotNet.Build.Tasks.Installers
*/
public class CreateWixBuildWixpack : Task
{
+ public string AdditionalOptions { get; set; }
+
public ITaskItem BindTrackingFile { get; set; }
public ITaskItem[] BindPaths { get; set; }
@@ -71,6 +73,8 @@ public class CreateWixBuildWixpack : Task
[Required]
public ITaskItem[] SourceFiles { get; set; }
+ public string[] SuppressSpecificWarnings { get; set; }
+
[Required]
public string WixpackWorkingDir { get; set; }
@@ -94,12 +98,6 @@ public override bool Execute()
WixpackWorkingDir = Path.Combine(Path.GetTempPath(), "WixpackTemp", Guid.NewGuid().ToString().Split('-')[0]);
}
- _wixprojDir = string.Empty;
- if (!_defineConstantsDictionary.TryGetValue("ProjectDir", out _wixprojDir))
- {
- throw new InvalidOperationException("ProjectDir not defined in DefineConstants. Task cannot proceed.");
- }
-
_installerFilename = Path.GetFileName(InstallerFile);
if (Directory.Exists(WixpackWorkingDir))
@@ -108,15 +106,22 @@ public override bool Execute()
}
Directory.CreateDirectory(WixpackWorkingDir);
- // Copy wixproj file - fail if ProjectPath is not defined
- if (_defineConstantsDictionary.TryGetValue("ProjectPath", out var projectPath))
+ if (_defineConstantsDictionary.TryGetValue("ProjectDir", out _wixprojDir))
{
- string destPath = Path.Combine(WixpackWorkingDir, Path.GetFileName(projectPath));
- File.Copy(projectPath, destPath, overwrite: true);
+ // Copy wixproj file - fail if ProjectPath is not defined
+ if (_defineConstantsDictionary.TryGetValue("ProjectPath", out var projectPath))
+ {
+ string destPath = Path.Combine(WixpackWorkingDir, Path.GetFileName(projectPath));
+ File.Copy(projectPath, destPath, overwrite: true);
+ }
+ else
+ {
+ throw new InvalidOperationException("ProjectPath not defined in DefineConstants. Task cannot proceed.");
+ }
}
else
{
- throw new InvalidOperationException("ProjectPath not defined in DefineConstants. Task cannot proceed.");
+ _wixprojDir = string.Empty;
}
CopyIncludeSearchPathsContents();
@@ -193,7 +198,7 @@ private void ProcessIncludeFile(string includeFile)
// We want to keep original files in wixpack, and only preprocess
// them for wixpack creation. This ensures that repacking process would not be
// affected by some unintentional change, or a bug in preprocessor.
- var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(includeFile));
+ var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
File.Copy(includeFile, tempFilePath, overwrite: true);
// We're processing a Wix include file, which contains preprocessor
@@ -333,6 +338,15 @@ private void GenerateWixBuildCommandLineFile()
}
}
+ // Add each Warning from SuppressSpecificWarnings array
+ if (SuppressSpecificWarnings != null && SuppressSpecificWarnings.Length > 0)
+ {
+ foreach (var warning in SuppressSpecificWarnings)
+ {
+ commandLineArgs.Add($"-sw{warning}");
+ }
+ }
+
// Add all define constants from dictionary
if (_defineConstantsDictionary != null && _defineConstantsDictionary.Count > 0)
{
@@ -395,6 +409,12 @@ private void GenerateWixBuildCommandLineFile()
commandLineArgs.Add($"-trackingfile {BindTrackingFile.ItemSpec}");
}
+ // Add AdditionalOptions if specified
+ if (!string.IsNullOrEmpty(AdditionalOptions))
+ {
+ commandLineArgs.Add(AdditionalOptions);
+ }
+
commandLineArgs.Add($"-nologo");
commandLineArgs.Add($"-wx");
@@ -407,7 +427,11 @@ private void GenerateWixBuildCommandLineFile()
}
}
- string commandLine = "wix.exe build " + string.Join(" ", commandLineArgs);
+ // The command lines can be quite long, and cmd would reject them. Wix does support
+ // response files, so create a response file (create.rsp) to package alongside.
+ File.WriteAllText(Path.Combine(WixpackWorkingDir, "create.rsp"), string.Join(System.Environment.NewLine, commandLineArgs));
+
+ string commandLine = "wix.exe build @create.rsp";
StringBuilder createCmdFileContents = new();
createCmdFileContents.AppendLine("@echo off");
@@ -493,6 +517,7 @@ private void CopySourceFilesAndContent()
// Copy the sourceFile to WixpackWorkingDir
var copiedXmlPath = Path.Combine(WixpackWorkingDir, Path.GetFileName(xmlPath));
File.Copy(xmlPath, copiedXmlPath, overwrite: true);
+ string sourceFileFolder = Path.GetDirectoryName(xmlPath);
// First preprocess the source file to remove non-applicable include files.
// We defer ingestion of variables, until all variables from include files
@@ -501,7 +526,7 @@ private void CopySourceFilesAndContent()
PreprocessWixSourceFile(copiedXmlPath);
// Ingest variables after file preprocessing
- ProcessAllReferencedIncludeFiles(copiedXmlPath);
+ ProcessAllReferencedIncludeFiles(copiedXmlPath, sourceFileFolder);
IngestDefineVariablesFromWixFile(copiedXmlPath);
try
@@ -515,7 +540,7 @@ private void CopySourceFilesAndContent()
("MsiPackage", "Id", ["SourceFile"]),
("ExePackage", "Id", ["SourceFile"]),
("Payload", "Id", ["SourceFile"]),
- ("WixStandardBootstrapperApplication", "Id", ["LicenseFile", "LocalizationFile", "ThemeFile"]),
+ ("WixStandardBootstrapperApplication", "Id", ["LicenseFile", "LocalizationFile", "ThemeFile", "LogoFile"]),
("WixVariable", "Id", ["Value"]),
("Icon", "Id", ["SourceFile"])
};
@@ -550,7 +575,7 @@ private void CopySourceFilesAndContent()
string pattern = source.Substring(startIdx, source.IndexOf(')', startIdx + 2) - startIdx + 1);
- source = GetAbsoluteSourcePath(source);
+ source = GetAbsoluteSourcePath(source, sourceFileFolder);
var parts = source.Split([$"\\{pattern}\\"], StringSplitOptions.None);
if (parts.Length < 2)
@@ -584,7 +609,7 @@ private void CopySourceFilesAndContent()
id = Path.GetFileName(source);
}
- CopySourceFile(id, source);
+ CopySourceFile(id, source, sourceFileFolder);
// Update the original attribute to "\\"
var newSourceValue = $"{id}\\{Path.GetFileName(source)}";
@@ -609,7 +634,7 @@ private void CopySourceFilesAndContent()
/// in the wixpack working directory.
///
///
- private void ProcessAllReferencedIncludeFiles(string file)
+ private void ProcessAllReferencedIncludeFiles(string file, string relativeRoot)
{
string content = File.ReadAllText(file);
@@ -620,13 +645,13 @@ private void ProcessAllReferencedIncludeFiles(string file)
if (match.Groups.Count > 1)
{
string filename = match.Groups[1].Value.Trim('\"');
- string includeFilePath = GetAbsoluteSourcePath(filename);
+ string includeFilePath = GetAbsoluteSourcePath(ResolvePath(filename), relativeRoot);
if (File.Exists(includeFilePath))
{
// Copy the include file, update the source file with new path
// and ingest the variables.
string id = Path.GetFileName(includeFilePath);
- string path = CopySourceFile(id, includeFilePath);
+ string path = CopySourceFile(id, includeFilePath, relativeRoot);
ProcessIncludeFile(path);
content = content.Replace(filename, $"{id}\\{id}");
}
@@ -634,13 +659,16 @@ private void ProcessAllReferencedIncludeFiles(string file)
{
// Include file could be in IncludeSearchPaths and already copied and processed.
bool foundInSearchPath = false;
- foreach (var searchPath in IncludeSearchPaths)
+ if (IncludeSearchPaths != null)
{
- var potentialPath = Path.Combine(WixpackWorkingDir, searchPath, Path.GetFileName(includeFilePath));
- if (File.Exists(potentialPath))
+ foreach (var searchPath in IncludeSearchPaths)
{
- foundInSearchPath = true;
- break;
+ var potentialPath = Path.Combine(WixpackWorkingDir, searchPath, Path.GetFileName(includeFilePath));
+ if (File.Exists(potentialPath))
+ {
+ foundInSearchPath = true;
+ break;
+ }
}
}
@@ -891,7 +919,12 @@ private void PreprocessWixSourceFile(string sourceFile)
if (keepBlock)
{
- output.Append(input.Substring(blockStart, blockEnd - blockStart));
+ string selectedContent = input.Substring(blockStart, blockEnd - blockStart);
+ output.Append(selectedContent);
+
+ // Ingest variables from the selected content asap as
+ // variables could be referenced in subsequent blocks or conditions.
+ IngestDefineVariablesFromString(selectedContent);
}
pos = endifStart + 9; // Move past
}
@@ -950,9 +983,17 @@ private bool EvaluateCondition(string condition)
if (varName.StartsWith("var.", StringComparison.OrdinalIgnoreCase))
{
- _defineVariablesDictionary.TryGetValue(varName.Substring(4), out actualValue);
+ varName = varName.Substring(4);
+ _defineVariablesDictionary.TryGetValue(varName, out actualValue);
}
- else
+ else if (varName.StartsWith("sys.", StringComparison.OrdinalIgnoreCase))
+ {
+ varName = varName.Substring(4);
+ _systemVariablesDictionary.TryGetValue(varName, out actualValue);
+ }
+
+ // Fallback to _defineConstantsDictionary if not found in variables
+ if (actualValue == null || actualValue == "")
{
_defineConstantsDictionary.TryGetValue(varName, out actualValue);
}
@@ -970,12 +1011,12 @@ private bool EvaluateCondition(string condition)
}
}
- private string CopySourceFile(string fileId, string source)
+ private string CopySourceFile(string fileId, string source, string relativeRoot = "")
{
var destDir = Path.Combine(WixpackWorkingDir, fileId);
Directory.CreateDirectory(destDir);
- source = GetAbsoluteSourcePath(source);
+ source = GetAbsoluteSourcePath(source, relativeRoot);
if (File.Exists(source))
{
@@ -1010,15 +1051,23 @@ private void CopyBindPathContents()
string bindName = BindPaths[i].GetMetadata("BindName");
if (!string.IsNullOrEmpty(bindName))
{
+ string wixpackSubfolder = Path.GetRandomFileName();
string bindPath = BindPaths[i].ItemSpec;
- if (!bindName.EndsWith(".dll"))
+
+ foreach (string file in Directory.GetFiles(bindPath, "*", SearchOption.TopDirectoryOnly))
{
- bindName += ".dll"; // Ensure the bind name ends with .dll
+ // Copy known usable files only
+ // .dll, .exe, .msi
+ if (file.EndsWith(".dll") ||
+ file.EndsWith(".exe") ||
+ file.EndsWith(".msi"))
+ {
+ CopySourceFile(wixpackSubfolder, file);
+ }
}
- CopySourceFile(bindName, Path.Combine(bindPath, bindName));
// Update the bind path item spec to the new relative folder
- BindPaths[i].ItemSpec = bindName;
+ BindPaths[i].ItemSpec = wixpackSubfolder;
continue;
}
}
@@ -1037,12 +1086,14 @@ private void CopyLocalizationFiles()
}
}
- private string GetAbsoluteSourcePath(string source)
+ private string GetAbsoluteSourcePath(string source, string relativeRoot = "")
{
// If the source is relative, resolve it against the project directory
if (!Path.IsPathRooted(source))
{
- return Path.Combine(_wixprojDir, source);
+ return string.IsNullOrEmpty(relativeRoot) ?
+ Path.Combine(_wixprojDir, source) :
+ Path.Combine(relativeRoot, source);
}
return source;
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeader.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeader.cs
index 35afda693df9..8bbdd7ff4dd9 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeader.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeader.cs
@@ -14,7 +14,7 @@
namespace Microsoft.DotNet.Build.Tasks.Installers
{
- internal sealed partial class RpmHeader(List.Entry> entries)
+ public sealed partial class RpmHeader(List.Entry> entries)
where TEntryTag : struct, Enum
{
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderEntryType.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderEntryType.cs
index a51257b92eb7..3b5558aa8a23 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderEntryType.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmHeaderEntryType.cs
@@ -3,7 +3,7 @@
namespace Microsoft.DotNet.Build.Tasks.Installers
{
- internal enum RpmHeaderEntryType : uint
+ public enum RpmHeaderEntryType : uint
{
Null = 0,
Char = 1,
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmLead.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmLead.cs
index d91e2e930aa6..6b4546c854fb 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmLead.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmLead.cs
@@ -13,7 +13,7 @@
namespace Microsoft.DotNet.Build.Tasks.Installers
{
[StructLayout(LayoutKind.Sequential)]
- internal struct RpmLead
+ public struct RpmLead
{
public string Name { get; set; }
public byte Major { get; set; }
diff --git a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmPackage.cs b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmPackage.cs
index e10381eea135..21f28eab24a3 100644
--- a/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmPackage.cs
+++ b/src/arcade/src/Microsoft.DotNet.Build.Tasks.Installers/src/RpmPackage.cs
@@ -12,7 +12,7 @@
namespace Microsoft.DotNet.Build.Tasks.Installers
{
- internal sealed class RpmPackage(RpmLead lead, RpmHeader signature, RpmHeader header, MemoryStream archiveStream) : IDisposable
+ public sealed class RpmPackage(RpmLead lead, RpmHeader signature, RpmHeader header, MemoryStream archiveStream) : IDisposable
{
public RpmLead Lead { get; set; } = lead;
public RpmHeader Signature { get; set; } = signature;
diff --git a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/AzureDevOpsTask.cs b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/AzureDevOpsTask.cs
index 3a77b797d74d..a102acb64dcd 100644
--- a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/AzureDevOpsTask.cs
+++ b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/AzureDevOpsTask.cs
@@ -8,6 +8,7 @@
using System.Net.Http.Headers;
using System.Net.Sockets;
using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -56,11 +57,44 @@ private async Task ExecuteAsync()
}
else
{
+ // Configure the cert revocation check in a fail-open state to avoid intermittent failures
+ // on Mac if the endpoint is not available. This is only available on .NET Core, but has only been
+ // observed on Mac anyway.
+ // https://github.com/dotnet/dnceng/issues/6410
+
+#if NET
+ using SocketsHttpHandler handler = new SocketsHttpHandler
+ {
+ AllowAutoRedirect = false,
+ };
+ handler.SslOptions.CertificateChainPolicy = new X509ChainPolicy
+ {
+ // Yes, check revocation.
+ // Yes, allow it to be downloaded if needed.
+ // Online is the default, but it doesn't hurt to be explicit.
+ RevocationMode = X509RevocationMode.Online,
+ // Roots never bother with revocation.
+ // ExcludeRoot is the default, but it doesn't hurt to be explicit.
+ RevocationFlag = X509RevocationFlag.ExcludeRoot,
+ // RevocationStatusUnknown at the EndEntity/Leaf certificate will not fail the chain build.
+ // RevocationStatusUnknown for any intermediate CA will not fail the chain build.
+ // IgnoreRootRevocationUnknown could also be specified, but it won't apply given ExcludeRoot above.
+ // The default is that all status codes are bad, this is not the default.
+ VerificationFlags =
+ X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown |
+ X509VerificationFlags.IgnoreEndRevocationUnknown,
+ // Always use the "now" when building the chain, rather than the "now" of when this policy object was constructed.
+ VerificationTimeIgnored = true,
+ };
+
+ using (var client = new HttpClient(handler)
+#else
using (var client = new HttpClient(new HttpClientHandler
{
AllowAutoRedirect = false,
CheckCertificateRevocationList = true,
})
+#endif
{
DefaultRequestHeaders =
{
diff --git a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAndroidWorkItems.cs b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAndroidWorkItems.cs
index fa0544c68a53..e8f00390894c 100644
--- a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAndroidWorkItems.cs
+++ b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAndroidWorkItems.cs
@@ -157,7 +157,9 @@ private string GetDefaultCommand(ITaskItem appPackage, int expectedExitCode)
"--timeout \"$timeout\" " +
"--package-name \"$package_name\" " +
" -v " +
- $"{ devOutArg } { instrumentationArg } { exitCodeArg } { extraArguments } { passthroughArgs }";
+ $"{ devOutArg } { instrumentationArg } { exitCodeArg } { extraArguments } " +
+ "--arg env:DOTNET_CI=true " +
+ $"{ passthroughArgs }";
}
private string GetHelixCommand(
diff --git a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAppleWorkItems.cs b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAppleWorkItems.cs
index 0eb88de121b1..a1d7c943d8cd 100644
--- a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAppleWorkItems.cs
+++ b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/CreateXHarnessAppleWorkItems.cs
@@ -213,6 +213,7 @@ private string GetDefaultCommand(bool includesTestRunner, bool resetSimulator) =
"-v " +
(!includesTestRunner ? "--expected-exit-code $expected_exit_code " : string.Empty) +
(resetSimulator ? $"--reset-simulator " : string.Empty) +
+ "--set-env=DOTNET_CI=true " +
(!string.IsNullOrEmpty(AppArguments) ? "-- " + AppArguments : string.Empty);
private string GetHelixCommand(
diff --git a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/FindDotNetCliPackage.cs b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/FindDotNetCliPackage.cs
index 671215d884ad..76a6faa1848e 100644
--- a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/FindDotNetCliPackage.cs
+++ b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/FindDotNetCliPackage.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
+using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Microsoft.Arcade.Common;
using Microsoft.Build.Framework;
@@ -59,7 +60,34 @@ public class FindDotNetCliPackage : MSBuildTaskBase
public override void ConfigureServices(IServiceCollection collection)
{
- _httpMessageHandler = new HttpClientHandler { CheckCertificateRevocationList = true };
+#if NET
+ var socketsHandler = new SocketsHttpHandler
+ {
+ AllowAutoRedirect = true,
+ };
+ socketsHandler.SslOptions.CertificateChainPolicy = new X509ChainPolicy
+ {
+ // Yes, check revocation.
+ // Yes, allow it to be downloaded if needed.
+ // Online is the default, but it doesn't hurt to be explicit.
+ RevocationMode = X509RevocationMode.Online,
+ // Roots never bother with revocation.
+ // ExcludeRoot is the default, but it doesn't hurt to be explicit.
+ RevocationFlag = X509RevocationFlag.ExcludeRoot,
+ // RevocationStatusUnknown at the EndEntity/Leaf certificate will not fail the chain build.
+ // RevocationStatusUnknown for any intermediate CA will not fail the chain build.
+ // IgnoreRootRevocationUnknown could also be specified, but it won't apply given ExcludeRoot above.
+ // The default is that all status codes are bad, this is not the default.
+ VerificationFlags =
+ X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown |
+ X509VerificationFlags.IgnoreEndRevocationUnknown,
+ // Always use the "now" when building the chain, rather than the "now" of when this policy object was constructed.
+ VerificationTimeIgnored = true,
+ };
+ _httpMessageHandler = socketsHandler;
+#else
+ _httpMessageHandler = new HttpClientHandler { CheckCertificateRevocationList = true };
+#endif
collection.TryAddSingleton(_httpMessageHandler);
collection.TryAddSingleton(Log);
}
@@ -81,7 +109,7 @@ private async Task FindCliPackage()
{
NormalizeParameters();
var feeds = new List();
- feeds.Add(new MSBuild.TaskItem("https://dotnetcli.blob.core.windows.net/dotnet"));
+ feeds.Add(new MSBuild.TaskItem("https://builds.dotnet.microsoft.com/dotnet"));
feeds.Add(new MSBuild.TaskItem("https://ci.dot.net/public"));
if (AdditionalFeeds != null)
{
diff --git a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/tools/Microsoft.DotNet.Helix.Sdk.MonoQueue.targets b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/tools/Microsoft.DotNet.Helix.Sdk.MonoQueue.targets
index f1e7cd0a4033..90456cf23943 100644
--- a/src/arcade/src/Microsoft.DotNet.Helix/Sdk/tools/Microsoft.DotNet.Helix.Sdk.MonoQueue.targets
+++ b/src/arcade/src/Microsoft.DotNet.Helix/Sdk/tools/Microsoft.DotNet.Helix.Sdk.MonoQueue.targets
@@ -71,9 +71,13 @@
<_AccessTokenSuffix />
<_AccessTokenSuffix Condition=" '$(HelixAccessToken)' != '' ">&access_token={Get this from helix.dot.net}
+ <_HelixBaseUri Condition="'$(HelixBaseUri)' == ''">https://helix.dot.net
+ <_HelixBaseUri Condition="'$(HelixBaseUri)' != ''">$(HelixBaseUri.TrimEnd('/'))
+ <_HelixJobName />
+ <_HelixJobName Condition="'$(HelixJobName)' != ''"> '$(HelixJobName)'
-
-
+
+
, IDisposable
+ {
+ private readonly ScriptRunner _scriptRunner;
+ private readonly string _testOutputDirectory;
+
+ public BoundaryConditionTests(SetupNugetSourcesFixture fixture)
+ {
+ _testOutputDirectory = Path.Combine(Path.GetTempPath(), "SetupNugetSourcesTests", Guid.NewGuid().ToString());
+ Directory.CreateDirectory(_testOutputDirectory);
+ _scriptRunner = fixture.ScriptRunner;
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (Directory.Exists(_testOutputDirectory))
+ {
+ Directory.Delete(_testOutputDirectory, true);
+ }
+ }
+ catch { }
+ }
+
+ [Fact]
+ public async Task EmptyConfiguration_FailsWithoutPackageSourcesSection()
+ {
+ // Arrange
+ var originalConfig = @"
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(1, "Script should fail when packageSources section is missing");
+
+ // Check both output and error for the message (scripts may write to stdout instead of stderr)
+ var errorMessage = string.IsNullOrEmpty(result.error) ? result.output : result.error;
+ errorMessage.Should().Contain("packageSources section", "should report missing packageSources section error");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Config should remain unchanged when script fails
+ modifiedConfig.Should().BeEquivalentTo(originalConfig, "config should not be modified when script fails");
+ }
+
+ [Fact]
+ public async Task ConfigWithoutPackageSourcesSection_FailsWithoutPackageSourcesSection()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(1, "Script should fail when packageSources section is missing");
+ // Check both output and error for the message (scripts may write to stdout instead of stderr)
+ var errorMessage = string.IsNullOrEmpty(result.error) ? result.output : result.error;
+ errorMessage.Should().Contain("packageSources section", "should report missing packageSources section error");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Config should remain unchanged when script fails
+ modifiedConfig.Should().BeEquivalentTo(originalConfig, "config should not be modified when script fails");
+ }
+
+ [Fact]
+ public async Task ConfigWithMissingDisabledPackageSourcesSection_StillAddsInternalFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should still add internal feeds
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal");
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport");
+ }
+
+ [Fact]
+ public async Task NonExistentConfigFile_ReturnsError()
+ {
+ // Arrange
+ var nonExistentPath = Path.Combine(_testOutputDirectory, "nonexistent.config");
+ // Act
+ var result = await _scriptRunner.RunScript(nonExistentPath);
+
+ // Assert
+ result.exitCode.Should().Be(1, "should return error code for nonexistent file");
+ // Check both output and error for the message (scripts may write to stdout instead of stderr)
+ var errorMessage = string.IsNullOrEmpty(result.error) ? result.output : result.error;
+ errorMessage.Should().Contain("Couldn't find the NuGet config file", "should report missing file error");
+ }
+
+ [Fact]
+ public async Task ConfigWithOnlyDisabledSources_FailsWithoutPackageSourcesSection()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(1, "Script should fail when packageSources section is missing");
+ // Check both output and error for the message (scripts may write to stdout instead of stderr)
+ var errorMessage = string.IsNullOrEmpty(result.error) ? result.output : result.error;
+ errorMessage.Should().Contain("packageSources section", "should report missing packageSources section error");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Config should remain unchanged when script fails
+ modifiedConfig.Should().BeEquivalentTo(originalConfig, "config should not be modified when script fails");
+ }
+
+ [Fact]
+ public async Task ConfigWithEmptyPackageSourcesSection_HandlesCorrectly()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should enable darc-int feeds but not add any dotnet internal feeds since no dotnet feeds exist
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-roslyn-12345", "should enable darc-int feed");
+ modifiedConfig.GetPackageSourceCount().Should().Be(0, "should not add dotnet internal feeds without dotnet public feeds");
+ }
+ }
+}
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/CredentialHandlingTests.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/CredentialHandlingTests.cs
new file mode 100644
index 000000000000..a9cf811728b2
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/CredentialHandlingTests.cs
@@ -0,0 +1,215 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.DotNet.XUnitExtensions;
+using Xunit;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ public class CredentialHandlingTests : IClassFixture, IDisposable
+ {
+ private readonly ScriptRunner _scriptRunner;
+ private readonly string _testOutputDirectory;
+
+ public CredentialHandlingTests(SetupNugetSourcesFixture fixture)
+ {
+ _testOutputDirectory = Path.Combine(Path.GetTempPath(), "SetupNugetSourcesTests", Guid.NewGuid().ToString());
+ Directory.CreateDirectory(_testOutputDirectory);
+ _scriptRunner = fixture.ScriptRunner;
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (Directory.Exists(_testOutputDirectory))
+ {
+ Directory.Delete(_testOutputDirectory, true);
+ }
+ }
+ catch { }
+ }
+
+ [Fact]
+ public async Task ConfigWithCredentialProvided_AddsCredentialsForInternalFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ var testCredential = "Placeholder";
+ // Act
+ var result = await _scriptRunner.RunScript(configPath, testCredential);
+
+ // Assert
+ result.exitCode.Should().Be(0, "script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should add internal feeds
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal");
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport");
+
+ // Should add credentials for internal feeds
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal", "dn-bot", "should add credentials for internal feed");
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal-transport", "dn-bot", "should add credentials for transport feed");
+
+ // Should use v2 endpoints when credentials are provided
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v2",
+ "should use v2 endpoint when credentials provided");
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v2",
+ "should use v2 endpoint when credentials provided");
+ }
+
+ [Fact]
+ public async Task ConfigWithNoCredential_DoesNotAddCredentials()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act - No credential provided
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should add internal feeds
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal");
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport");
+
+ // Should NOT add credentials
+ modifiedConfig.ShouldNotContainCredentials("dotnet6-internal", "should not add credentials without credential");
+ modifiedConfig.ShouldNotContainCredentials("dotnet6-internal-transport", "should not add credentials without credential");
+
+ // Should use v3 endpoints when no credentials are provided
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v3/index.json",
+ "should use v3 endpoint when no credentials provided");
+ }
+
+ [Fact]
+ public async Task ConfigWithExistingCredentials_PreservesAndAddsNew()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ var testCredential = "Placeholder";
+ // Act
+ var result = await _scriptRunner.RunScript(configPath, testCredential);
+
+ // Assert
+ result.exitCode.Should().Be(0, "script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should preserve existing credentials
+ modifiedConfig.ShouldContainCredentials("existing-private", "existing-user", "should preserve existing credentials");
+
+ // Should add new credentials for internal feeds
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal", "dn-bot", "should add credentials for new internal feed");
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal-transport", "dn-bot", "should add credentials for new transport feed");
+ }
+
+ [Fact]
+ public async Task ConfigWithDarcIntFeeds_AddsCredentialsForEnabledFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ var testCredential = "Placeholder";
+ // Act
+ var result = await _scriptRunner.RunScript(configPath, testCredential);
+
+ // Assert
+ result.exitCode.Should().Be(0, "script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should enable the darc-int feed
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-roslyn-12345", "darc-int feed should be enabled");
+
+ // Should add credentials for enabled darc-int feed
+ modifiedConfig.ShouldContainCredentials("darc-int-dotnet-roslyn-12345", "dn-bot", "should add credentials for enabled darc-int feed");
+
+ // Should add credentials for new internal feeds
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal", "dn-bot", "should add credentials for internal feed");
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal-transport", "dn-bot", "should add credentials for transport feed");
+ }
+
+ [Fact]
+ public async Task ConfigWithNoCredentialButExistingCredentials_DoesNotRemoveExistingCredentials()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act - No credential provided
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should preserve existing credentials
+ modifiedConfig.ShouldContainCredentials("dotnet6-internal", "dn-bot", "should preserve existing credentials");
+
+ // Should not add credentials for new feeds without credential
+ modifiedConfig.ShouldNotContainCredentials("dotnet6-internal-transport", "should not add credentials without credential");
+ }
+ }
+}
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/FeedEnablingTests.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/FeedEnablingTests.cs
new file mode 100644
index 000000000000..d38cab4887b0
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/FeedEnablingTests.cs
@@ -0,0 +1,214 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Xunit;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ public class FeedEnablingTests : IClassFixture, IDisposable
+ {
+ private readonly ScriptRunner _scriptRunner;
+ private readonly string _testOutputDirectory;
+
+ public FeedEnablingTests(SetupNugetSourcesFixture fixture)
+ {
+ _testOutputDirectory = Path.Combine(Path.GetTempPath(), "SetupNugetSourcesTests", Guid.NewGuid().ToString());
+ Directory.CreateDirectory(_testOutputDirectory);
+ _scriptRunner = fixture.ScriptRunner;
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (Directory.Exists(_testOutputDirectory))
+ {
+ Directory.Delete(_testOutputDirectory, true);
+ }
+ }
+ catch { }
+ }
+
+ [Fact]
+ public async Task ConfigWithDisabledDarcIntFeeds_EnablesFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Darc-int feeds should no longer be disabled
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-roslyn-12345", "darc-int feed should be enabled");
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-runtime-67890", "darc-int feed should be enabled");
+
+ // Should also add internal feeds for dotnet6
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v3/index.json",
+ "should add dotnet6-internal feed");
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v3/index.json",
+ "should add dotnet6-internal-transport feed");
+ }
+
+ [Fact]
+ public async Task ConfigWithMixedDisabledFeeds_OnlyEnablesDarcIntFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Darc-int feeds should be enabled
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-roslyn-12345", "darc-int feed should be enabled");
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-runtime-67890", "darc-int feed should be enabled");
+
+ // Non-darc-int feeds should remain disabled
+ modifiedConfig.ShouldBeDisabled("some-other-feed", "non-darc-int feed should remain disabled");
+ modifiedConfig.ShouldBeDisabled("another-disabled-feed", "non-darc-int feed should remain disabled");
+ }
+
+ [Fact]
+ public async Task ConfigWithDisabledInternalFeed_EnablesExistingInsteadOfAdding()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // The dotnet6-internal feed should be enabled (removed from disabled sources)
+ modifiedConfig.ShouldNotBeDisabled("dotnet6-internal", "internal feed should be enabled");
+
+ // Should still add the transport feed
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v3/index.json",
+ "should add transport feed");
+
+ // Should have 4 package sources (original 3, with dotnet6-internal enabled + transport added)
+ modifiedConfig.GetPackageSourceCount().Should().Be(4, "should enable existing feed and add transport feed");
+ }
+
+ [Fact]
+ public async Task ConfigWithNoDisabledSources_StillAddsInternalFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should add internal feeds even without disabled sources section
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v3/index.json",
+ "should add dotnet6-internal feed");
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v3/index.json",
+ "should add dotnet6-internal-transport feed");
+ }
+
+ [Fact]
+ public async Task ConfigWithCommentedOutDisabledDarcIntFeeds_RemovesEntriesAndProducesValidXml()
+ {
+ // Arrange - this test covers the issue where commented-out disabled entries would create invalid XML
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // The modified config should be valid XML (this would fail if nested comments were created)
+ Action parseXml = () => System.Xml.Linq.XDocument.Parse(modifiedConfig);
+ parseXml.Should().NotThrow("modified config should be valid XML without nested comments");
+
+ // The darc-int feed should not be disabled
+ modifiedConfig.ShouldNotBeDisabled("darc-int-dotnet-roslyn-12345", "darc-int feed should be enabled");
+
+ // The commented-out line should be removed entirely (no comment remnants)
+ modifiedConfig.Should().NotContain("Reenabled for build", "should not add comments when removing disabled entries");
+ }
+ }
+}
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/InternalFeedAdditionTests.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/InternalFeedAdditionTests.cs
new file mode 100644
index 000000000000..ca42421c4010
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/InternalFeedAdditionTests.cs
@@ -0,0 +1,149 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.DotNet.XUnitExtensions;
+using Xunit;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ public class InternalFeedAdditionTests : IClassFixture, IDisposable
+ {
+ private readonly ScriptRunner _scriptRunner;
+ private readonly string _testOutputDirectory;
+
+ public InternalFeedAdditionTests(SetupNugetSourcesFixture fixture)
+ {
+ _testOutputDirectory = Path.Combine(Path.GetTempPath(), "SetupNugetSourcesTests", Guid.NewGuid().ToString());
+ Directory.CreateDirectory(_testOutputDirectory);
+ _scriptRunner = fixture.ScriptRunner;
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (Directory.Exists(_testOutputDirectory))
+ {
+ Directory.Delete(_testOutputDirectory, true);
+ }
+ }
+ catch { }
+ }
+
+ [Theory]
+ [InlineData("dotnet5")]
+ [InlineData("dotnet6")]
+ [InlineData("dotnet7")]
+ [InlineData("dotnet8")]
+ [InlineData("dotnet9")]
+ [InlineData("dotnet10")]
+ public async Task ConfigWithSpecificDotNetVersion_AddsCorrespondingInternalFeeds(string dotnetVersion)
+ {
+ // Arrange
+ var originalConfig = $@"
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ modifiedConfig.ShouldContainPackageSource($"{dotnetVersion}-internal",
+ $"https://pkgs.dev.azure.com/dnceng/internal/_packaging/{dotnetVersion}-internal/nuget/v3/index.json",
+ $"should add {dotnetVersion}-internal feed");
+ modifiedConfig.ShouldContainPackageSource($"{dotnetVersion}-internal-transport",
+ $"https://pkgs.dev.azure.com/dnceng/internal/_packaging/{dotnetVersion}-internal-transport/nuget/v3/index.json",
+ $"should add {dotnetVersion}-internal-transport feed");
+ }
+
+ [Fact]
+ public async Task ConfigWithMultipleDotNetVersions_AddsAllInternalFeeds()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should add internal feeds for all versions
+ var versions = new[] { "dotnet5", "dotnet6", "dotnet7", "dotnet8", "dotnet9", "dotnet10" };
+ foreach (var version in versions)
+ {
+ modifiedConfig.ShouldContainPackageSource($"{version}-internal",
+ $"https://pkgs.dev.azure.com/dnceng/internal/_packaging/{version}-internal/nuget/v3/index.json",
+ $"should add {version}-internal feed");
+ modifiedConfig.ShouldContainPackageSource($"{version}-internal-transport",
+ $"https://pkgs.dev.azure.com/dnceng/internal/_packaging/{version}-internal-transport/nuget/v3/index.json",
+ $"should add {version}-internal-transport feed");
+ }
+
+ // Original count (7 sources) + 12 internal sources = 19 total
+ modifiedConfig.GetPackageSourceCount().Should().Be(19, "should have all original sources plus internal feeds");
+ }
+
+ [Fact]
+ public async Task ConfigWithExistingInternalFeed_DoesNotDuplicate()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+
+ // Should still contain the dotnet6-internal feed (only once)
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v3/index.json",
+ "existing internal feed should be preserved");
+
+ // Should add the missing transport feed
+ modifiedConfig.ShouldContainPackageSource("dotnet6-internal-transport",
+ "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v3/index.json",
+ "should add missing transport feed");
+
+ // Should have 4 total sources (3 original + 1 added transport)
+ modifiedConfig.GetPackageSourceCount().Should().Be(4, "should not duplicate existing sources");
+ }
+ }
+}
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/Microsoft.DotNet.SetupNugetSources.Tests.csproj b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/Microsoft.DotNet.SetupNugetSources.Tests.csproj
new file mode 100644
index 000000000000..83d868c3bdc2
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/Microsoft.DotNet.SetupNugetSources.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ $(NetToolCurrent)
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/NoChangeScenarioTests.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/NoChangeScenarioTests.cs
new file mode 100644
index 000000000000..632511d34411
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/NoChangeScenarioTests.cs
@@ -0,0 +1,86 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.DotNet.XUnitExtensions;
+using Xunit;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ public class NoChangeScenarioTests : IClassFixture, IDisposable
+ {
+ private readonly ScriptRunner _scriptRunner;
+ private readonly string _testOutputDirectory;
+
+ public NoChangeScenarioTests(SetupNugetSourcesFixture fixture)
+ {
+ _testOutputDirectory = Path.Combine(Path.GetTempPath(), "SetupNugetSourcesTests", Guid.NewGuid().ToString());
+ Directory.CreateDirectory(_testOutputDirectory);
+ _scriptRunner = fixture.ScriptRunner;
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (Directory.Exists(_testOutputDirectory))
+ {
+ Directory.Delete(_testOutputDirectory, true);
+ }
+ }
+ catch { }
+ }
+
+
+
+ [Fact]
+ public async Task BasicConfig_NoChanges()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+ modifiedConfig.ShouldBeSemanticallySame(originalConfig, "basic config with no special feeds should not be modified");
+ }
+
+ [Fact]
+ public async Task ConfigWithNonDotNetFeeds_NoChanges()
+ {
+ // Arrange
+ var originalConfig = @"
+
+
+
+
+
+
+";
+ var configPath = Path.Combine(_testOutputDirectory, "nuget.config");
+ await Task.Run(() => File.WriteAllText(configPath, originalConfig));
+ // Act
+ var result = await _scriptRunner.RunScript(configPath);
+
+ // Assert
+ result.exitCode.Should().Be(0, "Script should succeed, but got error: {result.error}");
+ var modifiedConfig = await Task.Run(() => File.ReadAllText(configPath));
+ modifiedConfig.ShouldBeSemanticallySame(originalConfig, "config with non-dotnet feeds should not be modified");
+ }
+ }
+}
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/NuGetConfigAssertions.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/NuGetConfigAssertions.cs
new file mode 100644
index 000000000000..0bd0f5b5dfdc
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/NuGetConfigAssertions.cs
@@ -0,0 +1,190 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Xml;
+using System.Xml.Linq;
+using FluentAssertions;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ public static class NuGetConfigAssertions
+ {
+ ///
+ /// Compares two NuGet.config files for semantic equality, ignoring whitespace differences
+ ///
+ public static void ShouldBeSemanticallySame(this string actualContent, string expectedContent, string because = "")
+ {
+ var actualNormalized = NormalizeXml(actualContent);
+ var expectedNormalized = NormalizeXml(expectedContent);
+
+ actualNormalized.Should().Be(expectedNormalized, because);
+ }
+
+ ///
+ /// Asserts that the config contains a package source with the specified key
+ ///
+ public static void ShouldContainPackageSource(this string configContent, string key, string value = null, string because = "")
+ {
+ var doc = XDocument.Parse(configContent);
+ var packageSources = doc.Root?.Element("packageSources");
+ packageSources.Should().NotBeNull($"packageSources section should exist {because}");
+
+ var source = packageSources.Elements("add").FirstOrDefault(e => e.Attribute("key")?.Value == key);
+ source.Should().NotBeNull($"package source '{key}' should exist {because}");
+
+ if (value != null)
+ {
+ source.Attribute("value")?.Value.Should().Be(value, $"package source '{key}' should have the correct value {because}");
+ }
+ }
+
+ ///
+ /// Asserts that the config does not contain a package source with the specified key
+ ///
+ public static void ShouldNotContainPackageSource(this string configContent, string key, string because = "")
+ {
+ var doc = XDocument.Parse(configContent);
+ var packageSources = doc.Root?.Element("packageSources");
+
+ if (packageSources != null)
+ {
+ var source = packageSources.Elements("add").FirstOrDefault(e => e.Attribute("key")?.Value == key);
+ source.Should().BeNull($"package source '{key}' should not exist {because}");
+ }
+ }
+
+ ///
+ /// Asserts that the config contains credentials for the specified source
+ ///
+ public static void ShouldContainCredentials(this string configContent, string sourceName, string username = null, string because = "")
+ {
+ var doc = XDocument.Parse(configContent);
+ var credentials = doc.Root?.Element("packageSourceCredentials");
+ credentials.Should().NotBeNull($"packageSourceCredentials section should exist {because}");
+
+ var sourceCredentials = credentials.Element(sourceName);
+ sourceCredentials.Should().NotBeNull($"credentials for '{sourceName}' should exist {because}");
+
+ if (username != null)
+ {
+ var usernameElement = sourceCredentials.Elements("add").FirstOrDefault(e => e.Attribute("key")?.Value == "Username");
+ usernameElement.Should().NotBeNull($"username credential should exist for '{sourceName}' {because}");
+ usernameElement.Attribute("value")?.Value.Should().Be(username, $"username should match for '{sourceName}' {because}");
+ }
+
+ var passwordElement = sourceCredentials.Elements("add").FirstOrDefault(e => e.Attribute("key")?.Value == "ClearTextPassword");
+ passwordElement.Should().NotBeNull($"password credential should exist for '{sourceName}' {because}");
+ }
+
+ ///
+ /// Asserts that the config does not contain credentials for the specified source
+ ///
+ public static void ShouldNotContainCredentials(this string configContent, string sourceName, string because = "")
+ {
+ var doc = XDocument.Parse(configContent);
+ var credentials = doc.Root?.Element("packageSourceCredentials");
+
+ if (credentials != null)
+ {
+ var sourceCredentials = credentials.Element(sourceName);
+ sourceCredentials.Should().BeNull($"credentials for '{sourceName}' should not exist {because}");
+ }
+ }
+
+ ///
+ /// Asserts that a source is not in the disabled sources list
+ ///
+ public static void ShouldNotBeDisabled(this string configContent, string sourceName, string because = "")
+ {
+ var doc = XDocument.Parse(configContent);
+ var disabledSources = doc.Root?.Element("disabledPackageSources");
+
+ if (disabledSources != null)
+ {
+ var disabledSource = disabledSources.Elements("add").FirstOrDefault(e => e.Attribute("key")?.Value == sourceName);
+ disabledSource.Should().BeNull($"source '{sourceName}' should not be disabled {because}");
+ }
+ }
+
+ ///
+ /// Asserts that a source is in the disabled sources list
+ ///
+ public static void ShouldBeDisabled(this string configContent, string sourceName, string because = "")
+ {
+ var doc = XDocument.Parse(configContent);
+ var disabledSources = doc.Root?.Element("disabledPackageSources");
+ disabledSources.Should().NotBeNull($"disabledPackageSources section should exist {because}");
+
+ var disabledSource = disabledSources.Elements("add").FirstOrDefault(e => e.Attribute("key")?.Value == sourceName);
+ disabledSource.Should().NotBeNull($"source '{sourceName}' should be disabled {because}");
+ }
+
+ ///
+ /// Counts the number of package sources in the config
+ ///
+ public static int GetPackageSourceCount(this string configContent)
+ {
+ var doc = XDocument.Parse(configContent);
+ var packageSources = doc.Root?.Element("packageSources");
+ return packageSources?.Elements("add").Count() ?? 0;
+ }
+
+ ///
+ /// Normalizes XML content for comparison by removing whitespace differences and sorting elements consistently
+ ///
+ private static string NormalizeXml(string xmlContent)
+ {
+ var doc = XDocument.Parse(xmlContent);
+
+ // Sort package sources by key for consistent comparison
+ var packageSources = doc.Root?.Element("packageSources");
+ if (packageSources != null)
+ {
+ var sortedSources = packageSources.Elements("add")
+ .OrderBy(e => e.Attribute("key")?.Value)
+ .ToList();
+ packageSources.RemoveAll();
+ foreach (var source in sortedSources)
+ {
+ packageSources.Add(source);
+ }
+ }
+
+ // Sort disabled sources by key
+ var disabledSources = doc.Root?.Element("disabledPackageSources");
+ if (disabledSources != null)
+ {
+ var sortedDisabled = disabledSources.Elements("add")
+ .OrderBy(e => e.Attribute("key")?.Value)
+ .ToList();
+ disabledSources.RemoveAll();
+ foreach (var source in sortedDisabled)
+ {
+ disabledSources.Add(source);
+ }
+ }
+
+ // Sort credentials by source name
+ var credentials = doc.Root?.Element("packageSourceCredentials");
+ if (credentials != null)
+ {
+ var sortedCredentials = credentials.Elements()
+ .OrderBy(e => e.Name.LocalName)
+ .ToList();
+ credentials.RemoveAll();
+ foreach (var cred in sortedCredentials)
+ {
+ credentials.Add(cred);
+ }
+ }
+
+ return doc.ToString(SaveOptions.DisableFormatting);
+ }
+ }
+}
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/ScriptRunner.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/ScriptRunner.cs
new file mode 100644
index 000000000000..37dd8cb9d378
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/ScriptRunner.cs
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ public enum ScriptType
+ {
+ PowerShell,
+ Shell
+ }
+
+ public class ScriptRunner
+ {
+ private readonly string _repoRoot;
+
+ public ScriptRunner(string repoRoot)
+ {
+ _repoRoot = repoRoot ?? throw new ArgumentNullException(nameof(repoRoot));
+ }
+
+ public async Task<(int exitCode, string output, string error)> RunPowerShellScript(string configFilePath, string password = null)
+ {
+ var scriptPath = Path.Combine(_repoRoot, "eng", "common", "SetupNugetSources.ps1");
+ var arguments = $"-ExecutionPolicy Bypass -File \"{scriptPath}\" -ConfigFile \"{configFilePath}\"";
+
+ if (!string.IsNullOrEmpty(password))
+ {
+ arguments += $" -Password \"{password}\"";
+ }
+
+ return await RunProcess("powershell.exe", arguments, _repoRoot);
+ }
+
+ public async Task<(int exitCode, string output, string error)> RunShellScript(string configFilePath, string credToken = null)
+ {
+ var scriptPath = Path.Combine(_repoRoot, "eng", "common", "SetupNugetSources.sh");
+
+ // Make script executable if on Unix
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ await RunProcess("chmod", $"+x \"{scriptPath}\"", _repoRoot);
+ }
+
+ var arguments = $"\"{scriptPath}\" \"{configFilePath}\"";
+ if (!string.IsNullOrEmpty(credToken))
+ {
+ arguments += $" \"{credToken}\"";
+ }
+
+ var shell = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "bash.exe" : "/bin/bash";
+ return await RunProcess(shell, arguments, _repoRoot);
+ }
+
+ private async Task<(int exitCode, string output, string error)> RunProcess(string fileName, string arguments, string workingDirectory = null)
+ {
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = fileName,
+ Arguments = arguments,
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true,
+ WorkingDirectory = workingDirectory ?? Directory.GetCurrentDirectory()
+ }
+ };
+
+ var outputBuilder = new StringBuilder();
+ var errorBuilder = new StringBuilder();
+
+ process.OutputDataReceived += (sender, e) =>
+ {
+ if (e.Data != null)
+ {
+ outputBuilder.AppendLine(e.Data);
+ }
+ };
+
+ process.ErrorDataReceived += (sender, e) =>
+ {
+ if (e.Data != null)
+ {
+ errorBuilder.AppendLine(e.Data);
+ }
+ };
+
+ process.Start();
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+
+ await Task.Run(() => process.WaitForExit());
+
+ return (process.ExitCode, outputBuilder.ToString(), errorBuilder.ToString());
+ }
+
+ public async Task<(int exitCode, string output, string error)> RunScript(string configFilePath, string credential = null)
+ {
+ var scriptType = GetPlatformAppropriateScriptType();
+ switch (scriptType)
+ {
+ case ScriptType.PowerShell:
+ return await RunPowerShellScript(configFilePath, credential);
+ case ScriptType.Shell:
+ return await RunShellScript(configFilePath, credential);
+ default:
+ throw new ArgumentException($"Unsupported script type: {scriptType}");
+ }
+ }
+
+ public static ScriptType GetPlatformAppropriateScriptType()
+ {
+ return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ScriptType.PowerShell : ScriptType.Shell;
+ }
+ }
+}
+
diff --git a/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/SetupNugetSourcesFixture.cs b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/SetupNugetSourcesFixture.cs
new file mode 100644
index 000000000000..7e25ccd1b88e
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SetupNugetSources.Tests/SetupNugetSourcesFixture.cs
@@ -0,0 +1,65 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.IO;
+
+namespace Microsoft.DotNet.SetupNugetSources.Tests
+{
+ ///
+ /// xUnit fixture that prepares a temporary repository root containing the
+ /// scaffolded files (global.json + eng/common scripts) copied from the
+ /// build output's RepoScaffold directory. Shared per test class.
+ ///
+ public class SetupNugetSourcesFixture : IDisposable
+ {
+ public string RepoRoot { get; }
+ public ScriptRunner ScriptRunner { get; }
+
+ public SetupNugetSourcesFixture()
+ {
+ var scaffoldRoot = Path.Combine(AppContext.BaseDirectory, "RepoScaffold");
+ if (!Directory.Exists(scaffoldRoot))
+ {
+ throw new InvalidOperationException($"Expected scaffold directory not found: {scaffoldRoot}");
+ }
+
+ RepoRoot = Path.Combine(Path.GetTempPath(), "SetupNugetSourcesTestRepo", Guid.NewGuid().ToString());
+ CopyDirectory(scaffoldRoot, RepoRoot);
+
+ ScriptRunner = new ScriptRunner(RepoRoot);
+ }
+
+ private static void CopyDirectory(string sourceDir, string destinationDir)
+ {
+ foreach (var dir in Directory.GetDirectories(sourceDir, "*", SearchOption.AllDirectories))
+ {
+ var relative = Path.GetRelativePath(sourceDir, dir);
+ Directory.CreateDirectory(Path.Combine(destinationDir, relative));
+ }
+
+ foreach (var file in Directory.GetFiles(sourceDir, "*", SearchOption.AllDirectories))
+ {
+ var relative = Path.GetRelativePath(sourceDir, file);
+ var destPath = Path.Combine(destinationDir, relative);
+ Directory.CreateDirectory(Path.GetDirectoryName(destPath)!);
+ File.Copy(file, destPath, overwrite: true);
+ }
+ }
+
+ public void Dispose()
+ {
+ try
+ {
+ if (Directory.Exists(RepoRoot))
+ {
+ Directory.Delete(RepoRoot, recursive: true);
+ }
+ }
+ catch
+ {
+ // Best effort cleanup.
+ }
+ }
+ }
+}
diff --git a/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets
index ba0448127660..3b2dbd56552d 100644
--- a/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets
+++ b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/sharedfx.targets
@@ -7,7 +7,7 @@
true
true
- true
+ true
true
$(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map;.r2rmap;.dbg;.debug;.dwarf
<_DefaultHostJsonTargetPath>runtimes/$(RuntimeIdentifier)/lib/$(TargetFramework)
@@ -62,11 +62,10 @@
-
+
diff --git a/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets
index a35b20c83847..09ee4c34a614 100644
--- a/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets
+++ b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix.targets
@@ -17,7 +17,8 @@
ComponentGroupName="InstallFiles"
DirectoryRef="SHARED" />
-
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/sharedfxdir.wxs b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix/product/sharedfxdir.wxs
similarity index 100%
rename from src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/product/sharedfxdir.wxs
rename to src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix/product/sharedfxdir.wxs
diff --git a/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix5/product/sharedfxdir.wxs b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix5/product/sharedfxdir.wxs
new file mode 100644
index 000000000000..86059da1ecd6
--- /dev/null
+++ b/src/arcade/src/Microsoft.DotNet.SharedFramework.Sdk/targets/windows/wix5/product/sharedfxdir.wxs
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/arcade/src/Microsoft.DotNet.SignTool.Tests/Resources/InnerZipFile.zip b/src/arcade/src/Microsoft.DotNet.SignTool.Tests/Resources/InnerZipFile.zip
new file mode 100644
index 000000000000..333b5199c4e4
Binary files /dev/null and b/src/arcade/src/Microsoft.DotNet.SignTool.Tests/Resources/InnerZipFile.zip differ
diff --git a/src/arcade/src/Microsoft.DotNet.SignTool.Tests/SignToolTests.cs b/src/arcade/src/Microsoft.DotNet.SignTool.Tests/SignToolTests.cs
index 47bcb2283818..879174e31497 100644
--- a/src/arcade/src/Microsoft.DotNet.SignTool.Tests/SignToolTests.cs
+++ b/src/arcade/src/Microsoft.DotNet.SignTool.Tests/SignToolTests.cs
@@ -327,7 +327,7 @@ public void Dispose()
private void ValidateGeneratedProject(
List itemsToSign,
Dictionary> strongNameSignInfo,
- Dictionary fileSignInfo,
+ Dictionary fileSignInfo,
Dictionary> extensionsSignInfo,
string[] expectedXmlElementsPerSigningRound,
Dictionary> additionalCertificateInfo = null,
@@ -381,7 +381,7 @@ private void ValidateGeneratedProject(
private void ValidateFileSignInfos(
List itemsToSign,
Dictionary> strongNameSignInfo,
- Dictionary fileSignInfo,
+ Dictionary fileSignInfo,
Dictionary> extensionsSignInfo,
string[] expected,
string[] expectedCopyFiles = null,
@@ -420,8 +420,11 @@ private void ValidateProducedDebContent(
Directory.CreateDirectory(controlLayout);
Directory.CreateDirectory(dataLayout);
- ZipData.ExtractTarballContents(dataArchive, dataLayout, skipSymlinks: false);
- ZipData.ExtractTarballContents(controlArchive, controlLayout);
+ var fakeBuildEngine = new FakeBuildEngine(_output);
+ var fakeLog = new TaskLoggingHelper(fakeBuildEngine, "TestLog");
+
+ ZipData.ExtractTarballContents(fakeLog, dataArchive, dataLayout, skipSymlinks: false);
+ ZipData.ExtractTarballContents(fakeLog, controlArchive, controlLayout);
string md5sumsContents = File.ReadAllText(Path.Combine(controlLayout, "md5sums"));
@@ -477,7 +480,9 @@ private void ValidateProducedRpmContent(
string layout = Path.Combine(tempDir, "layout");
Directory.CreateDirectory(layout);
- ZipData.ExtractRpmPayloadContents(rpmPackage, layout);
+ var fakeBuildEngine = new FakeBuildEngine(_output);
+ var fakeLog = new TaskLoggingHelper(fakeBuildEngine, "TestLog");
+ ZipData.ExtractRpmPayloadContents(fakeLog, rpmPackage, layout);
// Checks:
// Expected files are present
@@ -526,7 +531,7 @@ public void EmptySigningList()
var strongNameSignInfo = new Dictionary>();
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
var task = new SignToolTask { BuildEngine = new FakeBuildEngine() };
var signingInput = new Configuration(_tmpDir, itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, null, null, tarToolPath: s_tarToolPath, pkgToolPath: s_pkgToolPath, snPath: s_snPath, task.Log).GenerateListOfFiles();
@@ -593,7 +598,7 @@ public void OnlyContainer()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfoWithCollisionId, new[]
{
@@ -628,10 +633,10 @@ public void SkipSigning()
};
// Overriding information
- var fileSignInfo = new Dictionary
+ var fileSignInfo = new Dictionary
{
- { new ExplicitCertificateKey("NativeLibrary.dll"), "None" },
- { new ExplicitCertificateKey("ProjectOne.dll", publicKeyToken: "581d91ccdfc4ea9c", targetFramework: ".NETCoreApp,Version=v2.1"), "None" }
+ { new ExplicitSignInfoKey("NativeLibrary.dll"), new FileSignInfoEntry("None") },
+ { new ExplicitSignInfoKey("ProjectOne.dll", publicKeyToken: "581d91ccdfc4ea9c", targetFramework: ".NETCoreApp,Version=v2.1"), new FileSignInfoEntry("None") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -661,7 +666,7 @@ public void SkipStrongNamingForAlreadyStrongNamedBinary()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, Array.Empty());
}
@@ -682,7 +687,7 @@ public void DoNotSkipStrongNamingForDelaySignedBinary()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -706,7 +711,7 @@ public void SkipStrongNamingForCrossGennedBinary()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -730,7 +735,7 @@ public void SkipStrongNamingBinaryButDontSkipAuthenticode()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -758,7 +763,7 @@ public void OnlyAuthenticodeSignByPKT()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, new Dictionary>(), new[]
{
@@ -791,9 +796,9 @@ public void OnlyContainerAndOverridingByPKT()
};
// Overriding information
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("ProjectOne.dll", "581d91ccdfc4ea9c"), "OverriddenCertificate" }
+ { new ExplicitSignInfoKey("ProjectOne.dll", "581d91ccdfc4ea9c"), new FileSignInfoEntry("OverriddenCertificate") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -833,10 +838,10 @@ public void OnlyContainerAndOverridingByFileName()
};
// Overriding information
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("NativeLibrary.dll", collisionPriorityId: "123"), "OverriddenCertificate1" },
- { new ExplicitCertificateKey("ProjectOne.dll", collisionPriorityId: "123"), "3PartySHA2" }
+ { new ExplicitSignInfoKey("NativeLibrary.dll", collisionPriorityId: "123"), new FileSignInfoEntry("OverriddenCertificate1") },
+ { new ExplicitSignInfoKey("ProjectOne.dll", collisionPriorityId: "123"), new FileSignInfoEntry("3PartySHA2") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfoWithCollisionId, new[]
@@ -873,9 +878,9 @@ public void EmptyPKT()
};
// Overriding information
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("EmptyPKT.dll"), "3PartySHA2" }
+ { new ExplicitSignInfoKey("EmptyPKT.dll"), new FileSignInfoEntry("3PartySHA2") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -902,9 +907,9 @@ public void CrossGenerated()
};
// Overriding information
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("EmptyPKT.dll", collisionPriorityId: "123"), "3PartySHA2" }
+ { new ExplicitSignInfoKey("EmptyPKT.dll", collisionPriorityId: "123"), new FileSignInfoEntry("3PartySHA2") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, new Dictionary>(), new[]
@@ -938,7 +943,7 @@ public void DefaultCertificateForAssemblyWithoutStrongName()
{ "", new List{ new SignInfo("3PartySHA2", collisionPriorityId: "123") } }
};
- var fileSignInfo = new Dictionary() { };
+ var fileSignInfo = new Dictionary() { };
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -960,9 +965,9 @@ public void CustomTargetFrameworkAttribute()
{ "", new List{ new SignInfo("DefaultCertificate", collisionPriorityId: "123") } }
};
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("CustomTargetFrameworkAttribute.dll", targetFramework: ".NETFramework,Version=v2.0", collisionPriorityId: "123"), "3PartySHA2" }
+ { new ExplicitSignInfoKey("CustomTargetFrameworkAttribute.dll", targetFramework: ".NETFramework,Version=v2.0", collisionPriorityId: "123"), new FileSignInfoEntry("3PartySHA2") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -981,7 +986,7 @@ public void ThirdPartyLibraryMicrosoftCertificate()
};
var strongNameSignInfo = new Dictionary>() { };
- var fileSignInfo = new Dictionary() { };
+ var fileSignInfo = new Dictionary() { };
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1003,7 +1008,7 @@ public void NoWarnThirdPartyLibraryMicrosoftCertificate()
};
var strongNameSignInfo = new Dictionary>() { };
- var fileSignInfo = new Dictionary() { };
+ var fileSignInfo = new Dictionary() { };
var noWarn3rdPartySet = new HashSet(StringComparer.OrdinalIgnoreCase) { "EmptyPKT.dll" };
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -1030,7 +1035,7 @@ public void DoubleNestedContainer()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfoWithCollisionId, new[]
{
@@ -1081,7 +1086,7 @@ public void NestedContainer()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfoWithCollisionId, new[]
{
@@ -1160,9 +1165,9 @@ public void NestedContainerWithCollisions()
// Overriding information. Since ContainerOne.dll collides with ContainerTwo.dll already in the hash mapping
// table with collition id 123, we end up using ArcadeStrongTest instead of OverriddenCertificate1
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("ContainerOne.dll", collisionPriorityId: "456"), "OverriddenCertificate1" }
+ { new ExplicitSignInfoKey("ContainerOne.dll", collisionPriorityId: "456"), new FileSignInfoEntry("OverriddenCertificate1") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfoWithCollisionId, new[]
@@ -1242,7 +1247,7 @@ public void SignZipFile()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1278,6 +1283,93 @@ public void SignZipFile()
});
}
+ [Fact]
+ public void SignArchivesUsingDetachedSignature()
+ {
+ // List of files to be considered for signing
+ var itemsToSign = new List()
+ {
+ new ItemToSign(GetResourcePath("test.zip")),
+ new ItemToSign(GetResourcePath("test.tgz")),
+ new ItemToSign(GetResourcePath("NestedZip.zip")),
+ new ItemToSign(GetResourcePath("InnerZipFile.zip"))
+ };
+
+ var strongNameSignInfo = new Dictionary>();
+
+ // Overriding information
+ var explicitCertKeys = new Dictionary()
+ {
+ { new ExplicitSignInfoKey("test.zip"), new FileSignInfoEntry("ArchiveCert") },
+ { new ExplicitSignInfoKey("test.tgz"), new FileSignInfoEntry("ArchiveCert") },
+ { new ExplicitSignInfoKey("InnerZipFile.zip"), new FileSignInfoEntry("ArchiveCert") }
+ };
+
+ var additionalCertificateInfo = new Dictionary>()
+ {
+ { "ArchiveCert",
+ new List() {
+ new AdditionalCertificateInformation() { GeneratesDetachedSignature = true }
+ }
+ }
+ };
+
+ ValidateFileSignInfos(itemsToSign, strongNameSignInfo, explicitCertKeys, s_fileExtensionSignInfo, new[]
+ {
+ "File 'NativeLibrary.dll' Certificate='Microsoft400'",
+ "File 'SOS.NETCore.dll' TargetFramework='.NETCoreApp,Version=v1.0' Certificate='Microsoft400'",
+ "File 'Nested.NativeLibrary.dll' Certificate='Microsoft400'",
+ "File 'Nested.SOS.NETCore.dll' TargetFramework='.NETCoreApp,Version=v1.0' Certificate='Microsoft400'",
+ "File 'test.zip' Certificate='ArchiveCert'",
+ "File 'test.tgz' Certificate='ArchiveCert'",
+ "File 'InnerZipFile.zip' Certificate='ArchiveCert'",
+ "File 'Mid.SOS.NETCore.dll' TargetFramework='.NETCoreApp,Version=v1.0' Certificate='Microsoft400'",
+ "File 'MidNativeLibrary.dll' Certificate='Microsoft400'",
+ "File 'NestedZip.zip'",
+ },
+ additionalCertificateInfo: additionalCertificateInfo,
+ expectedCopyFiles: new[]
+ {
+ $"{Path.Combine(_tmpDir, "ContainerSigning", "6", "InnerZipFile.zip")} -> {Path.Combine(_tmpDir, "InnerZipFile.zip")}",
+ $"{Path.Combine(_tmpDir, "ContainerSigning", "6", "InnerZipFile.zip.sig")} -> {Path.Combine(_tmpDir, "InnerZipFile.zip.sig")}"
+ });
+
+ ValidateGeneratedProject(itemsToSign, strongNameSignInfo, explicitCertKeys, s_fileExtensionSignInfo, new[]
+ {
+$@"
+
+ Microsoft400
+
+
+ Microsoft400
+
+
+ Microsoft400
+
+
+ Microsoft400
+
+
+ Microsoft400
+
+
+ Microsoft400
+
+",
+$@"
+
+ ArchiveCert
+
+
+ ArchiveCert
+
+
+ ArchiveCert
+
+"
+ }, additionalCertificateInfo: additionalCertificateInfo);
+ }
+
///
/// Verifies that signing of pkgs can be done on Windows, even though
/// we will not unpack or repack them.
@@ -1298,7 +1390,7 @@ public void SignJustPkgWithoutUnpack()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1332,7 +1424,7 @@ public void UnpackAndSignPkg()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1399,9 +1491,9 @@ public void SignAndNotarizePkgFile()
};
// Overriding information
- var fileSignInfo = new Dictionary()
+ var fileSignInfo = new Dictionary()
{
- { new ExplicitCertificateKey("test.pkg"), "MacDeveloperHardenWithNotarization" }
+ { new ExplicitSignInfoKey("test.pkg"), new FileSignInfoEntry("MacDeveloperHardenWithNotarization") }
};
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -1465,7 +1557,7 @@ public void SignNestedPkgFile()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1517,7 +1609,7 @@ public void SignPkgFileWithApp()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
// When .apps are unpacked from .pkgs, they get zipped so they can be signed
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
@@ -1563,7 +1655,7 @@ public void SignTarGZipFile()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1615,7 +1707,7 @@ public void SymbolsNupkg()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1667,7 +1759,7 @@ public void SignedSymbolsNupkg()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
var tempFileExtensionSignInfo = s_fileExtensionSignInfo.Where(s => s.Key != ".symbols.nupkg").ToDictionary(e => e.Key, e => e.Value);
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, tempFileExtensionSignInfo, new[]
@@ -1718,7 +1810,7 @@ public void CheckDebSigning()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1744,7 +1836,7 @@ public void CheckDebSigning()
};
string[] signableFiles = ["usr/local/bin/mscorlib.dll"];
string expectedControlFileContent = "Package: test\nVersion: 1.0\nSection: base\nPriority: optional\nArchitecture: all\n";
- expectedControlFileContent +="Maintainer: Arcade \nInstalled-Size: 49697\nDescription: A simple test package\n This is a simple generated .deb package for testing purposes.\n";
+ expectedControlFileContent +="Maintainer: Arcade \nInstalled-Size: 48\nDescription: A simple test package\n This is a simple generated .deb package for testing purposes.\n";
ValidateProducedDebContent(Path.Combine(_tmpDir, "test.deb"), expectedFilesOriginalHashes, signableFiles, expectedControlFileContent);
}
@@ -1762,7 +1854,7 @@ public void CheckRpmSigningOnWindows()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1790,7 +1882,7 @@ public void CheckRpmSigning()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1833,7 +1925,7 @@ public void VerifyDebIntegrity()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
var expectedFilesToBeSigned = new List
{
@@ -1864,7 +1956,7 @@ public void VerifyRpmIntegrity()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
var expectedFilesToBeSigned = new List
{
@@ -1896,7 +1988,7 @@ public void CheckPowershellSigning()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1920,7 +2012,7 @@ public void VerifyNupkgIntegrity()
ValidateFileSignInfos(itemsToSign,
new Dictionary>(),
- new Dictionary(),
+ new Dictionary(),
s_fileExtensionSignInfo,
new[] { "File 'IncorrectlySignedPackage.1.0.0.nupkg' Certificate='NuGet'" });
}
@@ -1939,7 +2031,7 @@ public void SignNupkgWithUnsignedContents()
var strongNameSignInfo = new Dictionary>();
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -1967,7 +2059,7 @@ public void SignMsiEngine()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -2016,7 +2108,7 @@ public void SignBundleDoubleNested()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -2068,7 +2160,7 @@ public void MsiWithWixpack()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfoWithCollisionId, new[]
{
@@ -2135,7 +2227,7 @@ public void MPackFile()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary();
ValidateFileSignInfos(itemsToSign, strongNameSignInfo, fileSignInfo, s_fileExtensionSignInfo, new[]
{
@@ -2170,7 +2262,7 @@ public void VsixPackage_DuplicateVsixAfter()
};
// Overriding information
- var fileSignInfo = new Dictionary();
+ var fileSignInfo = new Dictionary