diff --git a/eng/pipelines/templates/jobs/ci.tests.yml b/eng/pipelines/templates/jobs/ci.tests.yml index 024ed415656..70c6c7b311b 100644 --- a/eng/pipelines/templates/jobs/ci.tests.yml +++ b/eng/pipelines/templates/jobs/ci.tests.yml @@ -17,6 +17,9 @@ parameters: type: number - name: TestProxy type: boolean +- name: InstallMsRust + type: boolean + default: false jobs: @@ -49,9 +52,42 @@ jobs: paths: - "/*" - - template: /eng/pipelines/templates/steps/use-rust.yml@self - parameters: - Toolchain: $(RustToolchainName) + - ${{ if eq(parameters.InstallMsRust, true) }}: + - pwsh: | + Move-Item $(Build.SourcesDirectory)/eng/templates/rust-toolchain.toml.template $(Build.SourcesDirectory)/rust-toolchain.toml -Force + displayName: 'Configure MS Rust rust-toolchain.toml' + + - task: RustInstaller@1 + inputs: + toolchainFeed: https://pkgs.dev.azure.com/azure-sdk/internal/_packaging/ms-rust-tools/nuget/v3/index.json + displayName: Install MS Rust toolchain + + # TODO: Refactor this into a template used in use-rust.yml + - pwsh: | + $cargoHome = $env:CARGO_HOME + if (-not $cargoHome) { $cargoHome = ([System.IO.Path]::Combine($HOME, '.cargo')) } + New-Item -ItemType Directory -Force -Path $cargoHome | Out-Null + + $configPath = ([System.IO.Path]::Combine($cargoHome, 'config.toml')) + Copy-Item ` + -Path '$(Build.SourcesDirectory)/eng/templates/config.toml.template' ` + -Destination $configPath ` + -Force + + Write-Host "Wrote cargo config to $configPath" + Get-Content $configPath + Write-Host "##vso[task.setvariable variable=CargoConfigPath]$configPath" + displayName: Configure cargo to use the azure-sdk-for-rust feed + + - task: CargoAuthenticate@0 + displayName: Authenticate cargo to the azure-sdk-for-rust feed + inputs: + configFile: $(CargoConfigPath) + + - ${{ else }}: + - template: /eng/pipelines/templates/steps/use-rust.yml@self + parameters: + Toolchain: $(RustToolchainName) - template: /eng/pipelines/templates/steps/nuget-config.yml diff --git a/eng/pipelines/templates/stages/archetype-sdk-client.yml b/eng/pipelines/templates/stages/archetype-sdk-client.yml index 8167c3d2cbf..0696ef5d378 100644 --- a/eng/pipelines/templates/stages/archetype-sdk-client.yml +++ b/eng/pipelines/templates/stages/archetype-sdk-client.yml @@ -124,6 +124,22 @@ extends: - ${{ parameters.AdditionalMatrixConfigs }} MatrixFilters: ${{ parameters.MatrixFilters }} MatrixReplace: ${{ parameters.MatrixReplace }} + - ${{ if eq(variables['System.TeamProject'], 'internal') }}: + - template: /eng/pipelines/templates/jobs/ci.tests.yml + parameters: + UsePlatformContainer: false + OSName: linux + # ci.tests.yml splices this into `$[ ... ]`, so it must be an expression + # fragment (not a JSON literal). `format` builds the single-leg matrix JSON + # at runtime with the pool/image variables already resolved. Matrix keys + # become job variables, so RUSTUP_EXE points the eng scripts at msrustup. + Matrix: format('{{"Linux-MSRust":{{"OSVmImage":"{0}","Pool":"{1}","RustToolchainName":"stable","RUSTUP_EXE":"msrustup"}}}}', variables['LINUXVMIMAGE'], variables['LINUXPOOL']) + DependsOn: '' + CloudConfig: Public + ServiceDirectory: ${{ parameters.ServiceDirectory }} + TimeoutInMinutes: ${{ parameters.TestTimeoutInMinutes }} + TestProxy: ${{ parameters.TestProxy }} + InstallMsRust: true # Run live tests for internal only, not public CI builds. This can be triggered manually via an `/azp run` comment. - ${{ if and(not(and(eq(parameters.SkipPrValidation, true), eq(variables['Build.Reason'], 'Manual'))), eq(variables['System.TeamProject'], 'internal'), eq(parameters.RunLiveTests, 'true')) }}: diff --git a/eng/scripts/shared/Cargo.ps1 b/eng/scripts/shared/Cargo.ps1 index a2fa0b78b08..8a0bf8f8000 100644 --- a/eng/scripts/shared/Cargo.ps1 +++ b/eng/scripts/shared/Cargo.ps1 @@ -2,15 +2,34 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +function Get-RustupExecutable() { + # msrustup manages MS Rust toolchains outside of rustup's registry, so rustup + # cannot resolve a custom channel like 'ms-prod-1.95' from rust-toolchain.toml. + # Jobs using MS Rust set RUSTUP_EXE to 'msrustup' to route toolchain queries there. + if ($env:RUSTUP_EXE) { + return $env:RUSTUP_EXE + } + + return 'rustup' +} + function Get-ActiveRustToolchain( [string]$ExecutePath ) { - $activeToolchain = (Invoke-LoggedCommand "rustup show active-toolchain" -ExecutePath $ExecutePath | Select-Object -First 1).Trim() + $rustup = Get-RustupExecutable + $output = Invoke-LoggedCommand "$rustup show active-toolchain" -ExecutePath $ExecutePath + + # msrustup prefixes its output with INFO lines, so take the first line that + # actually names a toolchain. + $activeToolchain = $output + | Where-Object { $_ -match '\S' -and $_ -notmatch '^\s*(INFO|WARN)\b' } + | Select-Object -First 1 + if (!$activeToolchain) { throw "Failed to determine the active Rust toolchain." } - return ($activeToolchain -split '\s+')[0] + return ($activeToolchain.Trim() -split '\s+')[0] } function Get-ResolvedRustToolchain( diff --git a/eng/templates/rust-toolchain.toml.template b/eng/templates/rust-toolchain.toml.template new file mode 100644 index 00000000000..3e72a02928d --- /dev/null +++ b/eng/templates/rust-toolchain.toml.template @@ -0,0 +1,12 @@ +[toolchain] +channel = "ms-prod-1.95" +# msrustup resolves `components` as host components only. The host `rust-std` ships +# with the toolchain, and additional target std libs go in `targets`, so listing +# "rust-std" here fails with US.host_component_not_found. +components = [ + "rustc", + "rustfmt", + "cargo", + "clippy", + "rust-analyzer", +]