Files
GenericAgent/.github/workflows/macos-desktop-release-package.yml
T
yiqi-017 87bc3bd14a feat(conductor): follow desktop-selected model live + build on test_yiqi
Conductor and its subagents always used the first model (llm_no=0)
because GenericAgent() defaults to index 0 and conductor never switched.
Read ui.llmNo from ~/.ga_desktop_settings.json and apply it before each
conductor task (live follow) and on every subagent spawn, so the
conductor uses whatever model the user picked in the desktop UI.

Also enable the three desktop package workflows on the test_yiqi branch
and add frontends/conductor.py to their path filters so conductor
changes trigger a build.
2026-06-19 00:26:11 +08:00

223 lines
8.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Build macOS Desktop Portable Package
"on":
push:
branches:
- test
- test_yiqi
paths:
- ".github/workflows/macos-desktop-release-package.yml"
- "desktop_release/scripts/macos/install_macos.sh"
- "frontends/desktop/**"
- "frontends/conductor.py"
workflow_dispatch:
inputs:
upload_release:
description: "Upload package to GitHub prerelease"
required: false
default: "true"
type: choice
options:
- "true"
- "false"
permissions:
contents: write
jobs:
build-macos:
name: Build macOS portable runtime package
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: Install frontend dependencies
working-directory: frontends/desktop
run: npm install
- name: Build Tauri app
working-directory: frontends/desktop
run: npm run tauri build -- --bundles app
- name: Assemble portable package
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
PKG_ROOT="artifacts/macos/GenericAgent-Desktop-macOS"
RUNTIME="$PKG_ROOT/runtime"
mkdir -p "$PKG_ROOT" "$RUNTIME"
APP_SRC="$(find frontends/desktop/src-tauri/target/release/bundle/macos -maxdepth 1 -name '*.app' -type d | head -n 1)"
test -n "$APP_SRC"
# Use ditto (not cp -R) so symlinks, resource forks and the ad-hoc
# code signature inside the .app bundle survive the copy. A broken
# signature is what makes Apple Silicon report the app as "damaged".
ditto "$APP_SRC" "$PKG_ROOT/GenericAgent.app"
# Re-apply an ad-hoc signature so the bundle verifies cleanly.
codesign --force --deep --sign - "$PKG_ROOT/GenericAgent.app"
codesign --verify --deep --strict "$PKG_ROOT/GenericAgent.app" || true
cp desktop_release/scripts/macos/install_macos.sh "$RUNTIME/install_macos.sh"
chmod +x "$RUNTIME/install_macos.sh"
# Embedded Python (python-build-standalone, macOS universal2 preferred, 3.12 install_only).
PBS_URL="$(python3 - <<'PY'
import json, os, urllib.request
api='https://api.github.com/repos/astral-sh/python-build-standalone/releases/latest'
req=urllib.request.Request(api)
token=os.environ.get('GH_TOKEN')
if token:
req.add_header('Authorization', 'Bearer ' + token)
data=json.load(urllib.request.urlopen(req, timeout=60))
assets=data.get('assets', [])
patterns=[
('aarch64-apple-darwin', 'install_only.tar.gz'),
('x86_64-apple-darwin', 'install_only.tar.gz'),
]
for arch, suffix in patterns:
for a in assets:
name=a.get('name','')
if 'cpython-3.12' in name and arch in name and name.endswith(suffix) and 'stripped' not in name:
print(a['browser_download_url'])
raise SystemExit
raise SystemExit('No suitable python-build-standalone macOS asset found')
PY
)"
echo "Using python-build-standalone: $PBS_URL"
curl -L --fail --retry 3 -o /tmp/pbs-macos.tar.gz "$PBS_URL"
mkdir -p "$RUNTIME/python"
tar -xzf /tmp/pbs-macos.tar.gz -C "$RUNTIME"
# python-build-standalone install_only archives contain python/ at archive root.
test -x "$RUNTIME/python/bin/python3"
PY="$RUNTIME/python/bin/python3"
"$PY" --version
mkdir -p "$RUNTIME/wheels"
"$PY" -m pip download --dest "$RUNTIME/wheels" \
"requests>=2.28" "beautifulsoup4>=4.12" "bottle>=0.12" \
"simple-websocket-server>=0.4" "aiohttp>=3.9" psutil \
fastapi uvicorn websockets pydantic setuptools wheel
mkdir -p "$RUNTIME/app"
tar \
--exclude='.git' \
--exclude='artifacts' \
--exclude='frontends/desktop/node_modules' \
--exclude='frontends/desktop/src-tauri/target' \
--exclude='**/__pycache__' \
--exclude='**/.venv' \
-cf - . | tar -xf - -C "$RUNTIME/app"
test -f "$RUNTIME/app/agentmain.py"
test -f "$RUNTIME/app/frontends/desktop_bridge.py"
test -f "$RUNTIME/app/frontends/desktop/static/index.html"
# One-click launcher: strips the com.apple.quarantine attribute the OS
# adds to downloaded files, then opens the app. This sidesteps the
# "GenericAgent.app is damaged" Gatekeeper error without the user
# having to run xattr in a terminal.
cat > "$PKG_ROOT/Start GenericAgent.command" <<'EOF'
#!/bin/bash
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
xattr -cr "$DIR/GenericAgent.app" 2>/dev/null || true
open "$DIR/GenericAgent.app"
EOF
chmod +x "$PKG_ROOT/Start GenericAgent.command"
cat > "$PKG_ROOT/README_MACOS.md" <<'EOF'
# GenericAgent Desktop macOS Portable
这是自包含 macOS portable 包:`GenericAgent.app`、内置 Python、离线 wheels、运行源码都在同一个目录中。
## 使用
推荐:双击 `Start GenericAgent.command` 启动。它会自动清除 macOS 下载隔离
标记(com.apple.quarantine)后打开 app,避免“GenericAgent.app 已损坏”提示。
也可以直接双击 `GenericAgent.app`。如果系统提示已损坏或来自未知开发者:
- 右键 `GenericAgent.app` -> 打开,或在系统设置 -> 隐私与安全性中允许;
- 或在终端执行:`xattr -cr /path/to/GenericAgent.app`。
解压后请保持目录结构不变。
## 目录结构
```text
GenericAgent-Desktop-macOS/
├── GenericAgent.app
├── Start GenericAgent.command 一键启动(自动解除隔离)
├── README_MACOS.md
├── SHA256SUMS.txt
└── runtime/
├── python/ 内置 Python
├── wheels/ 离线依赖
├── install_macos.sh 首次准备脚本
└── app/ 运行所需源码(含 desktop_bridge.py)
```
`runtime/` 是内置运行环境与源码,正常使用无需改动。
EOF
sed -i '' 's/^ //' "$PKG_ROOT/README_MACOS.md"
(
cd "$PKG_ROOT"
shasum -a 256 README_MACOS.md "Start GenericAgent.command" > SHA256SUMS.txt
find GenericAgent.app runtime -type f -print0 | sort -z | xargs -0 shasum -a 256 >> SHA256SUMS.txt
)
mkdir -p artifacts/macos/out
(cd artifacts/macos && zip -qry out/GenericAgent-Desktop-macOS.zip GenericAgent-Desktop-macOS)
cp "$PKG_ROOT/SHA256SUMS.txt" artifacts/macos/out/SHA256SUMS-macOS.txt
echo "Package tree (top levels):"
find "$PKG_ROOT" -maxdepth 2 -print | sort | head -80
- name: Upload workflow artifact
uses: actions/upload-artifact@v4
with:
name: GenericAgent-Desktop-macOS-Portable-${{ github.run_number }}
path: artifacts/macos/out/*
if-no-files-found: error
- name: Publish prerelease
if: ${{ github.event_name == 'push' || inputs.upload_release == 'true' }}
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
TAG_NAME="desktop-test-macos-latest"
TITLE="GenericAgent Desktop macOS Portable (test latest)"
NOTES=$(cat <<'EOF'
macOS self-contained desktop portable package built from the test branch.
Includes:
- GenericAgent.app
- runtime/python
- runtime/wheels
- runtime/app
- README_MACOS.md and SHA256SUMS-macOS.txt
EOF
)
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
gh release upload "$TAG_NAME" artifacts/macos/out/* --clobber
else
gh release create "$TAG_NAME" artifacts/macos/out/* \
--target "${{ github.sha }}" \
--title "$TITLE" \
--notes "$NOTES" \
--prerelease
fi