Files
navop/script/package-linux-product.sh
胡飞 b696f4ddb5 feat(release): 统一 tag 三产品发布,独立产品接入自更新链路
一个 tag 同时发布全量 navop、navop-shell、navop-data 三个产品:

- release.yml 矩阵加 product 维度(products 输入 all/full/standalone 可裁剪),
  独立产品覆盖四个主力平台,复用全量的构建/打包/上传步骤;独立产物公开命名
  统一 {product}-{version}-{label},Windows 补裸 exe zip 供自更新器直连。
- 版本校验(prepare job / release-tag.sh / beta-release.sh / release_pr.py)
  全部扩成四个 manifest(main + 三个 app crate)统一比对,app 版本对齐 0.22.0。
- upload-r2.yml 为三个产品各生成一份更新清单:全量 updates/latest.json,
  独立产品 updates/navop-shell/shell/latest.json 与 updates/navop-data/data/
  latest.json(beta 通道各插 beta/ 段),键位与 config.rs feed_url() 一致。
- install.rs 自更新安装器按运行时 identity 参数化 bundle/exe/binary 候选名,
  独立产品可自更新,全量保留 OnetCli.app / onetcli.exe legacy 兼容。
- 删除 standalone-products.yml(能力并入 release.yml);package-linux-product.sh
  支持显式产物命名并入统一发布;RELEASE.md 补统一发布与 products 输入文档。

验证:cargo test -p app_kit --lib 149 passed;clippy 无新告警;
node --test script/test-release-packaging.mjs 40/40;工作流 YAML 解析通过。
2026-10-31 23:24:48 +08:00

97 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# 打包独立产品(navop-shell / navop-data)的 Linux 产物。
#
# 用法: package-linux-product.sh <navop-shell|navop-data> [target] \
# [archive-out] [public-out] [portable-out]
#
# 输出名参数由 release.yml 传入,用于把产物对齐到公开命名
# {product}-{version}-{public_label}(如 navop-shell-0.22.0-linux-x64.tar.gz);
# 缺省时退回 {binary}-{version}-{target} 本地命名,便于手动调用。
PRODUCT="${1:?usage: package-linux-product.sh <navop-shell|navop-data> [target] [archive-out] [public-out] [portable-out]}"
TARGET="${2:-x86_64-unknown-linux-gnu}"
ARCHIVE_OUT="${3:-}"
PUBLIC_OUT="${4:-}"
PORTABLE_OUT="${5:-}"
VERSION="${NAVOP_VERSION:-${ONETCLI_VERSION:-0.0.0}}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="${ONETCLI_PROJECT_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
case "$PRODUCT" in
navop-shell)
BINARY_NAME="navop-shell"
APP_NAME="Navop Shell"
PORTABLE_MARKER="navop-shell.portable"
;;
navop-data)
BINARY_NAME="navop-data"
APP_NAME="Navop Data"
PORTABLE_MARKER="navop-data.portable"
;;
*)
echo "Error: unknown product '${PRODUCT}' (expected navop-shell, navop-data)" >&2
exit 1
;;
esac
BINARY_PATH="${ONETCLI_BINARY_PATH:-${PROJECT_DIR}/target/${TARGET}/release/${BINARY_NAME}}"
if [ ! -f "$BINARY_PATH" ]; then
echo "Error: binary not found at ${BINARY_PATH}" >&2
echo "Run: cargo build --release -p ${PRODUCT} --target ${TARGET}" >&2
exit 1
fi
DESKTOP_PATH="${PROJECT_DIR}/resources/linux/${PRODUCT}.desktop"
if [ ! -f "$DESKTOP_PATH" ]; then
echo "Error: desktop entry not found at ${DESKTOP_PATH}" >&2
exit 1
fi
STAGE_DIR="${PROJECT_DIR}/target/${PRODUCT}-linux-package"
rm -rf "$STAGE_DIR"
mkdir -p "$STAGE_DIR/usr/bin" \
"$STAGE_DIR/usr/share/applications" \
"$STAGE_DIR/usr/share/icons/hicolor/128x128/apps" \
"$STAGE_DIR/usr/share/icons/hicolor/256x256/apps" \
"$STAGE_DIR/usr/share/icons/hicolor/512x512/apps"
cp "$BINARY_PATH" "$STAGE_DIR/usr/bin/${BINARY_NAME}"
cp "$DESKTOP_PATH" "$STAGE_DIR/usr/share/applications/"
for size in 128 256 512; do
cp "${PROJECT_DIR}/resources/linux/${PRODUCT}-${size}.png" \
"$STAGE_DIR/usr/share/icons/hicolor/${size}x${size}/apps/${BINARY_NAME}.png"
done
# tar 参数与 release.yml 全量 Package (Linux) 步骤保持一致:固定
# mtime/owner 让同一 tag 的产物字节级可复现,sha256 才能对得上。
ARCHIVE="${ARCHIVE_OUT:-${PROJECT_DIR}/target/${BINARY_NAME}-${VERSION}-${TARGET}.tar.gz}"
tar \
--sort=name \
--mtime='UTC 1970-01-01' \
--owner=0 \
--group=0 \
--numeric-owner \
-czf "$ARCHIVE" -C "$STAGE_DIR" .
if [ -n "$PUBLIC_OUT" ]; then
cp "$ARCHIVE" "$PUBLIC_OUT"
fi
PORTABLE_DIR="${PROJECT_DIR}/target/${PRODUCT}-portable"
rm -rf "$PORTABLE_DIR"
mkdir -p "$PORTABLE_DIR"
cp "$BINARY_PATH" "$PORTABLE_DIR/${BINARY_NAME}"
printf '%s\n' "$APP_NAME" > "$PORTABLE_DIR/${PORTABLE_MARKER}"
PORTABLE_ARCHIVE="${PORTABLE_OUT:-${PROJECT_DIR}/target/${BINARY_NAME}-${VERSION}-${TARGET}-portable.tar.gz}"
tar \
--sort=name \
--mtime='UTC 1970-01-01' \
--owner=0 \
--group=0 \
--numeric-owner \
-czf "$PORTABLE_ARCHIVE" -C "$PORTABLE_DIR" .
echo "Successfully built: ${ARCHIVE}"
[ -n "$PUBLIC_OUT" ] && echo "Successfully built: ${PUBLIC_OUT}"
echo "Successfully built: ${PORTABLE_ARCHIVE}"