Skip to content

Build Windows

Build Windows #2

name: Build Windows
on:
workflow_call:
inputs:
binary_list:
required: true
type: string
workflow_dispatch:
inputs:
binary_list:
description: 'Binaries bundled into the plain zip artifacts (the NSIS installers always ship the full set)'
required: false
type: string
default: 'api-blockchain-scanner-daemon,api-web-server,dns-server,node-daemon,wallet-address-generator,wallet-cli,wallet-rpc-daemon'
jobs:
build:
runs-on: windows-latest
# Note: bounds the whole job, and in particular the installer smoke test below (every
# installed binary is executed with a per-process timeout as well; this is the backstop).
timeout-minutes: 120
permissions:
contents: read
env:
# With the default CARGO_HOME the job will fail due to Windows path length limit when
# checking out the trezor firmware repo. E.g. one of the paths looks like this:
# C:/Users/runneradmin/.cargo/git/checkouts/mintlayer-trezor-firmware-04bdf62619936e0b/596b3eb/vendor/libtropic/scripts/tropic01_model/provisioning_data/2025-06-27T07-51-29Z__prod_C2S_T200__provisioning__lab_batch_package/cert_chain/tropicsquare_root_ca_certificate_sn_101.der
CARGO_HOME: C:\crg
steps:
- uses: actions/checkout@v5
with:
submodules: recursive
fetch-depth: 0 # git describe needs history for the dispatch fallback version
persist-credentials: false # the checkout is only built, never pushed
- name: Extract version from tag
id: get_version
run: |
$VERSION = $env:GITHUB_REF -replace 'refs/tags/', '' -replace '^v', ''
if ($VERSION -eq $env:GITHUB_REF) {
$VERSION = git describe --tags --abbrev=0 2>$null
$VERSION = $VERSION -replace '^v', ''
}
if ([string]::IsNullOrEmpty($VERSION)) {
$VERSION = "0.0.0-ci"
}
# Validate the grammar up front, so a non-semver tag fails here with a clear message
# instead of deep inside a packaging script (the same grammar the NSIS tooling and the
# Linux builders enforce).
if ($VERSION -notmatch '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$') {
throw "derived version '$VERSION' is not X.Y.Z[-suffix]; tag a semver release"
}
echo "VERSION=$VERSION" >> $env:GITHUB_OUTPUT
echo "Version extracted: $VERSION"
shell: pwsh
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
- name: Build Mintlayer Node and GUI
run: cargo build --release --locked --features trezor,ledger
# Note: the version (and the workflow input) are passed through environment
# variables instead of direct ${{ }} interpolation into the run blocks, so
# that a crafted tag/ref/input cannot inject shell into the steps.
- name: Package Mintlayer Node
env:
VERSION: ${{ steps.get_version.outputs.VERSION }}
BINARY_LIST: ${{ inputs.binary_list }}
run: |
$DEST = "Mintlayer_Node_win_$env:VERSION"
New-Item -ItemType Directory -Path $DEST
$binary_list = $env:BINARY_LIST -split ',' | Where-Object { $_ -ne "node-gui" }
foreach ($binary in $binary_list) {
$binary = $binary.Trim()
if (Test-Path "target\release\$binary.exe") {
Copy-Item "target\release\$binary.exe" -Destination $DEST
} else {
Write-Warning "Binary not found: $binary.exe"
}
}
Compress-Archive -Path $DEST -DestinationPath "${DEST}.zip"
shell: pwsh
- name: Install NSIS
run: |
choco install nsis -y --force
echo "C:\Program Files (x86)\NSIS" >> $env:GITHUB_PATH
shell: pwsh
- name: Create License File
run: .\build-tools\win\create-license.ps1
shell: pwsh
- name: Create NSIS installers (node + GUI)
env:
VERSION: ${{ steps.get_version.outputs.VERSION }}
run: .\build-tools\win\create-nsis-installers.ps1 -Version $env:VERSION
shell: pwsh
- name: Smoke test installers (silent install/uninstall)
env:
VERSION: ${{ steps.get_version.outputs.VERSION }}
run: |
.\build-tools\win\smoke-install.ps1 -Installer "Mintlayer_Node_win_${env:VERSION}_Setup.exe" -AppName "Mintlayer Node" -Kind node -Version $env:VERSION
.\build-tools\win\smoke-install.ps1 -Installer "Mintlayer_Node_GUI_win_${env:VERSION}_Setup.exe" -AppName "Mintlayer Node GUI" -Kind gui -Version $env:VERSION
shell: pwsh
- name: Package Mintlayer Node GUI
env:
VERSION: ${{ steps.get_version.outputs.VERSION }}
run: |
$DEST = "Mintlayer_Node_GUI_win_$env:VERSION"
New-Item -ItemType Directory -Path $DEST
Copy-Item "target\release\node-gui.exe" -Destination $DEST
Compress-Archive -Path $DEST -DestinationPath "${DEST}.zip"
shell: pwsh
- name: Upload Node ZIP Artifact
uses: actions/upload-artifact@v4
with:
name: Mintlayer_Node_win_${{ steps.get_version.outputs.VERSION }}
path: Mintlayer_Node_win_${{ steps.get_version.outputs.VERSION }}.zip
- name: Upload GUI ZIP Artifact
uses: actions/upload-artifact@v4
with:
name: Mintlayer_Node_GUI_win_${{ steps.get_version.outputs.VERSION }}
path: Mintlayer_Node_GUI_win_${{ steps.get_version.outputs.VERSION }}.zip
- name: Upload Node NSIS Installer Artifact
uses: actions/upload-artifact@v4
with:
name: Mintlayer_Node_win_${{ steps.get_version.outputs.VERSION }}_Setup
path: Mintlayer_Node_win_${{ steps.get_version.outputs.VERSION }}_Setup.exe
- name: Upload GUI NSIS Installer Artifact
uses: actions/upload-artifact@v4
with:
name: Mintlayer_Node_GUI_win_${{ steps.get_version.outputs.VERSION }}_Setup
path: Mintlayer_Node_GUI_win_${{ steps.get_version.outputs.VERSION }}_Setup.exe