Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 89 additions & 2 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ on:
push:
pull_request:
workflow_dispatch:
inputs:
version:
description: Release version without the v prefix (for example, 0.1.0)
required: true
type: string
dry_run:
description: Build and validate release packages without creating a tag or release
required: false
default: false
type: boolean

permissions:
contents: read

jobs:
package:
Expand All @@ -19,13 +32,13 @@ jobs:
rust_target: x86_64-pc-windows-msvc
nuget_arch: amd64
vcvars_arch: x64
artifact: windbg-tool-windows-x64
artifact: windbg-tool-x64
can_run: true
- label: windows-arm64
rust_target: aarch64-pc-windows-msvc
nuget_arch: arm64
vcvars_arch: x64_arm64
artifact: windbg-tool-windows-arm64
artifact: windbg-tool-arm64
can_run: false

env:
Expand Down Expand Up @@ -170,3 +183,77 @@ jobs:
name: ${{ matrix.artifact }}
path: target\package\${{ matrix.artifact }}.zip
if-no-files-found: error

release:
name: Publish GitHub Release
needs: package
if: github.event_name == 'workflow_dispatch'
runs-on: windows-latest
timeout-minutes: 10
permissions:
contents: write
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ inputs.version }}

steps:
- name: Download packages
uses: actions/download-artifact@v6
with:
path: release-assets
pattern: windbg-tool-*
merge-multiple: true

- name: Validate release inputs and assets
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'

if ($env:VERSION -notmatch '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z][0-9A-Za-z.-]*)?(?:\+[0-9A-Za-z][0-9A-Za-z.-]*)?$') {
throw "Version must be a semantic version without the v prefix: $env:VERSION"
}

$tag = "v$env:VERSION"
$assets = @(
'windbg-tool-x64.zip',
'windbg-tool-arm64.zip'
)
foreach ($asset in $assets) {
$path = Join-Path $PWD "release-assets\$asset"
if (-not (Test-Path -Path $path -PathType Leaf)) {
throw "Release asset was not downloaded: $asset"
}
}

$response = & gh api --include "repos/$env:GITHUB_REPOSITORY/git/ref/tags/$tag" 2>&1
$exitCode = $LASTEXITCODE
if ($exitCode -eq 0) {
throw "Refusing to publish because tag $tag already exists."
}

$responseText = $response -join [Environment]::NewLine
if ($responseText -notmatch '(?m)^HTTP/\S+ 404') {
throw "Could not determine whether tag $tag exists: $responseText"
}

- name: Create release and upload packages
if: inputs.dry_run == false
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'

$tag = "v$env:VERSION"
$assets = @(
(Join-Path $PWD 'release-assets\windbg-tool-x64.zip'),
(Join-Path $PWD 'release-assets\windbg-tool-arm64.zip')
)
& gh release create $tag $assets `
--repo $env:GITHUB_REPOSITORY `
--target $env:GITHUB_SHA `
--title "windbg-tool $tag" `
--generate-notes

- name: Report dry run
if: inputs.dry_run
shell: pwsh
run: Write-Host "Dry run completed. Would create v$env:VERSION with the validated package ZIPs."
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ The built executable is:
target\debug\windbg-tool.exe
```

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`.
Release ZIP artifacts are built by the Windows packaging workflow. Run **Windows packages** manually with an unprefixed semantic version such as `0.1.0` to publish the `v0.1.0` GitHub Release. Select **dry_run** to build and validate the packages without creating a tag or release. The release contains `windbg-tool-x64.zip` and `windbg-tool-arm64.zip`.

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`. Both packages statically link the MSVC runtime and bundle their required TTD, DbgEng, symbol, and native-bridge DLLs.

For deeper setup, test commands, runtime details, and workspace notes, see [the development guide](docs/development.md).

Expand Down
11 changes: 10 additions & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ rustup target add x86_64-pc-windows-msvc
cargo xtask deps --arch amd64
cargo xtask native-build --arch amd64 --static-crt
cargo build -p windbg-tool --release --target x86_64-pc-windows-msvc
cargo xtask package --arch amd64 --target x86_64-pc-windows-msvc --profile release --out target\package\windbg-tool-windows-x64
cargo xtask package --arch amd64 --target x86_64-pc-windows-msvc --profile release --out target\package\windbg-tool-x64
```

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.
Expand All @@ -63,6 +63,15 @@ Release packages statically link the MSVC C runtime into Rust code with `RUSTFLA

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.

### Publishing a GitHub Release

Run the **Windows packages** workflow with **Run workflow** and enter an unprefixed semantic version such as `0.1.0`. After both package matrix jobs complete, the workflow creates the `v0.1.0` tag at the commit selected for the dispatch and publishes a GitHub Release containing:

- `windbg-tool-x64.zip`
- `windbg-tool-arm64.zip`

Select **dry_run** to build both ZIPs, validate their contents, validate the version, and confirm that the tag is available without creating a tag or GitHub Release. The workflow rejects existing tags and invalid versions rather than replacing a release. Each ZIP contains the statically linked Rust executable and native bridge plus the required dynamic TTD Replay, DbgEng, and symbol runtime DLLs.

To smoke-test the packaged MCP server:

```powershell
Expand Down