mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-29 16:56:25 +00:00
* fix(drm): turn the cursor by the output's real angle, and guess its hotspot upright Two things were wrong with a rotated output's cursor, and the maintainer's physical test found both. The bare-metal hotspot is a guess - the top-left of the sprite's opaque box, since HOTSPOT_X/Y only exist on para-virtualised drivers - and it was guessed on the sprite as scanned out, then mapped as if it were a point on it. A turned arrow's tip is never in that corner: at 90 the guess is off by the arrow's width along x, small enough to pass as fine, and at 270 by its height along y, which is what was noticed. Measured on an i915 box with a 64x64 Adwaita arrow, hotspot against tip: +11,0 at 90 and 0,+18 at 270 before, 0,0 at every angle after. A guessed hotspot is now guessed on the upright sprite, in the consumer, and the wire says whether the driver measured it so a real one still maps as a point. And 180 was clamped to 0 for the whole session because a hardware-rotated primary plane scans out upright. That holds for the frame and not for the cursor: the compositor pre-rotates the sprite in software either way, so it arrived upside down. The frame keeps the clamp; the cursor gets the real angle. (cherry picked from commit 6a73100b4783fbf9c8f43e0dc7651b7568db9ea9) * test(drm): drive the cursor path, and drop the field nothing reads The two tests called the helpers, so nothing pinned the production decision: restore master's `t == 90 || t == 270` in deliver_drm_cursor and both still pass while the 180 sprite goes back to upside down. The new test drives deliver_drm_cursor and reads back what it published, and it fails under exactly that mutation. The other way to reintroduce the bug was to point the receive thread at `Shared::transform` again. That field had no readers left once both gates moved to `cursor_transform` - it was stored and never loaded - so it is gone, and the doc above TRANSFORM_PENDING now names the field that actually holds a racing cursor back. Also four comments that said more than the code does: the sprite is treated as pre-rotated at every angle because wl_output cannot say otherwise, not because the compositor provably always does it; the old flow was off at every angle, not just at one of 90/270; the 180 symptom had its own cause, the clamp, rather than all of it coming out of the hotspot guess; and the test arrow's opaque box is its left three columns, not the whole bitmap. * docs(drm): say what the 180 measurement actually showed The loop asserts the old mapping was wrong at 180 too, and that is true of the mapping, but master never ran it there: the clamp sent 180 down the untouched branch, so guess and sprite turned together and the hotspot landed on the tip. The bench measured exactly that - (0,0) at 180, with only the sprite upside down. The comment said the old flow was wrong at every angle without that distinction, which is the kind of gap between a claim and a measurement worth closing before someone else finds it. * fix(drm): centre the guessed hotspot of an I-beam lying either way The bounding-box guess only centred TALL shapes, so a HORIZONTAL I-beam was handed the top-left corner of its box. Adwaita's `vertical-text` is exactly that shape: at 24 px its opaque box is 20x9 and the theme's own hotspot is (12, 11), its centre. The corner guess lands 11.2 px away; the centre lands 1.4 px away. It matters more since this branch turns the sprite upright before guessing. Such a cursor used to reach a quarter-turned output as a TALL bitmap, where the tall-only rule centred it by accident; guessing on the upright bitmap - correct in itself, and what fixes arrows at every angle - is what exposed the asymmetry. Found by fufesou at pixel level on rustdesk#16242, and reproduced here against the installed theme before changing anything: same declared hotspot, same bounding box, same two errors. Then checked across ALL 35 shapes of that theme at 24 px: making the aspect test symmetric moves exactly one of them, `vertical-text`, from 11.2 px to 1.4 px, and leaves the other 34 byte-identical. The old flow is not the fix. It was right for this one shape and wrong for arrows at every angle, which is what `a_guessed_hotspot_is_guessed_on_the_upright_sprite` pins; the fix belongs in the guess, not in the order of operations. The regression test that missed this used only `arrow()`, as fufesou pointed out. Three things the first version of the replacement got wrong, all of them in what it CLAIMED rather than in the fix: - Its expected point was the centre of the BITMAP, which equals the centre of the opaque box only because the fixtures filled their bitmaps symmetrically. Both I-beam fixtures are now off-centre in their buffers, the way a sprite sits in a 64x64 hardware cursor, and the test asserts up front that the two centres differ so the fixture cannot quietly stop discriminating. - It called the arrow's box "elongated by less than the factor of two", when 3x6 IS the factor of two and the arrow keeps its tip only because the comparison is strict. That makes the arrow the control for one side of the threshold, and it is now described as such. - It said the case was driven "through the whole delivery path" while chaining the helpers itself. It now calls `deliver_drm_cursor` and reads the published hotspot back out of DRM_CURSOR, at 0, 90, 180 and 270, feeding it what the producer really sends for a guessed hotspot: the producer's own guess, made on the sprite as scanned out. And the threshold was pinned from one side only. A third fixture carries the real 2.22:1 aspect of the shape that was wrong, so a stricter rule cannot pass on 6:1 bars while silently un-centring the actual cursor. Mutations, each restored byte-for-byte afterwards: back to tall-only, the bitmap centre instead of the box centre, the threshold loosened to one and tightened to three. All four fail the test. * build(drm): point the pin at the synced mirror and drop the helper fallback The mirror is synced, so the pin moves from 5da68a3a (libdrmtap 0.5.4) to 49b204f (0.5.6), which is what rustdesk-org/libdrmtap now carries. -Dhelper=disabled, as the maintainer asked on #16242. rustdesk never uses the privileged helper: every drmtap_open lives in src/ipc/drm.rs, i.e. the root service, which already holds CAP_SYS_ADMIN, and the unprivileged side opens a render node instead. What the library carries without the option is a fallback that walks six hardcoded paths, two of them under /usr/local, and execs the first one that passes access(X_OK) -- no check of its owner, no check of its mode -- from inside the ROOT process. The option compiles that path out. Asserted on the artifact as well as passed as a flag, for the same reason the EGL check is: a flag cannot notice a stale build-pkg or an object substituted by hand, and meson accepts an unknown -D silently on versions predating the option. Measured on the produced .so: socketpair 4 -> 0, the helper search paths 3 -> 0, and nm -D shows no fork, execl or socketpair import. The check fails as it should when pointed at a .so built with the helper. * fix(drm): use the library's hotspot provenance, and keep legacy IPC meaning Answers the two blockers in the maintainer's review of9acb37a9d, plus the three he marked should-fix. hot_measured no longer guesses. The pinned libdrmtap 0.5.6 exports drmtap_cursor_hotspot_valid, and the old test -- hot_x != 0 || hot_y != 0 -- cannot separate the two things a (0, 0) hotspot means: no HOTSPOT_X/Y on the plane, or a driver whose answer really is the corner. The symbol is resolved OPTIONALLY, the way drmtap_render_node and drmtap_list_devices already are, with the same version-aware warning when a library that reports 0.5.6 or newer does not carry it. An older deployed .so keeps the previous behaviour instead of the ABI floor moving under it and refusing to load. The IPC default is corrected. Data is JSON over a unix socket between two processes upgraded separately, so an old root service can be streaming to a freshly started --server and its DrmCursor has no hot_measured at all. Read as bool::default() the new consumer discards a hotspot the producer measured and re-infers one from the upright bitmap, moving the cursor on a rotated display for the length of the upgrade. The default is now true, which is not a claim that the value was measured: it means "no provenance available, so behave as the old protocol did". A new producer that wants re-inference sends false explicitly, which serializes, so new-to-new is unchanged. hot_measured is folded into the cursor id. It is not metadata about the cursor, it selects what the consumer does with it, so a sample whose pixels and (0, 0) hotspot are unchanged but whose provenance flipped is a different cursor and must not be deduped away by the producer. build.py reconfigures an existing meson build dir with -Dhelper=disabled instead of only configuring a fresh one; a directory from before the option kept its old configuration and the artifact assertion then failed the build. And the drm CI job now runs the drm-gated tests. It built the feature without ever executing them, so every cursor rotation and hotspot test had no continuous coverage. A cargo test filter that matches nothing exits 0, so the step also asserts it actually ran some. Verified by mutation, each caught by its own test and no other: ignoring the library's answer fails the two provenance tests; the serde default back to false fails the legacy-deserialization test; dropping hot_measured from the id fails the identity test. * feat(drm): say once where the cursor hotspot came from The provenance decision was unverifiable anywhere but a unit test: nothing on a running box distinguishes the three states, so a deploy proved nothing. One info line does, and with it all three are measured -- Some(false) on i915, None with a 0.5.4 library swapped in behind the soname, and Some(true) via a C probe on virtio-gpu, where no rustdesk build runs. Once per state, not once per sample. A cursor is read on every capture iteration and its provenance changes approximately never; a per-frame log line here is the same defect libdrmtap already shipped once. Measured on Sigma-26: one line across a whole session. The should-we-log decision is its own function so it cannot quietly become per-sample again. * test(drm): drive a legacy cursor message from the wire, not from a literal The upgrade window is the one thing in this round that could not be staged with two live processes: a --server from one build does not run inside the other's tree, so the old service respawns it and it dies with exit 127. Tried on two boxes, with two files swapped and with the whole tree. This is the honest form of that test and it runs in CI rather than once on a desk. It takes the exact bytes an old producer puts on the socket -- no hot_measured key at all, adjacently tagged as Data really is -- deserializes them the way the receive loop does, drives the real delivery path, and reads back what was published. The transform is non-zero on purpose: at 0 the path never consults hot_measured, so a test there could not tell the branches apart, and the fixture is asserted to make mapping and re-inferring disagree before anything is concluded from them. Verified by mutation: restoring #[serde(default)] -- the reported bug -- fails it, and so does a delivery path that ignores hot_measured. * fix(drm): run the tests that matter in ci, and keep provenance state per stream Answers the review of7dc6817plus the CI failure fufesou reported on401c2f7. The drm test step was broken three ways and none of them showed up as a red test: it reused the production $FEATURES, so the test binary failed to LINK (undefined reference to fcntl64 from hwcodec) and the tests never ran; it summed the counts with bc, which the ubuntu18.04 container does not install; and `cargo test --lib` at the repo root builds the ROOT package only, so the provenance tests in libs/scrap were never selected -- the "at least one test ran" guard passed on the root filters and hid it. Now: --features drm rather than the production set, awk instead of bc, and an explicit `-p scrap` run with the same assertion. Locally 36, 9 and 5 tests, and a bogus filter still fails the step. Provenance logging state was process-global on both sides. DRM runs one reader per captured display, and two outputs with different but STABLE provenance -- one publishing HOTSPOT_X/Y and one not, which is an ordinary multi-GPU host -- would overwrite each other and make every message look like a change, i.e. exactly the per-frame logging the one-shot was written to avoid. The producer's state moves into DrmReader, the consumer's is keyed by display. The hidden-cursor sentinel is no longer recorded: it carries hot_measured=false because it has no hotspot, so counting it turned every hide and show into a provenance transition. The 180 test is renamed to say what it pins -- i915 advertising rotate-180 with mutter -- and its comment says plainly that it is not a general contract, that Plasma is still wrong there, and that changing it means re-measuring. Verified by mutation: restoring the global slot fails the new per-display test, and so does recording the hidden sentinel. * fix(drm): centre the guessed hotspot on the axes a cursor mirrors about The guess put the click point at the top-left corner of the opaque box unless the box was more than twice as long as it is wide. That corner is where an arrow's tip is, because cursors are drawn pointing up and to the left, but a shape that mirrors onto itself has no tip to point with: a crosshair, a two-headed resize arrow, a cell marker. Those got a corner where the theme puts the middle, and the error is about half the glyph. So: centre the axis the shape is symmetric about, and keep the corner everywhere else. Measured against the hotspots the theme declares, which is the value a compositor programs into HOTSPOT_X/Y where the property exists: adwaita-icon-theme 50, 35 shapes at six nominal sizes, 210 cases mean error 0.43 -> 0.27 of the cursor size, 17 shapes improve, none worse adwaita-icon-theme 46, 34 shapes at five sizes, 170 more cases better at every size, none worse The threshold is not fitted: from 90 to 98 percent agreement nothing regresses, and below 90 three shapes do. The corpus is carried as fixtures so the expected value comes from the theme author rather than from our own heuristic, and two tests read it: the published hotspot must not move when the output turns, with the old flow's 15 px average movement as the control, and the guess must stay inside the measured bounds with the old rule frozen as the baseline. The elongation test stays ahead of the mirror test so an elongated shape that is not symmetric still keeps its centre. * fix(drm): put a directional cursor's hotspot on the edge it resizes The mirror rule centred the axes a shape is symmetric about and left the other axis on the top-left corner. That is right for an arrow, whose tip is that corner, and wrong for the resize cursors: those are a pointer plus the marker of the edge being resized, the theme puts the click point on the marker, and the marker is at whichever end the cursor names. Always taking the corner therefore had to be wrong for one of every mirrored pair, since e-resize and w-resize are the same picture reflected. So an axis is read as directional when the perpendicular axis mirrors, which is the n/e/s/w family, or when the shape mirrors about a diagonal, which is the corner family. A directional axis takes the heavier end. A diagonal reflection only lines up inside a square, and these boxes are not square, so where the box sits in that square decides the answer: ne-resize scores 0.62 anchored one way and 0.98 the other, and nw-resize is the reverse. Both anchorings are tried and the better answer wins. Measured against MASTER now, not against this PR's previous revision, which is what the maintainer asked for. Over the angles master handles (0, 90, 270), adwaita-icon-theme 50 at 24 px: mean error per shape 12.08 px -> 4.20 (shape, angle) cases 83 better, 18 the same, 4 worse of 105 shapes worse than master help (+4.73) and alias (+0.51) Both of those are semantic: the theme puts help's click point on the dot of its question mark. The same holds at 48 px and on adwaita-icon-theme 46, where ne-resize is also 1.34 px worse because its glyph is drawn differently there. The test baseline was wrong and is fixed here: it froze this PR's earlier symmetric aspect test rather than master's tall-only one, so it could only show that the new rule does not regress the old rule. It now freezes master's guess AND master's delivery, and names the two shapes it excuses with the measured size of each. The mirror threshold moves from 95 to 88, the middle of the 86 to 91 interval that regresses nothing on either theme version. --------- Co-authored-by: Mariano Abad <weimaraner@gmail.com>
2626 lines
111 KiB
YAML
2626 lines
111 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"
|
|
VCPKG_CMAKE_VERSION: "4.3.0"
|
|
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
|
|
with:
|
|
# Select the MSBuild process architecture; -p:Platform sets the MSI target.
|
|
# Native ARM64 tools give the compiler more address space for PCH files
|
|
# (C3859/C1076 were reported by HostX86\arm64\CL.exe).
|
|
# Keep the action's default x86 MSBuild for the existing x64 MSI job.
|
|
msbuild-architecture: ${{ matrix.job.arch == 'aarch64' && 'arm64' || 'x86' }}
|
|
|
|
- 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
|
|
shell: bash
|
|
run: |
|
|
# Sciter's abi_thiscall feature requires nightly Rust.
|
|
# Use an i686 host toolchain so build scripts can load the 32-bit LLVM installed above.
|
|
# Since rustup 1.29.1, i686 toolchains on x64 Windows require --force-non-host
|
|
# for both installation and default selection, even though WOW64 can run them.
|
|
# See https://github.com/rust-lang/rustup/pull/4935.
|
|
# Alternatively, an x64 compiler could use cargo build --target i686-pc-windows-msvc.
|
|
# This requires 64-bit LLVM for host build scripts and updated packaging paths,
|
|
# and has not been manually verified for RustDesk.
|
|
rustup toolchain install nightly-2023-10-13-${{ matrix.job.target }} \
|
|
--target ${{ matrix.job.target }} --component rustfmt \
|
|
--profile minimal --no-self-update --force-non-host
|
|
rustup default nightly-2023-10-13-${{ matrix.job.target }} --force-non-host
|
|
|
|
- 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: Test cursor sizing
|
|
if: ${{ !inputs.upload-artifact && matrix.job.arch == 'aarch64' }}
|
|
working-directory: flutter
|
|
run: flutter test --timeout 60s test/cursor_size_test.dart
|
|
|
|
- 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
|
|
# the identity secret carries its own shell quoting, so expand it inline like the dmg codesign below
|
|
bash ./.github/scripts/sign-macos-app.sh \
|
|
./flutter/build/macos/Build/Products/Release/RustDesk.app \
|
|
${{ secrets.MACOS_CODESIGN_IDENTITY }} \
|
|
./flutter/macos/Runner/Release.entitlements
|
|
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
|
|
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: ./
|
|
|
|
# vcpkg 2026.07.29's SPDX scripts require CMake 4.3+, but this ARM64 runner selects CMake 3.31.
|
|
- name: Install CMake for vcpkg on Linux ARM64
|
|
if: matrix.job.arch == 'aarch64' && env.UPLOAD_ARTIFACT == 'true'
|
|
run: |
|
|
python3 -m pip install --user "cmake==${VCPKG_CMAKE_VERSION}"
|
|
user_base="$(python3 -m site --user-base)"
|
|
"${user_base}/bin/cmake" --version
|
|
echo "${user_base}/bin" >> "${GITHUB_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
|
|
# Run the drm-gated unit tests HERE, because nowhere else does. The ordinary linux CI
|
|
# runs the suite, but `drm` is opt-in, so every test behind that feature -- the cursor
|
|
# rotation and hotspot ones especially -- has no continuous coverage at all otherwise.
|
|
# Debug rather than --release: these are pure logic tests and the release build is
|
|
# already the slow part of this job.
|
|
# A MINIMAL feature set, not the production $FEATURES: these are pure logic tests of
|
|
# the drm paths, and pulling hwcodec in makes the test binary fail to link at all
|
|
# (undefined reference to fcntl64 in this container), so the tests never run.
|
|
#
|
|
# Two packages, because `cargo test --lib` at the root builds the ROOT package only:
|
|
# the provenance tests live in libs/scrap and would never be selected from here. The
|
|
# ordinary linux CI runs --workspace but without the drm feature, so these are not
|
|
# covered there either.
|
|
#
|
|
# awk sums the counts rather than bc, which this container does not install.
|
|
#
|
|
# A cargo test FILTER that matches nothing exits 0, so a rename would turn this into a
|
|
# green no-op. Assert each command actually ran something.
|
|
run_drm_tests() {
|
|
local desc="$1"; shift
|
|
local out
|
|
out=$("$@" 2>&1) || { echo "$out"; echo "::error::drm tests failed: $desc"; exit 1; }
|
|
local ran
|
|
ran=$(echo "$out" | awk '/^running [0-9]+ tests?$/ { n += $2 } END { print n+0 }')
|
|
echo "$desc ran $ran tests"
|
|
if [ "$ran" -lt 1 ]; then
|
|
echo "::error::$desc selected no tests; it was renamed or removed"
|
|
exit 1
|
|
fi
|
|
}
|
|
run_drm_tests "rustdesk drm_capturer_tests" \
|
|
cargo test --locked --lib --features drm drm_capturer_tests
|
|
run_drm_tests "rustdesk ipc::test" \
|
|
cargo test --locked --lib --features drm ipc::test
|
|
run_drm_tests "scrap hotspot_provenance_tests" \
|
|
cargo test --locked -p scrap --features drm hotspot_provenance_tests
|
|
run_drm_tests "scrap hotspot_guess_tests" \
|
|
cargo test --locked -p scrap --features drm hotspot_guess_tests
|
|
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: Set Swap Space
|
|
if: matrix.job.arch == 'armv7'
|
|
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.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
|
|
# armv7 is the only 32-bit target in this job that links the whole binary, and the
|
|
# release profile uses fat LTO with codegen-units=1. LLVM then merges every module
|
|
# into a single unit and runs past the ~3GB address space a 32-bit process gets,
|
|
# aborting rustc with "Rust cannot catch foreign exceptions" (a C++ bad_alloc from
|
|
# LLVM unwinding into rustc's Rust frames). Thin LTO keeps peak memory bounded and
|
|
# still allows cross-crate inlining; 64-bit targets keep fat LTO untouched.
|
|
if [ "${{ matrix.job.arch }}" = "armv7" ]; then
|
|
export CARGO_PROFILE_RELEASE_LTO=thin
|
|
export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=16
|
|
fi
|
|
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
|