mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-05 15:41:23 +03:00
* feat(portable): load per-customer payload from a PE resource
Customizing a Windows client recompiled the packer for every customer,
because data.bin was baked in with include_bytes!. The generic payload is
identical across customers, so only the small per-customer delta needs to
vary: the branded runner exe, custom.txt and the icons.
The packer now also reads an RDPKG RCDATA resource holding a second blob in
the same format, and folds it over the compiled-in payload. A build can then
inject that resource into a prebuilt template instead of running cargo.
The executable to launch comes from the package trailer, and the extraction
directory follows its stem, which replaces the sed of APP_PREFIX. Where the
executable itself is not customized (sciter x86) it stays in the generic
payload and is only renamed, so the merge covers both shapes.
custom.txt keeps being written to disk next to the app: that is what the
client reads at startup and what the updater stages so a customization
survives an upgrade to a stock build.
Also fixes generate.py restoring os.curdir (the literal ".") instead of the
previous working directory, which left it inside the source folder.
CI: ship windows-aarch64 in the unsigned tarball, so ARM custom clients have
a template to build from.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* ci: publish msi templates for custom client builds
Custom clients rebuild the msi through WiX for every customer, though the
package only differs by the app name, a few GUIDs and four files.
Build the msi once more per release with a __RDAPPNAME__ placeholder and ship
it unsigned in the unsigned tarball, so a customer's build can patch it rather
than run msbuild. It stays unsigned because patching would invalidate a
signature anyway.
Doing this in CI is what makes ARM custom clients possible: preprocess.py runs
the packaged exe to read its version and build date, so an arm64 msi can only
be produced on a native arm64 machine, which the runner already is and the
build agents are not. Patching runs no exe, so an x64 agent can then patch the
arm64 template.
preprocess.py rewrites res/msi in place and locates the app as <app-name>.exe
inside the dist, so the tree is reset around the second build and the dist copy
is renamed to match. Sciter x86 ships no msi and is untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* refactor(msi): pass the app name to the printer custom actions
preprocess.py rewrote the CustomActions sources per customer so the printer
carried the app name, which meant the dll was recompiled for every custom
client and, worse, left the app name baked into a compiled binary.
Pass it through CustomActionData instead. Only the printer and its port ever
varied: the INF path and the driver name ship under their stock names and
preprocess.py already forced the driver name back to RustDesk, so a single
build of the dll now serves every custom client.
Both actions treat the name as optional and fall back to the stock name, so a
package built before this still installs and uninstalls its printer.
This also unblocks patching a prebuilt msi template, which cannot work while a
compiled dll contains the app name: replacing a string inside a PE would shift
everything after it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* ci: use an 8.3-safe placeholder for the msi template
WiX derives a short name for any name that is not valid 8.3, and a patch
cannot rewrite a truncated placeholder, so a long placeholder would leave the
package's short names pointing at it. RDAPPNAM is eight characters like
"RustDesk" and needs no short name, keeping the template as close to the
shipped package as the mechanism allows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* feat(msi): give a template its own cabinet for per-customer files
Rebranding recompressed the whole ~100MB payload because one cabinet held
everything. In template mode preprocess.py puts the handful of files a custom
client replaces on a second cabinet, so a patch rebuilds a few hundred KB and
leaves the payload cabinet alone. The shipped msi is built without template
mode and keeps its single cabinet.
The branding assets need conditional components. A stock build ships none of
them -- there is no icon.ico, icon.png or logo*.png, only icon.svg -- so the
template has to carry placeholders for the File rows to exist, and a customer
supplies whichever they want. Installing a placeholder unconditionally would
give a customer with no logo a placeholder image, where today a missing asset
means no logo at all: the client tries each candidate and treats the failure as
absence. So each optional asset installs only when its property says the
customer supplied one.
CI creates those placeholders and builds the template with the new mode.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* ci: build the msi template with a sentinel revision
preprocess.py appends a build-time revision as the fourth version field, so a
template built without one would bake the CI clock into every customer's
package. Revision 0 marks the field as the patcher's to fill in, and makes the
template deterministic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* fix(portable): delete files a later package no longer carries
The extraction directory is wiped only when the packer's compiled-in timestamp
changes. That used to be per customer, because generate.py ran for each build;
now the packer is compiled once per release, so every customer and every
rebuild within a release share one timestamp and nothing is ever wiped.
A customer who removes their logo and rebuilds would therefore keep showing it:
the new package simply omits logo.png, and md5 skipping only covers files that
are still present. Record the package's paths in the extraction's meta file and
delete the ones a later package drops.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* fix(portable): build the dropped-file path from plain components
meta.toml lives in a user-writable directory and now drives deletion, but the
traversal guard tested the normalised string while the join used the raw one.
Path::join replaces the base outright when handed an absolute path, so an
edited meta.toml could point remove_file anywhere.
The path is now rebuilt from Normal components only. A colon is rejected
explicitly rather than left to the host's parser: a drive-relative "C:x" parses
as a Normal component everywhere, and only a Windows host reads "C:/..." as a
prefix, so the same input escaped when the logic was exercised off-Windows --
which is what the new test catches.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* fix(msi): pass the printer name in a format the custom action can read
[~] is MSI's escape for a NUL character, not the delimiter WcaReadStringFromCaData
splits on -- that is a literal wide char 128, which a Formatted property value
cannot carry -- and WcaGetProperty returns a null-terminated string anyway. So
the second field was unreachable: InstallPrinter always fell back to the stock
name and installed a printer and port called "RustDesk Printer" inside a
customer's branded package, while UninstallPrinter, whose data is a single field
and parsed fine, went looking for "Acme Printer" and left the real one behind
for good.
Both actions now read CustomActionData directly and split on a character that
cannot occur in a Windows path or in a validated app name. A package built
before this carries no separator and keeps the stock name, as it did.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
* fix(portable): retry failed stale branding cleanup
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(portable): reject malformed RDPKG resources
Distinguish an absent customer package from an invalid resource and
propagate package errors instead of launching the stock payload.
Signed-off-by: fufesou <linlong1266@gmail.com>
* refact: format 2 files
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(msi): match process names case-insensitively during uninstall
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(custom-client): validate portable exclusion and MSI action data
Fail when --exclude-exe does not match a file, and propagate MSI
CustomActionData read failures while preserving legacy fallback behavior.
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix: generate.py, exclude-exe
Signed-off-by: fufesou <linlong1266@gmail.com>
* Revert "fix: generate.py, exclude-exe"
This reverts commit 5104664e95.
* fix: simple path fix in generate.py
Signed-off-by: fufesou <linlong1266@gmail.com>
* Remove useless comments
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(portable): remove expect() anyway
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix(portable): validate executable path boundaries
Reject executables outside the source folder and
reuse the package path normalization logic during
stale file cleanup.
Signed-off-by: fufesou <linlong1266@gmail.com>
* fix, remove useless file
Signed-off-by: fufesou <linlong1266@gmail.com>
---------
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2539 lines
106 KiB
YAML
2539 lines
106 KiB
YAML
name: Build the flutter version of the RustDesk
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
upload-artifact:
|
|
type: boolean
|
|
default: true
|
|
upload-tag:
|
|
type: string
|
|
default: "nightly"
|
|
|
|
# NOTE: F-Droid builder script 'flutter/build_fdroid.sh' reads environment
|
|
# variables from this workflow!
|
|
#
|
|
# It does NOT read build steps, however, so please fix 'flutter/build_fdroid.sh
|
|
# whenever you add changes to Android CI build action ('build-rustdesk-android')
|
|
# in this file!
|
|
|
|
env:
|
|
SCITER_RUST_VERSION: "1.75" # https://github.com/rustdesk/rustdesk/discussions/7503, also 1.78 has ABI change which causes our sciter version not working, https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
|
|
RUST_VERSION: "1.75" # sciter failed on m1 with 1.78 because of https://blog.rust-lang.org/2024/03/30/i128-layout-update.html
|
|
MAC_RUST_VERSION: "1.81" # 1.81 is requred for macos, because of https://github.com/yury/cidre requires 1.81
|
|
CARGO_NDK_VERSION: "3.1.2"
|
|
SCITER_ARMV7_CMAKE_VERSION: "3.29.7"
|
|
SCITER_NASM_DEBVERSION: "2.15.05-1"
|
|
LLVM_VERSION: "15.0.6"
|
|
FLUTTER_VERSION: "3.24.5"
|
|
ANDROID_FLUTTER_VERSION: "3.24.5"
|
|
# Windows arm64 only: the first stable Flutter to ship a native arm64 Windows Dart SDK +
|
|
# engine is 3.44. Every other platform stays on FLUTTER_VERSION (3.24.5) until Windows 7
|
|
# support is restored after the upstream-wide Flutter bump. The arm64 job patches the few
|
|
# 3.44-only source/pubspec changes on the fly (see "Patch RustDesk sources for Flutter 3.44").
|
|
FLUTTER_WINDOWS_ARM_VERSION: "3.44.9"
|
|
# for arm64 linux because official Dart SDK does not work
|
|
FLUTTER_ELINUX_VERSION: "3.16.9"
|
|
TAG_NAME: "${{ inputs.upload-tag }}"
|
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
|
# vcpkg version: 2026.07.29
|
|
# If we change the `VCPKG COMMIT_ID`, please remember:
|
|
# 1. Call `$VCPKG_ROOT/vcpkg x-update-baseline` to update the baseline in `vcpkg.json`.
|
|
# Or we may face build issue like
|
|
# https://github.com/rustdesk/rustdesk/actions/runs/14414119794/job/40427970174
|
|
# 2. Update the `VCPKG_COMMIT_ID` in `ci.yml` and `playground.yml`.
|
|
VCPKG_COMMIT_ID: "9e593bb18ea69cc5095e012465dcd675a822ed0d"
|
|
ARMV7_VCPKG_COMMIT_ID: "6f29f12e82a8293156836ad81cc9bf5af41fe836" # 2025.01.13, got "/opt/artifacts/vcpkg/vcpkg: No such file or directory" with latest version
|
|
VERSION: "1.5.0"
|
|
NDK_VERSION: "r28c"
|
|
#signing keys env variable checks
|
|
ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}"
|
|
MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}"
|
|
UPLOAD_ARTIFACT: "${{ inputs.upload-artifact }}"
|
|
SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}-2"
|
|
|
|
jobs:
|
|
generate-sbom:
|
|
runs-on: ubuntu-latest
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
steps:
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install Syft
|
|
uses: anchore/sbom-action/download-syft@v0
|
|
|
|
- name: Generate SBOM
|
|
run: |
|
|
syft dir:. \
|
|
-o cyclonedx-json=rustdesk.sbom.json
|
|
|
|
- name: Publish Release
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
rustdesk.sbom.json
|
|
|
|
generate-bridge:
|
|
uses: ./.github/workflows/bridge.yml
|
|
|
|
build-RustDeskTempTopMostWindow:
|
|
uses: ./.github/workflows/third-party-RustDeskTempTopMostWindow.yml
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- {
|
|
target: windows-2022,
|
|
platform: x64,
|
|
}
|
|
- {
|
|
target: windows-11-arm,
|
|
platform: ARM64,
|
|
}
|
|
with:
|
|
upload-artifact: ${{ inputs.upload-artifact }}
|
|
target: ${{ matrix.job.target }}
|
|
configuration: Release
|
|
platform: ${{ matrix.job.platform }}
|
|
target_version: Windows10
|
|
|
|
build-for-windows-flutter:
|
|
name: ${{ matrix.job.target }}
|
|
needs: [build-RustDeskTempTopMostWindow, generate-bridge]
|
|
runs-on: ${{ matrix.job.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
# - { target: i686-pc-windows-msvc , os: windows-2022 }
|
|
# - { target: x86_64-pc-windows-gnu , os: windows-2022 }
|
|
- {
|
|
target: x86_64-pc-windows-msvc,
|
|
os: windows-2022,
|
|
arch: x86_64,
|
|
flutter-arch: x64,
|
|
vcpkg-triplet: x64-windows-static,
|
|
build-args: "--vram",
|
|
}
|
|
- {
|
|
target: aarch64-pc-windows-msvc,
|
|
os: windows-11-arm,
|
|
arch: aarch64,
|
|
flutter-arch: arm64,
|
|
vcpkg-triplet: arm64-windows-static,
|
|
# vram is x86/x64-only (NVENC needs CUDA, Intel MediaSDK needs __rdtsc);
|
|
# no NV/Intel/AMD hardware exists on Windows-on-ARM, so vram stays disabled here.
|
|
build-args: "",
|
|
}
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Restore bridge files
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
# arm64 is on Flutter 3.44, so it needs the bridge generated with the same Flutter
|
|
# (its *.freezed.dart must match the freezed the arm64 build resolves). x64 and every
|
|
# other platform keep the default 3.22.3-generated bridge.
|
|
name: ${{ matrix.job.arch == 'aarch64' && 'bridge-artifact-flutter-3.44' || 'bridge-artifact' }}
|
|
path: ./
|
|
|
|
- name: Install LLVM and Clang
|
|
uses: KyleMayes/install-llvm-action@ebc0426251bc40c7cd31162802432c68818ab8f0 # v2.0.9
|
|
with:
|
|
version: ${{ env.LLVM_VERSION }}
|
|
|
|
- name: Install flutter
|
|
id: flutter
|
|
# arm64 builds with FLUTTER_WINDOWS_ARM_VERSION (>=3.44); x64 stays on FLUTTER_VERSION.
|
|
# subosito only ships an x64 Windows SDK (Flutter's release manifest lists x64 only),
|
|
# so it installs x64 on both arches. The arm64 runner re-bootstraps Dart to arm64 in
|
|
# the next step.
|
|
uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 # v2.12.0; https://github.com/subosito/flutter-action/issues/277
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ matrix.job.arch == 'aarch64' && env.FLUTTER_WINDOWS_ARM_VERSION || env.FLUTTER_VERSION }}
|
|
architecture: x64
|
|
|
|
- name: Force arm64 Dart SDK + engine
|
|
# The x64 SDK subosito installs bundles an x64 Dart with a matching engine-dart-sdk.stamp,
|
|
# so update_dart_sdk.ps1 short-circuits (stamp matches -> return) and keeps x64 Dart;
|
|
# `flutter build windows` then targets the Dart VM's arch = x64, even on this arm64 host.
|
|
# On this native-arm64 runner (PROCESSOR_ARCHITECTURE=ARM64), deleting the stamp and
|
|
# re-running update_dart_sdk.ps1 pulls the arm64 Dart (available since Flutter 3.44.0).
|
|
# https://github.com/flutter/flutter/issues/186730#issuecomment-4573214964
|
|
if: ${{ matrix.job.arch == 'aarch64' }}
|
|
run: |
|
|
$flutterRoot = "${{ steps.flutter.outputs['CACHE-PATH'] }}"
|
|
Write-Host "PROCESSOR_ARCHITECTURE=$env:PROCESSOR_ARCHITECTURE"
|
|
Write-Host "Flutter root: $flutterRoot"
|
|
Remove-Item -Force "$flutterRoot\bin\cache\engine-dart-sdk.stamp" -ErrorAction SilentlyContinue
|
|
& "$flutterRoot\bin\internal\update_dart_sdk.ps1"
|
|
# Confirm the Dart we ended up with is arm64 ("on windows_arm64"); fail loudly if not.
|
|
$dartVer = & "$flutterRoot\bin\dart.bat" --version 2>&1 | Out-String
|
|
Write-Host $dartVer
|
|
if ($dartVer -notmatch "windows_arm64") {
|
|
Write-Error "Expected an arm64 Dart SDK but got: $dartVer"
|
|
exit 1
|
|
}
|
|
& "$flutterRoot\bin\flutter.bat" precache --windows
|
|
# Fail fast if precache pulled the wrong-arch Windows engine: an arm64 Dart should
|
|
# fetch windows-arm64 engine artifacts. Bailing here saves the ~25min Rust build.
|
|
$engineDir = "$flutterRoot\bin\cache\artifacts\engine"
|
|
Write-Host "Engine artifacts present:"
|
|
Get-ChildItem $engineDir -Directory | Select-Object -ExpandProperty Name | Write-Host
|
|
if (-not (Test-Path "$engineDir\windows-arm64-release")) {
|
|
Write-Error "Expected windows-arm64-release engine artifacts but they are missing (wrong-arch SDK)."
|
|
exit 1
|
|
}
|
|
|
|
# https://github.com/flutter/flutter/issues/155685
|
|
# x64 only: arm64 uses the stock native arm64 Windows engine, and the rustdesk/engine
|
|
# windows-x64-release.zip is built for the 3.24-era x64 engine (matches FLUTTER_VERSION).
|
|
- name: Replace engine with rustdesk custom flutter engine
|
|
if: ${{ matrix.job.arch == 'x86_64' }}
|
|
run: |
|
|
flutter doctor -v
|
|
flutter precache --windows
|
|
Invoke-WebRequest -Uri https://github.com/rustdesk/engine/releases/download/main/windows-x64-release.zip -OutFile windows-x64-release.zip
|
|
Expand-Archive -Path windows-x64-release.zip -DestinationPath windows-x64-release
|
|
mv -Force windows-x64-release/* C:/hostedtoolcache/windows/flutter/stable-${{ env.FLUTTER_VERSION }}-x64/bin/cache/artifacts/engine/windows-x64-release/
|
|
|
|
- name: Patch flutter
|
|
# x64 stays on Flutter 3.24.5, which needs the dropdown filter patch.
|
|
# arm64 is on Flutter 3.44 (patched separately below) and does not use this patch.
|
|
if: ${{ matrix.job.arch == 'x86_64' }}
|
|
shell: bash
|
|
run: |
|
|
cp .github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff $(dirname $(dirname $(which flutter)))
|
|
cd $(dirname $(dirname $(which flutter)))
|
|
if [[ "3.24.5" == ${{env.FLUTTER_VERSION}} ]]; then
|
|
git apply flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
fi
|
|
|
|
- name: Patch RustDesk sources for Flutter 3.44 (arm64)
|
|
# arm64 is the only target on Flutter 3.44; apply its source/pubspec deltas on the fly
|
|
# (shared with the 3.44 bridge job) so the committed sources stay on Flutter 3.24.5.
|
|
# `flutter build` then runs `pub get`, regenerating pubspec.lock for the bumped deps.
|
|
if: ${{ matrix.job.arch == 'aarch64' }}
|
|
shell: bash
|
|
run: bash .github/patches/apply_flutter_3.44_source_patches.sh
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: ${{ env.SCITER_RUST_VERSION }}
|
|
targets: ${{ matrix.job.target }}
|
|
components: "rustfmt"
|
|
|
|
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
with:
|
|
prefix-key: ${{ matrix.job.os }}
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgDirectory: C:\vcpkg
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
env:
|
|
VCPKG_DEFAULT_HOST_TRIPLET: ${{ matrix.job.vcpkg-triplet }}
|
|
run: |
|
|
if ! $VCPKG_ROOT/vcpkg \
|
|
install \
|
|
--triplet ${{ matrix.job.vcpkg-triplet }} \
|
|
--x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
|
shell: bash
|
|
|
|
- name: Set SODIUM_LIB_DIR (arm64)
|
|
# libsodium-sys ships no arm64 Windows prebuilt lib; point it at the vcpkg-built one
|
|
# (only for arm64 — leaving it unset lets x64 use the crate's bundled lib).
|
|
if: ${{ matrix.job.arch == 'aarch64' }}
|
|
shell: bash
|
|
run: echo "SODIUM_LIB_DIR=$VCPKG_ROOT/installed/${{ matrix.job.vcpkg-triplet }}/lib" >> "$GITHUB_ENV"
|
|
|
|
- name: Build rustdesk
|
|
run: |
|
|
# Windows: build RustDesk
|
|
# --hwcodec is shared by all Windows targets; per-target extras (e.g. --vram) come from the matrix
|
|
python3 .\build.py --portable --flutter --skip-portable-pack --hwcodec ${{ matrix.job.build-args }}
|
|
mv ./flutter/build/windows/${{ matrix.job.flutter-arch }}/runner/Release ./rustdesk
|
|
|
|
# Download usbmmidd_v2.zip and extract it to ./rustdesk
|
|
Invoke-WebRequest -Uri https://github.com/rustdesk-org/rdev/releases/download/usbmmidd_v2/usbmmidd_v2.zip -OutFile usbmmidd_v2.zip
|
|
Expand-Archive usbmmidd_v2.zip -DestinationPath .
|
|
Remove-Item -Path usbmmidd_v2\Win32 -Recurse
|
|
Remove-Item -Path "usbmmidd_v2\deviceinstaller64.exe", "usbmmidd_v2\deviceinstaller.exe", "usbmmidd_v2\usbmmidd.bat"
|
|
mv -Force .\usbmmidd_v2 ./rustdesk
|
|
|
|
# Download printer driver files and extract them to ./rustdesk
|
|
try {
|
|
Invoke-WebRequest -Uri https://github.com/rustdesk/hbb_common/releases/download/driver/rustdesk_printer_driver_v4-1.4.zip -OutFile rustdesk_printer_driver_v4-1.4.zip
|
|
Invoke-WebRequest -Uri https://github.com/rustdesk/hbb_common/releases/download/driver/printer_driver_adapter.zip -OutFile printer_driver_adapter.zip
|
|
Invoke-WebRequest -Uri https://github.com/rustdesk/hbb_common/releases/download/driver/sha256sums -OutFile sha256sums
|
|
|
|
# Check and move the files
|
|
$checksum_driver = (Select-String -Path .\sha256sums -Pattern '^([a-fA-F0-9]{64}) \*rustdesk_printer_driver_v4-1.4\.zip$').Matches.Groups[1].Value
|
|
$downloadsum_driver = Get-FileHash -Path rustdesk_printer_driver_v4-1.4.zip -Algorithm SHA256
|
|
$checksum_adapter = (Select-String -Path .\sha256sums -Pattern '^([a-fA-F0-9]{64}) \*printer_driver_adapter\.zip$').Matches.Groups[1].Value
|
|
$downloadsum_adapter = Get-FileHash -Path printer_driver_adapter.zip -Algorithm SHA256
|
|
if ($checksum_driver -eq $downloadsum_driver.Hash -and $checksum_adapter -eq $downloadsum_adapter.Hash) {
|
|
Write-Output "rustdesk_printer_driver_v4-1.4, checksums match, extract the file."
|
|
Expand-Archive rustdesk_printer_driver_v4-1.4.zip -DestinationPath .
|
|
mkdir ./rustdesk/drivers
|
|
mv -Force .\rustdesk_printer_driver_v4-1.4 ./rustdesk/drivers/RustDeskPrinterDriver
|
|
Expand-Archive printer_driver_adapter.zip -DestinationPath .
|
|
mv -Force .\printer_driver_adapter.dll ./rustdesk
|
|
} elseif ($checksum_driver -ne $downloadsum_driver.Hash) {
|
|
Write-Output "rustdesk_printer_driver_v4-1.4, checksums do not match, ignore the file."
|
|
} else {
|
|
Write-Output "printer_driver_adapter.dll, checksums do not match, ignore the file."
|
|
}
|
|
} catch {
|
|
Write-Host "Ingore the printer driver error."
|
|
}
|
|
|
|
- name: find Runner.res
|
|
# Windows: find Runner.res (compiled from ./flutter/windows/runner/Runner.rc), copy to ./Runner.res
|
|
# Runner.rc does not contain actual version, but Runner.res does
|
|
continue-on-error: true
|
|
shell: bash
|
|
run: |
|
|
runner_res=$(find . -name "Runner.res");
|
|
if [ "$runner_res" == "" ]; then
|
|
echo "Runner.res: not found";
|
|
else
|
|
echo "Runner.res: $runner_res";
|
|
cp $runner_res ./libs/portable/Runner.res;
|
|
echo "list ./libs/portable/Runner.res";
|
|
ls -l ./libs/portable/Runner.res;
|
|
fi
|
|
|
|
- name: Download RustDeskTempTopMostWindow artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
if: ${{ inputs.upload-artifact }}
|
|
with:
|
|
name: ${{ matrix.job.arch == 'aarch64' && 'topmostwindow-artifacts-ARM64' || 'topmostwindow-artifacts-x64' }}
|
|
path: "./rustdesk"
|
|
|
|
- name: Upload unsigned
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustdesk-unsigned-windows-${{ matrix.job.arch }}
|
|
path: rustdesk
|
|
|
|
- name: Sign rustdesk files
|
|
if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '-2'
|
|
shell: bash
|
|
run: |
|
|
pip3 install requests argparse
|
|
BASE_URL=${{ env.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./rustdesk/
|
|
|
|
- name: Build self-extracted executable
|
|
shell: bash
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
sed -i '/dpiAware/d' res/manifest.xml
|
|
pushd ./libs/portable
|
|
pip3 install -r requirements.txt
|
|
python3 ./generate.py -f ../../rustdesk/ -o . -e ../../rustdesk/rustdesk.exe
|
|
popd
|
|
mkdir -p ./SignOutput
|
|
mv ./target/release/rustdesk-portable-packer.exe ./SignOutput/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.exe
|
|
|
|
- name: Add MSBuild to PATH
|
|
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2
|
|
|
|
- name: Build msi
|
|
# Builds the MSI for the matrix arch. res/msi (WiX v4 + native CustomActions) carries
|
|
# both x64 and ARM64 platform configs; WcaUtil/DUtil ship arm64 libs. msbuild platform
|
|
# is x64 / ARM64; the produced Package.msi is globbed since its bin/<platform>/ dir varies.
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
pushd ./res/msi
|
|
python preprocess.py --arp -d ../../rustdesk
|
|
nuget restore msi.sln
|
|
$msiPlatform = if ('${{ matrix.job.arch }}' -eq 'aarch64') { 'ARM64' } else { 'x64' }
|
|
msbuild msi.sln -p:Configuration=Release -p:Platform=$msiPlatform /p:TargetVersion=Windows10
|
|
$msi = Get-ChildItem ./Package/bin/*/Release/en-us/Package.msi | Select-Object -First 1
|
|
mv $msi.FullName ../../SignOutput/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.msi
|
|
sha256sum ../../SignOutput/rustdesk-*.msi
|
|
|
|
- name: Build pre-built MSI template
|
|
# Two things this works around: preprocess.py rewrites res/msi in place, so the
|
|
# tree is reset around this second variant; and it locates the app as
|
|
# <app-name>.exe inside the dist, so the dist copy is renamed to match.
|
|
#
|
|
# The placeholder is chosen to keep this template as close to the shipped msi as
|
|
# possible: eight characters like "RustDesk", and a valid 8.3 name, so WiX
|
|
# derives no short name for it. A longer placeholder would get one, and a patch
|
|
# cannot rewrite a truncated placeholder, leaving short names pointing at it.
|
|
#
|
|
# It still has to be unique, which is why "RustDesk" itself cannot be used:
|
|
# it also names payload that must never be renamed, such as librustdesk.dll
|
|
# and drivers\RustDeskPrinterDriver.
|
|
#
|
|
#
|
|
# Building the arm64 template on the native arm64 runner makes the ARM
|
|
# package available: the build agents are x64 and cannot run
|
|
# preprocess.py against an ARM exe.
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
git checkout -- res/msi
|
|
cp -r ./rustdesk ./rustdesk-msi-template
|
|
mv ./rustdesk-msi-template/rustdesk.exe ./rustdesk-msi-template/RDAPPNAM.exe
|
|
Set-Content -Path ./rustdesk-msi-template/custom.txt -Value 'placeholder' -NoNewline
|
|
$assets = './rustdesk-msi-template/data/flutter_assets/assets'
|
|
New-Item -ItemType Directory -Force -Path $assets | Out-Null
|
|
foreach ($a in 'icon.ico','icon.png','logo.png','logo_light.png','logo_dark.png') {
|
|
Set-Content -Path "$assets/$a" -Value 'placeholder' -NoNewline
|
|
}
|
|
pushd ./res/msi
|
|
python preprocess.py --arp --template --revision-version 0 -d ../../rustdesk-msi-template --app-name RDAPPNAM
|
|
$msiPlatform = if ('${{ matrix.job.arch }}' -eq 'aarch64') { 'ARM64' } else { 'x64' }
|
|
msbuild msi.sln -t:clean -p:Configuration=Release -p:Platform=$msiPlatform
|
|
msbuild msi.sln -p:Configuration=Release -p:Platform=$msiPlatform /p:TargetVersion=Windows10
|
|
$msi = Get-ChildItem ./Package/bin/*/Release/en-us/Package.msi | Select-Object -First 1
|
|
popd
|
|
mkdir ./msi-template
|
|
mv $msi.FullName ./msi-template/rustdesk-template-${{ matrix.job.arch }}.msi
|
|
git checkout -- res/msi
|
|
rm -r -fo ./rustdesk-msi-template
|
|
|
|
- name: Upload unsigned msi template
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustdesk-unsigned-msi-template-${{ matrix.job.arch }}
|
|
path: ./msi-template
|
|
|
|
- name: Sign rustdesk self-extracted file
|
|
if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '-2'
|
|
shell: bash
|
|
run: |
|
|
BASE_URL=${{ env.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./SignOutput
|
|
|
|
- name: Publish Release
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
./SignOutput/rustdesk-*.msi
|
|
./SignOutput/rustdesk-*.exe
|
|
|
|
# The fallback for the flutter version, we use Sciter for 32bit Windows.
|
|
build-for-windows-sciter:
|
|
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
|
|
runs-on: ${{ matrix.job.os }}
|
|
# Temporarily disable this action due to additional test is needed.
|
|
# if: false
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
# - { target: i686-pc-windows-msvc , os: windows-2022 }
|
|
# - { target: x86_64-pc-windows-gnu , os: windows-2022 }
|
|
- {
|
|
target: i686-pc-windows-msvc,
|
|
os: windows-2022,
|
|
arch: x86,
|
|
vcpkg-triplet: x86-windows-static,
|
|
}
|
|
# - { target: aarch64-pc-windows-msvc, os: windows-2022 }
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install LLVM and Clang
|
|
uses: rustdesk-org/install-llvm-action-32bit@6aa7d9ad3df84dff01cd4596dd0fc880a7f47fce # no release tag; commit 2026-05-26
|
|
with:
|
|
version: ${{ env.LLVM_VERSION }}
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: nightly-2023-10-13-${{ matrix.job.target }} # must use nightly here, because of abi_thiscall feature required
|
|
targets: ${{ matrix.job.target }}
|
|
components: "rustfmt"
|
|
|
|
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
with:
|
|
prefix-key: ${{ matrix.job.os }}-sciter
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgDirectory: C:\vcpkg
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
env:
|
|
VCPKG_DEFAULT_HOST_TRIPLET: ${{ matrix.job.vcpkg-triplet }}
|
|
run: |
|
|
if ! $VCPKG_ROOT/vcpkg \
|
|
install \
|
|
--triplet ${{ matrix.job.vcpkg-triplet }} \
|
|
--x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
|
shell: bash
|
|
|
|
- name: Build rustdesk
|
|
id: build
|
|
shell: bash
|
|
run: |
|
|
python3 res/inline-sciter.py
|
|
# Patch sciter x86
|
|
sed -i 's/branch = "dyn"/branch = "dyn_x86"/g' ./Cargo.toml
|
|
cargo update -p sciter-rs --precise 674e07d3066ca9a92ced3816203ab6b652629d1e
|
|
cargo build --locked --features inline,vram,hwcodec --release --bins
|
|
mkdir -p ./Release
|
|
mv ./target/release/rustdesk.exe ./Release/rustdesk.exe
|
|
curl -LJ -o ./Release/sciter.dll https://github.com/c-smile/sciter-sdk/raw/master/bin.win/x32/sciter.dll
|
|
echo "output_folder=./Release" >> $GITHUB_OUTPUT
|
|
curl -LJ -o ./usbmmidd_v2.zip https://github.com/rustdesk-org/rdev/releases/download/usbmmidd_v2/usbmmidd_v2.zip
|
|
unzip usbmmidd_v2.zip
|
|
# Do not remove x64 files, because the user may run the 32bit version on a 64bit system.
|
|
# Do not remove ./usbmmidd_v2/deviceinstaller64.exe, as x86 exe cannot install and uninstall drivers when running on x64,
|
|
# we need the x64 exe to install and uninstall the driver.
|
|
rm -rf ./usbmmidd_v2/deviceinstaller.exe ./usbmmidd_v2/usbmmidd.bat
|
|
mv ./usbmmidd_v2 ./Release || true
|
|
|
|
- name: find Runner.res
|
|
# Windows: find Runner.res (compiled from ./flutter/windows/runner/Runner.rc), copy to ./Runner.res
|
|
# Runner.rc does not contain actual version, but Runner.res does
|
|
continue-on-error: true
|
|
shell: bash
|
|
run: |
|
|
runner_res=$(find . -name "Runner.res");
|
|
if [ "$runner_res" == "" ]; then
|
|
echo "Runner.res: not found";
|
|
else
|
|
echo "Runner.res: $runner_res";
|
|
cp $runner_res ./libs/portable/Runner.res;
|
|
echo "list ./libs/portable/Runner.res";
|
|
ls -l ./libs/portable/Runner.res;
|
|
fi
|
|
|
|
- name: Upload unsigned
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustdesk-unsigned-windows-${{ matrix.job.arch }}
|
|
path: Release
|
|
|
|
- name: Sign rustdesk files
|
|
if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '-2'
|
|
shell: bash
|
|
run: |
|
|
pip3 install requests argparse
|
|
BASE_URL=${{ env.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./Release/
|
|
|
|
- name: Build self-extracted executable
|
|
shell: bash
|
|
run: |
|
|
sed -i '/dpiAware/d' res/manifest.xml
|
|
pushd ./libs/portable
|
|
pip3 install -r requirements.txt
|
|
python3 ./generate.py -f ../../Release/ -o . -e ../../Release/rustdesk.exe
|
|
popd
|
|
mkdir -p ./SignOutput
|
|
mv ./target/release/rustdesk-portable-packer.exe ./SignOutput/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}-sciter.exe
|
|
|
|
- name: Sign rustdesk self-extracted file
|
|
if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '-2'
|
|
shell: bash
|
|
run: |
|
|
BASE_URL=${{ env.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./SignOutput/
|
|
|
|
- name: Publish Release
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
./SignOutput/rustdesk-*.exe
|
|
|
|
build-rustdesk-ios:
|
|
if: ${{ inputs.upload-artifact }}
|
|
name: build rustdesk ios ipa
|
|
runs-on: ${{ matrix.job.os }}
|
|
needs: [generate-bridge]
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- {
|
|
arch: aarch64,
|
|
target: aarch64-apple-ios,
|
|
os: macos-latest,
|
|
vcpkg-triplet: arm64-ios,
|
|
}
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
brew install nasm yasm
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
|
|
- name: Patch flutter
|
|
run: |
|
|
cd $(dirname $(dirname $(which flutter)))
|
|
if [[ "3.24.5" == ${{env.FLUTTER_VERSION}} ]]; then
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
fi
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
run: |
|
|
if ! $VCPKG_ROOT/vcpkg \
|
|
install \
|
|
--triplet ${{ matrix.job.vcpkg-triplet }} \
|
|
--x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
|
shell: bash
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
targets: ${{ matrix.job.target }}
|
|
components: "rustfmt"
|
|
|
|
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
with:
|
|
prefix-key: rustdesk-lib-cache-ios
|
|
key: ${{ matrix.job.target }}
|
|
|
|
- name: Restore bridge files
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- name: Build rustdesk lib
|
|
run: |
|
|
rustup target add ${{ matrix.job.target }}
|
|
cargo build --locked --features flutter,hwcodec --release --target aarch64-apple-ios --lib
|
|
|
|
- name: Upload liblibrustdesk.a Artifacts
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: liblibrustdesk.a
|
|
path: target/aarch64-apple-ios/release/liblibrustdesk.a
|
|
|
|
- name: Build rustdesk
|
|
shell: bash
|
|
run: |
|
|
pushd flutter
|
|
# flutter build ipa --release --obfuscate --split-debug-info=./split-debug-info --no-codesign
|
|
# for easy debugging
|
|
flutter build ipa --release --no-codesign
|
|
|
|
# - name: Upload Artifacts
|
|
# # if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
|
|
# uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
# with:
|
|
# name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
|
# path: flutter/build/ios/ipa/*.ipa
|
|
|
|
# - name: Publish ipa package
|
|
# # if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
|
|
# uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
# with:
|
|
# prerelease: true
|
|
# tag_name: ${{ env.TAG_NAME }}
|
|
# files: |
|
|
# flutter/build/ios/ipa/*.ipa
|
|
|
|
|
|
build-for-macOS:
|
|
name: ${{ matrix.job.target }}
|
|
runs-on: ${{ matrix.job.os }}
|
|
needs: [generate-bridge]
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- {
|
|
target: x86_64-apple-darwin,
|
|
os: macos-15-intel, #macos-latest or macos-14 use M1 now, https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#:~:text=14%20GB-,macos%2Dlatest%20or%20macos%2D14,-The%20macos%2Dlatestlabel
|
|
extra-build-args: "",
|
|
arch: x86_64,
|
|
vcpkg-triplet: x64-osx,
|
|
}
|
|
- {
|
|
target: aarch64-apple-darwin,
|
|
os: macos-14,
|
|
# extra-build-args: "--disable-flutter-texture-render", # disable this for mac, because we see a lot of users reporting flickering both on arm and x64, and we can not confirm if texture rendering has better performance if htere is no vram, https://github.com/rustdesk/rustdesk/issues/6296
|
|
extra-build-args: "--screencapturekit",
|
|
arch: aarch64,
|
|
vcpkg-triplet: arm64-osx,
|
|
}
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Import the codesign cert
|
|
if: env.MACOS_P12_BASE64 != null
|
|
uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071 # v1
|
|
with:
|
|
p12-file-base64: ${{ secrets.MACOS_P12_BASE64 }}
|
|
p12-password: ${{ secrets.MACOS_P12_PASSWORD }}
|
|
keychain: rustdesk
|
|
|
|
- name: Check sign and import sign key
|
|
if: env.MACOS_P12_BASE64 != null
|
|
run: |
|
|
security default-keychain -s rustdesk.keychain
|
|
security find-identity -v
|
|
|
|
- name: Import notarize key
|
|
if: env.MACOS_P12_BASE64 != null
|
|
uses: timheuer/base64-to-file@adaa40c0c581f276132199d4cf60afa07ce60eac # v1.2
|
|
with:
|
|
# https://gregoryszorc.com/docs/apple-codesign/stable/apple_codesign_rcodesign.html#notarizing-and-stapling
|
|
fileName: rustdesk.json
|
|
fileDir: ${{ github.workspace }}
|
|
encodedString: ${{ secrets.MACOS_NOTARIZE_JSON }}
|
|
|
|
- name: Install rcodesign tool
|
|
if: env.MACOS_P12_BASE64 != null
|
|
shell: bash
|
|
run: |
|
|
pushd /tmp
|
|
wget https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.22.0/apple-codesign-0.22.0-macos-universal.tar.gz
|
|
tar -zxvf apple-codesign-0.22.0-macos-universal.tar.gz
|
|
mv apple-codesign-0.22.0-macos-universal/rcodesign /usr/local/bin
|
|
popd
|
|
|
|
- name: Install build runtime
|
|
run: |
|
|
brew install llvm create-dmg
|
|
# pkg-config is handled in a separate step, because it may be already installed by `macos-latest`(14.7.1) runner
|
|
if command -v pkg-config &>/dev/null; then
|
|
echo "pkg-config is already installed"
|
|
else
|
|
brew install pkg-config
|
|
fi
|
|
|
|
- name: Install NASM
|
|
run: |
|
|
# Install NASM 2.16.x from official release.
|
|
# Do NOT use `brew install nasm` which installs NASM 3.x.
|
|
# NASM 3.x is a complete rewrite with incompatible CLI options and removed features.
|
|
# aom and other multimedia libraries require NASM 2.x for x86/x86_64 assembly.
|
|
wget https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/macosx/nasm-2.16.03-macosx.zip
|
|
unzip nasm-2.16.03-macosx.zip
|
|
sudo cp nasm-2.16.03/nasm /usr/local/bin/nasm
|
|
nasm --version
|
|
|
|
- name: Install flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
|
|
- name: Patch flutter
|
|
run: |
|
|
cd $(dirname $(dirname $(which flutter)))
|
|
if [[ "3.24.5" == ${{env.FLUTTER_VERSION}} ]]; then
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
fi
|
|
|
|
- name: Workaround for flutter issue
|
|
shell: bash
|
|
run: |
|
|
cd "$(dirname "$(which flutter)")"
|
|
# https://github.com/flutter/flutter/issues/133533
|
|
sed -i -e 's/_setFramesEnabledState(false);/\/\/_setFramesEnabledState(false);/g' ../packages/flutter/lib/src/scheduler/binding.dart
|
|
grep -n '_setFramesEnabledState(false);' ../packages/flutter/lib/src/scheduler/binding.dart
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: ${{ env.MAC_RUST_VERSION }}
|
|
targets: ${{ matrix.job.target }}
|
|
components: "rustfmt"
|
|
|
|
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
with:
|
|
prefix-key: ${{ matrix.job.os }}
|
|
|
|
- name: Restore bridge files
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
run: |
|
|
if ! $VCPKG_ROOT/vcpkg \
|
|
install \
|
|
--x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
|
|
|
- name: Show version information (Rust, cargo, Clang)
|
|
shell: bash
|
|
run: |
|
|
clang --version || true
|
|
rustup -V
|
|
rustup toolchain list
|
|
rustup default
|
|
cargo -V
|
|
rustc -V
|
|
|
|
- name: Build rustdesk
|
|
run: |
|
|
if [ "${{ matrix.job.target }}" = "aarch64-apple-darwin" ]; then
|
|
MIN_MACOS_VERSION="12.3"
|
|
sed -i -e "s/MACOSX_DEPLOYMENT_TARGET\=[0-9]*.[0-9]*/MACOSX_DEPLOYMENT_TARGET=${MIN_MACOS_VERSION}/" build.py
|
|
sed -i -e "s/platform :osx, '.*'/platform :osx, '${MIN_MACOS_VERSION}'/" flutter/macos/Podfile
|
|
sed -i -e "s/osx_minimum_system_version = \"[0-9]*.[0-9]*\"/osx_minimum_system_version = \"${MIN_MACOS_VERSION}\"/" Cargo.toml
|
|
sed -i -e "s/MACOSX_DEPLOYMENT_TARGET = [0-9]*.[0-9]*;/MACOSX_DEPLOYMENT_TARGET = ${MIN_MACOS_VERSION};/" flutter/macos/Runner.xcodeproj/project.pbxproj
|
|
fi
|
|
./build.py --flutter --hwcodec --unix-file-copy-paste ${{ matrix.job.extra-build-args }}
|
|
|
|
- name: create unsigned dmg
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
CREATE_DMG="$(command -v create-dmg)"
|
|
CREATE_DMG="$(readlink -f "$CREATE_DMG")"
|
|
sed -i -e 's/MAXIMUM_UNMOUNTING_ATTEMPTS=3/MAXIMUM_UNMOUNTING_ATTEMPTS=7/' "$CREATE_DMG"
|
|
create-dmg --icon "RustDesk.app" 200 190 --hide-extension "RustDesk.app" --window-size 800 400 --app-drop-link 600 185 rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.dmg ./flutter/build/macos/Build/Products/Release/RustDesk.app
|
|
|
|
- name: Upload unsigned macOS app
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustdesk-unsigned-macos-${{ matrix.job.arch }}
|
|
path: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.dmg # can not upload the directory directly or tar.gz, which destroy the link structure, causing the codesign failed
|
|
|
|
- name: Codesign app and create signed dmg
|
|
if: env.MACOS_P12_BASE64 != null && env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
# Patch create-dmg to give more attempts to unmount image
|
|
CREATE_DMG="$(command -v create-dmg)"
|
|
CREATE_DMG="$(readlink -f "$CREATE_DMG")"
|
|
sed -i -e 's/MAXIMUM_UNMOUNTING_ATTEMPTS=3/MAXIMUM_UNMOUNTING_ATTEMPTS=7/' "$CREATE_DMG"
|
|
# Unlock keychain
|
|
security default-keychain -s rustdesk.keychain
|
|
security unlock-keychain -p ${{ secrets.MACOS_P12_PASSWORD }} rustdesk.keychain
|
|
# start sign the rustdesk.app and dmg
|
|
rm -rf *.dmg || true
|
|
codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep --strict ./flutter/build/macos/Build/Products/Release/RustDesk.app -vvv
|
|
create-dmg --icon "RustDesk.app" 200 190 --hide-extension "RustDesk.app" --window-size 800 400 --app-drop-link 600 185 rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/RustDesk.app
|
|
codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep --strict rustdesk-${{ env.VERSION }}.dmg -vvv
|
|
# notarize the rustdesk-${{ env.VERSION }}.dmg
|
|
rcodesign notary-submit --api-key-path ${{ github.workspace }}/rustdesk.json --staple rustdesk-${{ env.VERSION }}.dmg
|
|
|
|
- name: Rename rustdesk
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
for name in rustdesk*??.dmg; do
|
|
mv "$name" "${name%%.dmg}-${{ matrix.job.arch }}.dmg"
|
|
done
|
|
|
|
- name: Publish DMG package
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
rustdesk*-${{ matrix.job.arch }}.dmg
|
|
|
|
publish_unsigned:
|
|
needs:
|
|
- build-for-macOS
|
|
- build-for-windows-flutter
|
|
- build-for-windows-sciter
|
|
runs-on: ubuntu-latest
|
|
if: ${{ inputs.upload-artifact }}
|
|
steps:
|
|
- name: Download artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-macos-x86_64
|
|
path: ./
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-macos-aarch64
|
|
path: ./
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-windows-x86_64
|
|
path: ./windows-x86_64/
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-windows-aarch64
|
|
path: ./windows-aarch64/
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-windows-x86
|
|
path: ./windows-x86/
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-msi-template-x86_64
|
|
path: ./msi-template/
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-unsigned-msi-template-aarch64
|
|
path: ./msi-template/
|
|
|
|
- name: Combine unsigned app
|
|
run: |
|
|
tar czf rustdesk-${{ env.VERSION }}-unsigned.tar.gz *.dmg windows-x86_64 windows-aarch64 windows-x86 msi-template
|
|
|
|
- name: Publish unsigned app
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: rustdesk-${{ env.VERSION }}-unsigned.tar.gz
|
|
|
|
build-rustdesk-android:
|
|
needs: [generate-bridge]
|
|
name: build rustdesk android apk ${{ matrix.job.target }}
|
|
runs-on: ${{ matrix.job.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- {
|
|
arch: aarch64,
|
|
target: aarch64-linux-android,
|
|
os: ubuntu-24.04,
|
|
reltype: release,
|
|
suffix: "",
|
|
}
|
|
- {
|
|
arch: armv7,
|
|
target: armv7-linux-androideabi,
|
|
os: ubuntu-24.04,
|
|
reltype: release,
|
|
suffix: "",
|
|
}
|
|
- {
|
|
arch: x86_64,
|
|
target: x86_64-linux-android,
|
|
os: ubuntu-24.04,
|
|
reltype: release,
|
|
suffix: "",
|
|
}
|
|
steps:
|
|
- name: Free Disk Space (Ubuntu)
|
|
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
|
with:
|
|
tool-cache: false
|
|
android: false
|
|
dotnet: true
|
|
haskell: true
|
|
large-packages: false
|
|
docker-images: true
|
|
swap-storage: false
|
|
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
clang \
|
|
cmake \
|
|
curl \
|
|
gcc-multilib \
|
|
git \
|
|
g++ \
|
|
g++-multilib \
|
|
libayatana-appindicator3-dev \
|
|
libasound2-dev \
|
|
libc6-dev \
|
|
libclang-dev \
|
|
libunwind-dev \
|
|
libgstreamer1.0-dev \
|
|
libgstreamer-plugins-base1.0-dev \
|
|
libgtk-3-dev \
|
|
libpulse-dev \
|
|
libva-dev \
|
|
libxcb-randr0-dev \
|
|
libxcb-shape0-dev \
|
|
libxcb-xfixes0-dev \
|
|
libxdo-dev \
|
|
libxfixes-dev \
|
|
llvm-dev \
|
|
nasm \
|
|
ninja-build \
|
|
openjdk-17-jdk-headless \
|
|
pkg-config \
|
|
tree \
|
|
wget
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.ANDROID_FLUTTER_VERSION }}
|
|
|
|
- name: Patch flutter
|
|
run: |
|
|
cd $(dirname $(dirname $(which flutter)))
|
|
if [[ "3.24.5" == ${{env.ANDROID_FLUTTER_VERSION}} ]]; then
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
fi
|
|
|
|
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1
|
|
id: setup-ndk
|
|
with:
|
|
ndk-version: ${{ env.NDK_VERSION }}
|
|
add-to-path: true
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgDirectory: /opt/artifacts/vcpkg
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
run: |
|
|
case ${{ matrix.job.target }} in
|
|
aarch64-linux-android)
|
|
ANDROID_TARGET=arm64-v8a
|
|
;;
|
|
armv7-linux-androideabi)
|
|
ANDROID_TARGET=armeabi-v7a
|
|
;;
|
|
x86_64-linux-android)
|
|
ANDROID_TARGET=x86_64
|
|
;;
|
|
i686-linux-android)
|
|
ANDROID_TARGET=x86
|
|
;;
|
|
esac
|
|
if ! ./flutter/build_android_deps.sh "${ANDROID_TARGET}"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
shell: bash
|
|
|
|
- name: Restore bridge files
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
components: "rustfmt"
|
|
|
|
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
|
with:
|
|
prefix-key: rustdesk-lib-cache-android # TODO: drop '-android' part after caches are invalidated
|
|
key: ${{ matrix.job.target }}
|
|
|
|
- name: Build rustdesk lib
|
|
env:
|
|
ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
|
|
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
|
|
run: |
|
|
rustup target add ${{ matrix.job.target }}
|
|
cargo install cargo-ndk --version ${{ env.CARGO_NDK_VERSION }} --locked
|
|
case ${{ matrix.job.target }} in
|
|
aarch64-linux-android)
|
|
./flutter/ndk_arm64.sh
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/arm64-v8a
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
|
|
;;
|
|
armv7-linux-androideabi)
|
|
./flutter/ndk_arm.sh
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/armeabi-v7a
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
|
|
;;
|
|
x86_64-linux-android)
|
|
./flutter/ndk_x64.sh
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/x86_64
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
|
|
;;
|
|
i686-linux-android)
|
|
./flutter/ndk_x86.sh
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/x86
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86/librustdesk.so
|
|
;;
|
|
esac
|
|
|
|
- name: Upload Rustdesk library to Artifacts
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: librustdesk.so.${{ matrix.job.target }}
|
|
path: ./target/${{ matrix.job.target }}/release/liblibrustdesk.so
|
|
|
|
- name: Build rustdesk
|
|
shell: bash
|
|
env:
|
|
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
|
|
run: |
|
|
export PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH
|
|
# Increase Gradle JVM memory for CI builds
|
|
sed -i "s/org.gradle.jvmargs=-Xmx1024M/org.gradle.jvmargs=-Xmx2g/g" ./flutter/android/gradle.properties
|
|
# temporary use debug sign config
|
|
sed -i "s/signingConfigs.release/signingConfigs.debug/g" ./flutter/android/app/build.gradle
|
|
case ${{ matrix.job.target }} in
|
|
aarch64-linux-android)
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/arm64-v8a
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
|
|
# build flutter
|
|
pushd flutter
|
|
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm64 --split-per-abi
|
|
mv build/app/outputs/flutter-apk/app-arm64-v8a-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
|
|
;;
|
|
armv7-linux-androideabi)
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/armeabi-v7a
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
|
|
# build flutter
|
|
pushd flutter
|
|
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-arm --split-per-abi
|
|
mv build/app/outputs/flutter-apk/app-armeabi-v7a-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
|
|
;;
|
|
x86_64-linux-android)
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/x86_64
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86_64/
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
|
|
# build flutter
|
|
pushd flutter
|
|
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x64 --split-per-abi
|
|
mv build/app/outputs/flutter-apk/app-x86_64-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
|
|
;;
|
|
i686-linux-android)
|
|
mkdir -p ./flutter/android/app/src/main/jniLibs/x86
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86/
|
|
cp ./target/${{ matrix.job.target }}/release/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86/librustdesk.so
|
|
# build flutter
|
|
pushd flutter
|
|
flutter build apk "--${{ matrix.job.reltype }}" --target-platform android-x86 --split-per-abi
|
|
mv build/app/outputs/flutter-apk/app-x86-${{ matrix.job.reltype }}.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk
|
|
;;
|
|
esac
|
|
popd
|
|
mkdir -p signed-apk; pushd signed-apk
|
|
mv ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.apk .
|
|
|
|
# https://github.com/r0adkll/sign-android-release/issues/84#issuecomment-1889636075
|
|
- name: Setup sign tool version variable
|
|
shell: bash
|
|
run: |
|
|
BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
|
|
echo "ANDROID_SIGN_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
|
|
echo Last build tool version is: $BUILD_TOOL_VERSION
|
|
|
|
- uses: r0adkll/sign-android-release@349ebdef58775b1e0d8099458af0816dc79b6407 # v1
|
|
name: Sign app APK
|
|
if: env.ANDROID_SIGNING_KEY != null
|
|
id: sign-rustdesk
|
|
with:
|
|
releaseDirectory: ./signed-apk
|
|
signingKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }}
|
|
alias: ${{ secrets.ANDROID_ALIAS }}
|
|
keyStorePassword: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }}
|
|
keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
|
env:
|
|
# env.ANDROID_SIGN_TOOL_VERSION is set by Step "Setup sign tool version variable"
|
|
BUILD_TOOLS_VERSION: ${{ env.ANDROID_SIGN_TOOL_VERSION }}
|
|
|
|
- name: Upload Artifacts
|
|
if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
|
path: ${{steps.sign-rustdesk.outputs.signedReleaseFile}}
|
|
|
|
- name: Publish signed apk package
|
|
if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
${{steps.sign-rustdesk.outputs.signedReleaseFile}}
|
|
|
|
- name: Publish unsigned apk package
|
|
if: env.ANDROID_SIGNING_KEY == null && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
signed-apk/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
|
|
|
build-rustdesk-android-universal:
|
|
needs: [build-rustdesk-android]
|
|
name: build rustdesk android universal apk
|
|
if: ${{ inputs.upload-artifact }}
|
|
runs-on: ubuntu-24.04
|
|
env:
|
|
reltype: release
|
|
x86_target: "" # can be ",android-x86"
|
|
suffix: ""
|
|
steps:
|
|
- name: Free Disk Space (Ubuntu)
|
|
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1
|
|
with:
|
|
tool-cache: false
|
|
android: false
|
|
dotnet: true
|
|
haskell: true
|
|
large-packages: false
|
|
docker-images: true
|
|
swap-storage: false
|
|
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y \
|
|
clang \
|
|
cmake \
|
|
curl \
|
|
gcc-multilib \
|
|
git \
|
|
g++ \
|
|
g++-multilib \
|
|
libayatana-appindicator3-dev \
|
|
libasound2-dev \
|
|
libc6-dev \
|
|
libclang-dev \
|
|
libunwind-dev \
|
|
libgstreamer1.0-dev \
|
|
libgstreamer-plugins-base1.0-dev \
|
|
libgtk-3-dev \
|
|
libpulse-dev \
|
|
libva-dev \
|
|
libxcb-randr0-dev \
|
|
libxcb-shape0-dev \
|
|
libxcb-xfixes0-dev \
|
|
libxdo-dev \
|
|
libxfixes-dev \
|
|
llvm-dev \
|
|
nasm \
|
|
ninja-build \
|
|
openjdk-17-jdk-headless \
|
|
pkg-config \
|
|
tree \
|
|
wget
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Install flutter
|
|
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.ANDROID_FLUTTER_VERSION }}
|
|
|
|
- name: Patch flutter
|
|
run: |
|
|
cd $(dirname $(dirname $(which flutter)))
|
|
if [[ "3.24.5" == ${{env.ANDROID_FLUTTER_VERSION}} ]]; then
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
fi
|
|
|
|
- name: Restore bridge files
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- name: Download Rustdesk library from Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: librustdesk.so.aarch64-linux-android
|
|
path: ./flutter/android/app/src/main/jniLibs/arm64-v8a
|
|
|
|
- name: Download Rustdesk library from Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: librustdesk.so.armv7-linux-androideabi
|
|
path: ./flutter/android/app/src/main/jniLibs/armeabi-v7a
|
|
|
|
- name: Download Rustdesk library from Artifacts
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: librustdesk.so.x86_64-linux-android
|
|
path: ./flutter/android/app/src/main/jniLibs/x86_64
|
|
|
|
- name: Download Rustdesk library from Artifacts
|
|
if: ${{ env.reltype == 'debug' }}
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: librustdesk.so.i686-linux-android
|
|
path: ./flutter/android/app/src/main/jniLibs/x86
|
|
|
|
- name: Build rustdesk
|
|
shell: bash
|
|
env:
|
|
JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
|
|
run: |
|
|
export PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH
|
|
# Increase Gradle JVM memory for CI builds
|
|
sed -i "s/org.gradle.jvmargs=-Xmx1024M/org.gradle.jvmargs=-Xmx2g/g" ./flutter/android/gradle.properties
|
|
# temporary use debug sign config
|
|
sed -i "s/signingConfigs.release/signingConfigs.debug/g" ./flutter/android/app/build.gradle
|
|
mv ./flutter/android/app/src/main/jniLibs/arm64-v8a/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/librustdesk.so
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/arm64-v8a/
|
|
mv ./flutter/android/app/src/main/jniLibs/armeabi-v7a/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/librustdesk.so
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so ./flutter/android/app/src/main/jniLibs/armeabi-v7a/
|
|
mv ./flutter/android/app/src/main/jniLibs/x86_64/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86_64/librustdesk.so
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86_64/
|
|
if [ "${{ env.reltype }}" = "debug" ]; then
|
|
mv ./flutter/android/app/src/main/jniLibs/x86/liblibrustdesk.so ./flutter/android/app/src/main/jniLibs/x86/librustdesk.so
|
|
cp ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so ./flutter/android/app/src/main/jniLibs/x86/
|
|
fi
|
|
# build flutter
|
|
pushd flutter
|
|
flutter build apk "--${{ env.reltype }}" --target-platform android-arm64,android-arm,android-x64${{ env.x86_target }}
|
|
popd
|
|
mkdir -p signed-apk
|
|
mv ./flutter/build/app/outputs/flutter-apk/app-${{ env.reltype }}.apk signed-apk/rustdesk-${{ env.VERSION }}-universal${{ env.suffix }}.apk
|
|
|
|
# https://github.com/r0adkll/sign-android-release/issues/84#issuecomment-1889636075
|
|
- name: Setup sign tool version variable
|
|
shell: bash
|
|
run: |
|
|
BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
|
|
echo "ANDROID_SIGN_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
|
|
echo Last build tool version is: $BUILD_TOOL_VERSION
|
|
|
|
- uses: r0adkll/sign-android-release@349ebdef58775b1e0d8099458af0816dc79b6407 # v1
|
|
name: Sign app APK
|
|
if: env.ANDROID_SIGNING_KEY != null
|
|
id: sign-rustdesk
|
|
with:
|
|
releaseDirectory: ./signed-apk
|
|
signingKeyBase64: ${{ secrets.ANDROID_SIGNING_KEY }}
|
|
alias: ${{ secrets.ANDROID_ALIAS }}
|
|
keyStorePassword: ${{ secrets.ANDROID_KEY_STORE_PASSWORD }}
|
|
keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
|
|
env:
|
|
# env.ANDROID_SIGN_TOOL_VERSION is set by Step "Setup sign tool version variable"
|
|
BUILD_TOOLS_VERSION: ${{ env.ANDROID_SIGN_TOOL_VERSION }}
|
|
|
|
- name: Upload Artifacts
|
|
if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk
|
|
path: ${{steps.sign-rustdesk.outputs.signedReleaseFile}}
|
|
|
|
- name: Publish signed apk package
|
|
if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
${{steps.sign-rustdesk.outputs.signedReleaseFile}}
|
|
|
|
- name: Publish unsigned apk package
|
|
if: env.ANDROID_SIGNING_KEY == null && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
signed-apk/rustdesk-${{ env.VERSION }}-universal${{ env.suffix }}.apk
|
|
|
|
build-rustdesk-linux:
|
|
needs: [generate-bridge]
|
|
name: build rustdesk linux ${{ matrix.job.target }}
|
|
runs-on: ${{ matrix.job.on }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# use a high level qemu-user-static
|
|
job:
|
|
- {
|
|
arch: x86_64,
|
|
target: x86_64-unknown-linux-gnu,
|
|
distro: ubuntu18.04,
|
|
on: ubuntu-22.04,
|
|
deb_arch: amd64,
|
|
vcpkg-triplet: x64-linux,
|
|
}
|
|
- {
|
|
arch: aarch64,
|
|
target: aarch64-unknown-linux-gnu,
|
|
distro: ubuntu18.04,
|
|
on: ubuntu-22.04-arm,
|
|
deb_arch: arm64,
|
|
vcpkg-triplet: arm64-linux,
|
|
}
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Maximize build space
|
|
run: |
|
|
sudo rm -rf /opt/ghc
|
|
sudo rm -rf /usr/local/lib/android
|
|
sudo rm -rf /usr/share/dotnet
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y nasm
|
|
if [[ "${{ matrix.job.arch }}" == "x86_64" ]]; then
|
|
sudo apt-get install -y qemu-user-static
|
|
fi
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Set Swap Space
|
|
if: ${{ matrix.job.arch == 'x86_64' }}
|
|
uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0
|
|
with:
|
|
swap-size-gb: 12
|
|
|
|
- name: Free Space
|
|
run: |
|
|
df -h
|
|
free -m
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
targets: ${{ matrix.job.target }}
|
|
components: "rustfmt"
|
|
|
|
- name: Save Rust toolchain version
|
|
run: |
|
|
RUST_TOOLCHAIN_VERSION=$(cargo --version | awk '{print $2}')
|
|
echo "RUST_TOOLCHAIN_VERSION=$RUST_TOOLCHAIN_VERSION" >> $GITHUB_ENV
|
|
|
|
- name: Disable rust bridge build
|
|
run: |
|
|
# only build cdylib
|
|
sed -i "s/\[\"cdylib\", \"staticlib\", \"rlib\"\]/\[\"cdylib\"\]/g" Cargo.toml
|
|
|
|
- name: Restore bridge files
|
|
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgDirectory: /opt/artifacts/vcpkg
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
sudo apt install -y libva-dev && apt show libva-dev
|
|
if ! $VCPKG_ROOT/vcpkg \
|
|
install \
|
|
--triplet ${{ matrix.job.vcpkg-triplet }} \
|
|
--x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
|
shell: bash
|
|
|
|
- name: Restore bridge files
|
|
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- uses: rustdesk-org/run-on-arch-action@d3fcfbb632b84cf7f6bc772bfaaa2c2f4f8789a8 # no release tag; commit 2026-05-26
|
|
name: Build rustdesk
|
|
id: vcpkg
|
|
if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
arch: ${{ matrix.job.arch }}
|
|
distro: ${{ matrix.job.distro }}
|
|
githubToken: ${{ github.token }}
|
|
setup: |
|
|
ls -l "${PWD}"
|
|
ls -l /opt/artifacts/vcpkg/installed
|
|
dockerRunArgs: |
|
|
--volume "${PWD}:/workspace"
|
|
--volume "/opt/artifacts:/opt/artifacts"
|
|
shell: /bin/bash
|
|
install: |
|
|
apt-get update -y
|
|
echo -e "installing deps"
|
|
apt-get install -y \
|
|
build-essential \
|
|
clang \
|
|
cmake \
|
|
curl \
|
|
gcc \
|
|
git \
|
|
g++ \
|
|
libayatana-appindicator3-dev \
|
|
libasound2-dev \
|
|
libclang-10-dev \
|
|
libgstreamer1.0-dev \
|
|
libgstreamer-plugins-base1.0-dev \
|
|
libgtk-3-dev \
|
|
libpulse-dev \
|
|
libva-dev \
|
|
libxcb-randr0-dev \
|
|
libxcb-shape0-dev \
|
|
libxcb-xfixes0-dev \
|
|
libxdo-dev \
|
|
libxfixes-dev \
|
|
llvm-10-dev \
|
|
nasm \
|
|
ninja-build \
|
|
pkg-config \
|
|
tree \
|
|
python3 \
|
|
rpm \
|
|
unzip \
|
|
wget \
|
|
xz-utils \
|
|
libssl-dev
|
|
# we have libopus compiled by us.
|
|
apt-get remove -y libopus-dev || true
|
|
# output devs
|
|
ls -l ./
|
|
tree -L 3 /opt/artifacts/vcpkg/installed
|
|
run: |
|
|
# disable git safe.directory
|
|
git config --global --add safe.directory "*"
|
|
# rust
|
|
pushd /opt
|
|
# do not use rustup, because memory overflow in qemu
|
|
wget -O rust.tar.gz https://static.rust-lang.org/dist/rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}.tar.gz
|
|
tar -zxvf rust.tar.gz > /dev/null && rm rust.tar.gz
|
|
cd rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }} && ./install.sh
|
|
rm -rf rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}
|
|
# edit config
|
|
mkdir -p ~/.cargo/
|
|
echo """
|
|
[source.crates-io]
|
|
registry = 'https://github.com/rust-lang/crates.io-index'
|
|
""" > ~/.cargo/config
|
|
cat ~/.cargo/config
|
|
# start build
|
|
pushd /workspace
|
|
export VCPKG_ROOT=/opt/artifacts/vcpkg
|
|
if [[ "${{ matrix.job.arch }}" == "aarch64" ]]; then
|
|
export JOBS="--jobs 3"
|
|
else
|
|
export JOBS=""
|
|
fi
|
|
echo $JOBS
|
|
cargo build --locked --lib $JOBS --features hwcodec,flutter,unix-file-copy-paste --release
|
|
rm -rf target/release/deps target/release/build
|
|
rm -rf ~/.cargo
|
|
|
|
# Setup Flutter
|
|
# disable git safe.directory
|
|
git config --global --add safe.directory "*"
|
|
pushd /workspace
|
|
case ${{ matrix.job.arch }} in
|
|
aarch64)
|
|
export PATH=/opt/flutter-elinux/bin:$PATH
|
|
sed -i "s/flutter build linux --release/flutter-elinux build linux --verbose/g" ./build.py
|
|
sed -i "s/x64\/release/arm64\/release/g" ./build.py
|
|
;;
|
|
x86_64)
|
|
export PATH=/opt/flutter/bin:$PATH
|
|
;;
|
|
esac
|
|
popd
|
|
pushd /opt
|
|
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${{ env.FLUTTER_VERSION }}-stable.tar.xz
|
|
tar xf flutter_linux_${{ env.FLUTTER_VERSION }}-stable.tar.xz
|
|
case ${{ matrix.job.arch }} in
|
|
aarch64)
|
|
# clone repo and reset to flutter ${{ env.FLUTTER_VERSION }}
|
|
git clone https://github.com/sony/flutter-elinux.git || true
|
|
pushd flutter-elinux
|
|
git fetch
|
|
git reset --hard ${{ env.FLUTTER_VERSION }}
|
|
bin/flutter-elinux doctor -v
|
|
bin/flutter-elinux precache --linux
|
|
popd
|
|
cp -R flutter/bin/cache/artifacts/engine/linux-x64/shader_lib flutter-elinux/flutter/bin/cache/artifacts/engine/linux-arm64
|
|
rm -rf flutter
|
|
;;
|
|
x86_64)
|
|
flutter doctor -v
|
|
;;
|
|
esac
|
|
|
|
if [[ "3.24.5" == ${{ env.FLUTTER_VERSION }} ]]; then
|
|
case ${{ matrix.job.arch }} in
|
|
aarch64)
|
|
pushd /opt/flutter-elinux/flutter
|
|
;;
|
|
x86_64)
|
|
pushd /opt/flutter
|
|
;;
|
|
esac
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
popd
|
|
fi
|
|
|
|
# build flutter
|
|
pushd /workspace
|
|
export CARGO_INCREMENTAL=0
|
|
export DEB_ARCH=${{ matrix.job.deb_arch }}
|
|
python3 ./build.py --flutter --skip-cargo
|
|
for name in rustdesk*??.deb; do
|
|
mv "$name" "${name%%.deb}-${{ matrix.job.arch }}.deb"
|
|
done
|
|
|
|
# rpm package
|
|
echo -e "start packaging fedora package"
|
|
pushd /workspace
|
|
case ${{ matrix.job.arch }} in
|
|
aarch64)
|
|
sed -i "s/linux\/x64/linux\/arm64/g" ./res/rpm-flutter.spec
|
|
;;
|
|
esac
|
|
HBB=`pwd` rpmbuild ./res/rpm-flutter.spec -bb
|
|
pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }}
|
|
for name in rustdesk*??.rpm; do
|
|
mv "$name" /workspace/"${name%%.rpm}.rpm"
|
|
done
|
|
|
|
# rpm suse package
|
|
echo -e "start packaging suse package"
|
|
pushd /workspace
|
|
case ${{ matrix.job.arch }} in
|
|
aarch64)
|
|
sed -i "s/linux\/x64/linux\/arm64/g" ./res/rpm-flutter-suse.spec
|
|
;;
|
|
esac
|
|
HBB=`pwd` rpmbuild ./res/rpm-flutter-suse.spec -bb
|
|
pushd ~/rpmbuild/RPMS/${{ matrix.job.arch }}
|
|
for name in rustdesk*??.rpm; do
|
|
mv "$name" /workspace/"${name%%.rpm}-suse.rpm"
|
|
done
|
|
|
|
- name: Publish debian/rpm package
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
rustdesk-*.deb
|
|
rustdesk-*.rpm
|
|
|
|
- name: Upload deb
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.deb
|
|
path: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.deb
|
|
|
|
# only x86_64 for arch since we can not find newest arm64 docker image to build
|
|
# old arch image does not make sense for arch since it is "arch" which always update to date
|
|
# and failed to makepkg arm64 on x86_64
|
|
- name: Patch archlinux PKGBUILD
|
|
if: matrix.job.arch == 'x86_64' && env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
sed -i "s/x86_64/${{ matrix.job.arch }}/g" res/PKGBUILD
|
|
if [[ "${{ matrix.job.arch }}" == "aarch64" ]]; then
|
|
sed -i "s/x86_64/aarch64/g" ./res/PKGBUILD
|
|
fi
|
|
|
|
- name: Build archlinux package
|
|
if: matrix.job.arch == 'x86_64' && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: rustdesk-org/arch-makepkg-action@04200739ed1d0bf6f2188b6736b26a767c57a7f9 # no release tag; commit 2026-05-26
|
|
with:
|
|
packages:
|
|
scripts: |
|
|
cd res && HBB=`pwd`/.. FLUTTER=1 makepkg -f
|
|
|
|
- name: Publish archlinux package
|
|
if: matrix.job.arch == 'x86_64' && env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
res/rustdesk-${{ env.VERSION }}*.zst
|
|
|
|
# Same build as build-rustdesk-linux x86_64 -- same vcpkg/ffmpeg, same ubuntu18.04 container, same
|
|
# rust and flutter -- only with the drm feature on, so it ships as the separate
|
|
# rustdesk-unattended-wayland deb. libdrmtap is built on the runner because bionic's meson is too
|
|
# old for it. A separate job rather than a matrix entry of build-rustdesk-linux: appimage and
|
|
# flatpak need that job, and a failure here must not skip them.
|
|
build-rustdesk-linux-drm:
|
|
needs: [generate-bridge]
|
|
name: build rustdesk linux drm x86_64
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Maximize build space
|
|
run: |
|
|
sudo rm -rf /opt/ghc
|
|
sudo rm -rf /usr/local/lib/android
|
|
sudo rm -rf /usr/share/dotnet
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y nasm
|
|
sudo apt-get install -y qemu-user-static
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Set Swap Space
|
|
uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0
|
|
with:
|
|
swap-size-gb: 12
|
|
|
|
- name: Free Space
|
|
run: |
|
|
df -h
|
|
free -m
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: ${{ env.RUST_VERSION }}
|
|
targets: x86_64-unknown-linux-gnu
|
|
components: "rustfmt"
|
|
|
|
- name: Save Rust toolchain version
|
|
run: |
|
|
RUST_TOOLCHAIN_VERSION=$(cargo --version | awk '{print $2}')
|
|
echo "RUST_TOOLCHAIN_VERSION=$RUST_TOOLCHAIN_VERSION" >> $GITHUB_ENV
|
|
|
|
- name: Disable rust bridge build
|
|
run: |
|
|
# only build cdylib
|
|
sed -i "s/\[\"cdylib\", \"staticlib\", \"rlib\"\]/\[\"cdylib\"\]/g" Cargo.toml
|
|
|
|
- name: Restore bridge files
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: bridge-artifact
|
|
path: ./
|
|
|
|
- name: Setup vcpkg with Github Actions binary cache
|
|
uses: lukka/run-vcpkg@b1a0dd252f06b9e25b3c022a9a03bd7a427fb6a2 # v11
|
|
with:
|
|
vcpkgDirectory: /opt/artifacts/vcpkg
|
|
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
|
doNotCache: false
|
|
|
|
- name: Install vcpkg dependencies
|
|
run: |
|
|
sudo apt install -y libva-dev && apt show libva-dev
|
|
if ! $VCPKG_ROOT/vcpkg \
|
|
install \
|
|
--triplet x64-linux \
|
|
--x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-x64-linux-rel-out.log" || true
|
|
shell: bash
|
|
|
|
# The container's meson is too old to build libdrmtap, so build it here from the pin in
|
|
# build.py and hand the .so to the container below via DRMTAP_PREBUILT_DIR.
|
|
- name: Build libdrmtap
|
|
run: |
|
|
sudo apt-get install -y meson ninja-build pkg-config \
|
|
libdrm-dev libegl1-mesa-dev libgles2-mesa-dev
|
|
python3 - <<'PY'
|
|
import importlib.util, sys
|
|
spec = importlib.util.spec_from_file_location("b", "build.py")
|
|
b = importlib.util.module_from_spec(spec)
|
|
sys.argv = ["build.py"]
|
|
spec.loader.exec_module(b)
|
|
print(f"::notice::built {b.build_libdrmtap_so()}")
|
|
PY
|
|
shell: bash
|
|
|
|
- uses: rustdesk-org/run-on-arch-action@d3fcfbb632b84cf7f6bc772bfaaa2c2f4f8789a8 # no release tag; commit 2026-05-26
|
|
name: Build rustdesk
|
|
id: vcpkg
|
|
with:
|
|
arch: x86_64
|
|
distro: ubuntu18.04
|
|
githubToken: ${{ github.token }}
|
|
setup: |
|
|
ls -l "${PWD}"
|
|
ls -l /opt/artifacts/vcpkg/installed
|
|
dockerRunArgs: |
|
|
--volume "${PWD}:/workspace"
|
|
--volume "/opt/artifacts:/opt/artifacts"
|
|
shell: /bin/bash
|
|
install: |
|
|
apt-get update -y
|
|
echo -e "installing deps"
|
|
apt-get install -y \
|
|
build-essential \
|
|
clang \
|
|
cmake \
|
|
curl \
|
|
gcc \
|
|
git \
|
|
g++ \
|
|
libayatana-appindicator3-dev \
|
|
libasound2-dev \
|
|
libclang-10-dev \
|
|
libgstreamer1.0-dev \
|
|
libgstreamer-plugins-base1.0-dev \
|
|
libgtk-3-dev \
|
|
libpulse-dev \
|
|
libva-dev \
|
|
libxcb-randr0-dev \
|
|
libxcb-shape0-dev \
|
|
libxcb-xfixes0-dev \
|
|
libxdo-dev \
|
|
libxfixes-dev \
|
|
llvm-10-dev \
|
|
nasm \
|
|
ninja-build \
|
|
pkg-config \
|
|
tree \
|
|
python3 \
|
|
rpm \
|
|
unzip \
|
|
wget \
|
|
xz-utils \
|
|
libssl-dev
|
|
# we have libopus compiled by us.
|
|
apt-get remove -y libopus-dev || true
|
|
# output devs
|
|
ls -l ./
|
|
tree -L 3 /opt/artifacts/vcpkg/installed
|
|
run: |
|
|
# disable git safe.directory
|
|
git config --global --add safe.directory "*"
|
|
# rust
|
|
pushd /opt
|
|
# do not use rustup, because memory overflow in qemu
|
|
wget -O rust.tar.gz https://static.rust-lang.org/dist/rust-${{env.RUST_TOOLCHAIN_VERSION}}-x86_64-unknown-linux-gnu.tar.gz
|
|
tar -zxvf rust.tar.gz > /dev/null && rm rust.tar.gz
|
|
cd rust-${{env.RUST_TOOLCHAIN_VERSION}}-x86_64-unknown-linux-gnu && ./install.sh
|
|
rm -rf rust-${{env.RUST_TOOLCHAIN_VERSION}}-x86_64-unknown-linux-gnu
|
|
# edit config
|
|
mkdir -p ~/.cargo/
|
|
echo """
|
|
[source.crates-io]
|
|
registry = 'https://github.com/rust-lang/crates.io-index'
|
|
""" > ~/.cargo/config
|
|
cat ~/.cargo/config
|
|
# start build
|
|
pushd /workspace
|
|
export VCPKG_ROOT=/opt/artifacts/vcpkg
|
|
# use the .so built on the runner; build.py checks it is the pinned checkout
|
|
export DRMTAP_PREBUILT_DIR=/workspace/third_party/libdrmtap/build-pkg
|
|
# ask build.py for the features so this line and the packaging line cannot drift
|
|
FEATURES=$(python3 ./build.py --flutter --drm --hwcodec --unix-file-copy-paste --print-features)
|
|
# an empty or error-shaped value would silently build a stock binary
|
|
for want in drm drm-wake; do
|
|
case ",$FEATURES," in
|
|
*",$want,"*) ;;
|
|
*) echo "::error::build.py returned no '$want' feature: $FEATURES"; exit 1 ;;
|
|
esac
|
|
done
|
|
cargo build --locked --lib --features "$FEATURES" --release
|
|
rm -rf target/release/deps target/release/build
|
|
rm -rf ~/.cargo
|
|
|
|
# Setup Flutter
|
|
# disable git safe.directory
|
|
git config --global --add safe.directory "*"
|
|
export PATH=/opt/flutter/bin:$PATH
|
|
pushd /opt
|
|
wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_${{ env.FLUTTER_VERSION }}-stable.tar.xz
|
|
tar xf flutter_linux_${{ env.FLUTTER_VERSION }}-stable.tar.xz
|
|
flutter doctor -v
|
|
|
|
if [[ "3.24.5" == ${{ env.FLUTTER_VERSION }} ]]; then
|
|
pushd /opt/flutter
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
popd
|
|
fi
|
|
|
|
# build flutter
|
|
pushd /workspace
|
|
export CARGO_INCREMENTAL=0
|
|
export DEB_ARCH=amd64
|
|
python3 ./build.py --flutter --drm --hwcodec --unix-file-copy-paste --skip-cargo
|
|
for name in rustdesk*??.deb; do
|
|
mv "$name" "${name%%.deb}-x86_64.deb"
|
|
done
|
|
|
|
# build.py can exit 0 on some inner failures, so check the artifact rather than the status.
|
|
# The package name is the informed consent for consent-free capture, so a stock binary must
|
|
# never ship under it: assert the bundled library AND the dlopen path in the binary.
|
|
- name: Check the deb is a drm build
|
|
run: |
|
|
set -euo pipefail
|
|
# Resolve by glob, not from env.VERSION: build.py names the deb from Cargo.toml, so a
|
|
# hardcoded name fails with a bare exit 1 the first time those two drift.
|
|
shopt -s nullglob
|
|
debs=(rustdesk-unattended-wayland-*-x86_64.deb)
|
|
if [ "${#debs[@]}" -ne 1 ]; then
|
|
echo "::error::expected one rustdesk-unattended-wayland-*-x86_64.deb, found ${#debs[@]}: ${debs[*]-none}"
|
|
exit 1
|
|
fi
|
|
deb="${debs[0]}"
|
|
echo "DRM_DEB=$deb" >> "$GITHUB_ENV"
|
|
contents="$(dpkg -c "$deb")"
|
|
if [[ ! "$contents" =~ usr/lib/rustdesk/libdrmtap\.so\.0\.[0-9]+\.[0-9]+ ]]; then
|
|
echo "::error::$deb has no versioned libdrmtap.so.0.x.y"
|
|
exit 1
|
|
fi
|
|
if [[ "$contents" != *"usr/lib/rustdesk/libdrmtap.so.0 ->"* ]]; then
|
|
echo "::error::$deb has no libdrmtap.so.0 soname symlink"
|
|
exit 1
|
|
fi
|
|
rm -rf /tmp/deb && dpkg-deb -R "$deb" /tmp/deb
|
|
if ! grep -qF /usr/lib/rustdesk/libdrmtap.so.0 /tmp/deb/usr/share/rustdesk/lib/librustdesk.so; then
|
|
echo "::error::$deb was not built with the drm feature"
|
|
exit 1
|
|
fi
|
|
shell: bash
|
|
|
|
- name: Publish debian package
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
${{ env.DRM_DEB }}
|
|
|
|
# No UPLOAD_ARTIFACT gate: on a PR this is the only way to get at the deb that was just built.
|
|
# always(), because a deb that failed the check above is the one most worth downloading.
|
|
- name: Upload deb
|
|
if: always() && env.DRM_DEB != ''
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: ${{ env.DRM_DEB }}
|
|
path: ${{ env.DRM_DEB }}
|
|
|
|
build-rustdesk-linux-sciter:
|
|
if: ${{ inputs.upload-artifact }}
|
|
runs-on: ${{ matrix.job.on }}
|
|
name: build-rustdesk-linux-sciter ${{ matrix.job.target }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# use a high level qemu-user-static
|
|
job:
|
|
- {
|
|
arch: x86_64,
|
|
target: x86_64-unknown-linux-gnu,
|
|
on: ubuntu-22.04,
|
|
distro: ubuntu18.04,
|
|
deb_arch: amd64,
|
|
sciter_arch: x64,
|
|
vcpkg-triplet: x64-linux,
|
|
extra_features: ",hwcodec,unix-file-copy-paste",
|
|
}
|
|
- {
|
|
arch: armv7,
|
|
target: armv7-unknown-linux-gnueabihf,
|
|
on: ubuntu-22.04-arm,
|
|
distro: ubuntu18.04-rustdesk,
|
|
deb_arch: armhf,
|
|
sciter_arch: arm32,
|
|
vcpkg-triplet: arm-linux,
|
|
extra_features: ",unix-file-copy-paste",
|
|
}
|
|
steps:
|
|
- name: Export GitHub Actions cache environment variables
|
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
|
with:
|
|
script: |
|
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
|
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Modify vcpkg.json for armv7
|
|
if: matrix.job.vcpkg-triplet == 'arm-linux'
|
|
run: |
|
|
# Replace the baseline in vcpkg.json with ARMV7_VCPKG_COMMIT_ID for armv7 builds
|
|
sed -i 's/"baseline": ".*"/"baseline": "${{ env.ARMV7_VCPKG_COMMIT_ID }}"/' vcpkg.json
|
|
echo "Modified vcpkg.json for armv7 build:"
|
|
grep -A 2 -B 2 '"baseline"' vcpkg.json
|
|
|
|
- name: Free Space
|
|
run: |
|
|
df -h
|
|
free -m
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
|
with:
|
|
toolchain: ${{ env.SCITER_RUST_VERSION }}
|
|
targets: ${{ matrix.job.target }}
|
|
components: "rustfmt"
|
|
|
|
- name: Save Rust toolchain version
|
|
run: |
|
|
RUST_TOOLCHAIN_VERSION=$(cargo --version | awk '{print $2}')
|
|
echo "RUST_TOOLCHAIN_VERSION=$RUST_TOOLCHAIN_VERSION" >> $GITHUB_ENV
|
|
|
|
- uses: rustdesk-org/run-on-arch-action@d3fcfbb632b84cf7f6bc772bfaaa2c2f4f8789a8 # no release tag; commit 2026-05-26
|
|
name: Build rustdesk sciter binary for ${{ matrix.job.arch }}
|
|
id: vcpkg
|
|
with:
|
|
arch: ${{ matrix.job.arch }}
|
|
distro: ${{ matrix.job.distro }}
|
|
githubToken: ${{ github.token }}
|
|
setup: |
|
|
ls -l "${PWD}"
|
|
dockerRunArgs: |
|
|
--volume "${PWD}:/workspace"
|
|
shell: /bin/bash
|
|
install: |
|
|
apt-get update
|
|
apt-get install -y \
|
|
build-essential \
|
|
clang \
|
|
curl \
|
|
gcc \
|
|
git \
|
|
g++ \
|
|
libayatana-appindicator3-dev \
|
|
libasound2-dev \
|
|
libclang-dev \
|
|
libdbus-1-dev \
|
|
libglib2.0-dev \
|
|
libgstreamer1.0-dev \
|
|
libgstreamer-plugins-base1.0-dev \
|
|
libgtk-3-dev \
|
|
liblzma-dev \
|
|
libpulse-dev \
|
|
libva-dev \
|
|
libxcb-randr0-dev \
|
|
libxcb-shape0-dev \
|
|
libxcb-xfixes0-dev \
|
|
libxdo-dev \
|
|
libxfixes-dev \
|
|
ninja-build \
|
|
pkg-config \
|
|
python3 \
|
|
python3.7 \
|
|
rpm \
|
|
unzip \
|
|
wget \
|
|
xz-utils \
|
|
zip \
|
|
libssl-dev
|
|
# arm-linux needs CMake and vcokg built from source as there
|
|
# are no prebuilts available from Kitware and Microsoft
|
|
if [ "${{ matrix.job.vcpkg-triplet }}" = "arm-linux" ]; then
|
|
# install gcc/g++ 8 for vcpkg and OpenSSL headers for CMake
|
|
apt-get install -y gcc-8 g++-8
|
|
# bootstrap CMake amd add it to PATH
|
|
git clone --depth 1 https://github.com/kitware/cmake -b "v${{ env.SCITER_ARMV7_CMAKE_VERSION }}" /tmp/cmake
|
|
pushd /tmp/cmake
|
|
./bootstrap --generator='Unix Makefiles' "--prefix=/opt/cmake-${{ env.SCITER_ARMV7_CMAKE_VERSION }}-linux-armhf"
|
|
make -j1 install
|
|
popd
|
|
rm -rf /tmp/cmake
|
|
export PATH="/opt/cmake-${{ env.SCITER_ARMV7_CMAKE_VERSION }}-linux-armhf/bin:$PATH"
|
|
fi
|
|
# bootstrap vcpkg and set VCPKG_ROOT
|
|
export VCPKG_ROOT=/opt/artifacts/vcpkg
|
|
mkdir -p /opt/artifacts
|
|
pushd /opt/artifacts
|
|
rm -rf vcpkg
|
|
git clone https://github.com/microsoft/vcpkg
|
|
pushd vcpkg
|
|
# build vcpkg helper executable with gcc-8 for arm-linux but use prebuilt one on x64-linux
|
|
if [ "${{ matrix.job.vcpkg-triplet }}" = "arm-linux" ]; then
|
|
git reset --hard ${{ env.ARMV7_VCPKG_COMMIT_ID }}
|
|
CC=/usr/bin/gcc-8 CXX=/usr/bin/g++-8 sh bootstrap-vcpkg.sh -disableMetrics
|
|
else
|
|
git reset --hard ${{ env.VCPKG_COMMIT_ID }}
|
|
sh bootstrap-vcpkg.sh -disableMetrics
|
|
fi
|
|
popd
|
|
popd
|
|
# rust
|
|
pushd /opt
|
|
# do not use rustup, because memory overflow in qemu
|
|
wget --output-document rust.tar.gz https://static.rust-lang.org/dist/rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}.tar.gz
|
|
tar -zxvf rust.tar.gz > /dev/null && rm rust.tar.gz
|
|
pushd rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}
|
|
./install.sh
|
|
popd
|
|
rm -rf rust-${{env.RUST_TOOLCHAIN_VERSION}}-${{ matrix.job.target }}
|
|
popd
|
|
# install newer nasm for aom
|
|
wget --output-document nasm.deb "http://ftp.us.debian.org/debian/pool/main/n/nasm/nasm_${{ env.SCITER_NASM_DEBVERSION }}_${{ matrix.job.deb_arch }}.deb"
|
|
dpkg -i nasm.deb
|
|
rm -f nasm.deb
|
|
run: |
|
|
# disable git safe.directory
|
|
git config --global --add safe.directory "*"
|
|
# set python3.7 as default python3
|
|
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 1
|
|
# add built CMake to PATH and set VCPKG_FORCE_SYSTEM_BINARIES Afor arm-linux
|
|
if [ "${{ matrix.job.vcpkg-triplet }}" = "arm-linux" ]; then
|
|
export PATH="/opt/cmake-${{ env.SCITER_ARMV7_CMAKE_VERSION }}-linux-armhf/bin:$PATH"
|
|
export VCPKG_FORCE_SYSTEM_BINARIES=1
|
|
fi
|
|
# edit cargo config
|
|
mkdir -p ~/.cargo/
|
|
echo """
|
|
[source.crates-io]
|
|
registry = 'sparse+https://index.crates.io/'
|
|
""" > ~/.cargo/config
|
|
cat ~/.cargo/config
|
|
# install dependencies from vcpkg
|
|
export VCPKG_ROOT=/opt/artifacts/vcpkg
|
|
# remove this when support higher version
|
|
export USE_AOM_391=1
|
|
if ! $VCPKG_ROOT/vcpkg install --triplet ${{ matrix.job.vcpkg-triplet }} --x-install-root="$VCPKG_ROOT/installed"; then
|
|
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
|
echo "$_1:"
|
|
echo "======"
|
|
cat "$_1"
|
|
echo "======"
|
|
echo ""
|
|
done
|
|
exit 1
|
|
fi
|
|
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
|
# build rustdesk
|
|
python3 ./res/inline-sciter.py
|
|
export CARGO_INCREMENTAL=0
|
|
cargo build --locked --features inline${{ matrix.job.extra_features }} --release --bins --jobs 1
|
|
# make debian package
|
|
mkdir -p ./Release
|
|
mv ./target/release/rustdesk ./Release/rustdesk
|
|
wget -O ./Release/libsciter-gtk.so https://github.com/c-smile/sciter-sdk/raw/master/bin.lnx/${{ matrix.job.sciter_arch }}/libsciter-gtk.so
|
|
export DEB_ARCH=${{ matrix.job.deb_arch }}
|
|
./build.py --package ./Release
|
|
|
|
- name: Rename rustdesk
|
|
shell: bash
|
|
run: |
|
|
for name in rustdesk*??.deb; do
|
|
# use cp to duplicate deb files to fit other packages.
|
|
cp "$name" "${name%%.deb}-${{ matrix.job.arch }}-sciter.deb"
|
|
done
|
|
|
|
- name: Publish debian package
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}-sciter.deb
|
|
|
|
- name: Upload deb
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
with:
|
|
name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}-sciter.deb
|
|
path: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}-sciter.deb
|
|
|
|
build-appimage:
|
|
name: Build appimage ${{ matrix.job.target }}
|
|
needs: [build-rustdesk-linux]
|
|
runs-on: ubuntu-22.04
|
|
if: ${{ inputs.upload-artifact }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- { target: x86_64-unknown-linux-gnu, arch: x86_64 }
|
|
- { target: aarch64-unknown-linux-gnu, arch: aarch64 }
|
|
steps:
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Download Binary
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.deb
|
|
path: .
|
|
|
|
- name: Rename Binary
|
|
run: |
|
|
mv rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.deb appimage/rustdesk.deb
|
|
|
|
- name: Build appimage package
|
|
shell: bash
|
|
run: |
|
|
# install libarchive-tools for bsdtar command used in AppImageBuilder.yml
|
|
sudo apt-get update -y
|
|
# https://github.com/AppImage/AppImageKit/wiki/FUSE
|
|
sudo apt-get install -y libarchive-tools libfuse2
|
|
# set-up appimage-builder
|
|
# https://github.com/AppImage/AppImageKit/issues/1395
|
|
sudo pip3 install "setuptools_scm<10"
|
|
sudo pip3 install git+https://github.com/rustdesk-org/appimage-builder.git
|
|
# run appimage-builder
|
|
pushd appimage
|
|
sudo appimage-builder --skip-tests --recipe ./AppImageBuilder-${{ matrix.job.arch }}.yml
|
|
|
|
- name: Publish appimage package
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
./appimage/rustdesk-${{ env.VERSION }}-*.AppImage
|
|
|
|
build-flatpak:
|
|
name: Build flatpak ${{ matrix.job.target }}${{ matrix.job.suffix }}
|
|
needs:
|
|
- build-rustdesk-linux
|
|
- build-rustdesk-linux-sciter
|
|
runs-on: ${{ matrix.job.on }}
|
|
if: ${{ inputs.upload-artifact }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
job:
|
|
- {
|
|
target: x86_64-unknown-linux-gnu,
|
|
# https://github.com/ostreedev/ostree/commit/4bac96a8c817beda37448f9b8c662162bb619981
|
|
distro: ubuntu22.04,
|
|
on: ubuntu-22.04,
|
|
arch: x86_64,
|
|
suffix: "",
|
|
}
|
|
- {
|
|
target: x86_64-unknown-linux-gnu,
|
|
distro: ubuntu22.04,
|
|
on: ubuntu-22.04,
|
|
arch: x86_64,
|
|
suffix: "-sciter",
|
|
}
|
|
- {
|
|
target: aarch64-unknown-linux-gnu,
|
|
# try out newer flatpak since error of "error: Nothing matches org.freedesktop.Platform in remote flathub"
|
|
distro: ubuntu22.04,
|
|
on: ubuntu-22.04-arm,
|
|
arch: aarch64,
|
|
suffix: "",
|
|
}
|
|
steps:
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Download Binary
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.deb
|
|
path: .
|
|
|
|
- name: Rename Binary
|
|
run: |
|
|
mv rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.deb flatpak/rustdesk.deb
|
|
|
|
- uses: rustdesk-org/run-on-arch-action@d3fcfbb632b84cf7f6bc772bfaaa2c2f4f8789a8 # no release tag; commit 2026-05-26
|
|
name: Build rustdesk flatpak package for ${{ matrix.job.arch }}
|
|
id: flatpak
|
|
with:
|
|
arch: ${{ matrix.job.arch }}
|
|
distro: ${{ matrix.job.distro }}
|
|
githubToken: ${{ github.token }}
|
|
setup: |
|
|
ls -l "${PWD}"
|
|
dockerRunArgs: |
|
|
--volume "${PWD}:/workspace"
|
|
shell: /bin/bash
|
|
install: |
|
|
apt-get update -y
|
|
apt-get install -y git flatpak flatpak-builder
|
|
run: |
|
|
# disable git safe.directory
|
|
git config --global --add safe.directory "*"
|
|
pushd /workspace
|
|
# flatpak deps
|
|
flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
|
# package
|
|
pushd flatpak
|
|
git clone https://github.com/flathub/shared-modules.git --depth=1
|
|
flatpak-builder --user --install-deps-from=flathub -y --force-clean --repo=repo ./build ./rustdesk.json
|
|
flatpak build-bundle ./repo rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.flatpak com.rustdesk.RustDesk
|
|
|
|
- name: Publish flatpak package
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
flatpak/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}${{ matrix.job.suffix }}.flatpak
|
|
|
|
build-rustdesk-web:
|
|
if: False
|
|
name: build-rustdesk-web
|
|
runs-on: ubuntu-22.04
|
|
permissions:
|
|
contents: read
|
|
strategy:
|
|
fail-fast: false
|
|
env:
|
|
RELEASE_NAME: web-basic
|
|
steps:
|
|
- name: Checkout source code
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Prepare env
|
|
run: |
|
|
sudo apt-get update -y
|
|
sudo apt-get install -y wget npm
|
|
|
|
- name: Install flutter
|
|
uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 # v2.12.0; https://github.com/subosito/flutter-action/issues/277
|
|
with:
|
|
channel: "stable"
|
|
flutter-version: ${{ env.FLUTTER_VERSION }}
|
|
|
|
- name: Patch flutter
|
|
shell: bash
|
|
run: |
|
|
cd $(dirname $(dirname $(which flutter)))
|
|
if [[ "3.24.5" == ${{env.FLUTTER_VERSION}} ]]; then
|
|
git apply ${{ github.workspace }}/.github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff
|
|
fi
|
|
|
|
- name: Patch sources for Flutter 3.44 web
|
|
# No-op while the web stays on Flutter 3.24.5; makes this job work as-is
|
|
# once FLUTTER_VERSION moves to 3.44.x (qr_code_scanner + fonts, see script).
|
|
shell: bash
|
|
run: |
|
|
if [[ "${{ env.FLUTTER_VERSION }}" == 3.44.* ]]; then
|
|
bash .github/patches/apply_flutter_3.44_web_patches.sh
|
|
fi
|
|
|
|
# https://rustdesk.com/docs/en/dev/build/web/
|
|
- name: Build web
|
|
shell: bash
|
|
run: |
|
|
pushd flutter/web/js
|
|
npm install yarn -g
|
|
npm install typescript -g
|
|
npm install protoc -g
|
|
# Install protoc first, see: https://google.github.io/proto-lens/installing-protoc.html
|
|
npm install ts-proto
|
|
# Only works with vite <= 2.8, see: https://github.com/vitejs/vite/blob/main/docs/guide/build.md#chunking-strategy
|
|
npm install vite@2.8
|
|
yarn install && yarn build
|
|
popd
|
|
|
|
pushd flutter/web
|
|
wget https://github.com/rustdesk/doc.rustdesk.com/releases/download/console/web_deps.tar.gz
|
|
tar xzf web_deps.tar.gz
|
|
popd
|
|
|
|
pushd flutter
|
|
flutter build web --release
|
|
cd build
|
|
cp ../web/README.md web
|
|
# TODO: Remove the following line when the web is almost complete.
|
|
echo -e "\n\nThis build is for preview and not full functionality." >> web/README.md
|
|
dir_name="rustdesk-${{ env.VERSION }}-${{ env.RELEASE_NAME }}"
|
|
mv web "${dir_name}" && tar czf "${dir_name}".tar.gz "${dir_name}"
|
|
sha256sum "${dir_name}".tar.gz
|
|
popd
|
|
|
|
- name: Publish web
|
|
if: env.UPLOAD_ARTIFACT == 'true'
|
|
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
|
with:
|
|
prerelease: true
|
|
tag_name: ${{ env.TAG_NAME }}
|
|
files: |
|
|
flutter/build/rustdesk-${{ env.VERSION }}-${{ env.RELEASE_NAME }}.tar.gz
|