#!/usr/bin/env bash # 构建 Linux 解压即用包:包含 Python 运行时、依赖、CLI 可执行程序和脚本文档。 set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT_DIR" PYTHON_BIN="${PYTHON_BIN:-python3}" APP_NAME="pam-deploy-agent" RELEASE_NAME="${APP_NAME}-linux-x86_64" PACKAGE_EXTRAS="${PACKAGE_EXTRAS:-mcp}" BUILD_DIR="${BUILD_DIR:-$ROOT_DIR/build/linux_self_contained}" DIST_DIR="${DIST_DIR:-$ROOT_DIR/dist/linux_self_contained}" RELEASE_DIR="$DIST_DIR/$RELEASE_NAME" ARCHIVE_PATH="$DIST_DIR/${RELEASE_NAME}.tar.gz" if [[ "$(uname -s)" != "Linux" ]]; then echo "该脚本需要在 Linux x86_64 构建机上运行。" exit 1 fi if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then echo "未找到 Python: $PYTHON_BIN" exit 1 fi echo "==> 清理旧构建目录" rm -rf "$BUILD_DIR" "$RELEASE_DIR" "$ARCHIVE_PATH" mkdir -p "$BUILD_DIR" "$DIST_DIR" echo "==> 创建构建虚拟环境" "$PYTHON_BIN" -m venv "$BUILD_DIR/venv" source "$BUILD_DIR/venv/bin/activate" echo "==> 安装构建依赖" python -m pip install --upgrade pip setuptools wheel python -m pip install pyinstaller echo "==> 安装项目依赖" if [[ -n "$PACKAGE_EXTRAS" ]]; then python -m pip install -e ".[${PACKAGE_EXTRAS}]" else python -m pip install -e . fi echo "==> 使用 PyInstaller 生成自带 Python 运行时的可执行目录" python -m PyInstaller \ --clean \ --noconfirm \ --name "$APP_NAME" \ --onedir \ --console \ --distpath "$BUILD_DIR/pyinstaller_dist" \ --workpath "$BUILD_DIR/pyinstaller_build" \ --specpath "$BUILD_DIR" \ --collect-submodules pam_deploy_graph \ --collect-submodules langgraph \ --hidden-import pam_deploy_graph.cli \ packaging/pyinstaller_entry.py echo "==> 组装发布目录" mkdir -p "$RELEASE_DIR" cp -a "$BUILD_DIR/pyinstaller_dist/$APP_NAME/." "$RELEASE_DIR/" cp -a doc_scripts "$RELEASE_DIR/doc_scripts" cp -a README.md "$RELEASE_DIR/README.md" cp -a LICENSE "$RELEASE_DIR/LICENSE" cat > "$RELEASE_DIR/run.sh" <<'RUN_SCRIPT' #!/usr/bin/env bash set -euo pipefail DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$DIR" exec "$DIR/pam-deploy-agent" "$@" RUN_SCRIPT chmod +x "$RELEASE_DIR/run.sh" cat > "$RELEASE_DIR/使用说明.txt" <<'USAGE_TEXT' PAM 部署 Agent Linux 解压即用包 使用方式: ./run.sh --help ./run.sh chat --config doc_scripts/config.txt.example --strategy fake --checkpoint runtime/checkpoints/demo.json ./run.sh analyze --config doc_scripts/config.txt.example --text "请用 MCP 预演部署 HET PAM Node 版本 2.0.5,不要动环境" 说明: 1. 该包已包含 Python 运行时和 Python 依赖,目标机器不需要额外安装 Python 包。 2. 真实 LLM 仍需通过 PAM_LLM_BASE_URL、PAM_LLM_API_KEY、PAM_LLM_MODEL 或 CLI 参数配置。 3. 真实 MCP session 仍需由你在外部接入后传给 Agent;当前包已包含 MCP client adapter。 4. checkpoint 会保存完整运行参数,请放在受控目录。 USAGE_TEXT echo "==> 生成 tar.gz" tar -C "$DIST_DIR" -czf "$ARCHIVE_PATH" "$RELEASE_NAME" format_bytes() { local bytes="$1" python - "$bytes" <<'PY' import sys value = float(sys.argv[1]) units = ["B", "KB", "MB", "GB"] for unit in units: if value < 1024 or unit == units[-1]: print(f"{value:.1f} {unit}") break value /= 1024 PY } EXTRACTED_BYTES="$(du -sb "$RELEASE_DIR" | awk '{print $1}')" ARCHIVE_BYTES="$(du -sb "$ARCHIVE_PATH" | awk '{print $1}')" echo "==> 构建完成" echo "发布目录: $RELEASE_DIR" echo "压缩包: $ARCHIVE_PATH" echo "解压后大小: $(format_bytes "$EXTRACTED_BYTES")" echo "压缩包大小: $(format_bytes "$ARCHIVE_BYTES")"