name: playground on: #schedule: # schedule build every night # - cron: "0/6 * * * *" workflow_dispatch: env: RUST_VERSION: "1.75" # https://github.com/rustdesk/rustdesk/discussions/7503 CARGO_NDK_VERSION: "3.1.2" LLVM_VERSION: "15.0.6" FLUTTER_VERSION: "3.16.9" 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: "nightly" VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" # vcpkg version: 2024.06.15 VCPKG_COMMIT_ID: "f7423ee180c4b7f40d43402c2feb3859161ef625" VERSION: "1.2.7" 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-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, } 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@v3 - 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: 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 }}-flutter$${{ env.FLUTTER_VERSION }}.dmg build-rustdesk-android: if: false 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, openssl-arch: android-arm64, ref: master, # latest } steps: - name: Checkout source code uses: actions/checkout@v3 with: ref: ${{ matrix.job.ref }} - 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 \ yasm \ ninja-build \ openjdk-11-jdk-headless \ pkg-config \ tree \ wget - name: Install flutter uses: subosito/flutter-action@v2 with: channel: "stable" flutter-version: ${{ env.FLUTTER_VERSION }} - name: Install Rust toolchain uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ env.RUST_VERSION }} components: "rustfmt" - 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" sed -i 's/uni_links_desktop/#uni_links_desktop/g' flutter/pubspec.yaml pushd flutter/lib; find . | grep dart | xargs sed -i 's/textScaler: TextScaler.linear(\(.*\)),/textScaleFactor: \1,/g'; popd; 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 - 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 ;; esac shell: bash - name: Clone deps shell: bash run: | pushd /opt git clone https://github.com/rustdesk-org/rustdesk_thirdparty_lib.git --depth=1 ls -ls /opt/artifacts/vcpkg/installed/arm64-android/lib/ # cp -rf /opt/rustdesk_thirdparty_lib/vcpkg/* /opt/artifacts/vcpkg/ ls -ls /opt/artifacts/vcpkg/installed/arm64-android/lib/ - 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 ;; 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 --release --target-platform android-arm64 --split-per-abi mv build/app/outputs/flutter-apk/app-arm64-v8a-release.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.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 --release --target-platform android-arm --split-per-abi mv build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk ;; esac popd mkdir -p signed-apk; pushd signed-apk mv ../rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.apk ./rustdesk-test-${{ matrix.job.ref }}-${{ matrix.job.ndk }}.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: Publish signed apk package uses: softprops/action-gh-release@v1 with: prerelease: true tag_name: ${{ env.TAG_NAME }} files: | ${{steps.sign-rustdesk.outputs.signedReleaseFile}}