From 998ece0856ec6203a2237980143e32dcae99e534 Mon Sep 17 00:00:00 2001 From: Bryan Gerlach Date: Fri, 27 Sep 2024 20:10:41 -0500 Subject: [PATCH] change to using actions on rdgen, added linux and android initial support --- .github/shared-actions/code-changes.yml | 80 ++++ .github/workflows/generator-android.yml | 505 ++++++++++++++++++++++++ .github/workflows/generator-linux.yml | 420 ++++++++++++++++++++ .github/workflows/generator-windows.yml | 492 +++++++++++++++++++++++ rdgenerator/templates/generated.html | 12 +- rdgenerator/templates/waiting.html | 2 +- rdgenerator/views.py | 17 +- setup.txt | 9 +- 8 files changed, 1522 insertions(+), 15 deletions(-) create mode 100644 .github/shared-actions/code-changes.yml create mode 100644 .github/workflows/generator-android.yml create mode 100644 .github/workflows/generator-linux.yml create mode 100644 .github/workflows/generator-windows.yml diff --git a/.github/shared-actions/code-changes.yml b/.github/shared-actions/code-changes.yml new file mode 100644 index 0000000..3087820 --- /dev/null +++ b/.github/shared-actions/code-changes.yml @@ -0,0 +1,80 @@ +name: Rustdesk Code Changes +description: changes to the source code to fix connection delay and allow custom.txt. Also changes icon and app name +inputs: + extras: + required: true + appname: + required: true + iconbase64: + required: true + filename: + required: true +runs: + using: "composite" + steps: + - name: icon stuff + continue-on-error: true + shell: bash + run: | + mv ./res/icon.ico ./res/icon.ico.bak + mv ./res/icon.png ./res/icon.png.bak + mv ./res/tray-icon.ico ./res/tray-icon.ico.bak + echo "${{ inputs.iconbase64 }}" | base64 -d > ./res/icon.png + + - name: magick stuff + continue-on-error: true + run: | + mv ./res/32x32.png ./res/32x32.png.bak + mv ./res/64x64.png ./res/64x64.png.bak + mv ./res/128x128.png ./res/128x128.png.bak + mv ./res/128x128@2x.png ./res/128x128@2x.png.bak + magick ./res/icon.png -define icon:auto-resize=256,64,48,32,16 ./res/icon.ico + cp ./res/icon.ico ./res/tray-icon.ico + magick ./res/icon.png -resize 32x32 ./res/32x32.png + magick ./res/icon.png -resize 64x64 ./res/64x64.png + magick ./res/icon.png -resize 128x128 ./res/128x128.png + magick ./res/128x128.png -resize 200% ./res/128x128@2x.png + + + - name: ui.rs icon + continue-on-error: true + shell: bash + run: | + cp ./src/ui.rs ./src/ui.rs.bak + sed -i -e 's|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|${{ inputs.iconbase64 }}|' ./src/ui.rs + + - name: cargo.toml, runner.rc name, en.rs + continue-on-error: true + shell: bash + run: | + cp ./Cargo.toml ./Cargo.toml.bak + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml + cp ./libs/portable/Cargo.toml ./libs/portable/Cargo.toml.bak + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml + cp ./flutter/windows/runner/Runner.rc ./flutter/windows/runner/Runner.rc.bak + sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"Copyright © 2024 Purslane Ltd. All rights reserved."|"Copyright © 2024"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + cp ./src/lang/en.rs ./src/lang/en.rs.bak + sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs + sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py + sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart + sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart + sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart + sed -i -e '/const KEY:/,/};/d' ./src/common.rs + sed -i -e '/let Ok(data) = sign::verify(&data, &pk)/,/};/d' ./src/common.rs + + - name: fix connection delay + continue-on-error: true + if: ${{ fromJson(inputs.extras).delayFix == 'true' }} + shell: bash + run: | + sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs \ No newline at end of file diff --git a/.github/workflows/generator-android.yml b/.github/workflows/generator-android.yml new file mode 100644 index 0000000..b9d7dcd --- /dev/null +++ b/.github/workflows/generator-android.yml @@ -0,0 +1,505 @@ +name: Custom Android Client Generator +run-name: Custom Android Client Generator +on: + workflow_dispatch: + inputs: + server: + description: 'Rendezvous Server' + required: true + default: '' + type: string + key: + description: 'Public Key' + required: true + default: '' + type: string + apiServer: + description: 'API Server' + required: true + default: '' + type: string + custom: + description: "Custom JSON" + required: true + default: '' + type: string + uuid: + description: "uuid of request" + required: true + default: '' + type: string + iconbase64: + description: "icon in base64" + required: false + default: '' + type: string + logobase64: + description: "logo in base64" + required: false + default: '' + type: string + appname: + description: "app name" + required: true + default: 'rustdesk' + type: string + filename: + description: "Filename" + required: true + default: 'rustdesk' + type: string + extras: + description: "extra inputs in json" + required: true + default: '{}' + type: string + + +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.1" + NDK_VERSION: "r27" + #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: "${{ inputs.key }}" + RENDEZVOUS_SERVER: "${{ inputs.server }}" + CUSTOM: "${{ inputs.custom }}" + UUIDFOLDER: "${{ inputs.uuid }}" + API_SERVER: "${{ inputs.apiServer }}" + UPLOAD_ARTIFACT: 'true' + SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}" + ICONBASE64: "$${{ inputs.iconbase64 }}" + + +jobs: + 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: [self-hosted, linux] + 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: Free Disk Space (Ubuntu) + # uses: jlumbroso/free-disk-space@main + # 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@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: | + # echo ${{ secrets.SUDOPW }} | sudo -S apt-get update + # echo ${{ secrets.SUDOPW }} | sudo -S apt-get install -y \ + # clang \ + # cmake \ + # curl \ + # gcc-multilib \ + # git \ + # g++ \ + # g++-multilib \ + # imagemagick \ + # 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 + with: + repository: rustdesk/rustdesk + + # - 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 }} + # 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@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: | + cd flutter + sed -i 's/uni_links_desktop/#uni_links_desktop/g' pubspec.yaml + sed -i 's/extended_text: .*/extended_text: 11.1.0/' pubspec.yaml + flutter pub get + cd lib + find . | grep dart | xargs sed -i 's/textScaler: TextScaler.linear(\(.*\)),/textScaleFactor: \1,/g' + + ########################################################## + - name: icon stuff + continue-on-error: true + shell: bash + run: | + mv ./res/icon.ico ./res/icon.ico.bak + mv ./res/icon.png ./res/icon.png.bak + mv ./res/tray-icon.ico ./res/tray-icon.ico.bak + echo "${{ inputs.iconbase64 }}" | base64 -d > ./res/icon.png + + - name: magick stuff + continue-on-error: true + run: | + mv ./res/32x32.png ./res/32x32.png.bak + mv ./res/64x64.png ./res/64x64.png.bak + mv ./res/128x128.png ./res/128x128.png.bak + mv ./res/128x128@2x.png ./res/128x128@2x.png.bak + convert ./res/icon.png -define icon:auto-resize=256,64,48,32,16 ./res/icon.ico + cp ./res/icon.ico ./res/tray-icon.ico + convert ./res/icon.png -resize 32x32 ./res/32x32.png + convert ./res/icon.png -resize 64x64 ./res/64x64.png + convert ./res/icon.png -resize 128x128 ./res/128x128.png + convert ./res/128x128.png -resize 200% ./res/128x128@2x.png + + + - name: ui.rs icon + continue-on-error: true + shell: bash + run: | + #cp ./src/ui.rs ./src/ui.rs.bak + sed -i -e 's|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|${{ inputs.iconbase64 }}|' ./src/ui.rs + + - name: cargo.toml, runner.rc name, en.rs + continue-on-error: true + shell: bash + run: | + cp ./Cargo.toml ./Cargo.toml.bak + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml + cp ./libs/portable/Cargo.toml ./libs/portable/Cargo.toml.bak + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml + cp ./flutter/windows/runner/Runner.rc ./flutter/windows/runner/Runner.rc.bak + sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"Copyright © 2024 Purslane Ltd. All rights reserved."|"Copyright © 2024"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + cp ./src/lang/en.rs ./src/lang/en.rs.bak + sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs + sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py + sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart + sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart + sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart + sed -i -e '/const KEY:/,/};/d' ./src/common.rs + sed -i -e '/let Ok(data) = sign::verify(&data, &pk)/,/};/d' ./src/common.rs + #cp ./flutter/android/app/src/main/res/values/strings.xml ./flutter/android/app/src/main/res/values/strings.xml.bak + sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./flutter/android/app/src/main/res/values/strings.xml + sed -i -e "s|title: 'RustDesk'|title: '${{ inputs.appname }}'|" ./flutter/lib/main.dart + sed -i -e "s|return 'RustDesk';|return '${{ inputs.appname }}';|" ./flutter/lib/web/bridge.dart + + - name: fix connection delay + continue-on-error: true + if: ${{ fromJson(inputs.extras).delayFix == 'true' }} + shell: bash + run: | + sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs + + - name: replace flutter icons + run: | + cd ./flutter + flutter pub run flutter_launcher_icons + cd .. + ########################################################## + + - 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: Upload Rustdesk library to Artifacts + uses: actions/upload-artifact@master + 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-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 + echo -n "${{ env.CUSTOM }}" | cat > ./flutter/assets/custom.txt + convert ./res/icon.png ./flutter/assets/icon.svg + # 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 + # echo -n "${{ env.CUSTOM }}" | cat > ./flutter/android/app/src/main/custom.txt + # # 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 + # echo -n "${{ env.CUSTOM }}" | cat > ./flutter/android/app/src/main/custom.txt + # # 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 + # echo -n "${{ env.CUSTOM }}" | cat > ./flutter/android/app/src/main/custom.txt + # # 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 ./${{ inputs.filename }}.apk + popd + + - uses: r0adkll/sign-android-release@v1 + name: Sign app APK + continue-on-error: true + 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: ${{ inputs.filename }}-${{ 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 + + - name: Upload to FTP + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.GEN_FTP_SERVER }} + username: ${{ secrets.GEN_FTP_USER }} + password: ${{ secrets.GEN_FTP_PASSWORD }} + local-dir: ./signed-apk/ + server-dir: /root/rdgen/exe/${{ env.UUIDFOLDER }}/ + exclude: | + *.idsig + *.jks + *aligned.apk + + - name: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}' + + - name: failed + if: failure() + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}' + + - name: failed + if: cancelled() + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}' \ No newline at end of file diff --git a/.github/workflows/generator-linux.yml b/.github/workflows/generator-linux.yml new file mode 100644 index 0000000..f902584 --- /dev/null +++ b/.github/workflows/generator-linux.yml @@ -0,0 +1,420 @@ +name: Custom Linux Client Generator +run-name: Custom Linux Client Generator +on: + workflow_dispatch: + inputs: + server: + description: 'Rendezvous Server' + required: true + default: '' + type: string + key: + description: 'Public Key' + required: true + default: '' + type: string + apiServer: + description: 'API Server' + required: true + default: '' + type: string + custom: + description: "Custom JSON" + required: true + default: '' + type: string + uuid: + description: "uuid of request" + required: true + default: '' + type: string + iconbase64: + description: "icon in base64" + required: false + default: '' + type: string + logobase64: + description: "logo in base64" + required: false + default: '' + type: string + appname: + description: "app name" + required: true + default: 'rustdesk' + type: string + filename: + description: "Filename" + required: true + default: 'rustdesk' + type: string + extras: + description: "extra inputs in json" + required: true + default: '{}' + type: string + +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.1" + NDK_VERSION: "r27" + #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: "${{ inputs.key }}" + RENDEZVOUS_SERVER: "${{ inputs.server }}" + CUSTOM: "${{ inputs.custom }}" + UUIDFOLDER: "${{ inputs.uuid }}" + API_SERVER: "${{ inputs.apiServer }}" + UPLOAD_ARTIFACT: 'true' + SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}" + ICONBASE64: "$${{ inputs.iconbase64 }}" + + +jobs: + generate-bridge-linux: + uses: ./.github/workflows/bridge.yml + + 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 + with: + repository: rustdesk/rustdesk + + # - 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 }} + doNotCache: false + + - name: Install vcpkg dependencies + if: matrix.job.arch == 'x86_64' || env.UPLOAD_ARTIFACT == 'true' + 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 + 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 + mkdir output + chmod 777 output -R + 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" /workspace/output/"${{ inputs.filename }}-${{ 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/output/"${{ inputs.filename }}.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/output/"${{ inputs.filename }}-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 to FTP + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.FTP_SERVER }} + username: ${{ secrets.FTP_USERNAME }} + password: ${{ secrets.FTP_PASSWORD }} + local-dir: output/ + server-dir: /root/rdgen/exe/${{ env.UUIDFOLDER }}/ + + - 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 + + - name: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}' + + - name: failed + if: failure() + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}' + + - name: failed + if: cancelled() + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}' \ No newline at end of file diff --git a/.github/workflows/generator-windows.yml b/.github/workflows/generator-windows.yml new file mode 100644 index 0000000..85d7853 --- /dev/null +++ b/.github/workflows/generator-windows.yml @@ -0,0 +1,492 @@ +name: Custom Windows Client Generator +run-name: Custom Windows Client Generator +on: + workflow_dispatch: + inputs: + server: + description: 'Rendezvous Server' + required: true + default: '' + type: string + key: + description: 'Public Key' + required: true + default: '' + type: string + apiServer: + description: 'API Server' + required: true + default: '' + type: string + custom: + description: "Custom JSON" + required: true + default: '' + type: string + uuid: + description: "uuid of request" + required: true + default: '' + type: string + iconbase64: + description: "icon in base64" + required: false + default: '' + type: string + logobase64: + description: "logo in base64" + required: false + default: '' + type: string + appname: + description: "app name" + required: true + default: 'rustdesk' + type: string + filename: + description: "Filename" + required: true + default: 'rustdesk' + type: string + extras: + description: "extra inputs in json" + required: true + default: '{}' + type: string + + +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.1" + NDK_VERSION: "r27" + #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: "${{ inputs.key }}" + RENDEZVOUS_SERVER: "${{ inputs.server }}" + CUSTOM: "${{ inputs.custom }}" + UUIDFOLDER: "${{ inputs.uuid }}" + API_SERVER: "${{ inputs.apiServer }}" + UPLOAD_ARTIFACT: 'true' + SIGN_BASE_URL: "${{ secrets.SIGN_BASE_URL }}" + + +jobs: + # build-RustDeskTempTopMostWindow: + # uses: ./.github/workflows/third-party-RustDeskTempTopMostWindow.yml + # with: + # upload-artifact: true + # target: windows-2022 + # configuration: Release + # platform: x64 + # target_version: Windows10 + # strategy: + # fail-fast: false + + build-for-windows-flutter: + name: Build Windows + #needs: [build-RustDeskTempTopMostWindow] + runs-on: [self-hosted, windows] + 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: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}' + + - name: Checkout source code + uses: actions/checkout@v4 + with: + repository: rustdesk/rustdesk + + # - 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 }} + # 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 + # shell: bash + + - name: icon stuff + continue-on-error: true + shell: bash + run: | + mv ./res/icon.ico ./res/icon.ico.bak + mv ./res/icon.png ./res/icon.png.bak + mv ./res/tray-icon.ico ./res/tray-icon.ico.bak + echo "${{ inputs.iconbase64 }}" | base64 -d > ./res/icon.png + + - name: magick stuff + continue-on-error: true + run: | + mv ./res/32x32.png ./res/32x32.png.bak + mv ./res/64x64.png ./res/64x64.png.bak + mv ./res/128x128.png ./res/128x128.png.bak + mv ./res/128x128@2x.png ./res/128x128@2x.png.bak + magick ./res/icon.png -define icon:auto-resize=256,64,48,32,16 ./res/icon.ico + cp ./res/icon.ico ./res/tray-icon.ico + magick ./res/icon.png -resize 32x32 ./res/32x32.png + magick ./res/icon.png -resize 64x64 ./res/64x64.png + magick ./res/icon.png -resize 128x128 ./res/128x128.png + magick ./res/128x128.png -resize 200% ./res/128x128@2x.png + + + - name: ui.rs icon + continue-on-error: true + shell: bash + run: | + cp ./src/ui.rs ./src/ui.rs.bak + sed -i -e 's|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|${{ inputs.iconbase64 }}|' ./src/ui.rs + + - name: cargo.toml, runner.rc name, en.rs + continue-on-error: true + shell: bash + run: | + cp ./Cargo.toml ./Cargo.toml.bak + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml + cp ./libs/portable/Cargo.toml ./libs/portable/Cargo.toml.bak + sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml + sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml + cp ./flutter/windows/runner/Runner.rc ./flutter/windows/runner/Runner.rc.bak + sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"Copyright © 2024 Purslane Ltd. All rights reserved."|"Copyright © 2024"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc + sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc + cp ./src/lang/en.rs ./src/lang/en.rs.bak + sed -i -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs + sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py + sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart + sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart + sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart + sed -i -e '/const KEY:/,/};/d' ./src/common.rs + sed -i -e '/let Ok(data) = sign::verify(&data, &pk)/,/};/d' ./src/common.rs + + - name: fix connection delay + continue-on-error: true + if: ${{ fromJson(inputs.extras).delayFix == 'true' }} + shell: bash + run: | + sed -i -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs + + - name: run as admin + continue-on-error: true + if: ${{ fromJson(inputs.extras).runasadmin == 'true' }} + shell: bash + run: | + echo "SET_TARGET_PROPERTIES(\${BINARY_NAME} PROPERTIES LINK_FLAGS \"/MANIFESTUAC:\\\"level='requireAdministrator' uiAccess='false'\\\" /SUBSYSTEM:WINDOWS\")" >> ./flutter/windows/runner/CMakeLists.txt + sed -i '/administrator/d' res/manifest.xml + + - name: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}' + + - name: replace flutter icons + run: | + cd ./flutter + flutter pub run flutter_launcher_icons + cd .. + + - name: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "30% complete"}' + + - name: generate rustbridge + run: | + ~/.cargo/bin/flutter_rust_bridge_codegen --rust-input ./src/flutter_ffi.rs --dart-output ./flutter/lib/generated_bridge.dart + + - name: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}' + + - name: Build rustdesk + run: | + python .\build.py --portable --flutter --skip-portable-pack + mv ./flutter/build/windows/x64/runner/Release ./rustdesk + + - name: logo stuff + continue-on-error: true + shell: bash + run: | + echo "${{ inputs.logobase64 }}" | base64 -d > ./rustdesk/data/flutter_assets/assets/logo.png + + - name: icon stuff + continue-on-error: true + run: | + mv ./rustdesk/data/flutter_assets/assets/icon.svg ./rustdesk/data/flutter_assets/assets/icon.svg.bak + magick ./res/icon.png ./rustdesk/data/flutter_assets/assets/icon.svg + + + #lines removed from above: + #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 . -Force + #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 + + - 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: env.UPLOAD_ARTIFACT == 'true' + # 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: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}' + + - name: Sign rustdesk files + uses: GermanBluefox/code-sign-action@v7 + if: env.UPLOAD_ARTIFACT == 'true' + with: + certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}' + password: '${{ secrets.WINDOWS_PFX_PASSWORD }}' + certificatesha1: '${{ secrets.WINDOWS_PFX_SHA1_THUMBPRINT }}' + # certificatename: '${{ secrets.CERTNAME }}' + folder: './rustdesk/' + recursive: true + + - name: Create custom.txt file + shell: bash + run: | + echo -n "${{ env.CUSTOM }}" | cat > ./rustdesk/custom.txt + + #if [ "${{ env.DIRECTION }}" = "Incoming" ]; then echo -n "eyJjb25uLXR5cGUiOiJpbmNvbWluZyJ9" | cat > ./rustdesk/custom.txt; fi + #if [ "${{ env.DIRECTION }}" = "Outgoing" ]; then echo -n "eyJjb25uLXR5cGUiOiJvdXRnb2luZyJ9" | cat > ./rustdesk/custom.txt; fi + + - name: Build self-extracted executable + shell: bash + if: env.UPLOAD_ARTIFACT == 'true' + run: | + mv "./rustdesk/rustdesk.exe" "./rustdesk/${{ inputs.appname }}.exe" + sed -i '/dpiAware/d' res/manifest.xml + pushd ./libs/portable + pip3 install -r requirements.txt + python ./generate.py -f ../../rustdesk/ -o . -e "../../rustdesk/${{ inputs.appname }}.exe" + popd + mkdir -p ./SignOutput + mv ./target/release/rustdesk-portable-packer.exe "./SignOutput/rustdesk.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 + # cp ./Package/bin/x64/Release/en-us/Package.msi ../../SignOutput/rustdesk-latest.msi + # 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: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "85% complete"}' + + - name: Sign rustdesk self-extracted file + uses: GermanBluefox/code-sign-action@v7 + if: env.UPLOAD_ARTIFACT == 'true' + with: + certificate: '${{ secrets.WINDOWS_PFX_BASE64 }}' + password: '${{ secrets.WINDOWS_PFX_PASSWORD }}' + certificatesha1: '${{ secrets.WINDOWS_PFX_SHA1_THUMBPRINT }}' + # certificatename: '${{ secrets.WINDOWS_PFX_NAME }}' + folder: './SignOutput' + recursive: false + + # - 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 + + - name: rename rustdesk.exe to filename.exe + run: | + mv ./SignOutput/rustdesk.exe "./SignOutput/${{ inputs.filename }}.exe" + + - name: Upload to FTP + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.GEN_FTP_SERVER }} + username: ${{ secrets.GEN_FTP_USER }} + password: ${{ secrets.GEN_FTP_PASSWORD }} + local-dir: ./SignOutput/ + server-dir: /root/rdgen/exe/${{ env.UUIDFOLDER }}/ + + - name: Report Status + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}' + + - name: failed + if: failure() + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}' + + - name: failed + if: cancelled() + uses: fjogeleit/http-request-action@v1 + with: + url: ${{ secrets.GENURL }}/updategh + method: 'POST' + customHeaders: '{"Content-Type": "application/json"}' + data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}' diff --git a/rdgenerator/templates/generated.html b/rdgenerator/templates/generated.html index 8af93ea..6e2ecff 100644 --- a/rdgenerator/templates/generated.html +++ b/rdgenerator/templates/generated.html @@ -1 +1,11 @@ -{{filename}} \ No newline at end of file +{% if platform == 'windows' %} +{{filename}}.exe +{% elif platform == 'linux' %} +{{filename}}.deb
+{{filename}}.rpm
+{{filename}}-suse.rpm +{% elif platform == 'android' %} +{{filename}}.apk +{% else %} +Error, no file generated +{% endif %} \ No newline at end of file diff --git a/rdgenerator/templates/waiting.html b/rdgenerator/templates/waiting.html index a54d4a5..1c13564 100644 --- a/rdgenerator/templates/waiting.html +++ b/rdgenerator/templates/waiting.html @@ -8,7 +8,7 @@ Status: {{status}} diff --git a/rdgenerator/views.py b/rdgenerator/views.py index 680971a..e3ef49a 100644 --- a/rdgenerator/views.py +++ b/rdgenerator/views.py @@ -147,13 +147,13 @@ def generator_view(request): ####from here run the github action, we need user, repo, access token. if platform == 'windows': - url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/test.yml/dispatches' + url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rdgen/actions/workflows/generator-windows.yml/dispatches' elif platform == 'linux': - url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/generator-linux.yml/dispatches' + url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rdgen/actions/workflows/generator-linux.yml/dispatches' elif platform == 'android': - url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/generator-android.yml/dispatches' + url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rdgen/actions/workflows/generator-android.yml/dispatches' else: - url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/test.yml/dispatches' + url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rdgen/actions/workflows/generator-windows.yml/dispatches' #url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/test.yml/dispatches' data = { @@ -182,7 +182,7 @@ def generator_view(request): response = requests.post(url, json=data, headers=headers) print(response) - return render(request, 'waiting.html', {'filename':filename, 'uuid':myuuid, 'status':"Starting generator...please wait"}) + return render(request, 'waiting.html', {'filename':filename, 'uuid':myuuid, 'status':"Starting generator...please wait", 'platform':platform}) else: form = GenerateForm() return render(request, 'generator.html', {'form': form}) @@ -191,19 +191,20 @@ def generator_view(request): def check_for_file(request): filename = request.GET['filename'] uuid = request.GET['uuid'] + platform = request.GET['platform'] gh_run = GithubRun.objects.filter(Q(uuid=uuid)).first() status = gh_run.status #if file_exists: if status == "Success": - return render(request, 'generated.html', {'filename': filename, 'uuid':uuid}) + return render(request, 'generated.html', {'filename': filename, 'uuid':uuid, 'platform':platform}) else: - return render(request, 'waiting.html', {'filename':filename, 'uuid':uuid, 'status':status}) + return render(request, 'waiting.html', {'filename':filename, 'uuid':uuid, 'status':status, 'platform':platform}) def download(request): filename = request.GET['filename'] uuid = request.GET['uuid'] - filename = filename+".exe" + #filename = filename+".exe" file_path = os.path.join('exe',uuid,filename) with open(file_path, 'rb') as file: response = HttpResponse(file, headers={ diff --git a/setup.txt b/setup.txt index 6aaf976..308ec5a 100644 --- a/setup.txt +++ b/setup.txt @@ -1,9 +1,8 @@ To fully host the client generator yourself, you will need to following: -1) A Github account that has a fork of rustdesk -2) A Github fine-grained access token with permissions for your rustdesk repository -3) An FTP server to upload the generated clients -4) On the server running the client generator: +1) A Github account with a fork of this repo +2) A Github fine-grained access token with permissions for your rdgen repository +3) On the server running the client generator: a) environment variables: GHUSER="your github username" GHBEARER="your fine-graned access token" @@ -16,4 +15,4 @@ To fully host the client generator yourself, you will need to following: WINDOWS_PFX_BASE64 WINDOWS_PFX_PASSWORD WINDOWS_PFX_SHA1_THUMBPRINT -5) A windows computer or VM that is set up to build rustdesk, and is setup as a self-hosted github runner +4) A windows computer or VM that is set up to build rustdesk, and is setup as a self-hosted github runner