Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
35ea67f
feat: add desktop wrapper with frontend-only packaging
zouyonghe Feb 7, 2026
635990e
docs: add desktop build docs and track dashboard lockfile
zouyonghe Feb 7, 2026
dc2dbe8
fix: track desktop lockfile for npm ci
zouyonghe Feb 7, 2026
a99f3ab
fix: allow custom install directory for windows installer
zouyonghe Feb 7, 2026
f0cf0f3
chore: migrate desktop workflow to pnpm
zouyonghe Feb 8, 2026
78fb066
fix(desktop): build AppImage only on Linux
zouyonghe Feb 8, 2026
44fdafb
fix(desktop): harden packaged startup and backend bundling
zouyonghe Feb 8, 2026
43a3420
fix(desktop): adapt packaged restart and plugin dependency flow
zouyonghe Feb 8, 2026
6417182
fix(desktop): prevent backend respawn race on quit
zouyonghe Feb 8, 2026
470bf7d
fix(desktop): prefer pyproject version for desktop packaging
zouyonghe Feb 8, 2026
66fe0ce
fix(desktop): improve startup loading UX and reduce flicker
zouyonghe Feb 8, 2026
b1a9ca7
ci: add desktop multi-platform release workflow
zouyonghe Feb 8, 2026
ed2a616
ci: fix desktop release build and mac runner labels
zouyonghe Feb 8, 2026
52759a2
ci: disable electron-builder auto publish in desktop build
zouyonghe Feb 8, 2026
3644e36
ci: avoid electron-builder publish path in build matrix
zouyonghe Feb 8, 2026
6567533
ci: normalize desktop release artifact names
zouyonghe Feb 8, 2026
b6f5c18
ci: exclude blockmap files from desktop release assets
zouyonghe Feb 8, 2026
a29028f
ci: prefix desktop release assets with AstrBot and purge blockmaps
zouyonghe Feb 8, 2026
53d629d
feat: add electron bridge types and expose backend control methods in…
Soulter Feb 8, 2026
ae7fdf7
Update startup screen assets and styles
Soulter Feb 8, 2026
04b05ee
Update .gitignore to include package.json
Soulter Feb 8, 2026
c9084b8
chore: remove desktop gitkeep ignore exceptions
zouyonghe Feb 8, 2026
ff8059b
docs: update desktop troubleshooting for current runtime behavior
zouyonghe Feb 8, 2026
99dd297
refactor(desktop): modularize runtime and harden startup flow
zouyonghe Feb 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions .github/workflows/desktop_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
name: Desktop Release

on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
ref:
description: "Git ref to build (branch/tag/SHA)"
required: false
default: "master"
tag:
description: "Release tag to upload assets to (for example: v4.14.6)"
required: false

permissions:
contents: write

jobs:
build-desktop:
name: Build ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- name: linux-x64
runner: ubuntu-24.04
os: linux
arch: amd64
- name: linux-arm64
runner: ubuntu-24.04-arm
os: linux
arch: arm64
- name: windows-x64
runner: windows-2022
os: win
arch: amd64
- name: windows-arm64
runner: windows-11-arm
os: win
arch: arm64
- name: macos-x64
runner: macos-15-intel
os: mac
arch: amd64
- name: macos-arm64
runner: macos-15
os: mac
arch: arm64
env:
CSC_IDENTITY_AUTO_DISCOVERY: "false"
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ inputs.ref || github.ref }}

- name: Setup uv
uses: astral-sh/setup-uv@v6

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: "3.11"

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.28.2

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 20
cache: "pnpm"
cache-dependency-path: |
dashboard/pnpm-lock.yaml
desktop/pnpm-lock.yaml

- name: Install dependencies
run: |
uv sync
pnpm --dir dashboard install --frozen-lockfile
pnpm --dir desktop install --frozen-lockfile

- name: Build desktop package
run: |
pnpm --dir dashboard run build
pnpm --dir desktop run build:webui
pnpm --dir desktop run build:backend
pnpm --dir desktop run sync:version
pnpm --dir desktop exec electron-builder --publish never

- name: Resolve artifact tag
id: tag
shell: bash
run: |
if [ "${{ github.event_name }}" = "push" ]; then
tag="${GITHUB_REF_NAME}"
elif [ -n "${{ inputs.tag }}" ]; then
tag="${{ inputs.tag }}"
else
tag="$(git describe --tags --abbrev=0)"
fi
if [ -z "$tag" ]; then
echo "Failed to resolve artifact tag." >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"

- name: Normalize artifact names
shell: bash
env:
NAME_PREFIX: AstrBot-${{ steps.tag.outputs.tag }}-${{ matrix.arch }}-${{ matrix.os }}
run: |
shopt -s nullglob
out_dir="desktop/dist/release"
mkdir -p "$out_dir"
files=(
desktop/dist/*.AppImage
desktop/dist/*.dmg
desktop/dist/*.zip
desktop/dist/*.exe
)
if [ ${#files[@]} -eq 0 ]; then
echo "No desktop artifacts found to rename." >&2
exit 1
fi
for src in "${files[@]}"; do
file="$(basename "$src")"
case "$file" in
*.AppImage)
dest="$out_dir/${NAME_PREFIX}.AppImage"
;;
*.dmg)
dest="$out_dir/${NAME_PREFIX}.dmg"
;;
*.exe)
dest="$out_dir/${NAME_PREFIX}.exe"
;;
*.zip)
dest="$out_dir/${NAME_PREFIX}.zip"
;;
*)
continue
;;
esac
cp "$src" "$dest"
done
ls -la "$out_dir"

- name: Upload desktop artifacts
uses: actions/upload-artifact@v6
with:
name: AstrBot-${{ steps.tag.outputs.tag }}-${{ matrix.arch }}-${{ matrix.os }}
if-no-files-found: error
path: desktop/dist/release/*

publish-release:
name: Publish Release Assets
runs-on: ubuntu-24.04
needs: build-desktop
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ inputs.ref || github.ref }}

- name: Resolve release tag
id: tag
shell: bash
run: |
if [ "${{ github.event_name }}" = "push" ]; then
tag="${GITHUB_REF_NAME}"
elif [ -n "${{ inputs.tag }}" ]; then
tag="${{ inputs.tag }}"
else
tag="$(git describe --tags --abbrev=0)"
fi
if [ -z "$tag" ]; then
echo "Failed to resolve release tag." >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"

- name: Download built artifacts
uses: actions/download-artifact@v6
with:
pattern: AstrBot-${{ steps.tag.outputs.tag }}-*
path: release-assets
merge-multiple: true

- name: Ensure release exists
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
tag="${{ steps.tag.outputs.tag }}"
if ! gh release view "$tag" >/dev/null 2>&1; then
gh release create "$tag" --title "$tag" --notes ""
fi

- name: Remove stale desktop assets from release
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
tag="${{ steps.tag.outputs.tag }}"
while IFS= read -r asset; do
case "$asset" in
*.AppImage|*.dmg|*.zip|*.exe|*.blockmap)
gh release delete-asset "$tag" "$asset" -y || true
;;
esac
done < <(gh release view "$tag" --json assets --jq '.assets[].name')

- name: Upload assets to release
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
tag="${{ steps.tag.outputs.tag }}"
gh release upload "$tag" release-assets/* --clobber
11 changes: 9 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,15 @@ tests/astrbot_plugin_openai
# Dashboard
dashboard/node_modules/
dashboard/dist/
.pnpm-store/
desktop/node_modules/
desktop/dist/
desktop/out/
desktop/resources/backend/astrbot-backend*
desktop/resources/backend/*.exe
desktop/resources/webui/*
desktop/resources/.pyinstaller/
package-lock.json
package.json
yarn.lock

# Operating System
Expand All @@ -53,4 +60,4 @@ IFLOW.md

# genie_tts data
CharacterModels/
GenieData/
GenieData/
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ uv run main.py

或者请参阅官方文档 [通过源码部署 AstrBot](https://astrbot.app/deploy/astrbot/cli.html) 。

#### 桌面端 Electron 打包

桌面端(Electron 打包,`pnpm` 工作流)构建流程请参阅:[`desktop/README.md`](desktop/README.md)。

## 支持的消息平台

**官方维护**
Expand Down Expand Up @@ -269,4 +273,3 @@ _陪伴与能力从来不应该是对立面。我们希望创造的是一个既
_私は、高性能ですから!_

<img src="https://files.astrbot.app/watashiwa-koseino-desukara.gif" width="100"/>

4 changes: 4 additions & 0 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ uv run main.py

Or refer to the official documentation: [Deploy AstrBot from Source](https://astrbot.app/deploy/astrbot/cli.html).

#### Desktop Electron Build

For desktop build steps (Electron packaging, `pnpm` workflow), see [`desktop/README.md`](desktop/README.md).

## Supported Messaging Platforms

**Officially Maintained**
Expand Down
10 changes: 8 additions & 2 deletions astrbot/core/updator.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,20 @@ def _reboot(self, delay: int = 3):
py = sys.executable

try:
if "astrbot" in os.path.basename(sys.argv[0]): # 兼容cli
# 仅 CLI 模式走 `python -m astrbot.cli.__main__`,
# 打包后的后端可执行文件需要直接 exec 自身。
if os.environ.get("ASTRBOT_CLI") == "1":
if os.name == "nt":
args = [f'"{arg}"' if " " in arg else arg for arg in sys.argv[1:]]
else:
args = sys.argv[1:]
os.execl(sys.executable, py, "-m", "astrbot.cli.__main__", *args)
else:
os.execl(sys.executable, py, *sys.argv)
if getattr(sys, "frozen", False):
# Frozen executable should not receive argv[0] as a positional argument.
os.execl(sys.executable, py, *sys.argv[1:])
else:
os.execl(sys.executable, py, *sys.argv)
except Exception as e:
logger.error(f"重启失败({py}, {e}),请尝试手动重启。")
raise e
Expand Down
6 changes: 6 additions & 0 deletions astrbot/core/utils/astrbot_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
WebChat 数据目录路径:固定为数据目录下的 webchat 目录
临时文件目录路径:固定为数据目录下的 temp 目录
Skills 目录路径:固定为数据目录下的 skills 目录
第三方依赖目录路径:固定为数据目录下的 site-packages 目录
"""

import os
Expand Down Expand Up @@ -69,6 +70,11 @@ def get_astrbot_skills_path() -> str:
return os.path.realpath(os.path.join(get_astrbot_data_path(), "skills"))


def get_astrbot_site_packages_path() -> str:
"""获取Astrbot第三方依赖目录路径"""
return os.path.realpath(os.path.join(get_astrbot_data_path(), "site-packages"))


def get_astrbot_knowledge_base_path() -> str:
"""获取Astrbot知识库根目录路径"""
return os.path.realpath(os.path.join(get_astrbot_data_path(), "knowledge_base"))
Expand Down
Loading