mirror of
https://github.com/modelstudioai/cli.git
synced 2026-09-14 19:49:23 +08:00
build: multi channel install test
This commit is contained in:
@@ -1,171 +0,0 @@
|
||||
# 技术方案:GitHub Release 发布 + 外部 FC 同步 OSS 安装
|
||||
|
||||
> 状态:**已定架构**(本仓库不直传 OSS;安装脚本外置;**不含 Homebrew**)。
|
||||
> 范围:仅 `bailian-cli`(`bl`);不含 `kscli` 二进制。
|
||||
> 操作清单:[docs/agents/binary-distribution.md](../agents/binary-distribution.md)
|
||||
> 发版编排:[docs/agents/publish.md](../agents/publish.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标架构
|
||||
|
||||
```text
|
||||
Publish workflow(本仓库)
|
||||
├─ npm
|
||||
└─ GitHub Release(source of truth)
|
||||
↓
|
||||
调用外部 FC:拉取最新 Release → 同步 OSS
|
||||
↓
|
||||
别处维护的 install.sh / install.ps1 → 只拉 OSS
|
||||
```
|
||||
|
||||
| 环节 | 谁负责 | 本仓库是否实现 |
|
||||
| ------------------------- | ------------ | ------------------------------- |
|
||||
| npm publish | 本仓库 CI | ✅ |
|
||||
| Bun 编译 + GitHub Release | 本仓库 CI | ✅ |
|
||||
| Release → OSS 同步 | **外部 FC** | ❌(仅可选 webhook 触发) |
|
||||
| 生产安装脚本 | **别处维护** | ❌(`packaging/` 仅作契约参考) |
|
||||
| 用户 curl / irm | OSS 上的脚本 | ❌ |
|
||||
|
||||
本仓库**不存放、不上传 OSS AccessKey**;开源侧只用 `GITHUB_TOKEN`。
|
||||
|
||||
---
|
||||
|
||||
## 2. 本仓库发版(Publish)
|
||||
|
||||
入口:`.github/workflows/publish.yml` → `publish-stable.mjs` / `publish-channel.mjs`。
|
||||
|
||||
```text
|
||||
stable:
|
||||
check → npm latest → git tag v<ver> → gh release(正式)
|
||||
assets: bl-*, SHA256SUMS, latest.json
|
||||
(不再把 install.sh/ps1 挂到 Release;生产脚本外置)
|
||||
|
||||
channel:
|
||||
bump beta → npm @channel → gh prerelease v<beta>
|
||||
+ 滚动 prerelease tag channel-<name>(仅 <name>.json)
|
||||
```
|
||||
|
||||
可选:发版成功后 `POST` `BAILIAN_OSS_SYNC_WEBHOOK`,通知 FC 开始同步(Secret 配置,无则跳过)。
|
||||
|
||||
`--skip-binary`:只发 npm。
|
||||
|
||||
### 构建矩阵
|
||||
|
||||
| Bun target | 产物 |
|
||||
| ------------------ | ----------------- |
|
||||
| `bun-darwin-arm64` | `darwin-arm64` |
|
||||
| `bun-darwin-x64` | `darwin-x64` |
|
||||
| `bun-linux-x64` | `linux-x64` |
|
||||
| `bun-windows-x64` | `windows-x64.exe` |
|
||||
|
||||
不构建 `linux-arm64` / `windows-arm64`。
|
||||
|
||||
---
|
||||
|
||||
## 3. GitHub Release 约定(source of truth)
|
||||
|
||||
基址:`https://github.com/modelstudioai/cli/releases`
|
||||
|
||||
| 模式 | Tag | 资产 |
|
||||
| -------------- | ---------------------------------------------- | --------------------------------------- |
|
||||
| stable | `v<version>`(先 push tag,再 `--verify-tag`) | 矩阵二进制、`SHA256SUMS`、`latest.json` |
|
||||
| channel 版本化 | `v0.0.0-beta-<sha7>-<date>`(prerelease) | 二进制、`SHA256SUMS` |
|
||||
| channel 滚动 | `channel-<name>`(prerelease,clobber) | `<name>.json` |
|
||||
|
||||
Manifest 内 `url` 指向 GitHub download(给 FC / 镜像方解析用)。FC 同步到 OSS 时应**改写**为 OSS URL,或安装脚本忽略 `url`、按固定 OSS 路径拼接。
|
||||
|
||||
---
|
||||
|
||||
## 4. 外部 FC(本仓库不实现)
|
||||
|
||||
建议契约:
|
||||
|
||||
1. 触发:Publish webhook,或监听 `release` 事件 / 定时拉取 Latest
|
||||
2. 读取 GitHub Latest(stable)或约定 channel tag
|
||||
3. 下载资产 → 上传 OSS,建议布局:
|
||||
|
||||
```text
|
||||
https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli/
|
||||
channels/latest.json # 改写 url 后的正式版 manifest
|
||||
channels/<channel>.json # 可选测试渠道
|
||||
releases/<version>/
|
||||
bl-<version>-<os>-<arch>[.exe]
|
||||
SHA256SUMS
|
||||
install.sh # 由脚本维护方上传,非本仓库 CI
|
||||
install.ps1
|
||||
```
|
||||
|
||||
4. **完整校验后再对外**:SHA256 对齐、矩阵文件齐全,避免「Release 已发、OSS 半同步」窗口误导用户
|
||||
5. 失败告警(钉钉/飞书/SLS),因用户安装不经过本仓库 CI
|
||||
|
||||
---
|
||||
|
||||
## 5. 安装脚本(别处维护)
|
||||
|
||||
生产入口(示例,以实际 OSS 域名为准):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli/install.sh | bash
|
||||
# Windows:
|
||||
irm https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli/install.ps1 | iex
|
||||
```
|
||||
|
||||
脚本只依赖 OSS;不要求用户访问 GitHub。
|
||||
|
||||
本仓 `packaging/install.sh` / `install.ps1`:**契约参考**(路径、校验、`install-method=binary`),不作为生产分发物挂 Release。
|
||||
|
||||
### 与本仓的契约(脚本方必须遵守)
|
||||
|
||||
- 资产名:`bl-<ver>-<os>-<arch>[.exe]`
|
||||
- 校验:`SHA256SUMS`
|
||||
- 渠道:默认 `latest`;可选 `BAILIAN_CHANNEL`
|
||||
- 写入:`~/.bailian/install-method` = `binary`
|
||||
- 不支持:linux-arm64 / windows-arm64 → 提示 `npm i -g bailian-cli`
|
||||
|
||||
---
|
||||
|
||||
## 6. 运行时(本仓库)
|
||||
|
||||
- `BAILIAN_COMPILED=1`、install-method、`bl update` 分流仍在本仓
|
||||
- 二进制更新默认读 **OSS** manifest(`BAILIAN_CLI_CDN` 可覆盖);与用户安装源一致
|
||||
- GitHub Release 仍是发版真相源;更新链路走 OSS 镜像
|
||||
|
||||
---
|
||||
|
||||
## 7. 职责边界(验收标准)
|
||||
|
||||
| 验收项 | 通过条件 |
|
||||
| ----------------- | ----------------------------------------------------- |
|
||||
| 本仓库 Publish 绿 | npm 可装 + GitHub Release 资产齐全 |
|
||||
| 国内可一键安装 | FC 已同步 + 外置脚本可 curl(**不在本仓 CI 门禁内**) |
|
||||
| 无 AK 进 git | OSS 密钥只在 FC / 脚本发布流水线 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 风险
|
||||
|
||||
- Release 成功 ≠ 用户能装(依赖 FC)→ 必须有同步监控
|
||||
- 脚本外置 → 命名/矩阵变更要同步通知脚本方
|
||||
- `latest.json` 双份(GH / OSS)→ FC 负责改写与一致性
|
||||
- channel 是否进 OSS:由 FC 与脚本方另定;本仓照常发 prerelease
|
||||
|
||||
---
|
||||
|
||||
## 9. 本仓库代码落点
|
||||
|
||||
| 路径 | 职责 |
|
||||
| --------------------------------------------- | ------------------------------------- |
|
||||
| `publish-stable.mjs` / `publish-channel.mjs` | npm + Release + 可选 webhook |
|
||||
| `lib/binary-build.mjs` / `binary-compile.mjs` | 编译与 manifest |
|
||||
| `lib/binary-release.mjs` | `gh release`(不含生产 install 脚本) |
|
||||
| `packaging/*` | 安装契约参考 |
|
||||
| `.github/workflows/publish.yml` | CI |
|
||||
|
||||
调试:
|
||||
|
||||
```sh
|
||||
node tools/release/lib/binary-build.mjs --mode stable --host
|
||||
node tools/release/lib/binary-release.mjs --mode stable --skip-build --dry-run
|
||||
node tools/release/publish-stable.mjs --dry-run
|
||||
```
|
||||
@@ -1,78 +0,0 @@
|
||||
# REFERENCE install script for the OSS layout (production scripts are maintained elsewhere).
|
||||
# Expected production entry:
|
||||
# irm https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli/install.ps1 | iex
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$CdnBase = if ($env:BAILIAN_CLI_CDN) { $env:BAILIAN_CLI_CDN.TrimEnd("/") } else { "https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli" }
|
||||
$Channel = if ($env:BAILIAN_CHANNEL) { $env:BAILIAN_CHANNEL } else { "latest" }
|
||||
$Version = $env:BAILIAN_VERSION
|
||||
$InstallRoot = if ($env:BAILIAN_SHARE_DIR) { $env:BAILIAN_SHARE_DIR } else { Join-Path $env:LOCALAPPDATA "bailian-cli" }
|
||||
$ConfigDir = if ($env:BAILIAN_CONFIG_DIR) { $env:BAILIAN_CONFIG_DIR } else { Join-Path $env:USERPROFILE ".bailian" }
|
||||
|
||||
function Write-Log([string]$Message) {
|
||||
[Console]::Error.WriteLine($Message)
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($Version)) {
|
||||
$manifestUrl = "$CdnBase/channels/$Channel.json"
|
||||
Write-Log "Fetching $manifestUrl"
|
||||
$manifest = Invoke-RestMethod -Uri $manifestUrl
|
||||
$Version = $manifest.version
|
||||
if ([string]::IsNullOrWhiteSpace($Version)) {
|
||||
throw "Could not parse version from $Channel channel manifest"
|
||||
}
|
||||
}
|
||||
|
||||
$Arch = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "x64" }
|
||||
if ($Arch -eq "arm64") {
|
||||
throw "windows arm64 is not supported for binary install; use: npm install -g bailian-cli"
|
||||
}
|
||||
|
||||
$Asset = "bl-$Version-windows-$Arch.exe"
|
||||
$Url = "$CdnBase/releases/$Version/$Asset"
|
||||
$SumsUrl = "$CdnBase/releases/$Version/SHA256SUMS"
|
||||
|
||||
$TempDir = Join-Path ([System.IO.Path]::GetTempPath()) ("bailian-cli-install-" + [guid]::NewGuid().ToString("N"))
|
||||
New-Item -ItemType Directory -Path $TempDir | Out-Null
|
||||
try {
|
||||
$AssetPath = Join-Path $TempDir $Asset
|
||||
$SumsPath = Join-Path $TempDir "SHA256SUMS"
|
||||
Write-Log "Downloading $Asset…"
|
||||
Invoke-WebRequest -Uri $Url -OutFile $AssetPath
|
||||
Invoke-WebRequest -Uri $SumsUrl -OutFile $SumsPath
|
||||
|
||||
$Expected = $null
|
||||
Get-Content $SumsPath | ForEach-Object {
|
||||
if ($_ -match "^([a-fA-F0-9]+)\s+$([regex]::Escape($Asset))\s*$") {
|
||||
$Expected = $Matches[1].ToLowerInvariant()
|
||||
}
|
||||
}
|
||||
if (-not $Expected) { throw "Checksum for $Asset not found in SHA256SUMS" }
|
||||
$Actual = (Get-FileHash -Algorithm SHA256 -Path $AssetPath).Hash.ToLowerInvariant()
|
||||
if ($Expected -ne $Actual) { throw "Checksum mismatch for $Asset" }
|
||||
|
||||
$VersionDir = Join-Path $InstallRoot "versions\$Version"
|
||||
New-Item -ItemType Directory -Force -Path $VersionDir | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $ConfigDir | Out-Null
|
||||
$Target = Join-Path $VersionDir "bl.exe"
|
||||
Copy-Item -Force $AssetPath $Target
|
||||
$ShimDir = Join-Path $InstallRoot "bin"
|
||||
New-Item -ItemType Directory -Force -Path $ShimDir | Out-Null
|
||||
Copy-Item -Force $Target (Join-Path $ShimDir "bl.exe")
|
||||
Copy-Item -Force $Target (Join-Path $ShimDir "bailian.exe")
|
||||
Set-Content -Path (Join-Path $ConfigDir "install-method") -Value "binary" -NoNewline
|
||||
|
||||
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
||||
if (-not ($UserPath -split ";" | Where-Object { $_ -eq $ShimDir })) {
|
||||
[Environment]::SetEnvironmentVariable("Path", "$ShimDir;$UserPath", "User")
|
||||
Write-Log "Added $ShimDir to your user PATH. Open a new terminal to use bl."
|
||||
}
|
||||
|
||||
Write-Log "Installed: $Target (bailian-cli $Version)"
|
||||
Write-Log "Done. Run: bl --help"
|
||||
}
|
||||
finally {
|
||||
Remove-Item -Recurse -Force $TempDir -ErrorAction SilentlyContinue
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# REFERENCE install script for the OSS layout (production scripts are maintained elsewhere).
|
||||
# Production users should curl the copy hosted on OSS after FC sync, not this file from git.
|
||||
#
|
||||
# Expected production entry:
|
||||
# curl -fsSL https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli/install.sh | bash
|
||||
# BAILIAN_VERSION=1.10.1 bash install.sh
|
||||
# BAILIAN_CHANNEL=latest bash install.sh
|
||||
set -euo pipefail
|
||||
|
||||
CDN_BASE="${BAILIAN_CLI_CDN:-https://bailian-cli.oss-cn-hangzhou.aliyuncs.com/bailian-cli}"
|
||||
CDN_BASE="${CDN_BASE%/}"
|
||||
CHANNEL="${BAILIAN_CHANNEL:-latest}"
|
||||
VERSION="${BAILIAN_VERSION:-}"
|
||||
BIN_DIR="${BAILIAN_BIN_DIR:-${HOME}/.local/bin}"
|
||||
SHARE_DIR="${BAILIAN_SHARE_DIR:-${HOME}/.local/share/bailian-cli}"
|
||||
CONFIG_DIR="${BAILIAN_CONFIG_DIR:-${HOME}/.bailian}"
|
||||
|
||||
log() { printf '%s\n' "$*" >&2; }
|
||||
die() { log "error: $*"; exit 1; }
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
|
||||
}
|
||||
|
||||
detect_os_arch() {
|
||||
local uname_s uname_m
|
||||
uname_s="$(uname -s)"
|
||||
uname_m="$(uname -m)"
|
||||
|
||||
case "${uname_s}" in
|
||||
Darwin) OS="darwin" ;;
|
||||
Linux) OS="linux" ;;
|
||||
*) die "unsupported OS: ${uname_s}" ;;
|
||||
esac
|
||||
|
||||
case "${uname_m}" in
|
||||
arm64|aarch64) ARCH="arm64" ;;
|
||||
x86_64|amd64) ARCH="x64" ;;
|
||||
*) die "unsupported architecture: ${uname_m}" ;;
|
||||
esac
|
||||
|
||||
if [[ "${OS}" == "darwin" ]] && [[ "$(sysctl -n sysctl.proc_translated 2>/dev/null || true)" == "1" ]]; then
|
||||
ARCH="arm64"
|
||||
fi
|
||||
|
||||
if [[ "${OS}" == "linux" && "${ARCH}" == "arm64" ]]; then
|
||||
die "linux arm64 is not supported for binary install; use: npm install -g bailian-cli"
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_version() {
|
||||
if [[ -n "${VERSION}" ]]; then
|
||||
return
|
||||
fi
|
||||
need_cmd curl
|
||||
local manifest
|
||||
manifest="$(mktemp)"
|
||||
curl -fsSL "${CDN_BASE}/channels/${CHANNEL}.json" -o "${manifest}" \
|
||||
|| die "failed to download channel manifest: ${CDN_BASE}/channels/${CHANNEL}.json"
|
||||
VERSION="$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${manifest}" | head -n1)"
|
||||
rm -f "${manifest}"
|
||||
[[ -n "${VERSION}" ]] || die "could not parse version from ${CHANNEL} channel manifest"
|
||||
}
|
||||
|
||||
download_and_verify() {
|
||||
local asset="bl-${VERSION}-${OS}-${ARCH}"
|
||||
local url="${CDN_BASE}/releases/${VERSION}/${asset}"
|
||||
local sums_url="${CDN_BASE}/releases/${VERSION}/SHA256SUMS"
|
||||
local tmp_dir version_dir
|
||||
tmp_dir="$(mktemp -d)"
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '${tmp_dir}'" EXIT
|
||||
|
||||
log "Downloading ${asset}…"
|
||||
curl -fsSL "${url}" -o "${tmp_dir}/${asset}" || die "download failed: ${url}"
|
||||
curl -fsSL "${sums_url}" -o "${tmp_dir}/SHA256SUMS" || die "download failed: ${sums_url}"
|
||||
|
||||
need_cmd shasum
|
||||
local expected actual
|
||||
expected="$(awk -v file="${asset}" '$2 == file { print $1; exit }' "${tmp_dir}/SHA256SUMS")"
|
||||
[[ -n "${expected}" ]] || die "checksum for ${asset} not found in SHA256SUMS"
|
||||
actual="$(shasum -a 256 "${tmp_dir}/${asset}" | awk '{ print $1 }')"
|
||||
[[ "${expected}" == "${actual}" ]] || die "checksum mismatch for ${asset}"
|
||||
|
||||
version_dir="${SHARE_DIR}/versions/${VERSION}"
|
||||
mkdir -p "${version_dir}" "${BIN_DIR}" "${CONFIG_DIR}"
|
||||
install -m 755 "${tmp_dir}/${asset}" "${version_dir}/bl"
|
||||
ln -sfn "${version_dir}/bl" "${BIN_DIR}/bl"
|
||||
ln -sfn "${version_dir}/bl" "${BIN_DIR}/bailian"
|
||||
printf 'binary\n' > "${CONFIG_DIR}/install-method"
|
||||
chmod 600 "${CONFIG_DIR}/install-method" 2>/dev/null || true
|
||||
}
|
||||
|
||||
warn_path() {
|
||||
case ":${PATH}:" in
|
||||
*":${BIN_DIR}:"*) ;;
|
||||
*)
|
||||
log ""
|
||||
log "Add ${BIN_DIR} to your PATH, then open a new terminal:"
|
||||
log " export PATH=\"${BIN_DIR}:\$PATH\""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
warn_npm_conflict() {
|
||||
if command -v npm >/dev/null 2>&1; then
|
||||
local npm_bl
|
||||
npm_bl="$(npm root -g 2>/dev/null)/bailian-cli" || true
|
||||
if [[ -d "${npm_bl}" ]]; then
|
||||
log "warning: npm global bailian-cli is also installed; PATH may prefer one over the other."
|
||||
log " Consider: npm uninstall -g bailian-cli"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
need_cmd curl
|
||||
need_cmd uname
|
||||
detect_os_arch
|
||||
resolve_version
|
||||
log "Installing bailian-cli ${VERSION} (${OS}-${ARCH}) from ${CDN_BASE}"
|
||||
download_and_verify
|
||||
warn_npm_conflict
|
||||
warn_path
|
||||
log ""
|
||||
log "Installed: ${BIN_DIR}/bl → bailian-cli ${VERSION}"
|
||||
if command -v "${BIN_DIR}/bl" >/dev/null 2>&1 || [[ -x "${BIN_DIR}/bl" ]]; then
|
||||
"${BIN_DIR}/bl" --version >&2 || true
|
||||
fi
|
||||
log "Done. Run: bl --help"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user