Skip to content

Commit fa31a83

Browse files
committed
ci(release): add multi-platform build support and cross-compilation
1 parent 54d6499 commit fa31a83

File tree

4 files changed

+74
-25
lines changed

4 files changed

+74
-25
lines changed

.github/workflows/release.yml

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Build and Release
1+
name: Release
22

33
on:
44
push:
@@ -8,43 +8,86 @@ on:
88

99
jobs:
1010
build:
11-
runs-on: windows-latest
11+
strategy:
12+
matrix:
13+
include:
14+
- os: windows-latest
15+
target: x86_64-pc-windows-msvc
16+
artifact: llbot-win-x64.exe
17+
binary: llbot.exe
18+
- os: ubuntu-latest
19+
target: x86_64-unknown-linux-gnu
20+
artifact: llbot-linux-x64
21+
binary: llbot
22+
- os: ubuntu-latest
23+
target: aarch64-unknown-linux-gnu
24+
artifact: llbot-linux-arm64
25+
binary: llbot
26+
27+
runs-on: ${{ matrix.os }}
1228

1329
steps:
1430
- uses: actions/checkout@v4
1531

1632
- name: Setup Rust
1733
uses: dtolnay/rust-toolchain@stable
34+
with:
35+
targets: ${{ matrix.target }}
36+
37+
- name: Install cross-compilation tools
38+
if: matrix.target == 'aarch64-unknown-linux-gnu'
39+
run: |
40+
sudo apt-get update
41+
sudo apt-get install -y gcc-aarch64-linux-gnu
1842
1943
- name: Build
20-
run: cargo build --release
44+
run: cargo build --release --target ${{ matrix.target }}
45+
env:
46+
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
2147

2248
- name: Rename artifact
23-
run: |
24-
mv target/release/llbot.exe llbot-win-x64.exe
49+
shell: bash
50+
run: mv target/${{ matrix.target }}/release/${{ matrix.binary }} ${{ matrix.artifact }}
2551

2652
- name: Upload artifact
2753
uses: actions/upload-artifact@v4
2854
with:
29-
name: llbot-win-x64
30-
path: llbot-win-x64.exe
55+
name: ${{ matrix.artifact }}
56+
path: ${{ matrix.artifact }}
3157

3258
release:
3359
needs: build
3460
runs-on: ubuntu-latest
3561
if: startsWith(github.ref, 'refs/tags/')
3662

3763
steps:
38-
- name: Download artifact
64+
- name: Download artifacts
3965
uses: actions/download-artifact@v4
40-
with:
41-
name: llbot-win-x64
66+
67+
- name: Download PMHQ releases
68+
run: |
69+
PMHQ_RELEASE=$(curl -s https://api.github.com/repos/linyuchen/PMHQ.Rust/releases/latest)
70+
echo "$PMHQ_RELEASE" | jq -r '.assets[] | select(.name | endswith(".zip")) | .browser_download_url' | while read url; do
71+
echo "Downloading: $url"
72+
curl -L -O "$url"
73+
done
74+
75+
- name: Prepare files
76+
run: |
77+
mv llbot-win-x64.exe/llbot-win-x64.exe .
78+
mv llbot-linux-x64/llbot-linux-x64 .
79+
mv llbot-linux-arm64/llbot-linux-arm64 .
80+
chmod +x llbot-linux-x64 llbot-linux-arm64
4281
4382
- name: Create Release Draft
4483
uses: softprops/action-gh-release@v1
4584
with:
4685
draft: true
47-
files: llbot-win-x64.exe
86+
files: |
87+
llbot-win-x64.exe
88+
llbot-linux-x64
89+
llbot-linux-arm64
90+
*.zip
4891
generate_release_notes: true
4992
env:
5093
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ qrcode = "0.14"
1616
base64 = "0.22"
1717
ctrlc = "3"
1818

19-
[build-dependencies]
20-
winres = "0.1"
21-
2219
[target.'cfg(target_os = "windows")'.build-dependencies]
20+
winres = "0.1"
2321
static_vcruntime = "2.0"
2422

2523
[profile.release]

build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
fn main() {
2-
if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "windows" {
2+
#[cfg(target_os = "windows")]
3+
{
34
// 静态链接 VC 运行时
45
static_vcruntime::metabuild();
56

src/main.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,14 @@ const DEFAULT_PORT: u16 = 13000;
1919
const PORT_RANGE_END: u16 = 14000;
2020

2121
fn should_show_terminal_qrcode(exe_dir: &Path, args: &[String]) -> bool {
22-
// 非 Windows 平台始终显示终端二维码
2322
if cfg!(not(target_os = "windows")) {
2423
return true;
2524
}
2625

27-
// 检查命令行参数
2826
if args.iter().any(|a| a == "--headless") {
2927
return true;
3028
}
3129

32-
// 检查配置文件
3330
let config_path = exe_dir.join("bin/pmhq/pmhq_config.json");
3431
if let Ok(content) = fs::read_to_string(&config_path) {
3532
if let Ok(json) = serde_json::from_str::<serde_json::Value>(&content) {
@@ -39,38 +36,48 @@ fn should_show_terminal_qrcode(exe_dir: &Path, args: &[String]) -> bool {
3936
false
4037
}
4138

39+
fn get_exe_name(base: &str) -> String {
40+
if cfg!(target_os = "windows") {
41+
format!("{}.exe", base)
42+
} else {
43+
base.to_string()
44+
}
45+
}
46+
4247
fn main() {
4348
let exe_dir = env::current_exe()
4449
.ok()
4550
.and_then(|p| p.parent().map(|p| p.to_path_buf()))
4651
.unwrap_or_else(|| PathBuf::from("."));
4752

4853
let args: Vec<String> = env::args().skip(1).collect();
49-
let pmhq_exe = exe_dir.join("bin/pmhq/pmhq.exe");
54+
let pmhq_exe = exe_dir.join(format!("bin/pmhq/{}", get_exe_name("pmhq")));
5055

5156
// --help 或 --version 直接转发给 pmhq
5257
if args.iter().any(|a| a == "--help" || a == "-h" || a == "--version") {
5358
if pmhq_exe.exists() {
5459
let status = Command::new(&pmhq_exe).args(&args).status();
5560
std::process::exit(status.map(|s| s.code().unwrap_or(0)).unwrap_or(1));
5661
} else {
57-
eprintln!("错误: 未找到 pmhq.exe: {}", pmhq_exe.display());
62+
eprintln!("错误: 未找到 pmhq: {}", pmhq_exe.display());
5863
std::process::exit(1);
5964
}
6065
}
6166

6267
migrate_old_files(&exe_dir);
6368

6469
let llbot_dir = exe_dir.join("bin/llbot");
70+
let node_exe = get_exe_name("node");
6571

6672
if !pmhq_exe.exists() {
67-
eprintln!("错误: 未找到 pmhq.exe: {}", pmhq_exe.display());
73+
eprintln!("错误: 未找到 pmhq: {}", pmhq_exe.display());
6874
wait_exit(1);
6975
}
70-
if !llbot_dir.join("node.exe").exists() {
76+
if !llbot_dir.join(&node_exe).exists() {
7177
eprintln!(
72-
"错误: 未找到 node.exe: {}",
73-
llbot_dir.join("node.exe").display()
78+
"错误: 未找到 {}: {}",
79+
node_exe,
80+
llbot_dir.join(&node_exe).display()
7481
);
7582
wait_exit(1);
7683
}
@@ -102,7 +109,7 @@ fn main() {
102109
cmd.arg("--sub-cmd-workdir")
103110
.arg(&llbot_dir)
104111
.arg("--sub-cmd")
105-
.arg("node.exe")
112+
.arg(&node_exe)
106113
.arg("--enable-source-maps")
107114
.arg("llbot.js")
108115
.arg("--")

0 commit comments

Comments
 (0)