979 lines
29 KiB
YAML
979 lines
29 KiB
YAML
name: RustDesk Windows x64
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
RUSTDESK_VERSION: "1.4.9"
|
|
|
|
# Build target constants, not software versions.
|
|
RUST_TARGET: x86_64-pc-windows-msvc
|
|
VCPKG_TRIPLET: x64-windows-static
|
|
|
|
|
|
jobs:
|
|
resolve-config:
|
|
name: Resolve upstream build config
|
|
runs-on: rustdesk-android
|
|
|
|
steps:
|
|
- name: Clone selected RustDesk tag
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
rm -rf rustdesk-config build-config
|
|
|
|
git clone \
|
|
--branch "${RUSTDESK_VERSION}" \
|
|
--depth 1 \
|
|
https://github.com/rustdesk/rustdesk.git \
|
|
rustdesk-config
|
|
|
|
- name: Extract upstream tool versions
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
mkdir -p build-config
|
|
|
|
python3 - <<'PY'
|
|
import re
|
|
from pathlib import Path
|
|
|
|
repo = Path("rustdesk-config")
|
|
|
|
flutter_file = repo / ".github/workflows/flutter-build.yml"
|
|
bridge_file = repo / ".github/workflows/bridge.yml"
|
|
topmost_file = repo / ".github/workflows/third-party-RustDeskTempTopMostWindow.yml"
|
|
|
|
flutter = flutter_file.read_text(encoding="utf-8")
|
|
bridge = bridge_file.read_text(encoding="utf-8")
|
|
topmost = topmost_file.read_text(encoding="utf-8") if topmost_file.exists() else ""
|
|
|
|
def env_value(text, name, required=True):
|
|
m = re.search(
|
|
rf'(?m)^\s*{re.escape(name)}:\s*["\']?([^"\'#\s]+)',
|
|
text,
|
|
)
|
|
if m:
|
|
return m.group(1).strip()
|
|
if required:
|
|
raise SystemExit(f"Unable to resolve {name}")
|
|
return ""
|
|
|
|
windows_rust = (
|
|
env_value(flutter, "SCITER_RUST_VERSION", False)
|
|
or env_value(flutter, "RUST_VERSION")
|
|
)
|
|
|
|
bridge_flutter_match = re.search(
|
|
r'flutter-version:\s*["\']([^"\']+)["\']',
|
|
bridge,
|
|
)
|
|
if not bridge_flutter_match:
|
|
raise SystemExit("Unable to resolve bridge Flutter version")
|
|
|
|
topmost_match = re.search(
|
|
r"git\s+checkout\s+([0-9a-fA-F]{40})",
|
|
topmost,
|
|
)
|
|
|
|
values = {
|
|
"WINDOWS_RUST_VERSION": windows_rust,
|
|
"LLVM_VERSION": env_value(flutter, "LLVM_VERSION"),
|
|
"WINDOWS_FLUTTER_VERSION": env_value(flutter, "FLUTTER_VERSION"),
|
|
"VCPKG_COMMIT_ID": env_value(flutter, "VCPKG_COMMIT_ID"),
|
|
"BRIDGE_RUST_VERSION": env_value(bridge, "RUST_VERSION"),
|
|
"BRIDGE_FLUTTER_VERSION": bridge_flutter_match.group(1),
|
|
"FRB_VERSION": env_value(bridge, "FLUTTER_RUST_BRIDGE_VERSION"),
|
|
"CARGO_EXPAND_VERSION": env_value(bridge, "CARGO_EXPAND_VERSION", False),
|
|
"TOPMOST_COMMIT": topmost_match.group(1) if topmost_match else "HEAD",
|
|
"USE_CUSTOM_ENGINE": "1" if "windows-x64-release.zip" in flutter else "0",
|
|
}
|
|
|
|
out = Path("build-config/build-config.env")
|
|
out.write_text(
|
|
"".join(f"{k}={v}\n" for k, v in values.items()),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
for k, v in values.items():
|
|
print(f"{k}={v}")
|
|
PY
|
|
|
|
- name: Upload build config
|
|
uses: https://github.com/actions/upload-artifact@v7
|
|
with:
|
|
name: rustdesk-build-config
|
|
path: build-config/build-config.env
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
|
|
generate-bridge:
|
|
name: Generate Flutter Rust Bridge
|
|
needs: [resolve-config]
|
|
runs-on: rustdesk-android
|
|
|
|
steps:
|
|
- name: Download build config
|
|
uses: https://github.com/actions/download-artifact@v8
|
|
with:
|
|
name: rustdesk-build-config
|
|
path: build-config
|
|
|
|
- name: Load build config
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
|
|
while IFS='=' read -r key value; do
|
|
[ -z "${key}" ] && continue
|
|
echo "${key}=${value}" >> "${GITHUB_ENV}"
|
|
done < build-config/build-config.env
|
|
|
|
- name: Clone selected RustDesk tag
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
rm -rf rustdesk bridge-artifact
|
|
|
|
git clone \
|
|
--branch "${RUSTDESK_VERSION}" \
|
|
--depth 1 \
|
|
https://github.com/rustdesk/rustdesk.git \
|
|
rustdesk
|
|
|
|
git -C rustdesk submodule update --init --recursive
|
|
|
|
- name: Prepare bridge toolchain
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
|
|
rustup toolchain install \
|
|
"${BRIDGE_RUST_VERSION}" \
|
|
--profile minimal \
|
|
--component rustfmt
|
|
|
|
export RUSTUP_TOOLCHAIN="${BRIDGE_RUST_VERSION}"
|
|
echo "RUSTUP_TOOLCHAIN=${BRIDGE_RUST_VERSION}" >> "${GITHUB_ENV}"
|
|
|
|
if [ -x "/opt/flutter-${BRIDGE_FLUTTER_VERSION}/bin/flutter" ]; then
|
|
FLUTTER_DIR="/opt/flutter-${BRIDGE_FLUTTER_VERSION}"
|
|
else
|
|
FLUTTER_DIR="${HOME}/.cache/rustdesk/flutter-${BRIDGE_FLUTTER_VERSION}"
|
|
|
|
if [ ! -x "${FLUTTER_DIR}/bin/flutter" ]; then
|
|
rm -rf "${FLUTTER_DIR}"
|
|
mkdir -p "$(dirname "${FLUTTER_DIR}")"
|
|
|
|
git clone \
|
|
--branch "${BRIDGE_FLUTTER_VERSION}" \
|
|
--depth 1 \
|
|
https://github.com/flutter/flutter.git \
|
|
"${FLUTTER_DIR}"
|
|
fi
|
|
fi
|
|
|
|
git config --global --add safe.directory "${FLUTTER_DIR}" || true
|
|
|
|
export PATH="${FLUTTER_DIR}/bin:${HOME}/.cargo/bin:${PATH}"
|
|
echo "${FLUTTER_DIR}/bin" >> "${GITHUB_PATH}"
|
|
|
|
flutter config --no-analytics
|
|
flutter --version
|
|
rustc --version
|
|
|
|
if [ -n "${CARGO_EXPAND_VERSION}" ]; then
|
|
current="$(
|
|
cargo expand --version 2>/dev/null | awk '{print $2}' || true
|
|
)"
|
|
|
|
if [ "${current}" != "${CARGO_EXPAND_VERSION}" ]; then
|
|
cargo install \
|
|
cargo-expand \
|
|
--version "${CARGO_EXPAND_VERSION}" \
|
|
--locked \
|
|
--force
|
|
fi
|
|
fi
|
|
|
|
current="$(
|
|
flutter_rust_bridge_codegen --version 2>/dev/null |
|
|
awk '{print $2}' ||
|
|
true
|
|
)"
|
|
|
|
if [ "${current}" != "${FRB_VERSION}" ]; then
|
|
cargo install \
|
|
flutter_rust_bridge_codegen \
|
|
--version "${FRB_VERSION}" \
|
|
--features uuid \
|
|
--locked \
|
|
--force
|
|
fi
|
|
|
|
- name: Generate bridge
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
cd rustdesk
|
|
|
|
rm -rf flutter/.dart_tool
|
|
|
|
if ! (cd flutter && flutter pub get); then
|
|
if grep -q \
|
|
'extended_text:[[:space:]]*14\.0\.0' \
|
|
flutter/pubspec.yaml; then
|
|
|
|
sed -i \
|
|
's/extended_text:[[:space:]]*14\.0\.0/extended_text: 13.0.0/g' \
|
|
flutter/pubspec.yaml
|
|
|
|
(cd flutter && flutter pub get)
|
|
else
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
flutter_rust_bridge_codegen \
|
|
--rust-input ./src/flutter_ffi.rs \
|
|
--dart-output ./flutter/lib/generated_bridge.dart \
|
|
--c-output ./flutter/macos/Runner/bridge_generated.h
|
|
|
|
test -f ./src/bridge_generated.rs
|
|
test -f ./src/bridge_generated.io.rs
|
|
test -f ./flutter/lib/generated_bridge.dart
|
|
test -f ./flutter/lib/generated_bridge.freezed.dart
|
|
|
|
- name: Prepare bridge artifact
|
|
shell: bash
|
|
run: |
|
|
set -euxo pipefail
|
|
rm -rf bridge-artifact
|
|
|
|
mkdir -p bridge-artifact/src
|
|
mkdir -p bridge-artifact/flutter/lib
|
|
|
|
cp rustdesk/src/bridge_generated.rs \
|
|
bridge-artifact/src/
|
|
|
|
cp rustdesk/src/bridge_generated.io.rs \
|
|
bridge-artifact/src/
|
|
|
|
cp rustdesk/flutter/lib/generated_bridge.dart \
|
|
bridge-artifact/flutter/lib/
|
|
|
|
cp rustdesk/flutter/lib/generated_bridge.freezed.dart \
|
|
bridge-artifact/flutter/lib/
|
|
|
|
- name: Upload bridge
|
|
uses: https://github.com/actions/upload-artifact@v7
|
|
with:
|
|
name: rustdesk-bridge
|
|
path: bridge-artifact/
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
|
|
build-windows:
|
|
name: Build Windows x64
|
|
needs: [resolve-config, generate-bridge]
|
|
runs-on: rustdesk-windows
|
|
|
|
env:
|
|
RUSTUP_HOME: C:\BuildTools\rustup
|
|
CARGO_HOME: C:\BuildTools\cargo
|
|
PUB_CACHE: C:\BuildTools\pub-cache
|
|
VCPKG_ROOT: C:\vcpkg
|
|
|
|
steps:
|
|
- name: Download build config
|
|
uses: https://github.com/actions/download-artifact@v8
|
|
with:
|
|
name: rustdesk-build-config
|
|
path: build-config
|
|
|
|
- name: Load build config
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Get-Content ".\build-config\build-config.env" |
|
|
ForEach-Object {
|
|
if ([string]::IsNullOrWhiteSpace($_)) {
|
|
return
|
|
}
|
|
|
|
$parts = $_ -split "=", 2
|
|
$name = $parts[0]
|
|
$value = $parts[1]
|
|
|
|
[Environment]::SetEnvironmentVariable(
|
|
$name,
|
|
$value,
|
|
"Process"
|
|
)
|
|
|
|
Add-Content `
|
|
-Path $env:GITHUB_ENV `
|
|
-Value "$name=$value"
|
|
}
|
|
|
|
- name: Clone selected RustDesk tag
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Remove-Item ".\rustdesk" `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
Remove-Item ".\bridge-download" `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
git -c core.longpaths=true clone `
|
|
--branch "$env:RUSTDESK_VERSION" `
|
|
--depth 1 `
|
|
https://github.com/rustdesk/rustdesk.git `
|
|
rustdesk
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "RustDesk clone failed"
|
|
}
|
|
|
|
git -C rustdesk `
|
|
-c core.longpaths=true `
|
|
submodule update --init --recursive
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "RustDesk submodule checkout failed"
|
|
}
|
|
|
|
- name: Prepare selected Windows toolchain
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
Write-Host "RustDesk: $env:RUSTDESK_VERSION"
|
|
Write-Host "Rust: $env:WINDOWS_RUST_VERSION"
|
|
Write-Host "LLVM: $env:LLVM_VERSION"
|
|
Write-Host "Flutter: $env:WINDOWS_FLUTTER_VERSION"
|
|
Write-Host "vcpkg: $env:VCPKG_COMMIT_ID"
|
|
|
|
# Rust
|
|
rustup toolchain install `
|
|
"$env:WINDOWS_RUST_VERSION" `
|
|
--profile minimal `
|
|
--component rustfmt `
|
|
--target "$env:RUST_TARGET"
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Rust toolchain setup failed"
|
|
}
|
|
|
|
$env:RUSTUP_TOOLCHAIN = $env:WINDOWS_RUST_VERSION
|
|
|
|
Add-Content $env:GITHUB_ENV `
|
|
"RUSTUP_TOOLCHAIN=$env:WINDOWS_RUST_VERSION"
|
|
|
|
# LLVM: reuse installed version when possible, otherwise install
|
|
# the version requested by the selected RustDesk tag.
|
|
$clang = Get-Command clang -ErrorAction SilentlyContinue
|
|
$llvmBin = $null
|
|
|
|
if ($clang) {
|
|
$firstLine = (& $clang.Source --version |
|
|
Select-Object -First 1)
|
|
|
|
if ($firstLine -match [regex]::Escape($env:LLVM_VERSION)) {
|
|
$llvmBin = Split-Path $clang.Source -Parent
|
|
}
|
|
}
|
|
|
|
if (-not $llvmBin) {
|
|
$llvmRoot = "C:\BuildTools\llvm-$env:LLVM_VERSION"
|
|
$llvmBin = "$llvmRoot\bin"
|
|
|
|
if (-not (Test-Path "$llvmBin\clang.exe")) {
|
|
$installer = (
|
|
"C:\BuildTools\downloads\" +
|
|
"LLVM-$env:LLVM_VERSION-win64.exe"
|
|
)
|
|
|
|
$url = (
|
|
"https://github.com/llvm/llvm-project/releases/download/" +
|
|
"llvmorg-$env:LLVM_VERSION/" +
|
|
"LLVM-$env:LLVM_VERSION-win64.exe"
|
|
)
|
|
|
|
Invoke-WebRequest -Uri $url -OutFile $installer
|
|
|
|
$p = Start-Process `
|
|
-FilePath $installer `
|
|
-ArgumentList @("/S", "/D=$llvmRoot") `
|
|
-Wait `
|
|
-PassThru
|
|
|
|
if ($p.ExitCode -ne 0) {
|
|
throw "LLVM installation failed"
|
|
}
|
|
}
|
|
}
|
|
|
|
if (-not (Test-Path "$llvmBin\libclang.dll")) {
|
|
throw "libclang.dll not found"
|
|
}
|
|
|
|
$env:LIBCLANG_PATH = $llvmBin
|
|
$env:Path = "$llvmBin;$env:Path"
|
|
|
|
Add-Content $env:GITHUB_ENV `
|
|
"LIBCLANG_PATH=$llvmBin"
|
|
|
|
Add-Content $env:GITHUB_PATH $llvmBin
|
|
|
|
# Flutter
|
|
$flutterRoot = (
|
|
"C:\BuildTools\flutter-" +
|
|
$env:WINDOWS_FLUTTER_VERSION
|
|
)
|
|
|
|
if (-not (Test-Path "$flutterRoot\bin\flutter.bat")) {
|
|
Remove-Item $flutterRoot `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
git clone `
|
|
--branch "$env:WINDOWS_FLUTTER_VERSION" `
|
|
--depth 1 `
|
|
https://github.com/flutter/flutter.git `
|
|
$flutterRoot
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Flutter SDK setup failed"
|
|
}
|
|
}
|
|
|
|
git config --system --add safe.directory `
|
|
($flutterRoot -replace "\\", "/")
|
|
|
|
git -C $flutterRoot reset --hard HEAD
|
|
|
|
$env:FLUTTER_ROOT = $flutterRoot
|
|
$env:Path = "$flutterRoot\bin;$env:Path"
|
|
|
|
Add-Content $env:GITHUB_ENV `
|
|
"FLUTTER_ROOT=$flutterRoot"
|
|
|
|
Add-Content $env:GITHUB_PATH `
|
|
"$flutterRoot\bin"
|
|
|
|
& "$flutterRoot\bin\flutter.bat" config --no-analytics
|
|
& "$flutterRoot\bin\flutter.bat" config --enable-windows-desktop
|
|
& "$flutterRoot\bin\flutter.bat" precache --windows
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Flutter Windows precache failed"
|
|
}
|
|
|
|
# Apply every Flutter patch shipped by the selected RustDesk tag
|
|
# that cleanly applies to the selected Flutter SDK.
|
|
$patches = Get-ChildItem `
|
|
".\rustdesk\.github\patches" `
|
|
-Filter "flutter_*.diff" `
|
|
-File `
|
|
-ErrorAction SilentlyContinue
|
|
|
|
foreach ($patch in $patches) {
|
|
git -C $flutterRoot apply --check $patch.FullName 2>$null
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Host "Applying $($patch.Name)"
|
|
git -C $flutterRoot apply $patch.FullName
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Flutter patch failed: $($patch.Name)"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Replace stock engine only when the selected upstream workflow
|
|
# explicitly uses RustDesk's custom Windows x64 engine.
|
|
if ($env:USE_CUSTOM_ENGINE -eq "1") {
|
|
$zip = "C:\BuildTools\downloads\rustdesk-engine.zip"
|
|
$extract = (
|
|
"C:\BuildTools\rustdesk-engine-" +
|
|
$env:WINDOWS_FLUTTER_VERSION
|
|
)
|
|
|
|
Invoke-WebRequest `
|
|
-Uri "https://github.com/rustdesk/engine/releases/download/main/windows-x64-release.zip" `
|
|
-OutFile $zip
|
|
|
|
Remove-Item $extract `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
New-Item -ItemType Directory `
|
|
-Force -Path $extract | Out-Null
|
|
|
|
Expand-Archive `
|
|
-Path $zip `
|
|
-DestinationPath $extract `
|
|
-Force
|
|
|
|
$dest = Join-Path `
|
|
$flutterRoot `
|
|
"bin\cache\artifacts\engine\windows-x64-release"
|
|
|
|
Remove-Item "$dest\*" `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
Copy-Item "$extract\*" "$dest\" `
|
|
-Recurse -Force
|
|
}
|
|
|
|
# vcpkg
|
|
if (-not (Test-Path "$env:VCPKG_ROOT\.git")) {
|
|
Remove-Item $env:VCPKG_ROOT `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
git clone `
|
|
https://github.com/microsoft/vcpkg.git `
|
|
$env:VCPKG_ROOT
|
|
}
|
|
|
|
$current = git -C $env:VCPKG_ROOT rev-parse HEAD
|
|
|
|
if ($current -ne $env:VCPKG_COMMIT_ID) {
|
|
git -C $env:VCPKG_ROOT fetch `
|
|
origin "$env:VCPKG_COMMIT_ID"
|
|
|
|
git -C $env:VCPKG_ROOT checkout `
|
|
--force "$env:VCPKG_COMMIT_ID"
|
|
|
|
foreach ($dir in @("installed", "buildtrees", "packages")) {
|
|
Remove-Item `
|
|
(Join-Path $env:VCPKG_ROOT $dir) `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
& "$env:VCPKG_ROOT\bootstrap-vcpkg.bat" -disableMetrics
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "vcpkg bootstrap failed"
|
|
}
|
|
|
|
- name: Restore generated bridge
|
|
uses: https://github.com/actions/download-artifact@v8
|
|
with:
|
|
name: rustdesk-bridge
|
|
path: bridge-download
|
|
|
|
- name: Copy generated bridge into RustDesk
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$files = @{
|
|
"bridge-download\src\bridge_generated.rs" =
|
|
"rustdesk\src\bridge_generated.rs"
|
|
|
|
"bridge-download\src\bridge_generated.io.rs" =
|
|
"rustdesk\src\bridge_generated.io.rs"
|
|
|
|
"bridge-download\flutter\lib\generated_bridge.dart" =
|
|
"rustdesk\flutter\lib\generated_bridge.dart"
|
|
|
|
"bridge-download\flutter\lib\generated_bridge.freezed.dart" =
|
|
"rustdesk\flutter\lib\generated_bridge.freezed.dart"
|
|
}
|
|
|
|
foreach ($source in $files.Keys) {
|
|
if (-not (Test-Path $source)) {
|
|
throw "Missing bridge file: $source"
|
|
}
|
|
|
|
Copy-Item $source $files[$source] -Force
|
|
}
|
|
|
|
if (-not (Test-Path "rustdesk\flutter\windows\CMakeLists.txt")) {
|
|
throw "Selected RustDesk tag has no Flutter Windows project"
|
|
}
|
|
|
|
- name: Patch RustDesk server configuration
|
|
shell: pwsh
|
|
env:
|
|
ID_SERVER: ${{ secrets.RUSTDESK_ID_SERVER }}
|
|
PUB_KEY: ${{ secrets.RUSTDESK_KEY }}
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
if ([string]::IsNullOrWhiteSpace($env:ID_SERVER)) {
|
|
throw "RUSTDESK_ID_SERVER secret is empty"
|
|
}
|
|
|
|
if ([string]::IsNullOrWhiteSpace($env:PUB_KEY)) {
|
|
throw "RUSTDESK_KEY secret is empty"
|
|
}
|
|
|
|
@'
|
|
import json
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
path = Path(r"rustdesk/libs/hbb_common/src/config.rs")
|
|
|
|
if not path.exists():
|
|
raise SystemExit(f"config.rs not found: {path}")
|
|
|
|
server = os.environ["ID_SERVER"].strip()
|
|
key = os.environ["PUB_KEY"].strip()
|
|
|
|
text = path.read_text(encoding="utf-8")
|
|
|
|
text, server_count = re.subn(
|
|
r"pub const RENDEZVOUS_SERVERS\s*:\s*[^=]+?="
|
|
r"\s*&\[(?:.|\n)*?\];",
|
|
"pub const RENDEZVOUS_SERVERS: &[&str] = &["
|
|
+ json.dumps(server)
|
|
+ "];",
|
|
text,
|
|
count=1,
|
|
)
|
|
|
|
text, key_count = re.subn(
|
|
r"pub const RS_PUB_KEY\s*:\s*[^=]+?=\s*.*?;",
|
|
"pub const RS_PUB_KEY: &str = "
|
|
+ json.dumps(key)
|
|
+ ";",
|
|
text,
|
|
count=1,
|
|
flags=re.S,
|
|
)
|
|
|
|
if server_count != 1:
|
|
raise SystemExit(
|
|
f"RENDEZVOUS_SERVERS replacement count: {server_count}"
|
|
)
|
|
|
|
if key_count != 1:
|
|
raise SystemExit(
|
|
f"RS_PUB_KEY replacement count: {key_count}"
|
|
)
|
|
|
|
path.write_text(text, encoding="utf-8")
|
|
PY
|
|
|
|
- name: Install RustDesk vcpkg dependencies
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
Set-Location rustdesk
|
|
|
|
$env:VCPKG_DEFAULT_HOST_TRIPLET = $env:VCPKG_TRIPLET
|
|
|
|
& "$env:VCPKG_ROOT\vcpkg.exe" `
|
|
install `
|
|
--triplet "$env:VCPKG_TRIPLET" `
|
|
--x-install-root="$env:VCPKG_ROOT\installed"
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "vcpkg install failed"
|
|
}
|
|
|
|
- name: Build RustDesk
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$repo = (Resolve-Path "rustdesk").Path
|
|
$windowsCmake = Join-Path `
|
|
$repo `
|
|
"flutter\windows\CMakeLists.txt"
|
|
|
|
if (-not (Test-Path $windowsCmake)) {
|
|
git -C $repo restore `
|
|
--source=HEAD -- flutter/windows
|
|
}
|
|
|
|
if (-not (Test-Path $windowsCmake)) {
|
|
throw "flutter/windows/CMakeLists.txt is missing"
|
|
}
|
|
|
|
Push-Location (Join-Path $repo "libs\virtual_display\dylib")
|
|
try {
|
|
cargo build --locked --release
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "virtual display build failed"
|
|
}
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
|
|
Push-Location $repo
|
|
try {
|
|
cargo build `
|
|
--locked `
|
|
--features "hwcodec,vram,flutter" `
|
|
--lib `
|
|
--release
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "RustDesk Rust build failed"
|
|
}
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
|
|
$flutterDir = Join-Path $repo "flutter"
|
|
|
|
Push-Location $flutterDir
|
|
try {
|
|
flutter pub get
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "flutter pub get failed"
|
|
}
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
|
|
# Restore the Windows project after dependency resolution.
|
|
git -C $repo restore `
|
|
--source=HEAD -- flutter/windows
|
|
|
|
if (-not (Test-Path $windowsCmake)) {
|
|
throw "flutter/windows disappeared after pub get"
|
|
}
|
|
|
|
Push-Location $flutterDir
|
|
try {
|
|
flutter build windows --release --no-pub
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Flutter Windows build failed"
|
|
}
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
|
|
$release = Join-Path `
|
|
$repo `
|
|
"flutter\build\windows\x64\runner\Release"
|
|
|
|
if (-not (Test-Path "$release\rustdesk.exe")) {
|
|
throw "rustdesk.exe was not produced"
|
|
}
|
|
|
|
$virtualDisplayDll = Join-Path `
|
|
$repo `
|
|
"target\release\deps\dylib_virtual_display.dll"
|
|
|
|
if (-not (Test-Path $virtualDisplayDll)) {
|
|
throw "dylib_virtual_display.dll was not produced"
|
|
}
|
|
|
|
Copy-Item `
|
|
$virtualDisplayDll `
|
|
"$release\dylib_virtual_display.dll" `
|
|
-Force
|
|
|
|
$packageDir = Join-Path $repo "dist\rustdesk"
|
|
|
|
Remove-Item $packageDir `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
New-Item -ItemType Directory `
|
|
-Force -Path $packageDir | Out-Null
|
|
|
|
Copy-Item "$release\*" "$packageDir\" `
|
|
-Recurse -Force
|
|
|
|
- name: Build WindowInjection.dll
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
Set-Location rustdesk
|
|
|
|
$source = ".\third-party\RustDeskTempTopMostWindow"
|
|
|
|
Remove-Item $source `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
git clone `
|
|
https://github.com/rustdesk-org/RustDeskTempTopMostWindow `
|
|
$source
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "RustDeskTempTopMostWindow clone failed"
|
|
}
|
|
|
|
if ($env:TOPMOST_COMMIT -ne "HEAD") {
|
|
git -C $source checkout "$env:TOPMOST_COMMIT"
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "RustDeskTempTopMostWindow checkout failed"
|
|
}
|
|
}
|
|
|
|
$vswhere = `
|
|
"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
|
|
|
$msbuild = & $vswhere `
|
|
-latest `
|
|
-products * `
|
|
-find "MSBuild\**\Bin\MSBuild.exe" |
|
|
Select-Object -First 1
|
|
|
|
if (-not $msbuild) {
|
|
throw "MSBuild.exe not found"
|
|
}
|
|
|
|
& $msbuild `
|
|
"$source\WindowInjection\WindowInjection.vcxproj" `
|
|
"-p:Configuration=Release" `
|
|
"-p:Platform=x64" `
|
|
"/p:TargetVersion=Windows10"
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "WindowInjection.dll build failed"
|
|
}
|
|
|
|
$dll = "$source\WindowInjection\x64\Release\WindowInjection.dll"
|
|
|
|
if (-not (Test-Path $dll)) {
|
|
throw "WindowInjection.dll not found"
|
|
}
|
|
|
|
Copy-Item $dll `
|
|
".\dist\rustdesk\WindowInjection.dll" `
|
|
-Force
|
|
|
|
- name: Add usbmmidd
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
Set-Location rustdesk
|
|
|
|
$zip = ".\third-party\usbmmidd_v2.zip"
|
|
$extract = ".\third-party\usbmmidd"
|
|
|
|
Remove-Item $extract `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
Invoke-WebRequest `
|
|
-Uri "https://github.com/rustdesk-org/rdev/releases/download/usbmmidd_v2/usbmmidd_v2.zip" `
|
|
-OutFile $zip
|
|
|
|
Expand-Archive `
|
|
-Path $zip `
|
|
-DestinationPath $extract `
|
|
-Force
|
|
|
|
$usb = Join-Path $extract "usbmmidd_v2"
|
|
|
|
Remove-Item "$usb\Win32" `
|
|
-Recurse -Force -ErrorAction SilentlyContinue
|
|
|
|
foreach ($file in @(
|
|
"deviceinstaller64.exe",
|
|
"deviceinstaller.exe",
|
|
"usbmmidd.bat"
|
|
)) {
|
|
Remove-Item `
|
|
(Join-Path $usb $file) `
|
|
-Force `
|
|
-ErrorAction SilentlyContinue
|
|
}
|
|
|
|
Copy-Item $usb `
|
|
".\dist\rustdesk\usbmmidd_v2" `
|
|
-Recurse -Force
|
|
|
|
- name: Build portable executable
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
Set-Location rustdesk
|
|
|
|
$runnerRes = Get-ChildItem `
|
|
".\flutter\build\windows\x64" `
|
|
-Filter "Runner.res" `
|
|
-Recurse `
|
|
-ErrorAction SilentlyContinue |
|
|
Select-Object -First 1
|
|
|
|
if ($runnerRes) {
|
|
Copy-Item $runnerRes.FullName `
|
|
".\libs\portable\Runner.res" `
|
|
-Force
|
|
}
|
|
|
|
$manifest = ".\res\manifest.xml"
|
|
|
|
Get-Content $manifest |
|
|
Where-Object { $_ -notmatch "dpiAware" } |
|
|
Set-Content $manifest -Encoding utf8
|
|
|
|
Push-Location ".\libs\portable"
|
|
try {
|
|
python -m pip install `
|
|
--disable-pip-version-check `
|
|
-r requirements.txt
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "portable requirements installation failed"
|
|
}
|
|
|
|
python `
|
|
.\generate.py `
|
|
-f ..\..\dist\rustdesk\ `
|
|
-o . `
|
|
-e ..\..\dist\rustdesk\rustdesk.exe
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "portable packer generation failed"
|
|
}
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|
|
|
|
$packer = ".\target\release\rustdesk-portable-packer.exe"
|
|
|
|
if (-not (Test-Path $packer)) {
|
|
throw "rustdesk-portable-packer.exe not found"
|
|
}
|
|
|
|
$outputName = (
|
|
"rustdesk-" +
|
|
$env:RUSTDESK_VERSION +
|
|
"-custom-windows-x86_64.exe"
|
|
)
|
|
|
|
$output = Join-Path ".\dist" $outputName
|
|
|
|
Copy-Item $packer $output -Force
|
|
|
|
$hash = Get-FileHash $output -Algorithm SHA256
|
|
|
|
(
|
|
$hash.Hash.ToLower() +
|
|
" " +
|
|
$outputName
|
|
) | Set-Content "$output.sha256" -Encoding ASCII
|
|
|
|
- name: Upload Windows build
|
|
uses: https://github.com/actions/upload-artifact@v7
|
|
with:
|
|
name: rustdesk-windows-x86_64-${{ env.RUSTDESK_VERSION }}
|
|
path: |
|
|
rustdesk/dist/rustdesk-*-custom-windows-x86_64.exe
|
|
rustdesk/dist/rustdesk-*-custom-windows-x86_64.exe.sha256
|
|
rustdesk/dist/rustdesk/
|
|
if-no-files-found: error
|
|
retention-days: 14
|