A cross-platform firmware hub and burner for LILYGO and other ESP devices.
The project uses a dual-channel update strategy managed by GitHub Actions.
- Trigger: Push a git tag starting with
v(e.g.,v0.1.0). - Process:
- GitHub Actions builds the app.
- Sets the package version to match the tag (e.g.,
0.1.0). - Creates a GitHub Release with the tag name.
- Uploads artifacts (dmg, exe, AppImage, etc.).
- Update Check: Users on the default channel will receive this update.
- Trigger: Push to the
mainbranch or manually trigger theBuild/releaseworkflow via GitHub Actions UI. - Process:
- GitHub Actions builds the app.
- Generates a version number:
v{BaseVersion}-canary.{YYYYMMDD}.{HHMMSS}(e.g.,v0.1.0-canary.20260215.120000). - Creates a Pre-release on GitHub.
- Update Check: Users who enabled "Canary Channel" in Settings will receive this update.
The app relies on lilygo_config.json (committed to the repo) for API base URL, firmware manifest URL, and OSS domain. This file is bundled with the app when building.
| Field | Description |
|---|---|
api_base_url |
Server API root URL (e.g. upload, login) |
firmware_manifest_url |
Default firmware manifest URL |
firmware_manifest_mirrors |
Optional. Array of OSS mirror URLs for other regions. Tried in order when primary fails (e.g. mainland China mirror when Hong Kong OSS times out) |
oss_domain_prefix |
OSS domain prefix for firmware downloads |
- Built-in config: Read from
lilygo_config.jsonbundled in the app. - User override: If
lilygo_config.jsonexists in the user data directory, it overrides fields with the same name.
User config paths:
- macOS:
~/Library/Application Support/LILYGO Spark/lilygo_config.json - Windows:
%APPDATA%\LILYGO Spark\lilygo_config.json - Linux:
~/.config/LILYGO Spark/lilygo_config.json
Example (user override only needs fields to change; merges with built-in config):
{
"api_base_url": "https://your-api.example.com",
"firmware_manifest_url": "https://your-api.example.com/manifest/firmware_manifest.json",
"firmware_manifest_mirrors": [
"https://your-bucket.oss-cn-hangzhou.aliyuncs.com/firmware_manifest.json"
],
"oss_domain_prefix": "https://your-bucket.oss.region.aliyuncs.com"
}The app uses a JSON manifest to list available devices and firmware. The manifest URL is read from lilygo_config.json (see above).
- Multi-region mirrors: Configure
firmware_manifest_mirrorsinlilygo_config.jsonto add OSS URLs in other regions (e.g. mainland China). When the primary Hong Kong OSS times out (e.g. on some mobile carriers), the app will try mirrors in order. - Local fallback: If all remote URLs fail, the app falls back to a built-in
firmware_manifest.json. - Images: Stored in
public/devices/; in manifest use"image_url": "devices/t-deck.jpg". For remote manifests,image_urlcan be full URLs.
npm installnpm run devThe build includes lilygo_config.json from the repo root. No extra copy needed. If the file or required fields are missing, the app will show an error dialog and exit on startup.
npm run build # Current platform
npm run build:mac # macOS
npm run build:win # Windows
npm run build:linux # Linux
npm run build:mac:universal # macOS universal binaryThis project uses GitHub Actions for CI/CD, supporting Stable and Canary update channels.
Stable releases follow strict SemVer (e.g., v0.1.0). Triggered only by pushing a v* Git Tag.
Steps:
- Update
versioninpackage.json(e.g.,0.1.0). - Commit and Tag:
git commit -am "release: v0.1.0" git tag v0.1.0 git push origin main --tags - GitHub Actions will build and publish to "Latest" release. Users on default settings will see the update.
Canary builds are for testing latest changes. Version format: v{Version}-canary.{Date}.{Time}.
Triggers:
- Auto: Push to
mainbranch. - Manual: Run
Build/releaseworkflow in GitHub Actions.
How to Update:
Users must enable "Canary Channel" in "Settings -> Advanced" to receive these updates.
For hackers and makers who enjoy a bit of fun:
| Trigger | Effect |
|---|---|
| Konami Code | Press ↑ ↑ ↓ ↓ ← → ← → B A anywhere in the app → "ACCESS GRANTED" overlay |
| Flash Success | When firmware flashing completes successfully → "FLASH COMPLETE ✓" celebration |
| Device Detected | When an ESP32 device is detected → "// TARGET ACQUIRED" badge |
本项目采用 GitHub Actions 管理的双通道更新策略。
- 触发方式: 推送以
v开头的 Git Tag(例如v0.1.0)。 - 流程:
- GitHub Actions 自动构建应用。
- 将应用内部版本号修改为与 Tag 一致(如
0.1.0)。 - 创建 GitHub Release 并上传构建产物(dmg, exe, AppImage 等)。
- 更新检测: 默认通道的用户会收到此更新推送。
- 触发方式: 推送代码到
main分支,或在 GitHub Actions 页面手动触发Build/release工作流。 - 流程:
- GitHub Actions 自动构建应用。
- 生成带时间戳的版本号:
v{基础版本}-canary.{年月日}.{时分秒}(例如v0.1.0-canary.20260215.120000)。 - 创建一个 Pre-release(预发布版本)。
- 更新检测: 在设置中开启「Canary 更新频道」的用户会收到此更新推送。
应用依赖仓库内的 lilygo_config.json(已提交到 Git),用于配置 API 地址、固件清单地址和 OSS 域名。打包时该文件会随应用一起发布。
| 字段 | 说明 |
|---|---|
api_base_url |
服务端 API 根地址(如上传、登录等) |
firmware_manifest_url |
默认固件清单的在线 URL |
firmware_manifest_mirrors |
可选,多地区 OSS 镜像 URL 数组,主地址失败时按序尝试(如联通网络访问香港 OSS 超时时可回退到大陆镜像) |
oss_domain_prefix |
OSS 域名前缀(固件文件下载域名) |
- 内置配置:从应用包内读取仓库中的
lilygo_config.json。 - 用户覆盖:若用户数据目录下存在
lilygo_config.json,则覆盖同名字段。
用户配置路径:
- macOS:
~/Library/Application Support/LILYGO Spark/lilygo_config.json - Windows:
%APPDATA%\LILYGO Spark\lilygo_config.json - Linux:
~/.config/LILYGO Spark/lilygo_config.json
示例(用户覆盖时只需写要改的字段,可与内置配置合并):
{
"api_base_url": "https://your-api.example.com",
"firmware_manifest_url": "https://your-api.example.com/manifest/firmware_manifest.json",
"firmware_manifest_mirrors": [
"https://your-bucket.oss-cn-hangzhou.aliyuncs.com/firmware_manifest.json"
],
"oss_domain_prefix": "https://your-bucket.oss.region.aliyuncs.com"
}应用通过 JSON 清单列出可用设备和固件,清单 URL 从 lilygo_config.json 读取(见上文)。
- 多地区镜像:在
lilygo_config.json中配置firmware_manifest_mirrors可添加其他地区(如中国大陆)的 OSS 地址。当主香港 OSS 超时(如部分运营商网络)时,应用会按序尝试镜像。 - 本地回退:若所有远程 URL 均失败,应用会回退到内置的
firmware_manifest.json。 - 图片:存放在
public/devices/;清单中使用"image_url": "devices/t-deck.jpg"。远程清单中image_url可为完整 URL。
npm installnpm run dev打包会包含仓库根目录的 lilygo_config.json,无需额外复制。若缺少该文件或必填字段为空,应用启动时会弹窗报错并退出。
npm run build # 当前平台
npm run build:mac # macOS
npm run build:win # Windows
npm run build:linux # Linux
npm run build:mac:universal # macOS 通用包本项目采用自动化 CI/CD 流程(GitHub Actions)进行构建和发布,支持 Stable(正式版) 和 Canary(测试版) 两个更新频道。
正式版版本号严格遵循 SemVer 规范(如 v0.1.0)。只有打上 v* 格式的 Git Tag 才会触发正式版构建。
操作步骤:
- 修改
package.json中的version字段(如0.1.0)。 - 提交代码并打 Tag:
git commit -am "release: v0.1.0" git tag v0.1.0 git push origin main --tags - GitHub Actions 会自动构建,并发布到 GitHub Releases 的
Latest标记下。用户在默认设置下即可检测到更新。
测试版用于快速迭代,包含最新的功能修复。版本号格式为 v{版本}-canary.{日期}.{时间}(如 v0.1.0-canary.20260215.120000)。
触发方式:
- 自动触发:每次向
main分支推送代码(Push)或合并 PR 时,会自动构建 Canary 版本。 - 手动触发:在 GitHub Actions 页面手动运行
Build/releaseworkflow。
用户如何获取:
用户需在「设置 -> 高级模式」中开启「Canary 更新频道」,即可检测并更新到最新的 Canary 版本。
应用内置的更新检测遵循 SemVer 优先原则:
0.1.0(正式版) >0.1.0-canary...(测试版)0.1.0-canary.20260216...(新测试版) >0.1.0-canary.20260215...(旧测试版)
为喜欢小惊喜的极客和创客准备:
| 触发条件 | 效果 |
|---|---|
| Konami 彩蛋 | 在应用任意位置按 ↑ ↑ ↓ ↓ ← → ← → B A → 显示「ACCESS GRANTED」弹窗 |
| 烧录成功 | 固件烧录完成时 → 显示「FLASH COMPLETE ✓」庆祝 |
| 设备检测 | 检测到 ESP32 设备时 → 显示「// TARGET ACQUIRED」标识 |