Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 15 additions & 11 deletions .github/workflows/build-launcher.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
name: build-launcher

# 一键启动器(tools/launcher.py → AnimaLoraStudio.exe)的构建。
# Build for the one-click launcher (tools/launcher.py -> AnimaLoraStudio.exe).
#
# PyInstaller 产出的是**宿主平台**的可执行文件,没法交叉编译 —— Windows 的 exe
# 只能在 windows runner 上出。Linux 的那份顺带一起出,方便本机 Linux 用户。
# PyInstaller produces an executable for the **host platform** — it can't cross-compile,
# so the Windows exe can only be built on a windows runner. The Linux one is built
# alongside it for the convenience of local Linux users.
#
# 触发:
# - 改到启动器源码的 PR / push → 只构建,作为「exe 还能编出来」的守门
# - 打 tag(v*)→ 构建并把 exe 传成 release 附件
# - 手动 workflow_dispatch
# Triggers:
# - PR / push touching the launcher source -> build only, as a gate that "the exe
# still builds"
# - tag push (v*) -> build and attach the exe as a release asset
# - manual workflow_dispatch
on:
pull_request:
paths:
Expand Down Expand Up @@ -42,8 +44,9 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
# 启动器只用标准库,但**它自己**得能在用户机器上跑。用 3.10 构建
# 让产物的 glibc / API 需求落在我们声明支持的最低版本上。
# The launcher itself only uses the standard library, but **it** still has to
# run on the user's machine. Building with 3.10 keeps the produced binary's
# glibc/API requirements at the minimum version we claim to support.
python-version: "3.10"

- name: Install PyInstaller
Expand All @@ -52,8 +55,9 @@ jobs:
- name: Build
run: python tools/build_launcher.py

# 冒烟:产物必须能跑起来并认出自己在仓库里(--check 不装任何东西)。
# 这一步能挡住"打包成功但一运行就缺模块"这类只有跑一次才暴露的问题。
# Smoke test: the built binary must actually run and recognize itself inside the
# repo (--check installs nothing). This step catches "packaged fine but missing a
# module at runtime" issues that only surface when you actually run it once.
- name: Smoke test
run: ${{ matrix.binary }} --check

Expand Down
47 changes: 27 additions & 20 deletions .github/workflows/publish-launcher.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
name: publish-launcher

# 构建 Windows 版 `AnimaLoraStudio.exe` 并**提交回仓库**。
# Builds the Windows `AnimaLoraStudio.exe` and **commits it back to the repo**.
#
# 为什么 exe 进 git(一般来说二进制不该进):本 fork 的目标用户是「clone 完
# 想双击就用」的本机用户。让他们先去 Releases 翻附件、或先装 PyInstaller 自己
# 编,等于把要省的那一步又加了回来。exe 只有 7MB 且极少变(只在
# tools/launcher.py 改动时需要重出),代价可以接受。
# Why the exe goes into git (binaries usually shouldn't): this fork's target users are
# people who "clone it and want to double-click it right away." Making them first dig
# through Releases for the attachment, or install PyInstaller and build it themselves,
# just adds back the step we're trying to save them. The exe is only ~7MB and rarely
# changes (only needs rebuilding when tools/launcher.py changes), so the cost is
# acceptable.
#
# 为什么必须走 CI 而不是本地编:PyInstaller 产出的是**宿主平台**的可执行文件,
# 不能交叉编译 —— Windows 的 exe 只能在 Windows 上出。维护者用 Linux/macOS 时
# 这个 workflow 是唯一的出路。
# Why this has to go through CI instead of a local build: PyInstaller produces an
# executable for the **host platform** — it can't cross-compile, so the Windows exe can
# only be built on Windows. This workflow is the only path for maintainers on
# Linux/macOS.
#
# 手动触发(Actions → publish-launcher → Run workflow)。刻意**不**挂到 push:
# PyInstaller 的输出不是逐字节可复现的,每次 push 都重出会让仓库无谓地长胖,
# 而且会和用户的 commit 抢同一分支。
# Manually triggered (Actions -> publish-launcher -> Run workflow). Deliberately **not**
# hooked to push: PyInstaller's output isn't byte-for-byte reproducible, so rebuilding on
# every push would bloat the repo for no reason and would race with users' own commits on
# the same branch.
#
# 常规的「exe 还编得出来吗」守门在 build-launcher.yml(每次改启动器源码时跑,
# 不提交任何东西)。
# The routine "does the exe still build" gate lives in build-launcher.yml (runs on every
# change to the launcher source, commits nothing).
on:
workflow_dispatch:
inputs:
Expand All @@ -38,7 +42,8 @@ jobs:

- uses: actions/setup-python@v5
with:
# 用支持的最低版本构建,产物的运行时要求才落在我们声明的下限上。
# Build with the lowest supported version so the binary's runtime requirements
# stay at the floor we claim to support.
python-version: "3.10"

- name: Install PyInstaller
Expand All @@ -47,9 +52,10 @@ jobs:
- name: Build
run: python tools/build_launcher.py

# 冒烟:产物必须真的能跑起来并认出自己在仓库里。--check 不装任何东西。
# 提交一个编得出来但一运行就报缺模块的 exe,比不提交更糟 —— 用户拿到的
# 是「双击没反应」,而仓库看起来一切正常。
# Smoke test: the built binary must actually run and recognize itself inside the
# repo. --check installs nothing. Committing an exe that builds fine but errors out
# on a missing module at runtime is worse than not committing at all — the user
# gets a "double-click does nothing" experience while the repo looks perfectly fine.
- name: Smoke test
run: |
Copy-Item dist\AnimaLoraStudio.exe .\AnimaLoraStudio.exe -Force
Expand All @@ -61,9 +67,10 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -f AnimaLoraStudio.exe
# PyInstaller 的输出每次都有字节差异(时间戳等),所以这里不能靠
# 「有 diff 就提交」判断有没有意义 —— 用 --quiet 只是为了跳过
# 「一个文件都没变」这种(理论上不会出现的)空提交。
# PyInstaller's output differs byte-for-byte every time (timestamps etc.), so
# "there's a diff" can't be used to decide whether committing is meaningful —
# --quiet here is only to skip the (theoretically impossible) case where
# literally nothing changed, to avoid an empty commit.
if git diff --cached --quiet; then
echo "nothing to commit"
exit 0
Expand Down
13 changes: 7 additions & 6 deletions .github/workflows/version-check.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: version-check

# 跨文件 version drift gate。v0.8.1 release 漏 bump package-lock.json,结果
# npm install 启动期把 lockfile 改脏 → ZIP 用户 self-update preflight 卡 dirty
# tree。这个 workflow 防同类回归。
# Cross-file version drift gate. The v0.8.1 release forgot to bump package-lock.json,
# which meant npm install dirtied the lockfile at startup -> ZIP users' self-update
# preflight got stuck on a dirty tree. This workflow guards against the same regression.
#
# 跑两件事:
# 1. release_notes.yaml schema 校验(validate)
# 2. __init__.py / package.json / package-lock.json 四处 version 一致(verify-versions)
# Runs two checks:
# 1. release_notes.yaml schema validation (validate)
# 2. version consistency across __init__.py / package.json / package-lock.json
# (verify-versions)
on:
pull_request:
push:
Expand Down
41 changes: 24 additions & 17 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ studio/web/node_modules/
studio/web/dist/
studio/web/.vite/

# 顶层意外创建的 node_modules(vitest / 某些工具可能在 repo root 拉一份)
# Stray top-level node_modules (vitest / some tools may pull one at the repo root)
/node_modules/

# Studio 走 preset 池(studio_data/presets/,已被 studio_data/ 总规则覆盖),
# 旧的 config/ 目录已删,不再需要 user yaml 排除规则。
# Studio now uses the preset pool (studio_data/presets/, already covered by the
# studio_data/ blanket rule); the old config/ directory is gone, so the user
# yaml exclusion rule is no longer needed.

# OS / editor
.DS_Store
Expand Down Expand Up @@ -72,37 +73,43 @@ dataset/
nul
# Root-level AI agent files — gitignored so contributors can put personal
# config / @docs/AGENTS.md import here without conflicting with the repo.
# Project 公约 lives at docs/AGENTS.md (NOT ignored — note the leading /).
# The project conventions live at docs/AGENTS.md (NOT ignored — note the leading /).
/AGENTS.md
/CLAUDE.md

# 本地解压的设计稿原始目录(已整理进 mockup/)
# Local extracted design-mockup source directory (already organized into mockup/)
1/

# 工具生成的临时目录
# Temporary directory generated by tooling
.spec-workflow/

# Self-update 进程间通信用的瞬时标志(server 写 → cli.py / wrapper 读后立即删)
# Ephemeral flag used for self-update inter-process communication
# (server writes it -> cli.py / wrapper reads it and deletes it immediately)
tmp/

# 文档本地草稿(个人 TODO / 未定稿设计 / 临时笔记)
# Local documentation drafts (personal TODOs / unfinished designs / scratch notes)
docs/_local/

# Local UI snapshots before redesign (not for commit)
_ui_backup/

# 一键启动器的产物(tools/build_launcher.py 编出来的)。
# Build output of the one-click launcher (produced by tools/build_launcher.py).
#
# `AnimaLoraStudio.exe`(Windows)**故意不在此列** —— 它随仓库一起提交,
# 这样用户 `git clone` 下来就能直接双击,不用先去 Releases 找附件。
# 由 .github/workflows/publish-launcher.yml 在 windows runner 上构建并回提。
# `AnimaLoraStudio.exe` (Windows) is **deliberately not** in this list — it's
# committed alongside the repo so that after `git clone` a user can just
# double-click it, without first hunting for the attachment on Releases.
# It's built and committed back by .github/workflows/publish-launcher.yml on
# a windows runner.
#
# 非 Windows 的产物仍然忽略:Linux/macOS 用户直接 `./studio.sh` 就行,
# 不需要引导程序,提交进去只是给每个人多下几 MB。
# The non-Windows build output is still ignored: Linux/macOS users just run
# `./studio.sh` directly and don't need a bootstrapper, so committing it would
# only add a few extra MB for everyone to download.
/AnimaLoraStudio
/dist/

# 第三方库缓存(pip / HuggingFace / torch / npm / ...)—— 见
# studio/infrastructure/local_cache.py:默认收进项目文件夹,免得几个 GB
# 悄悄堆在系统盘上。整个目录随时可删,删了只是下次重下。
# Third-party library cache (pip / HuggingFace / torch / npm / ...) — see
# studio/infrastructure/local_cache.py: it's collected into the project
# folder by default so a few GB don't quietly pile up on the system drive.
# The whole directory can be deleted at any time; deleting it just means
# it gets re-downloaded next time.
/.cache/
Loading
Loading