Skip to content

Commit b2c4acc

Browse files
awakecodingCopilot
andcommitted
Add Windows release package workflow
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 44000c2 commit b2c4acc

7 files changed

Lines changed: 490 additions & 57 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
name: Windows packages
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
package:
10+
name: Package ${{ matrix.label }}
11+
runs-on: windows-latest
12+
timeout-minutes: 60
13+
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
include:
18+
- label: windows-x64
19+
rust_target: x86_64-pc-windows-msvc
20+
nuget_arch: amd64
21+
vcvars_arch: x64
22+
artifact: windbg-tool-windows-x64
23+
can_run: true
24+
- label: windows-arm64
25+
rust_target: aarch64-pc-windows-msvc
26+
nuget_arch: arm64
27+
vcvars_arch: x64_arm64
28+
artifact: windbg-tool-windows-arm64
29+
can_run: false
30+
31+
env:
32+
CARGO_TERM_COLOR: always
33+
RUSTFLAGS: -C target-feature=+crt-static
34+
35+
steps:
36+
- name: Checkout
37+
uses: actions/checkout@v5
38+
39+
- name: Select stable Rust
40+
shell: pwsh
41+
run: |
42+
rustup default stable
43+
rustup target add ${{ matrix.rust_target }}
44+
45+
- name: Restore debugger dependencies
46+
shell: pwsh
47+
run: cargo xtask deps --arch ${{ matrix.nuget_arch }}
48+
49+
- name: Ensure ARM64 MSVC toolset
50+
if: matrix.nuget_arch == 'arm64'
51+
shell: pwsh
52+
run: |
53+
$ErrorActionPreference = 'Stop'
54+
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
55+
$installer = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vs_installer.exe'
56+
if (-not (Test-Path $vswhere)) {
57+
throw "vswhere.exe was not found at $vswhere"
58+
}
59+
if (-not (Test-Path $installer)) {
60+
throw "vs_installer.exe was not found at $installer"
61+
}
62+
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
63+
if (-not $installationPath) {
64+
throw 'Could not find a Visual Studio installation with the MSVC x64 toolset'
65+
}
66+
& $installer modify `
67+
--installPath $installationPath `
68+
--add Microsoft.VisualStudio.Component.VC.Tools.ARM64 `
69+
--quiet `
70+
--norestart `
71+
--nocache `
72+
--wait
73+
if (($LASTEXITCODE -ne 0) -and ($LASTEXITCODE -ne 3010)) {
74+
exit $LASTEXITCODE
75+
}
76+
77+
- name: Build native bridge
78+
shell: pwsh
79+
run: |
80+
$ErrorActionPreference = 'Stop'
81+
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
82+
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
83+
if (-not $installationPath) {
84+
throw 'Could not find a Visual Studio installation with the MSVC x64 toolset'
85+
}
86+
$vcvars = Join-Path $installationPath 'VC\Auxiliary\Build\vcvarsall.bat'
87+
cmd /c "`"$vcvars`" ${{ matrix.vcvars_arch }} && cargo xtask native-build --arch ${{ matrix.nuget_arch }} --static-crt"
88+
89+
- name: Build windbg-tool
90+
shell: pwsh
91+
run: |
92+
$ErrorActionPreference = 'Stop'
93+
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
94+
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
95+
if (-not $installationPath) {
96+
throw 'Could not find a Visual Studio installation with the MSVC x64 toolset'
97+
}
98+
$vcvars = Join-Path $installationPath 'VC\Auxiliary\Build\vcvarsall.bat'
99+
cmd /c "`"$vcvars`" ${{ matrix.vcvars_arch }} && cargo build -p windbg-tool --release --target ${{ matrix.rust_target }}"
100+
101+
- name: Package runtime files
102+
shell: pwsh
103+
run: |
104+
cargo xtask package `
105+
--arch ${{ matrix.nuget_arch }} `
106+
--target ${{ matrix.rust_target }} `
107+
--profile release `
108+
--out "target\package\${{ matrix.artifact }}"
109+
110+
- name: Validate package and create ZIP
111+
shell: pwsh
112+
run: |
113+
$ErrorActionPreference = 'Stop'
114+
115+
$packageDir = Join-Path $PWD 'target\package\${{ matrix.artifact }}'
116+
$zipPath = Join-Path $PWD 'target\package\${{ matrix.artifact }}.zip'
117+
$requiredFiles = @(
118+
'windbg-tool.exe',
119+
'ttd_replay_bridge.dll',
120+
'TTDReplay.dll',
121+
'TTDReplayCPU.dll',
122+
'dbgeng.dll',
123+
'dbgcore.dll',
124+
'dbghelp.dll',
125+
'dbgmodel.dll',
126+
'msdia140.dll',
127+
'symsrv.dll',
128+
'srcsrv.dll'
129+
)
130+
131+
foreach ($file in $requiredFiles) {
132+
$path = Join-Path $packageDir $file
133+
if (-not (Test-Path $path)) {
134+
throw "Package is missing required file: $file"
135+
}
136+
}
137+
138+
if ('${{ matrix.can_run }}' -eq 'true') {
139+
Push-Location $packageDir
140+
try {
141+
& '.\windbg-tool.exe' discover | Out-Null
142+
}
143+
finally {
144+
Pop-Location
145+
}
146+
}
147+
148+
if (Test-Path $zipPath) {
149+
Remove-Item $zipPath -Force
150+
}
151+
Compress-Archive -Path (Join-Path $packageDir '*') -DestinationPath $zipPath -Force
152+
153+
Add-Type -AssemblyName System.IO.Compression.FileSystem
154+
$zip = [System.IO.Compression.ZipFile]::OpenRead($zipPath)
155+
try {
156+
$entries = @($zip.Entries | ForEach-Object { $_.FullName.Replace('/', '\') })
157+
foreach ($file in $requiredFiles) {
158+
if ($entries -notcontains $file) {
159+
throw "ZIP is missing required file: $file"
160+
}
161+
}
162+
}
163+
finally {
164+
$zip.Dispose()
165+
}
166+
167+
- name: Upload package
168+
uses: actions/upload-artifact@v6
169+
with:
170+
name: ${{ matrix.artifact }}
171+
path: target\package\${{ matrix.artifact }}.zip
172+
if-no-files-found: error

.github/workflows/smoke-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313

1414
steps:
1515
- name: Checkout
16-
uses: actions/checkout@v4
16+
uses: actions/checkout@v5
1717

1818
- name: Select stable Rust
1919
shell: pwsh
@@ -110,7 +110,7 @@ jobs:
110110
111111
- name: Upload dump on failure
112112
if: failure()
113-
uses: actions/upload-artifact@v4
113+
uses: actions/upload-artifact@v6
114114
with:
115115
name: ping-dump-smoke
116116
path: ${{ runner.temp }}\windbg-tool-smoke\ping.dmp

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ The built executable is:
4141
target\debug\windbg-tool.exe
4242
```
4343

44+
Release ZIP artifacts are built by the Windows packaging workflow. The local equivalent uses `cargo xtask deps --arch <amd64|arm64>`, `cargo xtask native-build --arch <amd64|arm64> --static-crt`, a release build for the matching MSVC Rust target, and `cargo xtask package --profile release`.
45+
4446
For deeper setup, test commands, runtime details, and workspace notes, see [the development guide](docs/development.md).
4547

4648
## CLI quick start

docs/architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ cargo xtask deps
2727

2828
or run [scripts/Get-TtdReplayRuntime.ps1](../scripts/Get-TtdReplayRuntime.ps1) directly.
2929

30-
The native bridge has a CMake project at [native/ttd-replay-bridge/CMakeLists.txt](../native/ttd-replay-bridge/CMakeLists.txt). `cargo xtask native-build` configures it against the restored `Microsoft.TimeTravelDebugging.Apis` package and emits the bridge under `target/native/ttd-replay-bridge`.
30+
The native bridge has a CMake project at [native/ttd-replay-bridge/CMakeLists.txt](../native/ttd-replay-bridge/CMakeLists.txt). `cargo xtask native-build` configures it against the restored `Microsoft.TimeTravelDebugging.Apis` package and emits the bridge under `target/native/ttd-replay-bridge`. Release packaging can pass `--arch amd64` or `--arch arm64` plus `--static-crt` so cross-compiled packages use the matching native bridge and statically link the MSVC runtime.
3131

3232
## Symbols
3333

@@ -37,7 +37,7 @@ The default symbol path is equivalent to:
3737
srv*.ttd-symbol-cache*https://msdl.microsoft.com/download/symbols
3838
```
3939

40-
`cargo xtask deps` stages `dbghelp.dll`, `symsrv.dll`, and `srcsrv.dll` from Microsoft Debugging Platform NuGet packages into `target/symbol-runtime`, and stages DbgEng process-server runtime DLLs into `target/dbgeng-runtime`. Keep this repo-local and process-local; do not set machine-wide `_NT_SYMBOL_PATH` or write debugger registry keys as part of normal server operation. If `_NT_SYMBOL_PATH` is already set in the server process environment, use it as a fallback only when the MCP request does not provide explicit `symbols.symbol_paths`.
40+
`cargo xtask deps` stages `dbghelp.dll`, `symsrv.dll`, and `srcsrv.dll` from Microsoft Debugging Platform NuGet packages into `target/symbol-runtime`, and stages DbgEng process-server runtime DLLs into `target/dbgeng-runtime`. Architecture-explicit release staging uses `target/runtime/<arch>/...` to keep x64 and ARM64 DLLs separate. Keep this repo-local and process-local; do not set machine-wide `_NT_SYMBOL_PATH` or write debugger registry keys as part of normal server operation. If `_NT_SYMBOL_PATH` is already set in the server process environment, use it as a fallback only when the MCP request does not provide explicit `symbols.symbol_paths`.
4141

4242
Callers can provide additional binary paths, symbol paths, and a symbol cache directory when loading a trace. Public symbols are useful for module/function names. Private symbols are needed for richer function signatures and local details.
4343

docs/development.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,23 @@ cargo xtask native-build
4646

4747
`cargo xtask native-build` configures and builds the C++ bridge under `target\native\ttd-replay-bridge`.
4848

49+
For release packaging, use explicit target architecture inputs so the Rust binary, native bridge, and staged debugger runtime DLLs all match:
50+
51+
```powershell
52+
$env:RUSTFLAGS = "-C target-feature=+crt-static"
53+
rustup target add x86_64-pc-windows-msvc
54+
cargo xtask deps --arch amd64
55+
cargo xtask native-build --arch amd64 --static-crt
56+
cargo build -p windbg-tool --release --target x86_64-pc-windows-msvc
57+
cargo xtask package --arch amd64 --target x86_64-pc-windows-msvc --profile release --out target\package\windbg-tool-windows-x64
58+
```
59+
60+
Use `--arch arm64` with `--target aarch64-pc-windows-msvc` for the Windows ARM64 package. Architecture-specific dependency staging uses `target\runtime\<arch>\...`, while the legacy no-argument `cargo xtask deps`, `cargo xtask native-build`, and `cargo xtask package` commands keep using the existing host-architecture directories.
61+
62+
Release packages statically link the MSVC C runtime into Rust code with `RUSTFLAGS=-C target-feature=+crt-static` and into the native bridge with `cargo xtask native-build --static-crt`. WinDbg, DbgEng, symbol, and TTD replay runtime DLLs remain dynamic dependencies and are copied into the package directory.
63+
64+
Cross-compiling the ARM64 package from an x64 machine requires the Visual Studio ARM64 MSVC toolset and an `x64_arm64` developer environment for the native bridge and Rust crates that compile C/C++ code.
65+
4966
To smoke-test the packaged MCP server:
5067

5168
```powershell

scripts/Get-TtdReplayRuntime.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ param(
66
)
77

88
$ErrorActionPreference = "Stop"
9+
$ProgressPreference = "SilentlyContinue"
910

1011
$resolvedOutDir = Resolve-Path -Path $OutDir -ErrorAction SilentlyContinue
1112
if ($null -eq $resolvedOutDir) {

0 commit comments

Comments
 (0)