diff --git a/.config/CredScanSuppressions.json b/.config/CredScanSuppressions.json index 28f5dd42f6..1780d0ab51 100644 --- a/.config/CredScanSuppressions.json +++ b/.config/CredScanSuppressions.json @@ -1,6 +1,7 @@ { "tool": "Credential Scanner", - "suppressions": [ + "suppressions": + [ { "file": "src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TDSServerArguments.cs", "justification": "Test projects should be skipped" diff --git a/.editorconfig b/.editorconfig index cbc3fa7858..9d8000b43f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -167,7 +167,9 @@ indent_size = 2 # Shell scripts [*.sh] +indent_size = 2 end_of_line = lf -[*.{cmd, bat}] +[*.{bat,cmd,ps1}] +indent_size = 2 end_of_line = crlf diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c5a76de2be..2197bda5f6 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -60,11 +60,7 @@ jobs: - name: Setup .NET Core SDK uses: actions/setup-dotnet@v5.0.1 with: - # TODO: Update this to .NET 10 once PR #3686 is complete. - # TODO: Replace this with global-json-file once PR #3797 is complete. - dotnet-version: 9.x - dotnet-quality: ga - #global-json-file: global.json + global-json-file: global.json # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index efeb747cad..c168d4cd18 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -2,6 +2,15 @@ This document provides all the necessary details to build the driver and run tests present in the repository. +## .NET SDK + +The projects in this repo require the .NET 10.0 SDK to build. Please ensure you +have the latest version of that SDK installed. + +Tests and tools may require different .NET Runtimes that may be installed +independently. For example, tests targeting .NET 8.0 will need that runtime +installed. + ## Visual Studio Pre-Requisites This project should be built with Visual Studio 2019+ for the best compatibility. The required set of components are provided in the below file: diff --git a/README.md b/README.md index 0397bae238..1a066c52d4 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,15 @@ When targeting .NET on Windows, a package reference to [Microsoft.Data.SqlClient | Topic | Link to File | | :---- | :------------- | -| Coding Style | [coding-style.md](/policy/coding-style.md) | | Best Practices | [coding-best-practices.md](/policy/coding-best-practices.md) | -| Review Process | [review-process.md](/policy/review-process.md) | -| Guidelines for building the driver | [BUILDGUIDE.md](BUILDGUIDE.md) | -| Guidelines for Contributors | [CONTRIBUTING.md](CONTRIBUTING.md) | -| Changelog for all driver releases | [CHANGELOG.md](CHANGELOG.md) | -| Support Policy | [SUPPORT.md](SUPPORT.md) | +| Build Guide | [BUILDGUIDE.md](/BUILDGUIDE.md) | +| Changelog | [CHANGELOG.md](CHANGELOG.md) | | Code of Conduct | [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) | +| Coding Style | [coding-style.md](/policy/coding-style.md) | +| Contributing | [CONTRIBUTING.md](CONTRIBUTING.md) | | Copyright Information | [COPYRIGHT.md](COPYRIGHT.md) | +| Review Process | [review-process.md](/policy/review-process.md) | +| Support Policy | [SUPPORT.md](SUPPORT.md) | ## Our Featured Contributors diff --git a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml index 7b72820534..795f172ed4 100644 --- a/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml +++ b/eng/pipelines/common/templates/jobs/ci-build-nugets-job.yml @@ -46,6 +46,9 @@ jobs: - ${{ if ne(parameters.prebuildSteps, '') }}: - ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration + # Install the .NET SDK. + - template: /eng/pipelines/steps/install-dotnet.yml@self + - template: ../steps/ci-project-build-step.yml@self parameters: platform: ${{ parameters.platform }} diff --git a/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml b/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml index de1397f680..e35bd8c4ad 100644 --- a/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml +++ b/eng/pipelines/common/templates/jobs/ci-code-coverage-job.yml @@ -59,16 +59,12 @@ jobs: - pwsh: 'Get-ChildItem env: | Sort-Object Name' displayName: '[Debug] List Environment Variables' - - template: ../steps/ensure-dotnet-version.yml@self + # Install the .NET SDK. + - template: /eng/pipelines/steps/install-dotnet.yml@self parameters: - packageType: sdk - version: '10.0' - - - template: ../steps/ensure-dotnet-version.yml@self - parameters: - packageType: runtime - version: '9.0' + debug: ${{ parameters.debug }} + # Install additional dotnet tools. - pwsh: | dotnet tool install --global dotnet-coverage dotnet tool install --global dotnet-reportgenerator-globaltool diff --git a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml index a2b7bdc2fa..2227625cad 100644 --- a/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml +++ b/eng/pipelines/common/templates/jobs/ci-run-tests-job.yml @@ -81,6 +81,11 @@ parameters: # The timeout, in minutes, for this job. - name: timeout type: number + + # True if this is an ARM64 job. + - name: isArm64 + type: boolean + default: false jobs: - job: ${{ format('{0}', coalesce(parameters.jobDisplayName, parameters.image, 'unknown_image')) }} @@ -102,6 +107,19 @@ jobs: value: '$(dotnetx86Path)' steps: + + # Install the .NET SDK and Runtimes. + - template: /eng/pipelines/steps/install-dotnet.yml@self + parameters: + ${{ if parameters.isArm64 }}: + architecture: arm64 + # ARM64 needs to specify slightly different runtime version formats. + # See the install-dotnet template docs for more info. + runtimes: ['8.0', '9.0'] + ${{ else }}: + runtimes: [8.x, 9.x] + debug: ${{ parameters.debug }} + - ${{ if ne(parameters.prebuildSteps, '') }}: - ${{ parameters.prebuildSteps }} # extra steps to run before the build like downloading sni and the required configuration @@ -121,6 +139,12 @@ jobs: } displayName: 'Verify Password' + - ${{ if eq(parameters.buildType, 'Project') }}: + - template: ../steps/ci-project-build-step.yml@self + parameters: + build: allNoDocs + buildConfiguration: ${{ parameters.buildConfiguration }} + - ${{ if ne(parameters.configProperties, '{}') }}: - template: ../steps/update-config-file-step.yml@self # update config.json file parameters: @@ -253,33 +277,14 @@ jobs: # it should be acceptable to just install a specific version in all cases. # @TODO: This setup is very confusing. Ideally we should just be utilizing the dotnet installation # earlier in the job. There has to be a cleaner way of doing this. - # As it stands now, we install dotnet LTS if we're running netfx tests, and the appropriate netX - # version if we're running netcore tests. Technically LTS is not supported by the UseDotNet task - # but we know we're using install-dotnet since we're on windows (for now ... this will not work - # forever and needs a serious rethinking). - ${{ if ne(variables['dotnetx86RootPath'], '') }}: - - ${{ if startswith(parameters.targetFramework, 'net4')}}: - - template: ../steps/ensure-dotnet-version.yml - parameters: - installDir: "$(dotnetx86RootPath)" - packageType: "sdk" - usePreview: "false" - version: "LTS" - windowsArchitecture: "x86" - - ${{ else }}: - - script: | - set FrameworkVersion=${{ parameters.targetFramework }} - echo %FrameworkVersion% - set TrimmedFrameworkVersion=%FrameworkVersion:~3% - echo %TrimmedFrameworkVersion% - echo ##vso[task.setvariable variable=netVersionX86]%TrimmedFrameworkVersion% - displayName: "Trim dotnet version" - - template: ../steps/ensure-dotnet-version.yml - parameters: - installDir: "$(dotnetx86RootPath)" - packageType: "sdk" - usePreview: "false" - version: $(netVersionX86) + # Install the .NET SDK and Runtimes for x86. + - template: /eng/pipelines/steps/install-dotnet.yml@self + parameters: + architecture: x86 + debug: ${{ parameters.debug }} + installDir: $(dotnetx86RootPath) + runtimes: [8.x, 9.x] - template: ../steps/run-all-tests-step.yml@self parameters: diff --git a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml index 363535aa7e..7676574451 100644 --- a/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml +++ b/eng/pipelines/common/templates/stages/ci-run-tests-stage.yml @@ -72,6 +72,7 @@ stages: publishTestResults: true configSqlFor: ${{ config.value.configSqlFor }} operatingSystem: ${{ config.value.operatingSystem }} + isArm64: ${{ eq(config.value.isArm64, 'true') }} ${{if ne(config.value.configProperties, '{}') }}: ${{ each x86TF in config.value.configProperties.x86TestTargetFrameworks }}: ${{ if eq(x86TF, targetFramework) }}: @@ -103,6 +104,7 @@ stages: publishTestResults: true configSqlFor: ${{ config.value.configSqlFor }} operatingSystem: ${{ config.value.operatingSystem }} + isArm64: ${{ eq(config.value.isArm64, 'true') }} ${{if and(eq(usemanagedSNI, false), ne(config.value.configProperties, '{}')) }}: ${{ each x86TF in config.value.configProperties.x86TestTargetFrameworks }}: ${{ if eq(x86TF, targetFramework) }}: diff --git a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml index ef19650643..8981f2d392 100644 --- a/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml +++ b/eng/pipelines/common/templates/steps/build-all-configurations-signed-dlls-step.yml @@ -25,34 +25,19 @@ parameters: - MSS steps: -- task: DownloadSecureFile@1 - displayName: 'Download Key Pair' - inputs: - secureFile: netfxKeypair.snk - retryCount: 5 - -- task: UseDotNet@2 - displayName: 'Use .NET 10.x sdk' - inputs: - packageType: sdk - version: '10.x' - -- task: UseDotNet@2 - displayName: 'Use .NET 9.x runtime' - inputs: - packageType: runtime - version: '9.x' + - task: DownloadSecureFile@1 + displayName: 'Download Key Pair' + inputs: + secureFile: netfxKeypair.snk + retryCount: 5 -- task: UseDotNet@2 - displayName: 'Install .NET 8.x runtime' - inputs: - packageType: runtime - version: '8.x' + # Install the .NET SDK. + - template: /eng/pipelines/steps/install-dotnet.yml@self -- ${{ if eq(parameters.product, 'MDS') }}: - - task: MSBuild@1 - displayName: 'BuildAllConfigurations using build.proj' - inputs: - solution: '**/build.proj' - configuration: '${{parameters.buildConfiguration }}' - msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAllConfigurations -p:GenerateNuget=false -p:SigningKeyPath=$(Agent.TempDirectory)\netfxKeypair.snk' + - ${{ if eq(parameters.product, 'MDS') }}: + - task: MSBuild@1 + displayName: 'BuildAllConfigurations using build.proj' + inputs: + solution: '**/build.proj' + configuration: '${{parameters.buildConfiguration }}' + msbuildArguments: '-p:AssemblyFileVersion=${{parameters.AssemblyFileVersion }} -t:BuildAllConfigurations -p:GenerateNuget=false -p:SigningKeyPath=$(Agent.TempDirectory)\netfxKeypair.snk' diff --git a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml index 4920482059..3774363ec3 100644 --- a/eng/pipelines/common/templates/steps/ci-prebuild-step.yml +++ b/eng/pipelines/common/templates/steps/ci-prebuild-step.yml @@ -25,24 +25,6 @@ parameters: - Package steps: -- template: ensure-dotnet-version.yml - parameters: - packageType: sdk - usePreview: false - version: 10.0 - -- template: ensure-dotnet-version.yml - parameters: - packageType: runtime - usePreview: false - version: 9.0 - -- template: ensure-dotnet-version.yml - parameters: - packageType: runtime - usePreview: false - version: 8.0 - - ${{if eq(parameters.debug, true)}}: - powershell: | Get-ChildItem env: | Sort-Object Name @@ -61,9 +43,3 @@ steps: parameters: downloadedNugetPath: $(Pipeline.Workspace)\${{parameters.artifactName }} debug: ${{ parameters.debug }} - -- ${{ else }}: # project - - template: ci-project-build-step.yml@self - parameters: - build: allNoDocs - buildConfiguration: ${{ parameters.buildConfiguration }} diff --git a/eng/pipelines/common/templates/steps/ci-project-build-step.yml b/eng/pipelines/common/templates/steps/ci-project-build-step.yml index 2b40aa8216..919958e8a2 100644 --- a/eng/pipelines/common/templates/steps/ci-project-build-step.yml +++ b/eng/pipelines/common/templates/steps/ci-project-build-step.yml @@ -37,21 +37,6 @@ parameters: - allNoDocs steps: -- template: ./ensure-dotnet-version.yml@self - parameters: - packageType: 'sdk' - version: '10.0' - -- template: ./ensure-dotnet-version.yml@self - parameters: - packageType: 'runtime' - version: '9.0' - -- template: ./ensure-dotnet-version.yml@self - parameters: - packageType: 'runtime' - version: '8.0' - - ${{ if or(eq(parameters.operatingSystem, 'Windows'), eq(parameters.operatingSystem, 'deferedToRuntime')) }}: - ${{ if or(eq(parameters.build, 'MDS'), eq(parameters.build, 'all'), eq(parameters.build, 'allNoDocs')) }}: - task: MSBuild@1 diff --git a/eng/pipelines/common/templates/steps/ensure-dotnet-version.yml b/eng/pipelines/common/templates/steps/ensure-dotnet-version.yml deleted file mode 100644 index fd6ba9674b..0000000000 --- a/eng/pipelines/common/templates/steps/ensure-dotnet-version.yml +++ /dev/null @@ -1,108 +0,0 @@ -################################################################################# -# Licensed to the .NET Foundation under one or more agreements. # -# The .NET Foundation licenses this file to you under the MIT license. # -# See the LICENSE file in the project root for more information. # -################################################################################# - -# Installs dotnet sdk/runtime using UseDotNet on non-windows agents, but uses a custom ps script -# for installation on Windows. -# -# Reason for not using UseDotNet task: -# [BUG]: UseDotNet task installs x86 build on Windows arm64 -# https://github.com/microsoft/azure-pipelines-tasks/issues/20300 - -parameters: - - # Directory where dotnet binaries should be installed. If not specified, defaults to the - # agent's tools directory. - name: installDir - type: string - default: '' - - - # Whether to install the full SDK or the "dotnet" runtime - name: packageType - type: string - values: - - runtime - - sdk - - - # Whether to enable preview versions of dotnet - name: usePreview - type: boolean - default: false - - - # Version to install - supports full major.minor.patch, but can be shortened to major.minor - # to get the latest within a given channel. Do not append .x to the end (as per UseDotNet), - # it is not supported by dotnet-install script, and we will add it if we use UseDotNet task. - name: version - type: string - - - # Specifies the architecture to install, only applies on Windows agents. If not provided, - # defaults to the same architecture as the agent. - name: windowsArchitecture - type: string - default: '' - values: - - '' - - 'x86' - - 'x64' - - 'arm64' - -steps: - # Note: as much as I'd love to use template expressions here, I can't because ${{ }} is - # evaluated at compile time, while Agent is not known until runtime. - - powershell: |- - # Propagate parameters from pipeline ####################### - $agentToolsDir = '$(Agent.ToolsDirectory)' - echo "agentToolsDir= $agentToolsDir" - - $architecture = '${{ parameters.windowsArchitecture }}' - echo "architecture= $architecture" - - $installDir = '${{ parameters.installDir }}' - echo "installDir= $installDir" - - $packageType = '${{ parameters.packageType }}' - echo "packageType= $packageType" - - $usePreview = '${{ parameters.usePreview }}' - echo "usePreview= $usePreview" - - $version = '${{ parameters.version }}' - echo "version= $version" - - # Install dotnet ########################################### - Invoke-WebRequest -Uri "https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1" - - $installDir = If ($installDir) { $installDir } Else { $agentToolsDir } - $installParams = @{ - Architecture = $architecture - Channel = $version - InstallDir = $installDir - Quality = If ($usePreview) { "GA" } Else { "preview" } - } - - if ($packageType -eq 'runtime') { - $installParams.add('Runtime', 'dotnet') - } - - & ./dotnet-install.ps1 @installParams - Remove-Item dotnet-install.ps1 -ErrorAction:Ignore - - # Propagate values back out to pipeline #################### - Write-Host "##vso[task.setvariable variable=DOTNET_ROOT]${installDir}" - Write-Host "##vso[task.prependpath]${installDir}" - displayName: 'Install dotnet ${{ parameters.version }} ${{ parameters.packageType }} for Windows ${{ parameters.windowsArchitecture }}' - condition: eq(variables['Agent.OS'], 'Windows_NT') - - - task: UseDotNet@2 - displayName: 'Install dotnet ${{ parameters.version }} ${{ parameters.packageType }}' - inputs: - ${{ if ne(parameters.installDir, '') }}: - installationPath: '${{ parameters.installDir }}' - ${{ else }}: - installationPath: '$(Agent.ToolsDirectory)' - packageType: '${{ parameters.packageType }}' - version: '${{ parameters.version }}.x' - - includePreviewVersions: '${{ parameters.usePreview }}' - condition: ne(variables['Agent.OS'], 'Windows_NT') diff --git a/eng/pipelines/common/templates/steps/pre-build-step.yml b/eng/pipelines/common/templates/steps/pre-build-step.yml index cfcd9a46f8..068223af70 100644 --- a/eng/pipelines/common/templates/steps/pre-build-step.yml +++ b/eng/pipelines/common/templates/steps/pre-build-step.yml @@ -4,33 +4,22 @@ # See the LICENSE file in the project root for more information. # ################################################################################# steps: -- template: ./ensure-dotnet-version.yml@self - parameters: - packageType: 'sdk' - version: '10.0' - usePreview: false + # Install the .NET SDK and Runtimes. + - template: /eng/pipelines/steps/install-dotnet.yml@self + parameters: + runtimes: [8.x, 9.x] -- template: ./ensure-dotnet-version.yml@self - parameters: - packageType: 'runtime' - version: '9.0' + - script: SET + displayName: 'Print Environment Variables' -- template: ./ensure-dotnet-version.yml@self - parameters: - packageType: 'runtime' - version: '8.0' + - powershell: | + # use sqlcmd to try to connect to localdb + $svc_name = "SQLBrowser" + Get-Service $svc_name | Select-Object -Property Name, StartType, Status + Set-Service -StartupType Automatic $svc_name + net start $svc_name + Get-Service $svc_name | Select-Object -Property Name, StartType, Status + displayName: 'Start SQLBrowser' -- script: SET - displayName: 'Print Environment Variables' - -- powershell: | - # use sqlcmd to try to connect to localdb - $svc_name = "SQLBrowser" - Get-Service $svc_name | Select-Object -Property Name, StartType, Status - Set-Service -StartupType Automatic $svc_name - net start $svc_name - Get-Service $svc_name | Select-Object -Property Name, StartType, Status - displayName: 'Start SQLBrowser' - -- task: NuGetToolInstaller@1 - displayName: 'Use NuGet' + - task: NuGetToolInstaller@1 + displayName: 'Use NuGet' diff --git a/eng/pipelines/common/templates/steps/prepare-test-db-step.yml b/eng/pipelines/common/templates/steps/prepare-test-db-step.yml index 3e01a7a9dc..250fab772a 100644 --- a/eng/pipelines/common/templates/steps/prepare-test-db-step.yml +++ b/eng/pipelines/common/templates/steps/prepare-test-db-step.yml @@ -10,7 +10,7 @@ parameters: - name: targetFramework type: string - default: net9.0 + default: net10.0 steps: - task: DotNetCoreCLI@2 diff --git a/eng/pipelines/dotnet-sqlclient-ci-core.yml b/eng/pipelines/dotnet-sqlclient-ci-core.yml index f94432880f..ac45df95b1 100644 --- a/eng/pipelines/dotnet-sqlclient-ci-core.yml +++ b/eng/pipelines/dotnet-sqlclient-ci-core.yml @@ -228,7 +228,7 @@ stages: pool: ${{parameters.defaultPoolName }} # pool name images: # list of images to run tests on Win22_Sql19_x86: ADO-MMS22-SQL19 # stage display name: image name from the pool - TargetFrameworks: [net8.0] #[net462, net8.0] # list of target frameworks to run + TargetFrameworks: [net462, net8.0, net9.0] netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }} buildPlatforms: ${{parameters.buildPlatforms }} testSets: ${{parameters.testSets }} # [1, 2, 3] # list of test sets to run @@ -249,7 +249,7 @@ stages: LocalDbSharedInstanceName: $(LocalDbSharedInstanceName) AliasName: $(SQLAliasName) # extra config properties - x86TestTargetFrameworks: [net8.0] # target frameworks should run tests on x86 + x86TestTargetFrameworks: [net462, net8.0, net9.0] SQLRootPath: $(SQL19RootPath) enableLocalDB: true # instanceName: default: MSSQLSERVER @@ -299,7 +299,7 @@ stages: pool: ${{parameters.defaultPoolName }} images: Win22_Sql22_x86: ADO-MMS22-SQL22 - TargetFrameworks: [net462] + TargetFrameworks: [net462, net8.0, net9.0] netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }} buildPlatforms: ${{parameters.buildPlatforms }} testSets: ${{parameters.testSets }} @@ -320,7 +320,7 @@ stages: LocalDbSharedInstanceName: $(LocalDbSharedInstanceName) AliasName: $(SQLAliasName) # extra config properties - x86TestTargetFrameworks: [net462] # target frameworks should run tests on x86 as well + x86TestTargetFrameworks: [net462, net8.0, net9.0] SQLRootPath: $(SQL22RootPath) enableLocalDB: true @@ -385,6 +385,7 @@ stages: pool: ADO-CI-PUBLIC-ARM64-1ES-EUS-POOL images: Win11_ARM64_Azure_Sql: ADO-WIN11-ARM64 + isArm64: true, TargetFrameworks: ${{parameters.targetFrameworks }} netcoreVersionTestUtils: ${{parameters.netcoreVersionTestUtils }} buildPlatforms: ${{parameters.buildPlatforms }} diff --git a/eng/pipelines/jobs/stress-tests-ci-job.yml b/eng/pipelines/jobs/stress-tests-ci-job.yml index 2e01470fe5..5683382597 100644 --- a/eng/pipelines/jobs/stress-tests-ci-job.yml +++ b/eng/pipelines/jobs/stress-tests-ci-job.yml @@ -131,19 +131,10 @@ jobs: steps: - # Install the .NET 9.0 SDK. - - task: UseDotNet@2 - displayName: Install .NET 9.0 SDK - inputs: - packageType: sdk - version: 9.x - - # Install the .NET 8.0 runtime. - - task: UseDotNet@2 - displayName: Install .NET 8.0 Runtime - inputs: - packageType: runtime - version: 8.x + # Install the .NET SDK and Runtimes. + - template: /eng/pipelines/steps/install-dotnet.yml@self + parameters: + runtimes: [8.x, 9.x] # Download the pipeline artifact that contains the MDS package to test. - task: DownloadPipelineArtifact@2 diff --git a/eng/pipelines/stages/stress-tests-ci-stage.yml b/eng/pipelines/stages/stress-tests-ci-stage.yml index b7cea84b82..1a2ace53c0 100644 --- a/eng/pipelines/stages/stress-tests-ci-stage.yml +++ b/eng/pipelines/stages/stress-tests-ci-stage.yml @@ -60,7 +60,7 @@ parameters: - name: netFrameworkTestRuntimes displayName: .NET Framework Test Runtimes type: object - default: [net462, net47, net471, net472, net48, net481] + default: [net462] # The verbosity level for the dotnet CLI commands. - name: verbosity diff --git a/eng/pipelines/steps/compound-build-akv-step.yml b/eng/pipelines/steps/compound-build-akv-step.yml index 2dd21d8514..ce8da41d52 100644 --- a/eng/pipelines/steps/compound-build-akv-step.yml +++ b/eng/pipelines/steps/compound-build-akv-step.yml @@ -10,54 +10,39 @@ # @TODO: NugetPackageVersion should not be used for MDS package version parameters: - - name: assemblyFileVersion - type: string + - name: assemblyFileVersion + type: string - - name: buildConfiguration - type: string - values: - - Debug - - Release + - name: buildConfiguration + type: string + values: + - Debug + - Release - - name: mdsPackageVersion - type: string + - name: mdsPackageVersion + type: string steps: - - task: DownloadSecureFile@1 - displayName: 'Download Signing Key' - inputs: - retryCount: 5 - secureFile: 'netfxKeypair.snk' - - - task: UseDotNet@2 - displayName: 'Install .NET 10.x SDK' - inputs: - packageType: 'sdk' - version: '10.x' - - - task: UseDotNet@2 - displayName: 'Install .NET 9.x Runtime' - inputs: - packageType: 'runtime' - version: '9.x' - - - task: UseDotNet@2 - displayName: 'Install .NET 8.x Runtime' - inputs: - packageType: 'runtime' - version: '8.x' - - - task: MSBuild@1 - displayName: 'Build.proj - BuildAkv' - inputs: - solution: '$(REPO_ROOT)/build.proj' - configuration: '${{ parameters.buildConfiguration }}' - msbuildArguments: >- - -t:BuildAkv - -p:AssemblyFileVersion=${{ parameters.assemblyFileVersion }} - -p:NugetPackageVersion=${{ parameters.mdsPackageVersion }} - -p:ReferenceType=Package - -p:SigningKeyPath=$(Agent.TempDirectory)/netfxKeypair.snk - - - script: tree /a /f $(BUILD_OUTPUT) - displayName: Output Build Output Tree + - task: DownloadSecureFile@1 + displayName: 'Download Signing Key' + inputs: + retryCount: 5 + secureFile: 'netfxKeypair.snk' + + # Install the .NET SDK. + - template: /eng/pipelines/steps/install-dotnet.yml@self + + - task: MSBuild@1 + displayName: 'Build.proj - BuildAkv' + inputs: + solution: '$(REPO_ROOT)/build.proj' + configuration: '${{ parameters.buildConfiguration }}' + msbuildArguments: >- + -t:BuildAkv + -p:AssemblyFileVersion=${{ parameters.assemblyFileVersion }} + -p:NugetPackageVersion=${{ parameters.mdsPackageVersion }} + -p:ReferenceType=Package + -p:SigningKeyPath=$(Agent.TempDirectory)/netfxKeypair.snk + + - script: tree /a /f $(BUILD_OUTPUT) + displayName: Output Build Output Tree diff --git a/eng/pipelines/steps/install-dotnet-arm64.ps1 b/eng/pipelines/steps/install-dotnet-arm64.ps1 new file mode 100644 index 0000000000..f73ade7ac0 --- /dev/null +++ b/eng/pipelines/steps/install-dotnet-arm64.ps1 @@ -0,0 +1,151 @@ +<# +.SYNOPSIS + This script installs dotnet SDKs and Runtimes for ARM64. + +.DESCRIPTION + Special handling is required for ARM64 due to a bug in UseDotNet@2: + + [BUG]: UseDotNet@2 task installs x86 build + https://github.com/microsoft/azure-pipelines-tasks/issues/20300 + + The downloaded dotnet-install.ps1 script is kept in the $InstallDir to avoid + downloading it multiple times during the pipeline job. + + The following environment variables are set for subsequent steps in the pipeline: + + DOTNET_ROOT: Set to $InstallDir. + PATH: $DOTNET_ROOT is prepended to the PATH environment variable. + +.PARAMETER Debug + True to emit debug messages. Default is false. + +.PARAMETER DryRun + True to perform a dry run of the installation. Default is false. + +.PARAMETER GlobalJson + The path to the global.json file that specifies the exact SDK version to + install. Default is 'global.json'. + +.PARAMETER InstallDir + The directory to install the SDKs and Runtimes into, typically the + pipeline's $(Agent.ToolsDirectory)/dotnet directory. + + The dotnet-install.ps1 script is downloaded into this directory if it is not + already present. + + Default is '.'. + +.PARAMETER Runtimes + The versions of the .NET Runtimes to install. These must be in the runtime + channel format of X.Y expected by the dotnet-install.ps1 script. Default is + an empty array. + +.NOTES + Licensed to the .NET Foundation under one or more agreements. + The .NET Foundation licenses this file to you under the MIT license. + See the LICENSE file in the project root for more information. +#> + +param +( + [switch]$Debug, + [switch]$DryRun, + [string]$GlobalJson = "global.json", + [string]$InstallDir = '.', + [string[]]$Runtimes = @() +) + +#------------------------------------------------------------------------------ +# Emit our command-line arguments. + +if ($Debug) +{ + Write-Host "Command-line arguments:" + Write-Host ($PSBoundParameters | ConvertTo-Json -Depth 1) +} + +#------------------------------------------------------------------------------ +# Download the dotnet-install.ps1 script if it isn't already present. + +if (-not (Test-Path -Path "$InstallDir/dotnet-install.ps1" -PathType Leaf)) +{ + Write-Host "Downloading dotnet-install.ps1..." + + Invoke-WebRequest ` + -Uri "https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1" ` + -OutFile "$InstallDir/dotnet-install.ps1" ` + -Verbose:$Debug + + if ($Debug) + { + Write-Host "Emitting dotnet-install.ps1 help:" + Get-Help "$InstallDir/dotnet-install.ps1" + } +} + +#------------------------------------------------------------------------------ +# Read the SDK versions from global.json. + +$globalJsonContent = Get-Content -Raw -Path "$GlobalJson" | ConvertFrom-Json +$sdkVersion = $globalJsonContent.sdk.version + +if ($Debug) +{ + Write-Host "global.json content:" + Write-Host ($globalJsonContent | ConvertTo-Json -Depth 1) + + Write-Host "SDK version: $sdkVersion" +} + +#------------------------------------------------------------------------------ +# Install the SDK. + +Write-Host "Installing .NET SDK version: $sdkVersion" + +$installParams = +@{ + Architecture = "arm64" + Version = "$sdkVersion" + InstallDir = "$InstallDir" +} + +if ($Debug) +{ + Write-Host "dotnet-install.ps1 parameters:" + Write-Host ($installParams | ConvertTo-Json -Depth 1) +} + +& ./dotnet-install.ps1 -Verbose:$Debug -DryRun:$DryRun @installParams + +#------------------------------------------------------------------------------ +# Install the Runtimes, if any. + +foreach ($channel in $Runtimes) +{ + Write-Host "Installing .NET Runtime GA channel: $channel" + + $installParams = + @{ + Architecture = "arm64" + Channel = "$channel" + InstallDir = "$InstallDir" + Quality = "GA" + Runtime = "dotnet" + } + + if ($Debug) + { + Write-Host "dotnet-install.ps1 parameters:" + Write-Host ($installParams | ConvertTo-Json -Depth 1) + } + + & ./dotnet-install.ps1 -Verbose:$Debug -DryRun:$DryRun @installParams +} + +#------------------------------------------------------------------------------ +# Set the DOTNET_ROOT environment variable, and add the tools dir to the path. +# These values propagate back out to the pipeline and are used by subsequent +# steps. + +Write-Host "##vso[task.setvariable variable=DOTNET_ROOT]$InstallDir" +Write-Host "##vso[task.prependpath]$InstallDir" diff --git a/eng/pipelines/steps/install-dotnet.yml b/eng/pipelines/steps/install-dotnet.yml new file mode 100644 index 0000000000..397ea897a2 --- /dev/null +++ b/eng/pipelines/steps/install-dotnet.yml @@ -0,0 +1,98 @@ +################################################################################ +# Licensed to the .NET Foundation under one or more agreements. # +# The .NET Foundation licenses this file to you under the MIT license. # +# See the LICENSE file in the project root for more information. # +################################################################################ + +# This template installs a single .NET SDK and zero or more .NET Runtimes. The +# SDK version is always read from the root global.json file. The Runtimes to +# install, if any, may be provided as an array of version strings. +# +# Special handling is required for ARM64 due to a bug in UseDotNet@2: +# +# [BUG]: UseDotNet@2 task installs x86 build +# https://github.com/microsoft/azure-pipelines-tasks/issues/20300 + +parameters: + + # The architecture to install for. + - name: architecture + type: string + values: + - x64 + - x86 + - arm64 + default: x64 + + # True to enable debug logging. + - name: debug + type: boolean + default: false + + # The directory to install to. + - name: installDir + type: string + default: $(Agent.ToolsDirectory)/dotnet + + # The list of .NET Runtimes to install, if any. + # + # When architecture is arm64, these must adhere to the format expected by the + # dotnet-install.ps1 script's -Channel option: + # + # https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script + # + # Otherwise, these must adhere to the format expected by the UseDotNet@2 task: + # + # https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/use-dotnet-v2 + # + - name: runtimes + type: object + default: [] + +steps: + + # Use the UseDotNet@2 task for all architectures except ARM64. + - ${{ if ne(parameters.architecture, 'arm64') }}: + + # Install the SDK listed in the global.json file. + - task: UseDotNet@2 + displayName: Install .NET SDK (global.json) + inputs: + installationPath: ${{ parameters.installDir }} + packageType: sdk + useGlobalJson: true + ${{ if eq(parameters.architecture, 'x86') }}: + env: + PROCESSOR_ARCHITECTURE: x86 + + # Install the desired Runtimes, if any. + - ${{ each version in parameters.runtimes }}: + - task: UseDotNet@2 + displayName: Install .NET ${{ version }} Runtime + inputs: + installationPath: ${{ parameters.installDir }} + packageType: runtime + version: ${{ version }} + ${{ if eq(parameters.architecture, 'x86') }}: + env: + PROCESSOR_ARCHITECTURE: x86 + + # Special handling for ARM64. + - ${{ else }}: + + # Use the install script for ARM64. + - task: PowerShell@2 + displayName: Install .NET SDK and Runtimes for ARM64 + pwsh: true + filePath: install-dotnet-arm64.ps1 + # Each runtime must be quoted to avoid PowerShell interpreting them as + # decimal numbers and truncating the fractional part. + arguments: > + -Debug:${{ parameters.debug }} + -GlobalJson "$(Build.SourcesDirectory)/global.json" + -InstallDir "${{ parameters.installDir }}" + -Runtimes "${{ join(parameters.runtimes, '", "') }}" + + # Report what was installed. + - pwsh: dotnet --info + displayName: Report installed .NET SDK and Runtimes diff --git a/global.json b/global.json new file mode 100644 index 0000000000..b0b5938971 --- /dev/null +++ b/global.json @@ -0,0 +1,29 @@ +{ + "sdk": + { + // We currently require the .NET 10 SDK to build and test the project. + // + // We specify the most recent release, and let rollForward pick the latest + // available suitable SDK per the rollForward setting. + // + // We must specify a complete version here since this file is also used by + // the Azure Pipelines UseDotNet@2 task, which doesn't support wildcards, + // and won't roll-forward. It uses the version verbatim. + // + // GOTCHA: This file is only used by the dotnet CLI and related tools. + // Other toolchains (IDEs like Visual Studio, the .NET Framework MSBuild + // system, etc.) may use their own installed SDKs unless configured + // otherwise. + // + "version": "10.0.100", + + // Any 10.x version is acceptable. + "rollForward": "latestMinor", + + // Do not allow pre-release versions. + // + // Set this to true if you are testing the viability of pre-release SDK + // versions in your local workspace. + "allowPrerelease": false + } +} diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln index 6696a8a31d..015bc91135 100644 --- a/src/Microsoft.Data.SqlClient.sln +++ b/src/Microsoft.Data.SqlClient.sln @@ -255,7 +255,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "steps", "steps", "{EABE3A3E ..\eng\pipelines\common\templates\steps\configure-sql-server-step.yml = ..\eng\pipelines\common\templates\steps\configure-sql-server-step.yml ..\eng\pipelines\common\templates\steps\configure-sql-server-win-step.yml = ..\eng\pipelines\common\templates\steps\configure-sql-server-win-step.yml ..\eng\pipelines\common\templates\steps\copy-dlls-for-test-step.yml = ..\eng\pipelines\common\templates\steps\copy-dlls-for-test-step.yml - ..\eng\pipelines\common\templates\steps\ensure-dotnet-version.yml = ..\eng\pipelines\common\templates\steps\ensure-dotnet-version.yml ..\eng\pipelines\common\templates\steps\esrp-code-signing-step.yml = ..\eng\pipelines\common\templates\steps\esrp-code-signing-step.yml ..\eng\pipelines\common\templates\steps\generate-nuget-package-step.yml = ..\eng\pipelines\common\templates\steps\generate-nuget-package-step.yml ..\eng\pipelines\common\templates\steps\override-sni-version.yml = ..\eng\pipelines\common\templates\steps\override-sni-version.yml @@ -297,6 +296,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "steps", "steps", "{AD738BD4 ..\eng\pipelines\steps\compound-publish-symbols-step.yml = ..\eng\pipelines\steps\compound-publish-symbols-step.yml ..\eng\pipelines\steps\roslyn-analyzers-akv-step.yml = ..\eng\pipelines\steps\roslyn-analyzers-akv-step.yml ..\eng\pipelines\steps\script-output-environment-variables-step.yml = ..\eng\pipelines\steps\script-output-environment-variables-step.yml + ..\eng\pipelines\steps\install-dotnet.yml = ..\eng\pipelines\steps\install-dotnet.yml + ..\eng\pipelines\steps\install-dotnet-arm64.ps1 = ..\eng\pipelines\steps\install-dotnet-arm64.ps1 EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Data.SqlClient.UnitTests", "Microsoft.Data.SqlClient\tests\UnitTests\Microsoft.Data.SqlClient.UnitTests.csproj", "{4461063D-2F2B-274C-7E6F-F235119D258E}"