Files
dingMCP/deploy/install.sh
T
gitea-admin 504145aec6
CI / Client installer (macos-latest) (push) Canceled after 0s
CI / Client installer (ubuntu-latest) (push) Canceled after 0s
CI / Client installer (windows-latest) (push) Canceled after 0s
CI / test (22) (push) Canceled after 0s
CI / test (24) (push) Canceled after 0s
CI / release-smoke (push) Canceled after 0s
feat: initial public release
2026-08-17 03:04:09 +00:00

118 lines
4.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -Eeuo pipefail
project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
domain="approval.justconn.top"
public_base_url="https://${domain}"
gateway_url="${public_base_url}/mcp"
download_base_url="${public_base_url}/downloads/dingmcp"
release_dir="${project_root}/release"
web_base="/var/www/${domain}"
web_root="${web_base}/downloads/dingmcp"
web_releases="${web_base}/releases"
acme_root="${web_base}/acme"
nginx_site="/etc/nginx/conf.d/${domain}.conf"
certificate="/etc/letsencrypt/live/${domain}/fullchain.pem"
npm_cache="${project_root}/.npm-cache"
release_private_key="${project_root}/.secrets/release-signing-private.pem"
release_public_key="${project_root}/distribution/release-signing-public.pem"
for command_name in node npm curl systemctl sudo nginx certbot stat sha256sum tar find sort tail cut date; do
command -v "${command_name}" >/dev/null 2>&1 || {
echo "缺少部署命令:${command_name}" >&2
exit 1
}
done
if [[ ! -f "${project_root}/.runtime/dingtalk-mcp.env" ]]; then
echo "缺少 .runtime/dingtalk-mcp.env;首次部署前需先配置网关企业凭证。" >&2
exit 1
fi
if [[ ! -f "${release_private_key}" || ! -f "${release_public_key}" ]]; then
echo "缺少 Ed25519 发布密钥;首次部署请先执行 npm run release:keygen 并安全备份私钥。" >&2
exit 1
fi
if [[ "$(stat -c '%a' "${release_private_key}")" != "600" ]]; then
echo "发布私钥权限必须为 600:${release_private_key}" >&2
exit 1
fi
echo "[1/7] 测试并构建"
cd "${project_root}"
npm --cache "${npm_cache}" test
echo "[2/7] 生成包含钉钉 OA 与薪福通的发行包"
npm --cache "${npm_cache}" run release:build -- \
--gateway-url "${gateway_url}" \
--download-base-url "${download_base_url}" \
--out release
npm run test-bundle:build -- \
--release-dir release \
--bundle release/dingmcp-test-bundle.tar.gz \
--bundle-url "${download_base_url}/dingmcp-test-bundle.tar.gz" \
--prompt release/agent-test-install.md
(cd "${release_dir}" && sha256sum -c SHA256SUMS)
npm run release:verify -- --release-dir release
echo "[3/7] 安装并重启用户级网关服务"
node dist/src/admin.js service start --project-root "${project_root}"
echo "[4/7] 原子发布安装文件"
release_version="$(node -p "require('./package.json').version")"
release_digest="$(sha256sum "${release_dir}/manifest.json" | cut -c1-12)"
release_name="${release_version}-${release_digest}"
release_target="${web_releases}/${release_name}"
release_staging="${web_releases}/.staging-${release_name}-$$"
sudo install -d -m 0755 "${web_base}/downloads" "${web_releases}" "${acme_root}/.well-known/acme-challenge"
sudo rm -rf "${release_staging}"
sudo install -d -m 0755 "${release_staging}"
sudo cp -a "${release_dir}/." "${release_staging}/"
if ! sudo test -e "${release_target}"; then
sudo mv "${release_staging}" "${release_target}"
else
sudo rm -rf "${release_staging}"
fi
if sudo test -d "${web_root}" && ! sudo test -L "${web_root}"; then
sudo mv "${web_root}" "${web_releases}/legacy-$(date -u +%Y%m%dT%H%M%SZ)"
fi
sudo ln -sfn "${release_target}" "${web_root}.next"
sudo mv -Tf "${web_root}.next" "${web_root}"
mapfile -t obsolete_releases < <(find "${web_releases}" -mindepth 1 -maxdepth 1 -type d -name '[0-9]*' ! -name "${release_name}" -printf '%T@ %f\n' | sort -nr | tail -n +3 | cut -d' ' -f2-)
for obsolete in "${obsolete_releases[@]}"; do
[[ "${obsolete}" =~ ^[A-Za-z0-9._-]+$ ]] || continue
sudo rm -rf "${web_releases:?}/${obsolete}"
done
if ! sudo test -f "${certificate}"; then
echo "[5/7] 首次签发 HTTPS 证书"
sudo install -m 0644 "${project_root}/deploy/${domain}.bootstrap.nginx.conf" "${nginx_site}"
sudo nginx -t
sudo systemctl reload nginx
sudo certbot certonly --webroot -w "${acme_root}" -d "${domain}"
else
echo "[5/7] 复用现有 HTTPS 证书"
fi
echo "[6/7] 安装正式 Nginx 配置"
sudo install -m 0644 "${project_root}/deploy/${domain}.nginx.conf" "${nginx_site}"
sudo nginx -t
sudo systemctl reload nginx
echo "[7/7] 验证公网服务"
curl --fail --silent --show-error --retry 10 --retry-delay 1 --retry-all-errors \
"${public_base_url}/healthz" >/dev/null
curl --fail --silent --show-error \
"${public_base_url}/.well-known/oauth-protected-resource/mcp" >/dev/null
curl --fail --silent --show-error "${download_base_url}/install.md" >/dev/null
curl --fail --silent --show-error "${download_base_url}/manifest.json" >/dev/null
curl --fail --silent --show-error "${download_base_url}/manifest.sig" >/dev/null
curl --fail --silent --show-error "${download_base_url}/dingtalk-approval-installer.mjs" >/dev/null
curl --fail --silent --show-error "${download_base_url}/release-signing-public.pem" >/dev/null
echo "部署完成。"
echo "MCP:${gateway_url}"
echo "用户安装链接:${download_base_url}/install.md"
echo "黑盒测试提示词:${download_base_url}/agent-test-install.md"