Add osslsigncode dependency and implement three-step signing workflow. Decode base64-encoded PFX certificate from secrets, sign bundled tunnel helper before build, then sign desktop executable and NSIS installer after build. Use configurable timestamp URL with DigiCert fallback. Clean up certificate file in always-run step to prevent secret leakage.
138 lines
4.5 KiB
YAML
138 lines
4.5 KiB
YAML
name: Build Windows Desktop Client
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
build-windows-client:
|
|
name: Build Windows Client
|
|
runs-on: ubuntu-latest
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
working-directory: desktop-client
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
targets: x86_64-pc-windows-msvc
|
|
|
|
- name: Install system dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
build-essential \
|
|
clang \
|
|
lld \
|
|
llvm \
|
|
curl \
|
|
wget \
|
|
file \
|
|
nsis \
|
|
osslsigncode \
|
|
pkg-config \
|
|
libssl-dev \
|
|
libayatana-appindicator3-dev \
|
|
librsvg2-dev \
|
|
patchelf
|
|
|
|
- name: Install cargo-xwin
|
|
run: |
|
|
if ! cargo xwin --version >/dev/null 2>&1; then
|
|
cargo install --locked cargo-xwin
|
|
fi
|
|
|
|
- name: Install desktop client dependencies
|
|
run: npm install
|
|
|
|
- name: Build bundled Windows tunnel helper
|
|
run: npm run helper:windows-x64
|
|
|
|
- name: Prepare signing certificate
|
|
if: ${{ secrets.WINDOWS_SIGN_PFX_B64 != '' && secrets.WINDOWS_SIGN_PFX_PASSWORD != '' }}
|
|
run: |
|
|
printf '%s' "${{ secrets.WINDOWS_SIGN_PFX_B64 }}" | base64 -d > /tmp/nexavpn-signing-cert.pfx
|
|
|
|
- name: Sign bundled Windows tunnel helper
|
|
if: ${{ secrets.WINDOWS_SIGN_PFX_B64 != '' && secrets.WINDOWS_SIGN_PFX_PASSWORD != '' }}
|
|
run: |
|
|
set -euo pipefail
|
|
timestamp_url="${{ secrets.WINDOWS_SIGN_TIMESTAMP_URL }}"
|
|
if [ -z "${timestamp_url}" ]; then
|
|
timestamp_url="http://timestamp.digicert.com"
|
|
fi
|
|
helper_path="src-tauri/bundled/windows-x64/nexavpn-tunnel-helper.exe"
|
|
signed_path="${helper_path}.signed"
|
|
osslsigncode sign \
|
|
-pkcs12 /tmp/nexavpn-signing-cert.pfx \
|
|
-pass "${{ secrets.WINDOWS_SIGN_PFX_PASSWORD }}" \
|
|
-h sha256 \
|
|
-ts "${timestamp_url}" \
|
|
-in "${helper_path}" \
|
|
-out "${signed_path}"
|
|
mv "${signed_path}" "${helper_path}"
|
|
|
|
- name: Build Windows installer
|
|
run: npm run tauri:build:windows-x64:linux
|
|
|
|
- name: Sign Windows desktop executable and installer
|
|
if: ${{ secrets.WINDOWS_SIGN_PFX_B64 != '' && secrets.WINDOWS_SIGN_PFX_PASSWORD != '' }}
|
|
run: |
|
|
set -euo pipefail
|
|
timestamp_url="${{ secrets.WINDOWS_SIGN_TIMESTAMP_URL }}"
|
|
if [ -z "${timestamp_url}" ]; then
|
|
timestamp_url="http://timestamp.digicert.com"
|
|
fi
|
|
|
|
sign_file() {
|
|
local input_path="$1"
|
|
local output_path="${input_path}.signed"
|
|
osslsigncode sign \
|
|
-pkcs12 /tmp/nexavpn-signing-cert.pfx \
|
|
-pass "${{ secrets.WINDOWS_SIGN_PFX_PASSWORD }}" \
|
|
-h sha256 \
|
|
-ts "${timestamp_url}" \
|
|
-in "${input_path}" \
|
|
-out "${output_path}"
|
|
mv "${output_path}" "${input_path}"
|
|
}
|
|
|
|
sign_file "src-tauri/target/x86_64-pc-windows-msvc/release/nexavpn-desktop.exe"
|
|
|
|
shopt -s nullglob
|
|
for installer in src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe; do
|
|
sign_file "${installer}"
|
|
done
|
|
|
|
- name: Cleanup signing certificate
|
|
if: ${{ always() && secrets.WINDOWS_SIGN_PFX_B64 != '' && secrets.WINDOWS_SIGN_PFX_PASSWORD != '' }}
|
|
run: rm -f /tmp/nexavpn-signing-cert.pfx
|
|
|
|
- name: Upload Windows installer
|
|
uses: christopherhx/gitea-upload-artifact@v4
|
|
with:
|
|
name: NexaVPN-windows-installer
|
|
path: |
|
|
desktop-client/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe
|
|
desktop-client/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.msi
|
|
if-no-files-found: error
|
|
|
|
- name: Upload raw Windows build outputs
|
|
uses: christopherhx/gitea-upload-artifact@v4
|
|
with:
|
|
name: NexaVPN-windows-raw-build
|
|
path: |
|
|
desktop-client/src-tauri/target/x86_64-pc-windows-msvc/release/nexavpn-desktop.exe
|
|
desktop-client/src-tauri/bundled/windows-x64/nexavpn-tunnel-helper.exe
|
|
if-no-files-found: error
|