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 CARGO_NDK_VERSION: "3.1.2" SCITER_ARMV7_CMAKE_VERSION: "3.29.7" SCITER_NASM_DEBVERSION: "2.14-1" LLVM_VERSION: "15.0.6" FLUTTER_VERSION: "3.19.6" ANDROID_FLUTTER_VERSION: "3.13.9" # >= 3.16 is very slow on my android phone, but work well on most of others. We may switch to new flutter after changing to texture rendering (I believe it can solve my problem). FLUTTER_RUST_BRIDGE_VERSION: "1.80.1" # 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: 2024.07.12 VCPKG_COMMIT_ID: "1de2026f28ead93ff1773e6e680387643e914ea1" VERSION: "1.3.0" NDK_VERSION: "r26d" #signing keys env variable checks ANDROID_SIGNING_KEY: "${{ secrets.ANDROID_SIGNING_KEY }}" MACOS_P12_BASE64: "${{ secrets.MACOS_P12_BASE64 }}" # To make a custom build with your own servers set the below secret values RS_PUB_KEY: "${{ secrets.RS_PUB_KEY }}" RENDEZVOUS_SERVER: "${{ secrets.RENDEZVOUS_SERVER }}" API_SERVER: "${{ secrets.API_SERVER }}" UPLOAD_ARTIFACT: "${{ inputs.upload-artifact }}" SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}" jobs: build-RustDeskTempTopMostWindow: uses: ./.github/workflows/third-party-RustDeskTempTopMostWindow.yml with: upload-artifact: ${{ inputs.upload-artifact }} target: windows-2022 configuration: Release platform: x64 target_version: Windows10 strategy: fail-fast: false build-for-windows-flutter: name: ${{ matrix.job.target }} needs: [build-RustDeskTempTopMostWindow] 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, vcpkg-triplet: x64-windows-static, } # - { target: aarch64-pc-windows-msvc, os: windows-2022, arch: aarch64 } steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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@v4 - name: Install LLVM and Clang uses: KyleMayes/install-llvm-action@v1 with: version: ${{ env.LLVM_VERSION }} - name: Install flutter uses: subosito/flutter-action@v2.12.0 #https://github.com/subosito/flutter-action/issues/277 with: channel: "stable" flutter-version: ${{ env.FLUTTER_VERSION }} cache: true - name: Install Rust toolchain uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env.SCITER_RUST_VERSION }} targets: ${{ matrix.job.target }} components: "rustfmt" - uses: Swatinem/rust-cache@v2 with: prefix-key: ${{ matrix.job.os }} - name: Install flutter rust bridge deps run: | git config --global core.longpaths true cargo install flutter_rust_bridge_codegen --version ${{ env.FLUTTER_RUST_BRIDGE_VERSION }} --features "uuid" Push-Location flutter ; flutter pub get ; Pop-Location ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart - name: Setup vcpkg with Github Actions binary cache uses: lukka/run-vcpkg@v11 with: vcpkgDirectory: C:\vcpkg vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} - name: Install vcpkg dependencies env: VCPKG_DEFAULT_HOST_TRIPLET: ${{ matrix.job.vcpkg-triplet }} run: | $VCPKG_ROOT/vcpkg install --triplet ${{ matrix.job.vcpkg-triplet }} --x-install-root="$VCPKG_ROOT/installed" shell: bash - name: Build rustdesk run: | 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 . python3 .\build.py --portable --hwcodec --flutter --vram --skip-portable-pack Remove-Item -Path usbmmidd_v2\Win32 -Recurse Remove-Item -Path "usbmmidd_v2\deviceinstaller64.exe", "usbmmidd_v2\deviceinstaller.exe", "usbmmidd_v2\usbmmidd.bat" mv ./flutter/build/windows/x64/runner/Release ./rustdesk mv -Force .\usbmmidd_v2 ./rustdesk - 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@master if: ${{ inputs.upload-artifact }} with: name: topmostwindow-artifacts path: "./rustdesk" - name: Upload unsigned if: env.UPLOAD_ARTIFACT == 'true' uses: actions/upload-artifact@master with: name: rustdesk-unsigned-windows-${{ matrix.job.arch }} path: rustdesk - name: Sign rustdesk files if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '' shell: bash run: | pip3 install requests argparse BASE_URL=${{ secrets.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@v2 - name: Build msi if: env.UPLOAD_ARTIFACT == 'true' run: | pushd ./res/msi python preprocess.py --arp -d ../../rustdesk nuget restore msi.sln msbuild msi.sln -p:Configuration=Release -p:Platform=x64 /p:TargetVersion=Windows10 mv ./Package/bin/x64/Release/en-us/Package.msi ../../SignOutput/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.msi sha256sum ../../SignOutput/rustdesk-*.msi - name: Sign rustdesk self-extracted file if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '' shell: bash run: | BASE_URL=${{ secrets.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./SignOutput - name: Publish Release uses: softprops/action-gh-release@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@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@v4 - name: Install LLVM and Clang uses: rustdesk-org/install-llvm-action-32bit@master with: version: ${{ env.LLVM_VERSION }} - name: Install Rust toolchain uses: dtolnay/rust-toolchain@v1 with: toolchain: nightly-2023-10-13-${{ matrix.job.target }} # must use nightly here, because of abi_thiscall feature required targets: ${{ matrix.job.target }} components: "rustfmt" - uses: Swatinem/rust-cache@v2 with: prefix-key: ${{ matrix.job.os }}-sciter - name: Setup vcpkg with Github Actions binary cache uses: lukka/run-vcpkg@v11 with: vcpkgDirectory: C:\vcpkg vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} - name: Install vcpkg dependencies env: VCPKG_DEFAULT_HOST_TRIPLET: ${{ matrix.job.vcpkg-triplet }} run: | $VCPKG_ROOT/vcpkg install --triplet ${{ matrix.job.vcpkg-triplet }} --x-install-root="$VCPKG_ROOT/installed" 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 build --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: Sign rustdesk files if: env.UPLOAD_ARTIFACT == 'true' && env.SIGN_BASE_URL != '' shell: bash run: | pip3 install requests argparse BASE_URL=${{ secrets.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 != '' shell: bash run: | BASE_URL=${{ secrets.SIGN_BASE_URL }} SECRET_KEY=${{ secrets.SIGN_SECRET_KEY }} python3 res/job.py sign_files ./SignOutput/ - name: Publish Release uses: softprops/action-gh-release@v1 if: env.UPLOAD_ARTIFACT == 'true' with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | ./SignOutput/rustdesk-*.exe build-for-macOS-arm64-selfhost: # use build-for-macOS instead if: false runs-on: [self-hosted, macOS, ARM64] steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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@v4 - name: Install flutter rust bridge deps shell: bash run: | cargo install flutter_rust_bridge_codegen --version ${{ env.FLUTTER_RUST_BRIDGE_VERSION }} --features "uuid" pushd flutter && flutter pub get && popd ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart --c-output ./flutter/macos/Runner/bridge_generated.h - name: Build rustdesk run: | ./build.py --flutter --hwcodec - 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 }}-arm64.dmg ./flutter/build/macos/Build/Products/Release/RustDesk.app - name: Upload unsigned macOS app if: env.UPLOAD_ARTIFACT == 'true' uses: actions/upload-artifact@master with: name: rustdesk-unsigned-macos-arm64 path: rustdesk-${{ env.VERSION }}-arm64.dmg # can not upload the directory directly or tar.gz file, 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" # start sign the rustdesk.app and dmg rm -rf *.dmg || true codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep --strict ./flutter/build/macos/Build/Products/Release/RustDesk.app -vvv create-dmg --icon "RustDesk.app" 200 190 --hide-extension "RustDesk.app" --window-size 800 400 --app-drop-link 600 185 rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/RustDesk.app codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep --strict rustdesk-${{ env.VERSION }}.dmg -vvv # notarize the rustdesk-${{ env.VERSION }}.dmg rcodesign notary-submit --api-key-path ~/.p12/api-key.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}-aarch64.dmg" done - name: Publish DMG package if: env.UPLOAD_ARTIFACT == 'true' uses: softprops/action-gh-release@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | rustdesk*-aarch64.dmg build-rustdesk-ios: if: ${{ inputs.upload-artifact }} name: build rustdesk ios ipa runs-on: ${{ matrix.job.os }} strategy: fail-fast: false matrix: job: - { arch: aarch64, target: aarch64-apple-ios, os: macos-13, vcpkg-triplet: arm64-ios, } steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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@v4 - name: Install flutter uses: subosito/flutter-action@v2 with: channel: "stable" flutter-version: ${{ env.FLUTTER_VERSION }} - name: Setup vcpkg with Github Actions binary cache uses: lukka/run-vcpkg@v11 with: vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} - name: Install vcpkg dependencies run: | $VCPKG_ROOT/vcpkg install --triplet ${{ matrix.job.vcpkg-triplet }} --x-install-root="$VCPKG_ROOT/installed" shell: bash - name: Install Rust toolchain uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env.RUST_VERSION }} targets: ${{ matrix.job.target }} components: "rustfmt" - uses: Swatinem/rust-cache@v2 with: prefix-key: rustdesk-lib-cache-ios key: ${{ matrix.job.target }} - name: Install flutter rust bridge deps shell: bash run: | cargo install flutter_rust_bridge_codegen --version ${{ env.FLUTTER_RUST_BRIDGE_VERSION }} --features "uuid" pushd flutter && flutter pub get && popd ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart --c-output ./flutter/ios/Runner/bridge_generated.h - name: Build rustdesk lib run: | rustup target add ${{ matrix.job.target }} cargo build --features flutter,hwcodec --release --target aarch64-apple-ios --lib - 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@master # 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@v1 # with: # prerelease: true # tag_name: ${{ env.TAG_NAME }} # files: | # flutter/build/ios/ipa/*.ipa build-rustdesk-ios-selfhost: #if: ${{ inputs.upload-artifact }} if: false runs-on: [self-hosted, macOS, ARM64] strategy: fail-fast: false steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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@v4 # $VCPKG_ROOT/vcpkg install --triplet arm64-ios --x-install-root="$VCPKG_ROOT/installed" - name: Install flutter rust bridge deps shell: bash run: | cargo install flutter_rust_bridge_codegen --version ${{ env.FLUTTER_RUST_BRIDGE_VERSION }} --features "uuid" pushd flutter && flutter pub get && popd ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart --c-output ./flutter/ios/Runner/bridge_generated.h - name: Build rustdesk lib run: | cargo build --features flutter,hwcodec --release --target aarch64-apple-ios --lib - name: Build rustdesk # ios sdk not installed on this machine, I will install it later after I am back home if: false 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@master # 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@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 }} strategy: fail-fast: false matrix: job: - { target: x86_64-apple-darwin, os: macos-13, #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, } - { target: aarch64-apple-darwin, os: macos-latest, # 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: "", arch: aarch64, } steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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@v4 - name: Import the codesign cert if: env.MACOS_P12_BASE64 != null uses: apple-actions/import-codesign-certs@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@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 nasm cmake gcc wget ninja pkg-config - name: Install flutter uses: subosito/flutter-action@v2 with: channel: "stable" flutter-version: ${{ env.FLUTTER_VERSION }} - 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@v1 with: toolchain: ${{ env.RUST_VERSION }} targets: ${{ matrix.job.target }} components: "rustfmt" - uses: Swatinem/rust-cache@v2 with: prefix-key: ${{ matrix.job.os }} - name: Install flutter rust bridge deps shell: bash run: | cargo install flutter_rust_bridge_codegen --version ${{ env.FLUTTER_RUST_BRIDGE_VERSION }} --features "uuid" pushd flutter && flutter pub get && popd ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart --c-output ./flutter/macos/Runner/bridge_generated.h - name: Setup vcpkg with Github Actions binary cache uses: lukka/run-vcpkg@v11 with: vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} - name: Install vcpkg dependencies run: | $VCPKG_ROOT/vcpkg install --x-install-root="$VCPKG_ROOT/installed" - 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: | ./build.py --flutter --hwcodec ${{ 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@master with: name: rustdesk-unsigned-macos-${{ matrix.job.arch }} path: rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.dmg # can not upload the directory directly or tar.gz, which destroy the link structure, causing the codesign failed - name: Codesign app and create signed dmg if: env.MACOS_P12_BASE64 != null && env.UPLOAD_ARTIFACT == 'true' run: | # Patch create-dmg to give more attempts to unmount image CREATE_DMG="$(command -v create-dmg)" CREATE_DMG="$(readlink -f "$CREATE_DMG")" sed -i -e 's/MAXIMUM_UNMOUNTING_ATTEMPTS=3/MAXIMUM_UNMOUNTING_ATTEMPTS=7/' "$CREATE_DMG" # Unlock keychain security default-keychain -s rustdesk.keychain security unlock-keychain -p ${{ secrets.MACOS_P12_PASSWORD }} rustdesk.keychain # start sign the rustdesk.app and dmg rm -rf *.dmg || true codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep --strict ./flutter/build/macos/Build/Products/Release/RustDesk.app -vvv create-dmg --icon "RustDesk.app" 200 190 --hide-extension "RustDesk.app" --window-size 800 400 --app-drop-link 600 185 rustdesk-${{ env.VERSION }}.dmg ./flutter/build/macos/Build/Products/Release/RustDesk.app codesign --force --options runtime -s ${{ secrets.MACOS_CODESIGN_IDENTITY }} --deep --strict rustdesk-${{ env.VERSION }}.dmg -vvv # notarize the rustdesk-${{ env.VERSION }}.dmg rcodesign notary-submit --api-key-path ${{ github.workspace }}/rustdesk.json --staple rustdesk-${{ env.VERSION }}.dmg - name: Rename rustdesk if: env.UPLOAD_ARTIFACT == 'true' run: | for name in rustdesk*??.dmg; do mv "$name" "${name%%.dmg}-${{ matrix.job.arch }}.dmg" done - name: Publish DMG package if: env.UPLOAD_ARTIFACT == 'true' uses: softprops/action-gh-release@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 runs-on: ubuntu-latest if: ${{ inputs.upload-artifact }} steps: - name: Download artifacts uses: actions/download-artifact@master with: name: rustdesk-unsigned-macos-x86_64 path: ./ - name: Download Artifacts uses: actions/download-artifact@master with: name: rustdesk-unsigned-macos-aarch64 path: ./ - name: Download Artifacts uses: actions/download-artifact@master with: name: rustdesk-unsigned-windows-x86_64 path: ./windows-x86_64/ - name: Combine unsigned app run: | tar czf rustdesk-${{ env.VERSION }}-unsigned.tar.gz *.dmg windows-x86_64 - name: Publish unsigned app uses: softprops/action-gh-release@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: rustdesk-${{ env.VERSION }}-unsigned.tar.gz generate-bridge-linux: uses: ./.github/workflows/bridge.yml build-rustdesk-android: needs: [generate-bridge-linux] 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-20.04, reltype: release, suffix: "", } - { arch: armv7, target: armv7-linux-androideabi, os: ubuntu-20.04, reltype: release, suffix: "", } - { arch: x86_64, target: x86_64-linux-android, os: ubuntu-20.04, reltype: release, suffix: "", } steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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 \ libappindicator3-dev \ libasound2-dev \ libc6-dev \ libclang-10-dev \ libgstreamer1.0-dev \ libgstreamer-plugins-base1.0-dev \ libgtk-3-dev \ libpam0g-dev \ libpulse-dev \ libva-dev \ libvdpau-dev \ libxcb-randr0-dev \ libxcb-shape0-dev \ libxcb-xfixes0-dev \ libxdo-dev \ libxfixes-dev \ llvm-10-dev \ nasm \ ninja-build \ openjdk-11-jdk-headless \ pkg-config \ tree \ wget - name: Checkout source code uses: actions/checkout@v4 - name: Install flutter uses: subosito/flutter-action@v2 with: channel: "stable" flutter-version: ${{ env.ANDROID_FLUTTER_VERSION }} - uses: nttld/setup-ndk@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@v11 with: vcpkgDirectory: /opt/artifacts/vcpkg vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} - name: Install vcpkg dependencies run: | case ${{ matrix.job.target }} in aarch64-linux-android) ./flutter/build_android_deps.sh arm64-v8a ;; armv7-linux-androideabi) ./flutter/build_android_deps.sh armeabi-v7a ;; x86_64-linux-android) ./flutter/build_android_deps.sh x86_64 ;; i686-linux-android) ./flutter/build_android_deps.sh x86 ;; esac shell: bash - name: Restore bridge files uses: actions/download-artifact@master with: name: bridge-artifact path: ./ - name: Install Rust toolchain uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env.RUST_VERSION }} components: "rustfmt" - uses: Swatinem/rust-cache@v2 with: prefix-key: rustdesk-lib-cache-android # TODO: drop '-android' part after caches are invalidated key: ${{ matrix.job.target }} - name: fix android for flutter 3.13 if: $${{ env.ANDROID_FLUTTER_VERSION == '3.13.9' }} run: | sed -i 's/uni_links_desktop/#uni_links_desktop/g' flutter/pubspec.yaml cd flutter/lib find . | grep dart | xargs sed -i 's/textScaler: TextScaler.linear(\(.*\)),/textScaleFactor: \1,/g' - 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 }} 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: Build rustdesk shell: bash env: JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64 run: | export PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH # 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 }}/debug/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 . - uses: r0adkll/sign-android-release@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: # override default build-tools version (29.0.3) -- optional BUILD_TOOLS_VERSION: "30.0.2" - name: Upload Artifacts if: env.ANDROID_SIGNING_KEY != null && env.UPLOAD_ARTIFACT == 'true' uses: actions/upload-artifact@master 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@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@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | signed-apk/rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk build-rustdesk-linux: needs: [generate-bridge-linux] 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-20.04, deb_arch: amd64, vcpkg-triplet: x64-linux, } - { arch: aarch64, target: aarch64-unknown-linux-gnu, distro: ubuntu18.04, on: [self-hosted, Linux, ARM64], deb_arch: arm64, vcpkg-triplet: arm64-linux, } steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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 if: ${{ matrix.job.arch == 'x86_64' }} 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 qemu-user-static - name: Checkout source code uses: actions/checkout@v4 - name: Set Swap Space if: ${{ matrix.job.arch == 'x86_64' }} uses: pierotofy/set-swap-space@master with: swap-size-gb: 12 - name: Free Space run: | df -h free -m - name: Install Rust toolchain uses: dtolnay/rust-toolchain@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@master with: name: bridge-artifact path: ./ - name: Setup vcpkg with Github Actions binary cache if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true' uses: lukka/run-vcpkg@v11 with: vcpkgDirectory: /opt/artifacts/vcpkg vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }} - name: Install vcpkg dependencies if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true' run: | $VCPKG_ROOT/vcpkg install --triplet ${{ matrix.job.vcpkg-triplet }} --x-install-root="$VCPKG_ROOT/installed" shell: bash - name: Restore bridge files if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true' uses: actions/download-artifact@master with: name: bridge-artifact path: ./ - uses: rustdesk-org/run-on-arch-action@amd64-support 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++ \ libappindicator3-dev \ libasound2-dev \ libclang-10-dev \ libgstreamer1.0-dev \ libgstreamer-plugins-base1.0-dev \ libgtk-3-dev \ libpam0g-dev \ libpulse-dev \ libva-dev \ libvdpau-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 # 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 --lib $JOBS --features hwcodec,flutter --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 # 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@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | rustdesk-*.deb rustdesk-*.rpm - name: Upload deb uses: actions/upload-artifact@master 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@master 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@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | res/rustdesk-${{ env.VERSION }}*.zst build-rustdesk-linux-sciter: if: ${{ inputs.upload-artifact }} needs: build-rustdesk-linux # not for dep, just make it run later for parallelism 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-20.04, distro: ubuntu18.04, deb_arch: amd64, sciter_arch: x64, vcpkg-triplet: x64-linux, extra_features: ",hwcodec", } - { arch: armv7, target: armv7-unknown-linux-gnueabihf, on: [self-hosted, Linux, ARM64], distro: ubuntu18.04-rustdesk, deb_arch: armhf, sciter_arch: arm32, vcpkg-triplet: arm-linux, extra_features: "", } steps: - name: Export GitHub Actions cache environment variables uses: actions/github-script@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@v4 - name: Free Space run: | df -h free -m - name: Install Rust toolchain uses: dtolnay/rust-toolchain@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@amd64-support 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++ \ libappindicator3-dev \ libasound2-dev \ libclang-dev \ libdbus-1-dev \ libglib2.0-dev \ libgstreamer1.0-dev \ libgstreamer-plugins-base1.0-dev \ libgtk-3-dev \ liblzma-dev \ libpam0g-dev \ libpulse-dev \ libva-dev \ libvdpau-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 # 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 libssl-dev # 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 git reset --hard ${{ env.VCPKG_COMMIT_ID }} # 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 CC=/usr/bin/gcc-8 CXX=/usr/bin/g++-8 sh bootstrap-vcpkg.sh -disableMetrics else 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 = 'https://github.com/rust-lang/crates.io-index' """ > ~/.cargo/config cat ~/.cargo/config # install dependencies from vcpkg export VCPKG_ROOT=/opt/artifacts/vcpkg $VCPKG_ROOT/vcpkg install --triplet ${{ matrix.job.vcpkg-triplet }} --x-install-root="$VCPKG_ROOT/installed" # build rustdesk python3 ./res/inline-sciter.py export CARGO_INCREMENTAL=0 cargo build --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@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@master 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-20.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@v4 - name: Download Binary uses: actions/download-artifact@master 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 sudo apt-get install -y libarchive-tools # set-up appimage-builder pushd /tmp wget -O appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage chmod +x appimage-builder-x86_64.AppImage sudo mv appimage-builder-x86_64.AppImage /usr/local/bin/appimage-builder popd # 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@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, distro: ubuntu18.04, on: ubuntu-20.04, arch: x86_64, suffix: "", } - { target: x86_64-unknown-linux-gnu, distro: ubuntu18.04, on: ubuntu-20.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: [self-hosted, Linux, ARM64], arch: aarch64, suffix: "", } steps: - name: Checkout source code uses: actions/checkout@v4 - name: Download Binary uses: actions/download-artifact@master 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@amd64-support 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 \ curl \ git \ rpm \ wget run: | # disable git safe.directory git config --global --add safe.directory "*" pushd /workspace # install apt-get update -y apt-get install -y \ cmake \ curl \ flatpak \ flatpak-builder \ gcc \ git \ g++ \ libgtk-3-dev \ nasm \ wget # flatpak deps flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo flatpak --user install -y flathub org.freedesktop.Platform/${{ matrix.job.arch }}/23.08 flatpak --user install -y flathub org.freedesktop.Sdk/${{ matrix.job.arch }}/23.08 # package pushd flatpak git clone https://github.com/flathub/shared-modules.git --depth=1 flatpak-builder --user --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@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-20.04 strategy: fail-fast: false env: RELEASE_NAME: web-basic steps: - name: Checkout source code uses: actions/checkout@v4 - name: Prepare env run: | sudo apt-get update -y sudo apt-get install -y wget npm - name: Install flutter uses: subosito/flutter-action@v2.12.0 #https://github.com/subosito/flutter-action/issues/277 with: channel: "stable" flutter-version: ${{ env.FLUTTER_VERSION }} cache: true # 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@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | flutter/build/rustdesk-${{ env.VERSION }}-${{ env.RELEASE_NAME }}.tar.gz