added macos, update status/download pages
This commit is contained in:
783
.github/workflows/generator-macos.yml
vendored
Normal file
783
.github/workflows/generator-macos.yml
vendored
Normal file
@@ -0,0 +1,783 @@
|
||||
name: Custom macOS Client Generator
|
||||
run-name: Custom macOS 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
|
||||
iconlink:
|
||||
description: "icon link"
|
||||
required: false
|
||||
default: 'false'
|
||||
type: string
|
||||
logolink:
|
||||
description: "logo link"
|
||||
required: false
|
||||
default: 'false'
|
||||
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
|
||||
MAC_RUST_VERSION: "1.81"
|
||||
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.24.5"
|
||||
ANDROID_FLUTTER_VERSION: "3.24.5" # >= 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: "b2cb0da531c2f1f740045bfe7c4dac59f0b2b69c"
|
||||
VERSION: "${{ fromJson(inputs.extras).version }}"
|
||||
NDK_VERSION: "r27c"
|
||||
#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 }}"
|
||||
STATUS_URL: "${{ secrets.GENURL }}/updategh"
|
||||
|
||||
jobs:
|
||||
generate-bridge:
|
||||
uses: ./.github/workflows/bridge.yml
|
||||
with:
|
||||
version: ${{ fromJson(inputs.extras).version }}
|
||||
|
||||
build-for-macos-flutter:
|
||||
name: Build macOS
|
||||
runs-on: macos-latest
|
||||
needs: [generate-bridge]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- {
|
||||
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: "--screencapturekit",
|
||||
arch: aarch64,
|
||||
vcpkg-triplet: arm64-osx,
|
||||
}
|
||||
|
||||
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: Set rdgen value
|
||||
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
|
||||
run: |
|
||||
echo "STATUS_URL=${{ secrets.GENURL }}/updategh" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Set rdgen value
|
||||
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
|
||||
run: |
|
||||
echo "STATUS_URL=${{ inputs.apiServer }}/api/updategh" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}'
|
||||
|
||||
|
||||
|
||||
- name: Checkout source code
|
||||
if: ${{ env.VERSION != 'master' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: rustdesk/rustdesk
|
||||
ref: refs/tags/${{ env.VERSION }}
|
||||
|
||||
- name: Checkout source code
|
||||
if: ${{ env.VERSION == 'master' }}
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: rustdesk/rustdesk
|
||||
|
||||
- name: Restore bridge files
|
||||
uses: actions/download-artifact@master
|
||||
with:
|
||||
name: bridge-artifact
|
||||
path: ./
|
||||
|
||||
- name: Install imagemagick and potrace and nasm and and
|
||||
shell: bash
|
||||
run: |
|
||||
brew install imagemagick potrace nasm cmake gcc wget ninja
|
||||
echo "$(brew --prefix imagemagick)/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Update macOS Info.plist and settings
|
||||
continue-on-error: false
|
||||
shell: bash
|
||||
run: |
|
||||
# MACSTUFF Backup the original Info.plist
|
||||
cp ./flutter/macos/Runner/Info.plist ./flutter/macos/Runner/Info.plist.bak
|
||||
|
||||
# MACSTUFF Update application name and display name
|
||||
sed -i '' -e 's|<key>CFBundleName</key>\s*<string>$(PRODUCT_NAME)</string>|<key>CFBundleName</key>\n\t<string>${{ inputs.appname }}</string>|' ./flutter/macos/Runner/Info.plist
|
||||
sed -i '' -e 's|<key>CFBundleDisplayName</key>\s*<string>$(PRODUCT_NAME)</string>|<key>CFBundleDisplayName</key>\n\t<string>${{ inputs.appname }}</string>|' ./flutter/macos/Runner/Info.plist
|
||||
sed -i '' -e 's|<key>CFBundleIdentifier</key>\s*<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>|<key>CFBundleIdentifier</key>\n\t<string>com.${{ inputs.appname }}.app</string>|' ./flutter/macos/Runner/Info.plist
|
||||
|
||||
# MACSTUFF Update copyright information if needed
|
||||
sed -i '' -e 's|<key>NSHumanReadableCopyright</key>\s*<string>$(PRODUCT_COPYRIGHT)</string>|<key>NSHumanReadableCopyright</key>\n\t<string>${{ inputs.appname }}</string>|' ./flutter/macos/Runner/Info.plist
|
||||
|
||||
# MACSTUFF Update window title and bundle settings
|
||||
cp ./flutter/macos/Runner/Configs/AppInfo.xcconfig ./flutter/macos/Runner/Configs/AppInfo.xcconfig.bak
|
||||
sed -i '' -e 's|PRODUCT_NAME = .*|PRODUCT_NAME = ${{ inputs.appname }}|' ./flutter/macos/Runner/Configs/AppInfo.xcconfig
|
||||
sed -i '' -e 's|PRODUCT_BUNDLE_IDENTIFIER = .*|PRODUCT_BUNDLE_IDENTIFIER = com.${{ inputs.appname }}.app|' ./flutter/macos/Runner/Configs/AppInfo.xcconfig
|
||||
# Keep DEVELOPMENT_TEAM if it exists, don't blank it out
|
||||
|
||||
# Update Xcode project settings
|
||||
sed -i '' -e 's/PRODUCT_NAME = "RustDesk"/PRODUCT_NAME = "${{ inputs.appname }}"/' ./flutter/macos/Runner.xcodeproj/project.pbxproj
|
||||
sed -i '' -e 's/PRODUCT_BUNDLE_IDENTIFIER = ".*"/PRODUCT_BUNDLE_IDENTIFIER = "com.${{ inputs.appname }}.app"/' ./flutter/macos/Runner.xcodeproj/project.pbxproj
|
||||
# Don't modify DEVELOPMENT_TEAM in project.pbxproj
|
||||
|
||||
# Update CMake settings
|
||||
if [ -f "./flutter/macos/CMakeLists.txt" ]; then
|
||||
sed -i '' -e 's/set(BINARY_NAME ".*")/set(BINARY_NAME "${{ inputs.appname }}")/' ./flutter/macos/CMakeLists.txt
|
||||
fi
|
||||
|
||||
# Update Podfile - keep the target as 'Runner'
|
||||
# sed -i '' -e 's/target '"'"'Runner'"'"' do/target '"'"'${{ inputs.appname }}'"'"' do/' ./flutter/macos/Podfile
|
||||
sed -i '' -e 's/target '"'"'Runner'"'"' do/target '"'"'Runner'"'"' do/' ./flutter/macos/Podfile
|
||||
|
||||
cp ./src/lang/en.rs ./src/lang/en.rs.bak
|
||||
cp ./src/lang/nl.rs ./src/lang/nl.rs.bak
|
||||
sed -i '' -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/en.rs
|
||||
sed -i '' -e 's|RustDesk|${{ inputs.appname }}|' ./src/lang/nl.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|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./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 "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart
|
||||
sed -i '' -e "s|https://rustdesk.com/privacy.html|${{ fromJson(inputs.extras).urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_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
|
||||
|
||||
# Update pubspec.yaml with proper YAML formatting
|
||||
cp ./flutter/pubspec.yaml ./flutter/pubspec.yaml.bak
|
||||
echo " archive: ^3.6.1" > ./flutter/temp_dependency.txt
|
||||
awk '/intl:/{print;system("cat ./flutter/temp_dependency.txt");next}1' ./flutter/pubspec.yaml > ./flutter/pubspec.yaml.tmp
|
||||
mv ./flutter/pubspec.yaml.tmp ./flutter/pubspec.yaml
|
||||
rm ./flutter/temp_dependency.txt
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "10% complete"}'
|
||||
|
||||
- name: Install flutter
|
||||
uses: subosito/flutter-action@v2.12.0
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
cache: true
|
||||
|
||||
- name: Patch flutter
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cp .github/patches/flutter_3.24.4_dropdown_menu_enableFilter.diff $(dirname $(dirname $(which flutter)))
|
||||
cd $(dirname $(dirname $(which flutter)))
|
||||
[[ "3.24.4" == 3.24.5 ]] && git apply flutter_3.24.4_dropdown_menu_enableFilter.diff
|
||||
|
||||
- name: Workaround for flutter issue
|
||||
shell: bash
|
||||
run: |
|
||||
cd "$(dirname "$(which flutter)")"
|
||||
# https://github.com/flutter/flutter/issues/1.3.43
|
||||
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.MAC_RUST_VERSION }}
|
||||
targets: ${{ matrix.job.target }}
|
||||
components: "rustfmt"
|
||||
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Setup vcpkg with Github Actions binary cache
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
||||
doNotCache: false
|
||||
|
||||
- name: Install vcpkg dependencies
|
||||
run: |
|
||||
if ! $VCPKG_ROOT/vcpkg \
|
||||
install \
|
||||
--x-install-root="$VCPKG_ROOT/installed"; then
|
||||
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
||||
echo "$_1:"
|
||||
echo "======"
|
||||
cat "$_1"
|
||||
echo "======"
|
||||
echo ""
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
head -n 100 "${VCPKG_ROOT}/buildtrees/ffmpeg/build-${{ matrix.job.vcpkg-triplet }}-rel-out.log" || true
|
||||
shell: bash
|
||||
|
||||
- name: Magick stuff for macOS
|
||||
if: ${{ inputs.iconlink != 'false' }}
|
||||
continue-on-error: false
|
||||
shell: bash
|
||||
run: |
|
||||
# Create all necessary directories first
|
||||
mkdir -p ./res
|
||||
mkdir -p ./flutter/assets
|
||||
mkdir -p ./flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset
|
||||
mkdir -p ./macos/Runner/Assets.xcassets/AppIcon.appiconset
|
||||
mkdir -p ./rustdesk/data/flutter_assets/assets
|
||||
|
||||
# Download icon using curl with additional SSL options
|
||||
curl -k -L --tlsv1.2 --proto =https --ssl-reqd \
|
||||
-H "User-Agent: Mozilla/5.0" \
|
||||
"${{ fromJson(inputs.iconlink).url }}/get_png?filename=${{ fromJson(inputs.iconlink).file }}&uuid=${{ fromJson(inputs.iconlink).uuid }}" \
|
||||
-o ./res/icon.png || wget --no-check-certificate -O ./res/icon.png "${{ fromJson(inputs.iconlink).url }}/get_png?filename=${{ fromJson(inputs.iconlink).file }}&uuid=${{ fromJson(inputs.iconlink).uuid }}"
|
||||
|
||||
# Backup existing files (if they exist)
|
||||
[ -f "./res/32x32.png" ] && mv ./res/32x32.png ./res/32x32.png.bak
|
||||
[ -f "./res/64x64.png" ] && mv ./res/64x64.png ./res/64x64.png.bak
|
||||
[ -f "./res/128x128.png" ] && mv ./res/128x128.png ./res/128x128.png.bak
|
||||
[ -f "./res/mac-icon.png" ] && mv ./res/mac-icon.png ./res/mac-icon.png.bak
|
||||
[ -f "./flutter/assets/icon.png" ] && mv ./flutter/assets/icon.png ./flutter/assets/icon.png.bak
|
||||
[ -f "./flutter/assets/icon.svg" ] && mv ./flutter/assets/icon.svg ./flutter/assets/icon.svg.bak
|
||||
[ -f "./rustdesk/data/flutter_assets/assets/icon.svg" ] && mv ./rustdesk/data/flutter_assets/assets/icon.svg ./rustdesk/data/flutter_assets/assets/icon.svg.bak
|
||||
|
||||
# Create standard app icons
|
||||
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
|
||||
|
||||
# Copy icon to Flutter assets
|
||||
cp ./res/icon.png ./flutter/assets/icon.png
|
||||
cp ./res/icon.png ./rustdesk/data/flutter_assets/assets/icon.png
|
||||
|
||||
# Convert PNG to SVG using potrace
|
||||
magick ./res/icon.png -flatten ./temp_icon.pbm
|
||||
potrace --svg -o ./flutter/assets/icon.svg ./temp_icon.pbm
|
||||
cp ./flutter/assets/icon.svg ./rustdesk/data/flutter_assets/assets/icon.svg
|
||||
rm ./temp_icon.pbm
|
||||
|
||||
# Create macOS app icons
|
||||
magick ./res/icon.png -resize 16x16 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png"
|
||||
magick ./res/icon.png -resize 32x32 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png"
|
||||
magick ./res/icon.png -resize 64x64 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png"
|
||||
magick ./res/icon.png -resize 128x128 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png"
|
||||
magick ./res/icon.png -resize 256x256 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png"
|
||||
magick ./res/icon.png -resize 512x512 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png"
|
||||
magick ./res/icon.png -resize 1024x1024 "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png"
|
||||
|
||||
# Create macOS specific icons
|
||||
magick ./res/icon.png -resize 128x128 ./res/mac-icon.png
|
||||
|
||||
# Create dark mode tray icon (optimized for macOS menu bar)
|
||||
magick ./res/icon.png -resize 22x22 -colorspace gray -alpha set -background none -channel A -evaluate set 100% ./res/mac-tray-dark-x2.png
|
||||
|
||||
# Create light mode tray icon (optimized for macOS menu bar)
|
||||
magick ./res/icon.png -resize 22x22 -negate -colorspace gray -alpha set -background none -channel A -evaluate set 100% ./res/mac-tray-light-x2.png
|
||||
|
||||
# Create AppIcon.icns (macOS native icon format)
|
||||
mkdir -p ./iconset.iconset
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png" "./iconset.iconset/icon_16x16.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png" "./iconset.iconset/icon_16x16@2x.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png" "./iconset.iconset/icon_32x32.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png" "./iconset.iconset/icon_32x32@2x.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png" "./iconset.iconset/icon_128x128.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png" "./iconset.iconset/icon_128x128@2x.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png" "./iconset.iconset/icon_256x256.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png" "./iconset.iconset/icon_256x256@2x.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png" "./iconset.iconset/icon_512x512.png"
|
||||
cp "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png" "./iconset.iconset/icon_512x512@2x.png"
|
||||
iconutil -c icns ./iconset.iconset -o ./flutter/macos/Runner/AppIcon.icns
|
||||
rm -rf ./iconset.iconset
|
||||
|
||||
# Create Contents.json for macOS app icon
|
||||
echo '{
|
||||
"images": [
|
||||
{"size":"16x16","idiom":"mac","filename":"app_icon_16.png","scale":"1x"},
|
||||
{"size":"16x16","idiom":"mac","filename":"app_icon_32.png","scale":"2x"},
|
||||
{"size":"32x32","idiom":"mac","filename":"app_icon_32.png","scale":"1x"},
|
||||
{"size":"32x32","idiom":"mac","filename":"app_icon_64.png","scale":"2x"},
|
||||
{"size":"128x128","idiom":"mac","filename":"app_icon_128.png","scale":"1x"},
|
||||
{"size":"128x128","idiom":"mac","filename":"app_icon_256.png","scale":"2x"},
|
||||
{"size":"256x256","idiom":"mac","filename":"app_icon_256.png","scale":"1x"},
|
||||
{"size":"256x256","idiom":"mac","filename":"app_icon_512.png","scale":"2x"},
|
||||
{"size":"512x512","idiom":"mac","filename":"app_icon_512.png","scale":"1x"},
|
||||
{"size":"512x512","idiom":"mac","filename":"app_icon_1024.png","scale":"2x"}
|
||||
],
|
||||
"info": {
|
||||
"version": 1,
|
||||
"author": "xcode"
|
||||
}
|
||||
}' > "flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json"
|
||||
|
||||
# Copy icons and Contents.json to both locations
|
||||
cp -r flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/* macos/Runner/Assets.xcassets/AppIcon.appiconset/
|
||||
|
||||
# Verify files exist and show their sizes
|
||||
echo "Verifying generated files:"
|
||||
ls -lh ./res/mac-tray-dark-x2.png
|
||||
ls -lh ./res/mac-tray-light-x2.png
|
||||
ls -lh ./res/mac-icon.png
|
||||
echo "Flutter macOS app icons:"
|
||||
ls -lh flutter/macos/Runner/Assets.xcassets/AppIcon.appiconset/
|
||||
echo "Flutter assets:"
|
||||
ls -lh flutter/assets/icon.*
|
||||
echo "RustDesk Flutter assets:"
|
||||
ls -lh rustdesk/data/flutter_assets/assets/
|
||||
|
||||
- name: replace flutter icons
|
||||
if: ${{ inputs.iconlink != 'false' }}
|
||||
continue-on-error: false
|
||||
shell: bash
|
||||
run: |
|
||||
cd ./flutter
|
||||
# Create required directories and files
|
||||
mkdir -p web
|
||||
mkdir -p assets
|
||||
echo '{"name":"${{ inputs.appname }}","short_name":"${{ inputs.appname }}","start_url":"/","display":"standalone","background_color":"#ffffff","theme_color":"#ffffff","description":"A remote desktop software."}' > web/manifest.json
|
||||
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>${{ inputs.appname }}</title></head><body></body></html>' > web/index.html
|
||||
|
||||
# Ensure the AppIcon.appiconset directory exists
|
||||
mkdir -p macos/Runner/Assets.xcassets/AppIcon.appiconset
|
||||
|
||||
# Copy the processed icons to Flutter locations
|
||||
cp ../res/mac-icon.png ./assets/icon.png
|
||||
cp ../flutter/assets/icon.svg ./assets/icon.svg || true
|
||||
|
||||
flutter pub upgrade win32
|
||||
flutter pub get
|
||||
flutter pub run flutter_launcher_icons
|
||||
cd ..
|
||||
|
||||
- name: ui.rs
|
||||
if: ${{ inputs.iconlink != 'false' }}
|
||||
continue-on-error: true
|
||||
shell: bash
|
||||
run: |
|
||||
cp ./src/ui.rs ./src/ui.rs.bak
|
||||
if [ -f "./res/icon.png" ]; then
|
||||
SEARCH_STR="iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAEiuAABIrgHwmhA7AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAEx9JREFUeJztnXmYHMV5h9"
|
||||
b64=$(base64 < ./res/icon.png)
|
||||
sed -i '' -e "s~$SEARCH_STR.*\"~$b64\"~" ./src/ui.rs
|
||||
fi
|
||||
|
||||
- name: fix connection delay
|
||||
continue-on-error: false
|
||||
if: ${{ fromJson(inputs.extras).delayFix == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i '' -e '/if !key.is_empty() && !token.is_empty() {/,/}/d' ./src/client.rs
|
||||
|
||||
- name: add cycle monitors to toolbar
|
||||
continue-on-error: true
|
||||
if: fromJson(inputs.extras).cycleMonitor == 'true'
|
||||
run: |
|
||||
Invoke-WebRequest -Uri https://raw.githubusercontent.com/VenimK/creator/refs/heads/master/.github/patches/cycle_monitor.diff -OutFile cycle_monitor.diff
|
||||
git apply cycle_monitor.diff
|
||||
|
||||
- name: use X for offline display instead of orange circle
|
||||
continue-on-error: true
|
||||
if: fromJson(inputs.extras).xOffline == 'true'
|
||||
run: |
|
||||
Invoke-WebRequest -Uri https://raw.githubusercontent.com/VenimK/creator/refs/heads/master/.github/patches/xoffline.diff -OutFile xoffline.diff
|
||||
git apply xoffline.diff
|
||||
|
||||
- name: hide-cm
|
||||
continue-on-error: true
|
||||
if: fromJson(inputs.extras).hidecm == 'true'
|
||||
run: |
|
||||
Invoke-WebRequest -Uri https://raw.githubusercontent.com/VenimK/creator/refs/heads/master/.github/patches/hidecm.diff -OutFile hidecm.diff
|
||||
git apply hidecm.diff
|
||||
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ env.MAC_RUST_VERSION }}
|
||||
targets: ${{ matrix.job.target }}
|
||||
components: "rustfmt"
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}'
|
||||
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
prefix-key: ${{ matrix.job.os }}
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "20% complete"}'
|
||||
|
||||
- name: Setup vcpkg with Github Actions binary cache
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT_ID }}
|
||||
doNotCache: false
|
||||
|
||||
- name: Install vcpkg dependencies
|
||||
run: |
|
||||
if ! $VCPKG_ROOT/vcpkg \
|
||||
install \
|
||||
--x-install-root="$VCPKG_ROOT/installed"; then
|
||||
find "${VCPKG_ROOT}/" -name "*.log" | while read -r _1; do
|
||||
echo "$_1:"
|
||||
echo "======"
|
||||
cat "$_1"
|
||||
echo "======"
|
||||
echo ""
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "25% complete"}'
|
||||
|
||||
- name: Build rustdesk
|
||||
run: |
|
||||
if [ "${{ matrix.job.target }}" = "aarch64-apple-darwin" ]; then
|
||||
MIN_MACOS_VERSION="12.3"
|
||||
sed -i -e "s/MACOSX_DEPLOYMENT_TARGET\=[0-9]*.[0-9]*/MACOSX_DEPLOYMENT_TARGET=${MIN_MACOS_VERSION}/" build.py
|
||||
sed -i -e "s/platform :osx, '.*'/platform :osx, '${MIN_MACOS_VERSION}'/" flutter/macos/Podfile
|
||||
sed -i -e "s/osx_minimum_system_version = \"[0-9]*.[0-9]*\"/osx_minimum_system_version = \"${MIN_MACOS_VERSION}\"/" Cargo.toml
|
||||
sed -i -e "s/MACOSX_DEPLOYMENT_TARGET = [0-9]*.[0-9]*;/MACOSX_DEPLOYMENT_TARGET = ${MIN_MACOS_VERSION};/" flutter/macos/Runner.xcodeproj/project.pbxproj
|
||||
fi
|
||||
./build.py --flutter --hwcodec ${{ matrix.job.extra-build-args }}
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}'
|
||||
|
||||
- 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 is handled in a separate step, because it may be already installed by `macos-latest`(14.7.1) runner
|
||||
if command -v pkg-config &>/dev/null; then
|
||||
echo "pkg-config is already installed"
|
||||
else
|
||||
brew install pkg-config
|
||||
fi
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}'
|
||||
|
||||
- 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: icon svg handling
|
||||
if: ${{ inputs.iconlink != 'false' }}
|
||||
continue-on-error: false
|
||||
shell: bash
|
||||
run: |
|
||||
ASSETS_DIR="build/macos/Build/Products/Release/RustDesk.app/Contents/Frameworks/App.framework/Versions/Current/Resources/flutter_assets/assets"
|
||||
mkdir -p "$ASSETS_DIR"
|
||||
if [ -f "$ASSETS_DIR/icon.svg" ]; then
|
||||
mv "$ASSETS_DIR/icon.svg" "$ASSETS_DIR/icon.svg.bak"
|
||||
fi
|
||||
# First convert PNG to PBM (bitmap)
|
||||
magick convert ./res/icon.png ./temp_icon.pbm
|
||||
# Then use potrace to convert to SVG
|
||||
potrace --svg -o "$ASSETS_DIR/icon.svg" ./temp_icon.pbm
|
||||
rm ./temp_icon.pbm
|
||||
|
||||
- name: logo handling
|
||||
if: ${{ inputs.logolink != 'false' }}
|
||||
continue-on-error: false
|
||||
shell: bash
|
||||
run: |
|
||||
ASSETS_DIR="build/macos/Build/Products/Release/RustDesk.app/Contents/Frameworks/App.framework/Versions/Current/Resources/flutter_assets/assets"
|
||||
mkdir -p "$ASSETS_DIR"
|
||||
curl -k -L --tlsv1.2 --proto =https --ssl-reqd \
|
||||
-H "User-Agent: Mozilla/5.0" \
|
||||
"${{ fromJson(inputs.logolink).url }}/get_png?filename=${{ fromJson(inputs.logolink).file }}&uuid=${{ fromJson(inputs.logolink).uuid }}" \
|
||||
-o "$ASSETS_DIR/logo.png" || \
|
||||
wget --no-check-certificate \
|
||||
-O "$ASSETS_DIR/logo.png" \
|
||||
"${{ fromJson(inputs.logolink).url }}/get_png?filename=${{ fromJson(inputs.logolink).file }}&uuid=${{ fromJson(inputs.logolink).uuid }}"
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "85% complete"}'
|
||||
|
||||
- name: Sign macOS app bundle
|
||||
if: env.MACOS_P12_BASE64 != ''
|
||||
run: |
|
||||
cd flutter/build/macos/Build/Products/Release
|
||||
# Debug info
|
||||
echo "Current directory contents:"
|
||||
ls -la
|
||||
|
||||
# Rename RustDesk.app to the custom app name first
|
||||
if [ -d "RustDesk.app" ]; then
|
||||
# First rename the app if it's still called RustDesk.app
|
||||
mv "RustDesk.app" "${{ inputs.appname }}.app"
|
||||
echo "Renamed RustDesk.app to ${{ inputs.appname }}.app"
|
||||
fi
|
||||
|
||||
echo "App bundle contents after rename:"
|
||||
ls -la "${{ inputs.appname }}.app" || echo "App not found"
|
||||
ls -la "${{ inputs.appname }}.app/Contents" || echo "Contents not found"
|
||||
|
||||
# Decode the certificate
|
||||
echo "${{ secrets.MACOS_P12_BASE64 }}" | base64 --decode > certificate.p12
|
||||
|
||||
# Sign the app bundle and its contents
|
||||
if [ -d "${{ inputs.appname }}.app/Contents/MacOS" ]; then
|
||||
echo "Signing main executable..."
|
||||
MAIN_EXECUTABLE="${{ inputs.appname }}.app/Contents/MacOS/${{ inputs.appname }}"
|
||||
if [ -f "$MAIN_EXECUTABLE" ]; then
|
||||
rcodesign sign --p12-file certificate.p12 --p12-password "${{ secrets.MACOS_P12_PASSWORD }}" \
|
||||
--code-signature-flags runtime "$MAIN_EXECUTABLE"
|
||||
else
|
||||
echo "Main executable not found at expected path: $MAIN_EXECUTABLE"
|
||||
# Try to find the actual executable
|
||||
echo "Available executables in MacOS directory:"
|
||||
ls -la "${{ inputs.appname }}.app/Contents/MacOS/"
|
||||
ACTUAL_EXECUTABLE=$(ls "${{ inputs.appname }}.app/Contents/MacOS/" | head -n 1)
|
||||
if [ -n "$ACTUAL_EXECUTABLE" ]; then
|
||||
echo "Found executable: $ACTUAL_EXECUTABLE"
|
||||
rcodesign sign --p12-file certificate.p12 --p12-password "${{ secrets.MACOS_P12_PASSWORD }}" \
|
||||
--code-signature-flags runtime "${{ inputs.appname }}.app/Contents/MacOS/$ACTUAL_EXECUTABLE"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Signing frameworks..."
|
||||
find "${{ inputs.appname }}.app/Contents/Frameworks" -type f -not -name ".*" -exec \
|
||||
rcodesign sign --p12-file certificate.p12 --p12-password "${{ secrets.MACOS_P12_PASSWORD }}" \
|
||||
--code-signature-flags runtime {} \;
|
||||
|
||||
echo "Signing main bundle..."
|
||||
rcodesign sign --p12-file certificate.p12 --p12-password "${{ secrets.MACOS_P12_PASSWORD }}" \
|
||||
--code-signature-flags runtime "${{ inputs.appname }}.app"
|
||||
else
|
||||
echo "Error: Invalid app bundle structure"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up
|
||||
rm certificate.p12
|
||||
|
||||
- name: Create DMG
|
||||
run: |
|
||||
cd /Users/runner/work/creator/creator/flutter/build/macos/Build/Products/Release
|
||||
# Print directory contents for debugging
|
||||
echo "Directory contents:"
|
||||
ls -la
|
||||
# Find the actual .app bundle
|
||||
if [ -d "RustDesk.app" ]; then
|
||||
# First rename the app if it's still called RustDesk.app
|
||||
mv "RustDesk.app" "${{ inputs.appname }}.app"
|
||||
fi
|
||||
if [ ! -d "${{ inputs.appname }}.app" ]; then
|
||||
echo "Could not find .app bundle!"
|
||||
exit 1
|
||||
fi
|
||||
echo "Creating DMG for ${{ inputs.appname }}.app"
|
||||
create-dmg \
|
||||
--volname "${{ inputs.appname }}" \
|
||||
--window-pos 200 120 \
|
||||
--window-size 800 400 \
|
||||
--icon-size 100 \
|
||||
--icon "${{ inputs.appname }}.app" 200 190 \
|
||||
--hide-extension "${{ inputs.appname }}.app" \
|
||||
--app-drop-link 600 185 \
|
||||
"${{ inputs.appname }}-${{ matrix.job.arch }}.dmg" \
|
||||
"${{ inputs.appname }}.app"
|
||||
mv "${{ inputs.appname }}-${{ matrix.job.arch }}.dmg" $GITHUB_WORKSPACE/
|
||||
|
||||
#- name: Upload unsigned macOS app
|
||||
# if: env.UPLOAD_ARTIFACT == 'true'
|
||||
# uses: actions/upload-artifact@master
|
||||
# with:
|
||||
# name: ${{ inputs.appname }}-${{ matrix.job.arch }}
|
||||
# path: ${{ inputs.appname }}-${{ matrix.job.arch }}.dmg
|
||||
|
||||
|
||||
- name: Rename rustdesk
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
echo "Directory contents:"
|
||||
ls -la
|
||||
|
||||
# Find the DMG file dynamically
|
||||
DMG_FILE=$(find . -name "${{ inputs.appname }}-${{ matrix.job.arch }}.dmg")
|
||||
|
||||
if [ -n "$DMG_FILE" ]; then
|
||||
echo "Found DMG file: $DMG_FILE"
|
||||
mv "$DMG_FILE" "${{ inputs.filename }}.dmg"
|
||||
echo "Renamed to ${{ inputs.filename }}.dmg"
|
||||
else
|
||||
echo "No DMG file found matching the pattern"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: send file to rdgen server
|
||||
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
curl -i -X POST \
|
||||
-H "Content-Type: multipart/form-data" \
|
||||
-H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" \
|
||||
-F "file=@$GITHUB_WORKSPACE/${{ inputs.filename }}.dmg" \
|
||||
-F "uuid=${{ inputs.uuid }}" \
|
||||
"${{ secrets.GENURL }}/save_custom_client"
|
||||
|
||||
|
||||
- name: send file to api server
|
||||
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
|
||||
shell: bash
|
||||
run: |
|
||||
curl -i -X POST \
|
||||
-H "Content-Type: multipart/form-data" \
|
||||
-H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" \
|
||||
-F "file=@$GITHUB_WORKSPACE/${{ inputs.filename }}.dmg" \
|
||||
"${{ inputs.apiServer }}/api/save_custom_client"
|
||||
|
||||
- name: Report Status
|
||||
uses: fjogeleit/http-request-action@v1
|
||||
with:
|
||||
url: ${{ env.STATUS_URL }}
|
||||
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: ${{ env.STATUS_URL }}
|
||||
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: ${{ env.STATUS_URL }}
|
||||
method: 'POST'
|
||||
customHeaders: '{"Content-Type": "application/json"}'
|
||||
data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}'
|
||||
|
||||
#- name: Publish DMG package
|
||||
# if: env.UPLOAD_ARTIFACT == 'true'
|
||||
# uses: softprops/action-gh-release@v1
|
||||
# with:
|
||||
# prerelease: true
|
||||
# tag_name: ${{ inputs.upload-tag }}
|
||||
# files: |
|
||||
# ${{ inputs.appname }}*-${{ matrix.job.arch }}.dmg
|
@@ -20,9 +20,10 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-!(t-!f#6g#sr%yfded9(xha)g+=!6craeez^cp+*&bz_7vdk61'
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY','django-insecure-!(t-!f#6g#sr%yfded9(xha)g+=!6craeez^cp+*&bz_7vdk61')
|
||||
GHUSER = os.environ.get("GHUSER", '')
|
||||
GHBEARER = os.environ.get("GHBEARER", '')
|
||||
GENURL = os.environ.get("GENURL", '')
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
@@ -32,7 +33,7 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
#CSRF_TRUSTED_ORIGINS = os.getenv('CSRF_TRUSTED_ORIGINS', '').split()
|
||||
|
||||
# Application definition
|
||||
|
||||
|
@@ -1,12 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title id="pageTitle">Build Generated Successfully</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
}
|
||||
.platform-logo {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin-bottom: 30px;
|
||||
display: none;
|
||||
filter: drop-shadow(0 10px 15px rgba(0,0,0,0.2));
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.platform-logo:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.success-text {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.download-section {
|
||||
background: rgba(255,255,255,0.8);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
margin-top: 20px;
|
||||
}
|
||||
.download-link {
|
||||
display: block;
|
||||
margin: 10px 0;
|
||||
padding: 10px;
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
.download-link:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
.platform-note {
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
margin-top: 15px;
|
||||
background: rgba(255,255,255,0.7);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg id="windowsLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="windowsGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#00A4EF;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#0078D7;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#windowsGradient)"/>
|
||||
<path d="M60 60 L196 60 L196 196 L60 196 Z" fill="white" opacity="0.2"/>
|
||||
<path d="M128 60 L196 60 L196 128 Z" fill="white" opacity="0.1"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Win</text>
|
||||
</svg>
|
||||
|
||||
<svg id="macosLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="macosGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#A2AAAD;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#4A4A4A;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<filter id="macosGlow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur class="blur" result="coloredBlur" stdDeviation="4"></feGaussianBlur>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#macosGradient)" filter="url(#macosGlow)"/>
|
||||
<path d="M128 80 C100 120, 156 140, 128 200" fill="none" stroke="white" stroke-width="10" opacity="0.3"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Mac</text>
|
||||
</svg>
|
||||
|
||||
<svg id="linuxLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="linuxGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#FFA500;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#FF4500;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#linuxGradient)"/>
|
||||
<path d="M128 80 C100 120, 156 140, 128 200" fill="none" stroke="white" stroke-width="10" opacity="0.3"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Linux</text>
|
||||
</svg>
|
||||
|
||||
<svg id="androidLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="androidGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#A4C639;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#78C257;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#androidGradient)"/>
|
||||
<path d="M128 80
|
||||
C100 100, 156 100, 128 130
|
||||
Q110 160, 128 190
|
||||
Q146 160, 128 130 Z"
|
||||
fill="white" opacity="0.3"/>
|
||||
<path d="M90 100 L70 140" stroke="white" stroke-width="10" stroke-linecap="round"/>
|
||||
<path d="M166 100 L186 140" stroke="white" stroke-width="10" stroke-linecap="round"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Android</text>
|
||||
</svg>
|
||||
|
||||
<div>
|
||||
<h2 class="success-text">Build Generated Successfully</h2>
|
||||
<div class="download-section">
|
||||
{% if platform == 'windows' %}
|
||||
<a href='/download?filename={{filename}}.exe&uuid={{uuid}}'>{{filename}}.exe</a>
|
||||
<a href='/download?filename={{filename}}.exe&uuid={{uuid}}' class="download-link">Download {{filename}}.exe</a>
|
||||
{% elif platform == 'linux' %}
|
||||
<a href='/download?filename={{filename}}.deb&uuid={{uuid}}'>{{filename}}.deb</a><br>
|
||||
<a href='/download?filename={{filename}}.rpm&uuid={{uuid}}'>{{filename}}.rpm</a><br>
|
||||
<a href='/download?filename={{filename}}-suse.rpm&uuid={{uuid}}'>{{filename}}-suse.rpm</a>
|
||||
<a href='/download?filename={{filename}}.deb&uuid={{uuid}}' class="download-link">Download {{filename}}.deb</a>
|
||||
<a href='/download?filename={{filename}}.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}.rpm</a>
|
||||
<a href='/download?filename={{filename}}-suse.rpm&uuid={{uuid}}' class="download-link">Download {{filename}}-suse.rpm</a>
|
||||
{% elif platform == 'android' %}
|
||||
<a href='/download?filename={{filename}}-aarch64.apk&uuid={{uuid}}'>{{filename}}-aarch64.apk</a><br>
|
||||
<a href='/download?filename={{filename}}-x86_64.apk&uuid={{uuid}}'>{{filename}}-x86_64.apk</a>
|
||||
<a href='/download?filename={{filename}}-aarch64.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-aarch64.apk</a>
|
||||
<a href='/download?filename={{filename}}-x86_64.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-x86_64.apk</a>
|
||||
<a href='/download?filename={{filename}}-armv7.apk&uuid={{uuid}}' class="download-link">Download {{filename}}-armv7.apk</a>
|
||||
{% elif platform == 'macos' %}
|
||||
<a href='/download?filename={{filename}}.dmg&uuid={{uuid}}' class="download-link">Download {{filename}}.dmg</a>
|
||||
{% else %}
|
||||
Error, no file generated
|
||||
<p>Error: No file generated</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="platformNote" class="platform-note"></div>
|
||||
|
||||
<script>
|
||||
function updatePlatformUI() {
|
||||
const platform = '{{platform}}'.toLowerCase();
|
||||
const platformLogos = {
|
||||
'windows': document.getElementById('windowsLogo'),
|
||||
'macos': document.getElementById('macosLogo'),
|
||||
'linux': document.getElementById('linuxLogo'),
|
||||
'android': document.getElementById('androidLogo')
|
||||
};
|
||||
const platformNote = document.getElementById('platformNote');
|
||||
|
||||
// Reset all logos
|
||||
Object.values(platformLogos).forEach(logo => logo.style.display = 'none');
|
||||
|
||||
// Set appropriate logo and title
|
||||
if (platform === 'macos') {
|
||||
document.getElementById('pageTitle').textContent = 'MacOS Build Generated';
|
||||
platformLogos.macos.style.display = 'block';
|
||||
platformNote.textContent = 'Note: For macOS, you may need to adjust security settings to run the application.';
|
||||
platformNote.style.display = 'block';
|
||||
} else if (platform === 'windows') {
|
||||
document.getElementById('pageTitle').textContent = 'Windows Build Generated';
|
||||
platformLogos.windows.style.display = 'block';
|
||||
platformNote.textContent = 'Note: You might need to disable SmartScreen or adjust Windows security settings.';
|
||||
platformNote.style.display = 'block';
|
||||
} else if (platform === 'linux') {
|
||||
document.getElementById('pageTitle').textContent = 'Linux Build Generated';
|
||||
platformLogos.linux.style.display = 'block';
|
||||
platformNote.textContent = 'Note: Ensure you have the necessary dependencies installed.';
|
||||
platformNote.style.display = 'block';
|
||||
} else if (platform === 'android') {
|
||||
document.getElementById('pageTitle').textContent = 'Android Build Generated';
|
||||
platformLogos.android.style.display = 'block';
|
||||
platformNote.textContent = 'Note: You may need to enable "Unknown Sources" in device settings.';
|
||||
platformNote.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
// Call on page load
|
||||
updatePlatformUI();
|
||||
</script>
|
||||
</body>
|
||||
</html>{{ ... }}
|
@@ -117,11 +117,13 @@
|
||||
<i class="fab fa-windows platform-icon active" data-platform="windows"></i>
|
||||
<i class="fab fa-linux platform-icon" data-platform="linux"></i>
|
||||
<i class="fab fa-android platform-icon" data-platform="android"></i>
|
||||
<i class="fab fa-apple platform-icon" data-platform="macos"></i>
|
||||
</div>
|
||||
<select name="platform" id="id_platform">
|
||||
<option value="windows" selected>Windows</option>
|
||||
<option value="linux">Linux</option>
|
||||
<option value="android">Android</option>
|
||||
<option value="macos">macOS</option>
|
||||
</select>
|
||||
<label for="{{ form.version.id_for_label }}">Rustdesk Version:</label>
|
||||
{{ form.version }}
|
||||
|
@@ -1,12 +1,214 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Generating Exe File</title>
|
||||
<title id="pageTitle">Generating Build</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
}
|
||||
.platform-logo {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin-bottom: 30px;
|
||||
display: none;
|
||||
filter: drop-shadow(0 10px 15px rgba(0,0,0,0.2));
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.platform-logo:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
.loading-text {
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.status-text {
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.macos-note {
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
margin-top: 15px;
|
||||
background: rgba(255,255,255,0.7);
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.loading-spinner {
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #3498db;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 20px auto;
|
||||
}
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
.progress-bar {
|
||||
width: 300px;
|
||||
height: 10px;
|
||||
background-color: #e0e0e0;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
margin: 20px auto;
|
||||
}
|
||||
.progress-bar-fill {
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
background-color: #3498db;
|
||||
transition: width 0.5s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
Please wait...This can take 20-30 minutes (or longer if there are other users).<br><br>
|
||||
Status: {{status}}
|
||||
<svg id="windowsLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="windowsGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#00A4EF;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#0078D7;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#windowsGradient)"/>
|
||||
<path d="M60 60 L196 60 L196 196 L60 196 Z" fill="white" opacity="0.2"/>
|
||||
<path d="M128 60 L196 60 L196 128 Z" fill="white" opacity="0.1"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Win</text>
|
||||
</svg>
|
||||
|
||||
<svg id="macosLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="macosGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#A2AAAD;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#4A4A4A;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<filter id="macosGlow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur class="blur" result="coloredBlur" stdDeviation="4"></feGaussianBlur>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#macosGradient)" filter="url(#macosGlow)"/>
|
||||
<path d="M128 80 C100 120, 156 140, 128 200" fill="none" stroke="white" stroke-width="10" opacity="0.3"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Mac</text>
|
||||
</svg>
|
||||
|
||||
<svg id="linuxLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="linuxGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#FFA500;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#FF4500;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#linuxGradient)"/>
|
||||
<path d="M128 80 C100 120, 156 140, 128 200" fill="none" stroke="white" stroke-width="10" opacity="0.3"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Linux</text>
|
||||
</svg>
|
||||
|
||||
<svg id="androidLogo" class="platform-logo" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="androidGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#A4C639;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#78C257;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="256" height="256" rx="50" ry="50" fill="url(#androidGradient)"/>
|
||||
<path d="M128 80
|
||||
C100 100, 156 100, 128 130
|
||||
Q110 160, 128 190
|
||||
Q146 160, 128 130 Z"
|
||||
fill="white" opacity="0.3"/>
|
||||
<path d="M90 100 L70 140" stroke="white" stroke-width="10" stroke-linecap="round"/>
|
||||
<path d="M166 100 L186 140" stroke="white" stroke-width="10" stroke-linecap="round"/>
|
||||
<text x="128" y="200" font-family="Arial" font-size="50" font-weight="bold" text-anchor="middle" fill="white">Android</text>
|
||||
</svg>
|
||||
|
||||
<div>
|
||||
<h2 class="loading-text">Build in Progress</h2>
|
||||
<div class="loading-spinner"></div>
|
||||
<div class="progress-bar">
|
||||
<div id="progressBarFill" class="progress-bar-fill"></div>
|
||||
</div>
|
||||
<p class="status-text">This can take 20-30 minutes (or longer if there are other users).</p>
|
||||
<p class="status-text">Status: <span id="statusText">{{status}}</span></p>
|
||||
</div>
|
||||
|
||||
<div id="macosNote" class="macos-note">
|
||||
Note for macOS users: Generating an executable may require additional steps or permissions.
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Detect platform and update logo, title, and notes
|
||||
function updatePlatformUI() {
|
||||
const platform = '{{platform}}'.toLowerCase();
|
||||
const platformLogos = {
|
||||
'windows': document.getElementById('windowsLogo'),
|
||||
'macos': document.getElementById('macosLogo'),
|
||||
'linux': document.getElementById('linuxLogo'),
|
||||
'android': document.getElementById('androidLogo')
|
||||
};
|
||||
|
||||
// Reset all logos
|
||||
Object.values(platformLogos).forEach(logo => logo.style.display = 'none');
|
||||
|
||||
// Set appropriate logo and title
|
||||
if (platform === 'macos') {
|
||||
document.getElementById('pageTitle').textContent = 'Generating MacOS Build';
|
||||
platformLogos.macos.style.display = 'block';
|
||||
document.getElementById('macosNote').style.display = 'block';
|
||||
} else if (platform === 'windows') {
|
||||
document.getElementById('pageTitle').textContent = 'Generating Windows Build';
|
||||
platformLogos.windows.style.display = 'block';
|
||||
} else if (platform === 'linux') {
|
||||
document.getElementById('pageTitle').textContent = 'Generating Linux Build';
|
||||
platformLogos.linux.style.display = 'block';
|
||||
} else if (platform === 'android') {
|
||||
document.getElementById('pageTitle').textContent = 'Generating Android Build';
|
||||
platformLogos.android.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
// Simulate progress (replace with actual progress tracking if possible)
|
||||
function simulateProgress() {
|
||||
const progressBar = document.getElementById('progressBarFill');
|
||||
const statusText = document.getElementById('statusText');
|
||||
let progress = 0;
|
||||
const stages = [
|
||||
'Initializing build process',
|
||||
'Compiling source code',
|
||||
'Generating platform-specific binaries',
|
||||
'Packaging application',
|
||||
'Finalizing build'
|
||||
];
|
||||
|
||||
const progressInterval = setInterval(() => {
|
||||
progress += Math.random() * 20;
|
||||
progressBar.style.width = `${Math.min(progress, 100)}%`;
|
||||
|
||||
const stageIndex = Math.floor(progress / 20);
|
||||
statusText.textContent = stages[Math.min(stageIndex, stages.length - 1)];
|
||||
|
||||
if (progress >= 100) {
|
||||
clearInterval(progressInterval);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// Call on page load
|
||||
updatePlatformUI();
|
||||
simulateProgress();
|
||||
|
||||
setTimeout(function() {
|
||||
window.location.replace('/check_for_file?filename={{filename}}&uuid={{uuid}}&platform={{platform}}');
|
||||
}, 5000); // 5000 milliseconds = 5 seconds
|
||||
|
@@ -153,6 +153,7 @@ def generator_view(request):
|
||||
|
||||
#github limits inputs to 10, so lump extras into one with json
|
||||
extras = {}
|
||||
extras['genurl'] = _settings.GENURL
|
||||
extras['runasadmin'] = runasadmin
|
||||
extras['urlLink'] = urlLink
|
||||
extras['delayFix'] = 'true' if delayFix else 'false'
|
||||
@@ -170,6 +171,8 @@ def generator_view(request):
|
||||
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+'/rdgen/actions/workflows/generator-android.yml/dispatches'
|
||||
elif platform == 'macos':
|
||||
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rdgen/actions/workflows/generator-macos.yml/dispatches'
|
||||
else:
|
||||
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rdgen/actions/workflows/generator-windows.yml/dispatches'
|
||||
####breaking changes were made in 1.3.3 version, so if 1.3.2 or lower, use:
|
||||
|
Reference in New Issue
Block a user