ci: publish cross-platform releases

This commit is contained in:
TuxMonkey
2026-07-26 17:01:59 +08:00
parent 3dc9f2b243
commit 4b17ecad83
4 changed files with 147 additions and 11 deletions

View File

@@ -7,7 +7,7 @@ on:
- "v*" - "v*"
permissions: permissions:
contents: read contents: write
jobs: jobs:
package: package:
@@ -17,15 +17,26 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- platform: windows - artifact: windows-x64
platform: windows
os: windows-latest os: windows-latest
command: dist:win target: win
- platform: linux arch: x64
- artifact: linux-x64
platform: linux
os: ubuntu-22.04 os: ubuntu-22.04
command: dist:linux target: linux
- platform: macos arch: x64
- artifact: macos-x64
platform: macos
os: macos-14 os: macos-14
command: dist:mac target: mac
arch: x64
- artifact: macos-arm64
platform: macos
os: macos-14
target: mac
arch: arm64
env: env:
CSC_IDENTITY_AUTO_DISCOVERY: "false" CSC_IDENTITY_AUTO_DISCOVERY: "false"
@@ -44,12 +55,47 @@ jobs:
run: npm ci run: npm ci
- name: Build packages - name: Build packages
run: npm run ${{ matrix.command }} run: |
npm run build
npm run pack:${{ matrix.target }} -- --${{ matrix.arch }}
- name: Write checksums
run: node scripts/write-checksums.cjs release/${{ matrix.platform }} ${{ matrix.artifact }}
- name: Upload packages - name: Upload packages
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ArborFlow-${{ matrix.platform }} name: ArborFlow-${{ matrix.artifact }}
path: release/${{ matrix.platform }}/ path: |
release/${{ matrix.platform }}/*.exe
release/${{ matrix.platform }}/*.blockmap
release/${{ matrix.platform }}/*.AppImage
release/${{ matrix.platform }}/*.deb
release/${{ matrix.platform }}/*.dmg
release/${{ matrix.platform }}/*.zip
release/${{ matrix.platform }}/SHA256SUMS-${{ matrix.artifact }}.txt
if-no-files-found: error if-no-files-found: error
compression-level: 0 compression-level: 0
release:
name: Publish GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
needs: package
runs-on: ubuntu-22.04
steps:
- name: Download package artifacts
uses: actions/download-artifact@v4
with:
pattern: ArborFlow-*
path: release-assets
merge-multiple: true
- name: Create release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" release-assets/* \
--verify-tag \
--generate-notes \
--title "ArborFlow $GITHUB_REF_NAME"

View File

@@ -1,9 +1,38 @@
# ArborFlow # ArborFlow
[![Build release packages](https://github.com/RoboMaster-DLMU-CONE/Arborflow/actions/workflows/build-release.yml/badge.svg)](https://github.com/RoboMaster-DLMU-CONE/Arborflow/actions/workflows/build-release.yml)
[![GitHub release](https://img.shields.io/github/v/release/RoboMaster-DLMU-CONE/Arborflow)](https://github.com/RoboMaster-DLMU-CONE/Arborflow/releases/latest)
[![License](https://img.shields.io/github/license/RoboMaster-DLMU-CONE/Arborflow)](LICENSE)
ArborFlow 是一个面向 [BehaviorTree.CPP](https://github.com/BehaviorTree/BehaviorTree.CPP) 的跨平台行为树生成、编辑与运行状态可视化工具。 ArborFlow 是一个面向 [BehaviorTree.CPP](https://github.com/BehaviorTree/BehaviorTree.CPP) 的跨平台行为树生成、编辑与运行状态可视化工具。
项目使用 Electron、React、TypeScript 和 React Flow 构建,可在 Windows、Linux 与 macOS 上运行。一个工程可以包含多棵行为树,并通过 `SubTree` 节点相互引用。 项目使用 Electron、React、TypeScript 和 React Flow 构建,可在 Windows、Linux 与 macOS 上运行。一个工程可以包含多棵行为树,并通过 `SubTree` 节点相互引用。
## 下载与安装
安装包统一发布在 [GitHub Releases](https://github.com/RoboMaster-DLMU-CONE/Arborflow/releases/latest)。自动构建提供以下版本:
| 平台 | 架构 | 发行格式 |
| --- | --- | --- |
| Windows | x64 | NSIS 安装包、Portable 便携版 |
| Linux | x64 | AppImage、deb |
| macOS | Intel x64、Apple Silicon arm64 | dmg、zip |
Linux AppImage 首次运行前需要增加执行权限:
```bash
chmod +x ArborFlow-*.AppImage
./ArborFlow-*.AppImage
```
deb 包可使用系统包管理器安装:
```bash
sudo apt install ./arborflow_*.deb
```
当前自动构建未配置商业代码签名证书。Windows 可能显示 SmartScreen 提示;macOS 首次运行时可在 Finder 中右键应用并选择“打开”。每个 Release 都附带分平台的 `SHA256SUMS-*.txt` 校验文件。
## 主要功能 ## 主要功能
- 拖拽创建节点并通过端口连接父子关系 - 拖拽创建节点并通过端口连接父子关系
@@ -220,7 +249,7 @@ npm run dist:mac
输出按平台分别保存到 `release/windows/`、`release/linux/` 和 `release/macos/`。建议在目标操作系统上执行对应打包命令,特别是 macOS 签名、公证以及不同 CPU 架构的构建。 输出按平台分别保存到 `release/windows/`、`release/linux/` 和 `release/macos/`。建议在目标操作系统上执行对应打包命令,特别是 macOS 签名、公证以及不同 CPU 架构的构建。
仓库内的 `.github/workflows/build-release.yml` 会在 Windows、Ubuntu 和 macOS 原生运行器上并行打包。可在 GitHub Actions 中手动运行,也会在推送 `v*` 标签时自动执行并上传三个独立平台产物。 仓库内的 `.github/workflows/build-release.yml` 会在 Windows、Ubuntu 和 macOS 原生运行器上并行打包。可在 GitHub Actions 中手动运行;推送 `v*` 标签时会自动创建 GitHub Release,并上传安装包及 SHA-256 校验文件。
可用的默认目标: 可用的默认目标:

View File

@@ -6,6 +6,14 @@
"main": "electron/main.cjs", "main": "electron/main.cjs",
"author": "ArborFlow Contributors", "author": "ArborFlow Contributors",
"license": "MIT", "license": "MIT",
"homepage": "https://github.com/RoboMaster-DLMU-CONE/Arborflow#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/RoboMaster-DLMU-CONE/Arborflow.git"
},
"bugs": {
"url": "https://github.com/RoboMaster-DLMU-CONE/Arborflow/issues"
},
"scripts": { "scripts": {
"dev": "concurrently -k \"vite --host 127.0.0.1\" \"wait-on http://127.0.0.1:5173 && electron .\"", "dev": "concurrently -k \"vite --host 127.0.0.1\" \"wait-on http://127.0.0.1:5173 && electron .\"",
"build": "tsc -b && vite build", "build": "tsc -b && vite build",

View File

@@ -0,0 +1,53 @@
const { createHash } = require('node:crypto');
const { createReadStream, promises: fs } = require('node:fs');
const path = require('node:path');
const [directory, artifactName] = process.argv.slice(2);
if (!directory || !artifactName) {
console.error('Usage: node scripts/write-checksums.cjs <directory> <artifact-name>');
process.exit(1);
}
const releaseExtensions = new Set([
'.AppImage',
'.blockmap',
'.deb',
'.dmg',
'.exe',
'.zip',
]);
function hashFile(filePath) {
return new Promise((resolve, reject) => {
const hash = createHash('sha256');
const stream = createReadStream(filePath);
stream.on('data', (chunk) => hash.update(chunk));
stream.on('error', reject);
stream.on('end', () => resolve(hash.digest('hex')));
});
}
async function main() {
const entries = await fs.readdir(directory, { withFileTypes: true });
const files = entries
.filter((entry) => entry.isFile() && releaseExtensions.has(path.extname(entry.name)))
.sort((left, right) => left.name.localeCompare(right.name));
if (files.length === 0) {
throw new Error(`No release packages found in ${directory}`);
}
const lines = [];
for (const file of files) {
lines.push(`${await hashFile(path.join(directory, file.name))} ${file.name}`);
}
const output = path.join(directory, `SHA256SUMS-${artifactName}.txt`);
await fs.writeFile(output, `${lines.join('\n')}\n`, 'ascii');
console.log(`Wrote ${output}`);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});