Compare commits

...

7 Commits

Author SHA1 Message Date
Gordon Lam (SH)
31aba26780 ci(wtr): fix cargo build PowerShell script and add x86 triple mapping
Two fixes:
1. Replace splat-array invocation with explicit if/else branches.
   The splat was passing a malformed argument (cargo's clap reported
   'unexpected argument "-"').
2. Add 'x86' -> 'i686-pc-windows-msvc' case in the switch and include
   that target in RustInstaller's additionalTargets. The pipeline matrix
   builds x86 too, not just x64/arm64.

Also added a LASTEXITCODE check so cargo build failures surface
properly even with ErrorActionPreference set.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-11 11:22:47 +08:00
Gordon Lam (SH)
754fff6915 ci(wtr): drop cratesIoFeedOverride; let config.toml + CargoAuthenticate own the registry
Investigation of the failing build showed that RustInstaller's
cratesIoFeedOverride parameter injects an env-var registry named
'ms_crates_io' that CargoAuthenticate cannot discover (it scans config
files only), so the override registry stays unauthenticated and Azure
Artifacts returns 404 on its sparse-index endpoint:

  note: name of alternative registry [...sudo_public_cargo...] set to ms_crates_io
  error: failed to query replaced source registry 'crates-io'
  Caused by: config.json not found in registry

Fix: remove cratesIoFeedOverride. The registry + source replacement
already live in src/tools/wtr/.cargo/config.toml, which CargoAuthenticate
reads and tokens. Cargo's normal config-file resolution then picks up
the authenticated registry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-11 10:55:30 +08:00
Gordon Lam (SH)
2bbdaf2e29 ci(wtr): add CargoAuthenticate@0 to issue Bearer token for Cargo feed
Mirrors microsoft/edit's 1ES Rust workflow. Without explicit auth,
Azure Artifacts returns 404 on the sparse index endpoint and cargo
reports 'config.json not found in registry'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-11 07:49:57 +08:00
Gordon Lam (SH)
9905c7ba49 ci(wtr): move Rust step early, harden VC tools workaround for empty-folder case (DD-1541167)
- Move Rust install/build before vcpkg/nuget/Set-LatestVCToolsVersion so
  Rust pipeline validation is independent of C++ build env setup.
- Patch Set-LatestVCToolsVersion.ps1 to also detect empty/partial VC
  tools folders (package metadata advertises a version but the folder
  has no bin/). Falls back to scanning siblings for a directory whose
  bin subdir actually contains files. Hard-fail if none found.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-09 10:41:20 +08:00
Yeelam Gordon
c1453406f3 ci(wtr): default-enable Rust build for ADO smoke test
Flips enableRustBuild parameter default from false to true so the gated Rust steps run on this branch when no top-level pipeline forwards the parameter (none currently do).

Revert before merging to main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-08 12:31:15 +08:00
Gordon Lam (SH)
2eb4b9036d Forgot to add the empty one 2026-05-07 17:57:51 +08:00
Gordon Lam (SH)
edcf2fabe7 Add testing on Cargo.toml 2026-05-07 17:56:58 +08:00
9 changed files with 2370 additions and 2 deletions

View File

@@ -21,6 +21,10 @@ parameters:
displayName: "Build Everything (Overrides all other build options)"
type: boolean
default: false
- name: enableRustBuild
displayName: "Build src/tools/wtr (requires RustInstaller extension + microsoft/Dart Azure Artifact feeds)"
type: boolean
default: true
- name: pgoBuildMode
type: string
default: None
@@ -166,6 +170,80 @@ jobs:
.\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
displayName: Generate NOTICE.html from NOTICE.md
- ${{ if eq(parameters.enableRustBuild, true) }}:
# ────────────────────────────────────────────────────────────────────────
# Rust toolchain for src/tools/wtr (1ES-compliant pattern).
# Placed early — before vcpkg/nuget/VC-tools setup — so that Rust pipeline
# validation is independent of any C++ build environment problems.
#
# Pipeline lives at: https://microsoft.visualstudio.com/Dart/
# Reference for this pattern: microsoft/sudo (.pipelines/OneBranch.Common.yml)
#
# Compliance notes (per 1ES Rust workflow guidance):
# 1. Toolchain comes from the org-level `RustTools` Azure Artifact NuGet
# feed (already exists on `microsoft` ADO org; same feed used by
# microsoft/sudo, microsoft/vscode, microsoft/edit, microsoft/qdk).
# 2. Crates resolve through a project-level Azure Artifact Cargo feed
# named `Cargo` in microsoft/Dart (with crates.io upstream).
# 3. The Rust version uses the `ms-prod-X.YY` channel, pinned in
# `src/tools/wtr/rust-toolchain.toml`.
# 4. Component Governance scanning of Cargo.lock is auto-injected by
# 1ES PT (no extra task needed here).
#
# Prerequisites — until in place, leave `enableRustBuild` parameter false:
# - Azure Artifact Cargo feed `Cargo` exists in microsoft/Dart with
# `crates.io` upstream. (Project-scope, terminal team can create it.)
# - The CI account ("Project Collection Build Service (microsoft)") has
# at least Collaborator permission on the `RustTools` feed.
# ────────────────────────────────────────────────────────────────────────
- task: RustInstaller@1
displayName: Install Rust toolchain (MSRustup)
inputs:
rustVersion: ms-prod-1.93
toolchainFeed: https://pkgs.dev.azure.com/microsoft/_packaging/RustTools/nuget/v3/index.json
# NOTE: we deliberately do NOT set `cratesIoFeedOverride` here. That
# parameter injects an env-var registry override named `ms_crates_io`
# which CargoAuthenticate cannot see (it scans config files, not env
# vars), so the override registry ends up unauthenticated and Azure
# Artifacts returns 404 on its sparse-index endpoint.
# Instead, the registry + source replacement lives in
# src/tools/wtr/.cargo/config.toml — CargoAuthenticate@0 (next step)
# tokens it, and cargo's normal config-file resolution picks it up.
additionalTargets: 'x86_64-pc-windows-msvc i686-pc-windows-msvc aarch64-pc-windows-msvc'
# CargoAuthenticate issues a Bearer token (using System.AccessToken) for
# every Azure Artifacts Cargo feed referenced in the config file.
# Required: without it, Azure Artifacts returns 404 on the sparse index
# endpoint and cargo reports "config.json not found in registry".
# This is the canonical 1ES Rust auth pattern (mirrors microsoft/edit).
- task: CargoAuthenticate@0
displayName: Authenticate Cargo feeds
inputs:
configFile: src/tools/wtr/.cargo/config.toml
# Separate fetch step: some 1ES pools disable network during the build
# phase. Fetching upfront keeps `cargo build --frozen` fully offline.
- script: cargo fetch --manifest-path src/tools/wtr/Cargo.toml --locked
displayName: Fetch crates (offline-friendly)
- pwsh: |-
$ErrorActionPreference = 'Stop'
$triple = switch ('$(BuildPlatform)') {
'x64' { 'x86_64-pc-windows-msvc' }
'x86' { 'i686-pc-windows-msvc' }
'arm64' { 'aarch64-pc-windows-msvc' }
default { 'x86_64-pc-windows-msvc' }
}
$config = '$(BuildConfiguration)'
Write-Host "Building wtr for $triple ($config)"
if ($config -eq 'Release') {
cargo build --manifest-path src/tools/wtr/Cargo.toml --target $triple --frozen --release
} else {
cargo build --manifest-path src/tools/wtr/Cargo.toml --target $triple --frozen
}
if ($LASTEXITCODE -ne 0) { throw "cargo build failed with exit code $LASTEXITCODE" }
displayName: Build src/tools/wtr (Cargo)
- template: .\steps-install-vcpkg.yml
- template: .\steps-restore-nuget.yml

View File

@@ -10,13 +10,30 @@ $VCToolsRoot = Join-Path $VSRoot "VC\Tools\MSVC"
# differs from the version on the files themselves. We might as well check
# whether the version we just found _actually exists_ before we use it.
# We'll use whichever highest version exists.
#
# Some pool images report a package version (e.g. 14.44.35208) but ship only
# package metadata, not the actual toolchain — the version folder either
# doesn't exist or is empty. Detect both cases by also requiring a non-empty
# `bin` subdirectory (where cl.exe / link.exe live).
$PackageVCToolPath = Join-Path $VCToolsRoot $LatestVCToolsVersion
If ($Null -Eq (Get-Item $PackageVCToolPath -ErrorAction:Ignore)) {
$VCToolsVersions = Get-ChildItem $VCToolsRoot | ForEach-Object {
$PackageVCBinPath = Join-Path $PackageVCToolPath "bin"
$PackageIsValid = ($Null -Ne (Get-Item $PackageVCToolPath -ErrorAction:Ignore)) -And `
($Null -Ne (Get-Item $PackageVCBinPath -ErrorAction:Ignore))
If (-Not $PackageIsValid) {
$VCToolsVersions = Get-ChildItem $VCToolsRoot -Directory -ErrorAction:Ignore | Where-Object {
# Only consider directories that actually contain a populated `bin`.
$binDir = Join-Path $_.FullName "bin"
(Test-Path $binDir) -And ((Get-ChildItem $binDir -Recurse -File -ErrorAction:Ignore | Select-Object -First 1) -Ne $Null)
} | ForEach-Object {
[Version]$_.Name
} | Sort -Descending
$LatestActualVCToolsVersion = $VCToolsVersions | Select -First 1
If ($Null -Eq $LatestActualVCToolsVersion) {
Write-Error "No usable VC Tools installation found under $VCToolsRoot. Package version was $LatestVCToolsVersion. This typically indicates a partial/broken pool image (DD-1541167)."
Exit 1
}
If ([Version]$LatestVCToolsVersion -Ne $LatestActualVCToolsVersion) {
Write-Output "VC Tools Mismatch: Directory = $LatestActualVCToolsVersion, Package = $LatestVCToolsVersion"
$LatestVCToolsVersion = $LatestActualVCToolsVersion.ToString(3)

View File

@@ -24,6 +24,21 @@
<EntryPointProjectUniqueName>..\WindowsTerminal\WindowsTerminal.vcxproj</EntryPointProjectUniqueName>
<DebuggerType>NativeOnly</DebuggerType>
</PropertyGroup>
<!-- Map MSBuild Platform to Rust target triple for wtr.exe inclusion. -->
<PropertyGroup>
<WtrRustTarget Condition="'$(Platform)'=='x64'">x86_64-pc-windows-msvc</WtrRustTarget>
<WtrRustTarget Condition="'$(Platform)'=='ARM64'">aarch64-pc-windows-msvc</WtrRustTarget>
<WtrRustProfile Condition="'$(Configuration)'=='Debug'">debug</WtrRustProfile>
<WtrRustProfile Condition="'$(Configuration)'!='Debug'">release</WtrRustProfile>
</PropertyGroup>
<ItemGroup>
<Content Include="$(SolutionDir)src\tools\wtr\target\$(WtrRustTarget)\$(WtrRustProfile)\wtr.exe"
Condition="Exists('$(SolutionDir)src\tools\wtr\target\$(WtrRustTarget)\$(WtrRustProfile)\wtr.exe')">
<Link>wtr.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<PropertyGroup Condition="!Exists('CascadiaPackage_TemporaryKey.pfx')">
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<AppxBundle>Never</AppxBundle>

View File

@@ -0,0 +1,12 @@
# Cargo source replacement: route crates-io fetches through an Azure Artifact
# Cargo feed (1ES compliance — disallow direct public crates.io access).
#
# Reusing the sudo team's `sudo_public_cargo` feed in microsoft/Dart for now.
# TODO(wtr): replace with our own `microsoft/Dart` Cargo feed once provisioned.
[registries]
WindowsTerminalCargo = { index = "sparse+https://pkgs.dev.azure.com/microsoft/Dart/_packaging/sudo_public_cargo/Cargo/index/" }
[source.crates-io]
replace-with = "WindowsTerminalCargo"

1
src/tools/wtr/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target/

2208
src/tools/wtr/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

32
src/tools/wtr/Cargo.toml Normal file
View File

@@ -0,0 +1,32 @@
[package]
name = "wtr"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "wtr"
path = "src/main.rs"
[dependencies]
tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.7", features = ["compat"] }
async-trait = "0.1"
anyhow = "1"
serde_json = "1"
clap = { version = "4", features = ["derive"] }
ratatui = "0.30"
crossterm = { version = "0.29", features = ["event-stream"] }
futures = "0.3"
unicode-width = "0.2"
textwrap = "0.16"
base64 = "0.22"
serde = { version = "1", features = ["derive"] }
windows-sys = { version = "0.61", features = [
"Win32_Foundation",
"Win32_System_Environment",
"Win32_System_Registry",
"Win32_System_Threading",
] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
tracing-appender = "0.2"

View File

@@ -0,0 +1,4 @@
# Pin the Rust toolchain channel for both local dev and 1ES CI.
# Use the MSRustup `ms-prod-X.YY` channel for compliance.
[toolchain]
channel = "ms-prod-1.93"

View File

@@ -0,0 +1 @@
fn main() {}