ci(macos): add macos build
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
name: build-macos
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [pro-features]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_suffix:
|
||||
description: "Version suffix (e.g. 'cst', 'beta1'). Empty = vanilla."
|
||||
type: string
|
||||
default: "cst"
|
||||
|
||||
env:
|
||||
RUST_VERSION: "1.81" # MAC_RUST_VERSION upstream (cidre needs >=1.81)
|
||||
FLUTTER_VERSION: "3.24.5"
|
||||
VCPKG_COMMIT_ID: "120deac3062162151622ca4860575a33844ba10b"
|
||||
CARGO_EXPAND_VERSION: "1.0.95"
|
||||
FLUTTER_RUST_BRIDGE_VERSION: "1.80.1"
|
||||
VERSION_BASE: "1.4.6"
|
||||
VERSION_SUFFIX: ${{ inputs.version_suffix || 'cst' }}
|
||||
|
||||
jobs:
|
||||
build-x64:
|
||||
name: build-macos-x64
|
||||
# Intel Mac runner. provision.sh tags x86_64 macOS hosts with the X64 label.
|
||||
runs-on: [self-hosted, macOS, X64]
|
||||
timeout-minutes: 240
|
||||
env:
|
||||
VCPKG_ROOT: /opt/vcpkg
|
||||
VCPKG_BINARY_SOURCES: "clear;files,/var/cache/vcpkg,readwrite"
|
||||
VCPKG_DEFAULT_TRIPLET: x64-osx
|
||||
VCPKG_DEFAULT_HOST_TRIPLET: x64-osx
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Verify host toolchain
|
||||
shell: bash
|
||||
run: |
|
||||
required=(git bash python3 rustc cargo rustup clang flutter cmake ninja nasm pkg-config create-dmg)
|
||||
missing=()
|
||||
for t in "${required[@]}"; do
|
||||
if command -v "$t" >/dev/null 2>&1; then
|
||||
printf '%-15s %s\n' "$t" "$(command -v "$t")"
|
||||
else
|
||||
missing+=("$t")
|
||||
printf '%-15s MISSING\n' "$t"
|
||||
fi
|
||||
done
|
||||
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||
echo "Missing tools: ${missing[*]}. Re-run provision.sh on the runner host."
|
||||
exit 1
|
||||
fi
|
||||
[[ -d "$VCPKG_ROOT" && -x "$VCPKG_ROOT/vcpkg" ]] || {
|
||||
echo "VCPKG_ROOT=$VCPKG_ROOT invalid"; exit 1; }
|
||||
|
||||
- name: Compute version strings
|
||||
shell: bash
|
||||
run: |
|
||||
base="${VERSION_BASE}"
|
||||
suffix="${VERSION_SUFFIX}"
|
||||
[[ "$base" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
|
||||
echo "VERSION_BASE '$base' must be major.minor.patch"; exit 1; }
|
||||
if [[ -n "$suffix" ]]; then display="${base}-${suffix}"; else display="${base}"; fi
|
||||
echo "Display : $display"
|
||||
echo "VERSION_DISPLAY=$display" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Patch Cargo.toml with display version
|
||||
shell: bash
|
||||
run: |
|
||||
# BSD sed (macOS): -i requires an empty backup-suffix arg.
|
||||
sed -i '' -E "1,/^version[[:space:]]*=/{s/^version[[:space:]]*=[[:space:]]*\"${VERSION_BASE}\"/version = \"${VERSION_DISPLAY}\"/;}" Cargo.toml
|
||||
grep '^version' Cargo.toml | head -1
|
||||
|
||||
# No deployment-target patch on x86_64: build.py's build_flutter_dmg()
|
||||
# already exports MACOSX_DEPLOYMENT_TARGET=10.14 internally, matching the
|
||||
# Flutter Xcode project. Upstream only patches the target for arm64
|
||||
# (which needs 12.3+).
|
||||
|
||||
- name: Ensure Rust toolchain configured
|
||||
shell: bash
|
||||
run: |
|
||||
rustup toolchain install "$RUST_VERSION" --profile minimal --component rustfmt
|
||||
rustup default "$RUST_VERSION"
|
||||
rustup target add x86_64-apple-darwin
|
||||
rustc --version
|
||||
cargo --version
|
||||
|
||||
- name: Install flutter_rust_bridge codegen tools
|
||||
shell: bash
|
||||
run: |
|
||||
tools=/opt/cargo-tools
|
||||
mkdir -p "$tools/bin"
|
||||
cargo install --root "$tools" cargo-expand --version "$CARGO_EXPAND_VERSION" --locked
|
||||
cargo install --root "$tools" flutter_rust_bridge_codegen --version "$FLUTTER_RUST_BRIDGE_VERSION" --features uuid --locked
|
||||
ls -la "$tools/bin"
|
||||
[[ -x "$tools/bin/flutter_rust_bridge_codegen" ]] || { echo "missing fr_bridge_codegen"; exit 1; }
|
||||
echo "$tools/bin" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Generate Rust <-> Dart bridge (with Flutter 3.22.3)
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
# Same dual-SDK trick as Linux: bridge codegen 1.80.1 produces broken
|
||||
# Dart on Flutter 3.24.5; provision.sh installs 3.22.3 at
|
||||
# /opt/flutter-bridge for codegen only. Switch back to 3.24.5 after.
|
||||
export PATH="/opt/cargo-tools/bin:/opt/flutter-bridge/bin:$PATH"
|
||||
flutter --version
|
||||
command -v flutter_rust_bridge_codegen
|
||||
|
||||
# Match the Linux fix: don't pass --llvm-path, let ffigen find Xcode
|
||||
# CLT's libclang via system defaults. Passing brew's llvm or a custom
|
||||
# libclang path triggered fr_bridge_codegen 1.80.1's bad-emission bug
|
||||
# (stray `typedef bool = NativeFunction<...>`) on Linux; same logic
|
||||
# carries over here.
|
||||
unset LIBCLANG_PATH
|
||||
|
||||
(cd flutter && sed -i '' -e 's/extended_text: 14.0.0/extended_text: 13.0.0/g' pubspec.yaml)
|
||||
(cd flutter && flutter pub get)
|
||||
|
||||
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
|
||||
cp ./flutter/macos/Runner/bridge_generated.h ./flutter/ios/Runner/bridge_generated.h
|
||||
|
||||
(cd flutter && git checkout -- pubspec.yaml)
|
||||
(cd flutter && /opt/flutter/bin/flutter pub get)
|
||||
|
||||
- name: Diagnose generated bridge files
|
||||
shell: bash
|
||||
run: |
|
||||
set +e
|
||||
echo "============================================================"
|
||||
echo " generated_bridge.dart (first 80 lines)"
|
||||
echo "============================================================"
|
||||
head -80 flutter/lib/generated_bridge.dart 2>/dev/null || echo "(missing)"
|
||||
echo
|
||||
echo "============================================================"
|
||||
echo " Search: typedef declarations that might shadow bool/Int/Pointer"
|
||||
echo "============================================================"
|
||||
grep -nE 'typedef (bool|Int|Pointer|Bool)' \
|
||||
flutter/lib/generated_bridge.dart \
|
||||
flutter/lib/generated_bridge.freezed.dart 2>/dev/null || echo "(no shadowing typedefs)"
|
||||
|
||||
- name: vcpkg install dependencies (x64-osx)
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p /var/cache/vcpkg
|
||||
if ! "$VCPKG_ROOT/vcpkg" install \
|
||||
--triplet x64-osx \
|
||||
--x-install-root="$VCPKG_ROOT/installed"; then
|
||||
find "$VCPKG_ROOT/" -name '*.log' -exec sh -c 'echo "===== {} ====="; cat "{}"' \;
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build RustDesk (.app + .dmg)
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
# build.py -> build_flutter_dmg() does:
|
||||
# - MACOSX_DEPLOYMENT_TARGET=10.14 cargo build --features <features> --release
|
||||
# - cp liblibrustdesk.dylib librustdesk.dylib
|
||||
# - flutter build macos --release
|
||||
# - cp -rf ../target/release/service .../RustDesk.app/Contents/MacOS/
|
||||
# It does NOT package the .dmg (the create-dmg call is commented out).
|
||||
# We package below.
|
||||
#
|
||||
# No --screencapturekit on x86_64: upstream's matrix only enables it
|
||||
# on aarch64 (cidre's ScreenCaptureKit bindings target arm64-only APIs).
|
||||
python3 build.py --flutter --hwcodec --unix-file-copy-paste
|
||||
|
||||
mkdir -p ./SignOutput
|
||||
# Patch create-dmg's unmount-attempts upward (CI runners are flaky).
|
||||
CREATE_DMG="$(command -v create-dmg)"
|
||||
CREATE_DMG_REAL="$(readlink "$CREATE_DMG" 2>/dev/null || echo "$CREATE_DMG")"
|
||||
# readlink may return relative; resolve.
|
||||
[[ "$CREATE_DMG_REAL" == /* ]] || CREATE_DMG_REAL="$(cd "$(dirname "$CREATE_DMG")" && pwd)/$CREATE_DMG_REAL"
|
||||
sed -i '' -e 's/MAXIMUM_UNMOUNTING_ATTEMPTS=3/MAXIMUM_UNMOUNTING_ATTEMPTS=7/' "$CREATE_DMG_REAL" || true
|
||||
|
||||
create-dmg \
|
||||
--icon "RustDesk.app" 200 190 \
|
||||
--hide-extension "RustDesk.app" \
|
||||
--window-size 800 400 \
|
||||
--app-drop-link 600 185 \
|
||||
"./SignOutput/rustdesk-${VERSION_DISPLAY}-x86_64.dmg" \
|
||||
./flutter/build/macos/Build/Products/Release/RustDesk.app
|
||||
|
||||
- name: Report signing status of build artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
for f in ./SignOutput/*.dmg; do
|
||||
[[ -f "$f" ]] || continue
|
||||
size=$(stat -f%z "$f")
|
||||
sig=$(codesign -dv "$f" 2>&1 | grep -E '^Authority' | head -1 || true)
|
||||
if [[ -z "$sig" ]]; then
|
||||
printf '[UNSIGNED] %s (%d bytes)\n' "$(basename "$f")" "$size"
|
||||
else
|
||||
printf '[ SIGNED ] %s (%d bytes) %s\n' "$(basename "$f")" "$size" "$sig"
|
||||
fi
|
||||
done
|
||||
echo "::warning title=Unsigned .dmg::Wire up codesign + notarytool before distributing."
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: rustdesk-macos-x64-${{ github.sha }}
|
||||
path: SignOutput/rustdesk-*.dmg
|
||||
if-no-files-found: warn
|
||||
retention-days: 14
|
||||
Executable
+291
@@ -0,0 +1,291 @@
|
||||
#!/usr/bin/env bash
|
||||
# Provisions a macOS host (Apple Silicon, macOS 14+) as a Gitea Actions runner
|
||||
# for RustDesk desktop (.dmg) builds. Idempotent: safe to re-run.
|
||||
#
|
||||
# Versions are pinned to .gitea/workflows/build-macos.yml. Bump them there and
|
||||
# here together.
|
||||
#
|
||||
# Usage:
|
||||
# sudo ./provision.sh \
|
||||
# --gitea-url https://gitea.example.com \
|
||||
# --runner-token <token>
|
||||
#
|
||||
# Toolchains land in /opt/* (chowned to the runner user). Service is installed
|
||||
# as a LaunchDaemon running as that user.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ---- pinned versions (mirror .gitea/workflows/build-macos.yml env block) ----
|
||||
RUST_VERSION="1.81.0" # MAC_RUST_VERSION upstream (cidre crate needs >=1.81)
|
||||
FLUTTER_VERSION="3.24.5" # used for `flutter build macos`
|
||||
FLUTTER_BRIDGE_VERSION="3.22.3" # used for `flutter pub get` + flutter_rust_bridge_codegen
|
||||
VCPKG_COMMIT="120deac3062162151622ca4860575a33844ba10b"
|
||||
NASM_VERSION="2.16.03" # 3.x has incompatible CLI; aom/dav1d need 2.x
|
||||
RUNNER_VERSION="0.2.11"
|
||||
|
||||
# ---- defaults ----
|
||||
RUNNER_NAME="$(hostname -s)-rustdesk"
|
||||
RUNNER_LABELS=""
|
||||
SERVICE_USER="gitea-runner"
|
||||
GITEA_URL=""
|
||||
RUNNER_TOKEN=""
|
||||
|
||||
# ---- arg parse ----
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--gitea-url) GITEA_URL="$2"; shift 2 ;;
|
||||
--runner-token) RUNNER_TOKEN="$2"; shift 2 ;;
|
||||
--runner-name) RUNNER_NAME="$2"; shift 2 ;;
|
||||
--runner-labels) RUNNER_LABELS="$2"; shift 2 ;;
|
||||
--service-user) SERVICE_USER="$2"; shift 2 ;;
|
||||
-h|--help)
|
||||
sed -n '2,15p' "$0"
|
||||
exit 0 ;;
|
||||
*) echo "Unknown arg: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ "$EUID" -eq 0 ]] || { echo "Run as root (use sudo)." >&2; exit 1; }
|
||||
[[ -n "$GITEA_URL" && -n "$RUNNER_TOKEN" ]] \
|
||||
|| { echo "Missing --gitea-url or --runner-token" >&2; exit 2; }
|
||||
|
||||
# ---- arch + macOS version detection ----
|
||||
ARCH="$(uname -m)"
|
||||
case "$ARCH" in
|
||||
arm64) HOMEBREW_PREFIX="/opt/homebrew"; ARCH_LABEL="ARM64" ;;
|
||||
x86_64) HOMEBREW_PREFIX="/usr/local"; ARCH_LABEL="X64" ;;
|
||||
*) echo "Unsupported arch: $ARCH" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
OS_MAJOR="$(sw_vers -productVersion | cut -d. -f1)"
|
||||
[[ "$OS_MAJOR" -ge 14 ]] || {
|
||||
echo "WARNING: tested only on macOS 14+. You're on $(sw_vers -productVersion)."
|
||||
sleep 3
|
||||
}
|
||||
DISTRO_LABEL="macos-${OS_MAJOR}"
|
||||
|
||||
if [[ -z "$RUNNER_LABELS" ]]; then
|
||||
RUNNER_LABELS="${DISTRO_LABEL},self-hosted,${ARCH_LABEL},macOS"
|
||||
fi
|
||||
|
||||
log() { printf '\n==> %s\n' "$*"; }
|
||||
|
||||
# ---- 1. Xcode Command Line Tools ----
|
||||
log "Verifying Xcode Command Line Tools"
|
||||
if ! /usr/bin/xcode-select -p >/dev/null 2>&1; then
|
||||
echo "Xcode Command Line Tools not installed. Run:" >&2
|
||||
echo " xcode-select --install" >&2
|
||||
echo "Then re-run this script." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo " $(xcode-select -p)"
|
||||
|
||||
# ---- 2. Homebrew (machine-wide) ----
|
||||
# Homebrew refuses to install under root (its installer aborts with
|
||||
# "Don't run this as root!"). It must be installed manually by a regular
|
||||
# user before this script runs.
|
||||
log "Verifying Homebrew"
|
||||
if [[ ! -x "$HOMEBREW_PREFIX/bin/brew" ]]; then
|
||||
echo "Homebrew not installed at $HOMEBREW_PREFIX." >&2
|
||||
echo "Install it as your regular user (NOT root), then re-run this script:" >&2
|
||||
echo " /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"" >&2
|
||||
exit 1
|
||||
fi
|
||||
export PATH="$HOMEBREW_PREFIX/bin:$PATH"
|
||||
echo " $(brew --version | head -1)"
|
||||
|
||||
# brew install must also run as a non-root user. Determine which user invoked
|
||||
# sudo so we can drop privileges for brew commands below.
|
||||
BREW_USER="${SUDO_USER:-}"
|
||||
if [[ -z "$BREW_USER" || "$BREW_USER" == "root" ]]; then
|
||||
echo "Could not determine the non-root user that ran sudo (SUDO_USER unset)." >&2
|
||||
echo "Re-run with: sudo ./provision.sh ..." >&2
|
||||
exit 1
|
||||
fi
|
||||
brew_as_user() { sudo -u "$BREW_USER" -H "$HOMEBREW_PREFIX/bin/brew" "$@"; }
|
||||
|
||||
# ---- 3. brew packages ----
|
||||
log "Installing brew packages"
|
||||
brew_pkgs=(llvm create-dmg pkg-config cmake ninja yasm autoconf automake libtool wget)
|
||||
for p in "${brew_pkgs[@]}"; do
|
||||
if brew_as_user list --versions "$p" >/dev/null 2>&1; then
|
||||
echo " $p (already installed)"
|
||||
else
|
||||
brew_as_user install "$p"
|
||||
fi
|
||||
done
|
||||
|
||||
# ---- 4. NASM 2.16.x (NOT brew's nasm 3.x; aom/dav1d need 2.x) ----
|
||||
if ! /usr/local/bin/nasm --version 2>/dev/null | grep -q "version $NASM_VERSION"; then
|
||||
log "Installing NASM $NASM_VERSION"
|
||||
tmp="$(mktemp -d)"
|
||||
curl -fsSL -o "$tmp/nasm.zip" \
|
||||
"https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/macosx/nasm-${NASM_VERSION}-macosx.zip"
|
||||
unzip -q "$tmp/nasm.zip" -d "$tmp"
|
||||
install -m 0755 "$tmp/nasm-${NASM_VERSION}/nasm" /usr/local/bin/nasm
|
||||
rm -rf "$tmp"
|
||||
fi
|
||||
/usr/local/bin/nasm --version | head -1
|
||||
|
||||
# ---- 5. dedicated runner user ----
|
||||
if ! /usr/bin/id -u "$SERVICE_USER" >/dev/null 2>&1; then
|
||||
log "Creating user $SERVICE_USER"
|
||||
# Find an unused UID >= 600
|
||||
uid=600
|
||||
while dscl . -list /Users UniqueID | awk '{print $2}' | grep -qx "$uid"; do
|
||||
uid=$((uid + 1))
|
||||
done
|
||||
dscl . -create "/Users/$SERVICE_USER"
|
||||
dscl . -create "/Users/$SERVICE_USER" UserShell /bin/bash
|
||||
dscl . -create "/Users/$SERVICE_USER" RealName "Gitea Runner"
|
||||
dscl . -create "/Users/$SERVICE_USER" UniqueID "$uid"
|
||||
dscl . -create "/Users/$SERVICE_USER" PrimaryGroupID 20
|
||||
dscl . -create "/Users/$SERVICE_USER" NFSHomeDirectory "/Users/$SERVICE_USER"
|
||||
mkdir -p "/Users/$SERVICE_USER"
|
||||
chown "$SERVICE_USER:staff" "/Users/$SERVICE_USER"
|
||||
fi
|
||||
RUNNER_HOME="/Users/$SERVICE_USER"
|
||||
|
||||
# ---- 6. Rust (machine-wide) ----
|
||||
export RUSTUP_HOME=/opt/rustup
|
||||
export CARGO_HOME=/opt/cargo
|
||||
mkdir -p "$RUSTUP_HOME" "$CARGO_HOME"
|
||||
|
||||
if [[ ! -x "$CARGO_HOME/bin/rustup" ]]; then
|
||||
log "Installing rustup at $RUSTUP_HOME / $CARGO_HOME"
|
||||
curl -fsSL https://sh.rustup.rs | RUSTUP_HOME="$RUSTUP_HOME" CARGO_HOME="$CARGO_HOME" \
|
||||
sh -s -- -y --default-toolchain none --profile minimal --no-modify-path
|
||||
fi
|
||||
"$CARGO_HOME/bin/rustup" toolchain install "$RUST_VERSION" --profile minimal --component rustfmt
|
||||
"$CARGO_HOME/bin/rustup" target add --toolchain "$RUST_VERSION" aarch64-apple-darwin x86_64-apple-darwin
|
||||
"$CARGO_HOME/bin/rustup" default "$RUST_VERSION"
|
||||
|
||||
# ---- 7. Flutter (two SDKs: 3.24.5 for build, 3.22.3 for bridge gen) ----
|
||||
# Same rationale as Linux: bridge codegen 1.80.1 + freezed produces broken Dart
|
||||
# under newer Flutter. Run codegen under 3.22.3, build under 3.24.5.
|
||||
install_flutter() {
|
||||
local ver="$1" dir="$2"
|
||||
if [[ ! -x "$dir/bin/flutter" ]]; then
|
||||
log "Installing Flutter $ver -> $dir"
|
||||
local tmp; tmp="$(mktemp -d)"
|
||||
local parent; parent="$(dirname "$dir")"
|
||||
# Flutter URL pattern differs between archs: Apple Silicon has an
|
||||
# `_arm64_` infix, Intel has no arch infix at all.
|
||||
local flutter_url_base="https://storage.googleapis.com/flutter_infra_release/releases/stable/macos/flutter_macos"
|
||||
local flutter_url
|
||||
case "$ARCH" in
|
||||
arm64) flutter_url="${flutter_url_base}_arm64_${ver}-stable.zip" ;;
|
||||
x86_64) flutter_url="${flutter_url_base}_${ver}-stable.zip" ;;
|
||||
esac
|
||||
curl -fsSL -o "$tmp/flutter.zip" "$flutter_url"
|
||||
mkdir -p "$parent"
|
||||
unzip -q "$tmp/flutter.zip" -d "$tmp"
|
||||
mv "$tmp/flutter" "$dir"
|
||||
rm -rf "$tmp"
|
||||
fi
|
||||
"$dir/bin/flutter" config --no-analytics >/dev/null
|
||||
"$dir/bin/flutter" precache --macos >/dev/null
|
||||
}
|
||||
install_flutter "$FLUTTER_VERSION" /opt/flutter
|
||||
install_flutter "$FLUTTER_BRIDGE_VERSION" /opt/flutter-bridge
|
||||
|
||||
# ---- 8. vcpkg ----
|
||||
VCPKG_DIR=/opt/vcpkg
|
||||
if [[ ! -d "$VCPKG_DIR/.git" ]]; then
|
||||
log "Cloning vcpkg"
|
||||
git clone https://github.com/microsoft/vcpkg.git "$VCPKG_DIR"
|
||||
fi
|
||||
git -C "$VCPKG_DIR" fetch --tags origin
|
||||
git -C "$VCPKG_DIR" -c advice.detachedHead=false checkout "$VCPKG_COMMIT"
|
||||
[[ -x "$VCPKG_DIR/vcpkg" ]] || "$VCPKG_DIR/bootstrap-vcpkg.sh" -disableMetrics
|
||||
|
||||
mkdir -p /var/cache/vcpkg
|
||||
chown -R "$SERVICE_USER:staff" /var/cache/vcpkg
|
||||
|
||||
# ---- 9. Permissions ----
|
||||
log "Setting up permissions for $SERVICE_USER"
|
||||
chown -R "$SERVICE_USER:staff" "$CARGO_HOME" "$RUSTUP_HOME" \
|
||||
/opt/flutter /opt/flutter-bridge "$VCPKG_DIR"
|
||||
mkdir -p /opt/cargo-tools
|
||||
chown -R "$SERVICE_USER:staff" /opt/cargo-tools
|
||||
|
||||
git config --system --add safe.directory '*' || true
|
||||
|
||||
# ---- 10. act_runner ----
|
||||
RUNNER_DIR="/usr/local/var/gitea-runner"
|
||||
mkdir -p "$RUNNER_DIR"
|
||||
chown -R "$SERVICE_USER:staff" "$RUNNER_DIR"
|
||||
|
||||
if [[ ! -x "$RUNNER_DIR/act_runner" ]]; then
|
||||
log "Downloading act_runner $RUNNER_VERSION"
|
||||
case "$ARCH" in
|
||||
arm64) rarch="arm64" ;;
|
||||
x86_64) rarch="amd64" ;;
|
||||
esac
|
||||
curl -fsSL -o "$RUNNER_DIR/act_runner" \
|
||||
"https://gitea.com/gitea/act_runner/releases/download/v${RUNNER_VERSION}/act_runner-${RUNNER_VERSION}-darwin-${rarch}"
|
||||
chmod +x "$RUNNER_DIR/act_runner"
|
||||
chown "$SERVICE_USER:staff" "$RUNNER_DIR/act_runner"
|
||||
fi
|
||||
|
||||
if [[ ! -f "$RUNNER_DIR/.runner" ]]; then
|
||||
log "Registering runner with $GITEA_URL"
|
||||
sudo -u "$SERVICE_USER" -H bash -c "
|
||||
cd '$RUNNER_DIR' && \
|
||||
./act_runner register --no-interactive \
|
||||
--instance '$GITEA_URL' \
|
||||
--token '$RUNNER_TOKEN' \
|
||||
--name '$RUNNER_NAME' \
|
||||
--labels '$RUNNER_LABELS'
|
||||
"
|
||||
fi
|
||||
|
||||
# ---- 11. launchd service ----
|
||||
log "Installing LaunchDaemon"
|
||||
PLIST=/Library/LaunchDaemons/com.rustdesk.gitea-runner.plist
|
||||
cat > "$PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.rustdesk.gitea-runner</string>
|
||||
<key>UserName</key>
|
||||
<string>${SERVICE_USER}</string>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>${RUNNER_DIR}</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>${RUNNER_DIR}/act_runner</string>
|
||||
<string>daemon</string>
|
||||
</array>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>RUSTUP_HOME</key> <string>${RUSTUP_HOME}</string>
|
||||
<key>CARGO_HOME</key> <string>${CARGO_HOME}</string>
|
||||
<key>VCPKG_ROOT</key> <string>${VCPKG_DIR}</string>
|
||||
<key>HOMEBREW_PREFIX</key> <string>${HOMEBREW_PREFIX}</string>
|
||||
<key>PATH</key>
|
||||
<string>${CARGO_HOME}/bin:/opt/flutter/bin:/opt/cargo-tools/bin:${HOMEBREW_PREFIX}/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
||||
</dict>
|
||||
<key>RunAtLoad</key> <true/>
|
||||
<key>KeepAlive</key> <true/>
|
||||
<key>StandardOutPath</key><string>${RUNNER_DIR}/stdout.log</string>
|
||||
<key>StandardErrorPath</key><string>${RUNNER_DIR}/stderr.log</string>
|
||||
<key>SoftResourceLimits</key>
|
||||
<dict>
|
||||
<key>NumberOfFiles</key> <integer>65535</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
chmod 0644 "$PLIST"
|
||||
|
||||
launchctl bootout system "$PLIST" 2>/dev/null || true
|
||||
launchctl bootstrap system "$PLIST"
|
||||
launchctl enable "system/com.rustdesk.gitea-runner"
|
||||
|
||||
log "Done."
|
||||
echo " Verify with: sudo launchctl print system/com.rustdesk.gitea-runner | head"
|
||||
echo " Tail logs with: tail -F $RUNNER_DIR/stderr.log"
|
||||
echo " Runner should appear (online) at $GITEA_URL > Site Admin > Actions > Runners"
|
||||
Reference in New Issue
Block a user