pipeline-app/build.sh

223 lines
8.7 KiB
Bash
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 -e
cdir=$(cd "$(dirname "$0")" && pwd)
cd "$cdir"
echo "=== Pipeline App Build ==="
# 1. Create venv
if [ ! -d py3 ]; then
python3 -m venv py3
fi
source py3/bin/activate
# 2. Install foundation packages (clone to pkgs)
mkdir -p pkgs
for m in apppublic sqlor ahserver bricks-for-python xls2ddl rbac appbase dapi; do
echo "install $m ..."
cd "$cdir/pkgs"
if [ ! -d "$m" ]; then
git clone https://git.opencomputing.cn/yumoqing/$m || echo "SKIP: $m clone failed"
fi
if [ -d "$m" ]; then
cd "$m"
"$cdir/py3/bin/pip" install . 2>&1 | tail -1
fi
cd "$cdir"
done
# 3. Build bricks frontend
cd "$cdir/pkgs"
if [ ! -d bricks ]; then
git clone https://git.opencomputing.cn/yumoqing/bricks || true
fi
if [ ! -f bricks/dist/bricks.js ]; then
mkdir -p bricks/dist
if [ -d bricks/bricks ]; then
cd bricks/bricks
bash build.sh 2>&1 | tail -3
cd "$cdir/pkgs"
fi
fi
# Link dist to wwwroot
rm -rf "$cdir/wwwroot/bricks" 2>/dev/null
ln -sf "$cdir/pkgs/bricks/dist" "$cdir/wwwroot/bricks"
echo "bricks: $(readlink "$cdir/wwwroot/bricks")"
# 4. Move local business modules into pkgs/
cd "$cdir"
for mod in pipeline_core pipeline_ops pipeline_dist; do
if [ -d "$mod" ]; then
mv "$mod" "pkgs/$mod"
fi
done
# 5. Install business modules (clone external, local already in pkgs)
for mod in pipeline-sdlc showcase evaluate pipeline-service pipeline-task tenant app_audit product_management discount pricing unipay smssend accounting; do
cd "$cdir/pkgs"
if [ ! -d "$mod" ]; then
git clone https://git.opencomputing.cn/yumoqing/$mod || echo "SKIP: $mod"
fi
cd "$cdir"
done
# 6. pip install all modules from pkgs/pipeline-service 是普通 install 非 editable部署必 pull+pip install 都做)
for mod in pipeline_core pipeline_ops pipeline_dist pipeline-sdlc showcase pipeline-service tenant app_audit product_management discount pricing unipay smssend accounting; do
if [ -d "pkgs/$mod" ]; then
"$cdir/py3/bin/pip" install "pkgs/$mod/" 2>&1 | tail -1
fi
done
# 6c. Runtime deps: pymupdfoffice-text-extract 技能的 pdf 提取脚本依赖)
"$cdir/py3/bin/pip" install pymupdf 2>&1 | tail -1
# 6b. Deploy skills: global(public skills) + packs(skill pack manifests)
if [ -d "pkgs/pipeline_core/skills_library" ]; then
mkdir -p "$cdir/skills/global"
# 公共技能:预置技能全量复制到 global所有 agent 默认加载,目录层按触发词匹配,正文按需 load_skill
cp -r "pkgs/pipeline_core/skills_library/all/." "$cdir/skills/global/"
# 技能集清单manifest 引用 global 里的技能名)
rm -rf "$cdir/skills/packs"
cp -r "pkgs/pipeline_core/skills_library/packs" "$cdir/skills/packs"
# 产线技能pipelines/{pipeline_id}/common/ + roles/{role}/SDLC 等产线默认规范loader 按此路径扫描)
rm -rf "$cdir/skills/pipelines"
if [ -d "pkgs/pipeline_core/skills_library/pipelines" ]; then
cp -r "pkgs/pipeline_core/skills_library/pipelines" "$cdir/skills/pipelines"
echo " skills: pipelines(产线技能) 已部署,共 $(ls "$cdir/skills/pipelines" | wc -l) 个产线"
fi
echo " skills: global(公共技能)+packs(技能集) 已部署global 共 $(ls "$cdir/skills/global" | wc -l) 个技能"
fi
# 7. Regenerate CRUD from json for all pipeline modules
for mod in appbase pipeline_core pipeline_ops pipeline_dist pipeline-sdlc rbac dapi accounting; do
json_dir="pkgs/$mod/json"
models_dir="pkgs/$mod/models"
wwwroot_dir="pkgs/$mod/wwwroot"
if [ -d "$json_dir" ] && ls "$json_dir"/*.json >/dev/null 2>&1; then
cd "$json_dir"
"$cdir/py3/bin/xls2ui" -m "../models" -o "../wwwroot" "$mod" *.json 2>&1 | grep -c 'handle' | xargs -I{} echo " xls2ui $mod: {} tables"
cd "$cdir"
fi
done
# 8. Link module wwwroot directories (symlinks from pkgs/)
for mod in pipeline-sdlc showcase tenant pipeline_core pipeline_ops pipeline_dist appbase app_audit product_management discount pricing unipay rbac dapi accounting; do
src="pkgs/$mod/wwwroot"
dst="wwwroot/$mod"
if [ -d "$src" ]; then
rm -rf "$dst" 2>/dev/null
ln -sf "../pkgs/$mod/wwwroot" "$dst"
echo " wwwroot: $mod linked"
fi
done
# pipeline_task has no separate module
mkdir -p wwwroot/pipeline_task
# 9. Sync password_key from Sage (not databases — those are app-specific)
if [ -f /d/apitest/sage/conf/config.json ]; then
python3 -c "
import json
cs=json.load(open('/d/apitest/sage/conf/config.json'))
c=json.load(open('$cdir/conf/config.json'))
c['password_key']=cs.get('password_key','')
json.dump(c,open('$cdir/conf/config.json','w'),ensure_ascii=False,indent=2)
print(' config: password_key synced')
"
fi
# 10. Create runtime dirs
mkdir -p "$cdir/logs" "$cdir/files" "$cdir/conf" "$cdir/bin"
# 10.5 Install bwrap (zero-root: 系统已有则复用,否则 apt download + dpkg -x)
if [ ! -x "$cdir/bin/bwrap" ]; then
if command -v bwrap >/dev/null 2>&1; then
cp "$(command -v bwrap)" "$cdir/bin/bwrap" 2>/dev/null || true
else
tmpd=$(mktemp -d)
( cd "$tmpd" && apt download bubblewrap >/dev/null 2>&1 && dpkg -x bubblewrap*.deb . && cp usr/bin/bwrap "$cdir/bin/bwrap" ) 2>/dev/null || true
rm -rf "$tmpd"
fi
fi
if [ -x "$cdir/bin/bwrap" ]; then
echo " bwrap: $("$cdir/bin/bwrap" --version 2>/dev/null | head -1)"
else
echo " WARN: bwrap not available (deploy sandbox will degrade to dir isolation)"
fi
# 10.8 Install Nodeoffice 技能脚本依赖,无 sudo官方预编译二进制
# 解压到 bin/nodejs/symlink node/npm/npx 到 bin/start.sh 已把 $cdir/bin 加进 PATH
NODE_VER="v22.23.2"
if [ ! -x "$cdir/bin/nodejs/bin/node" ]; then
echo " node: downloading $NODE_VER (linux-x64) ..."
tmpn=$(mktemp -d)
if curl -sL --max-time 180 "https://nodejs.org/dist/$NODE_VER/node-$NODE_VER-linux-x64.tar.xz" -o "$tmpn/node.tar.xz" && \
tar -xJf "$tmpn/node.tar.xz" -C "$tmpn"; then
mkdir -p "$cdir/bin/nodejs"
cp -a "$tmpn/node-$NODE_VER-linux-x64/." "$cdir/bin/nodejs/"
else
echo " WARN: node 下载失败office 技能脚本不可用)"
fi
rm -rf "$tmpn"
fi
ln -sf nodejs/bin/node "$cdir/bin/node"
ln -sf nodejs/bin/npm "$cdir/bin/npm"
ln -sf nodejs/bin/npx "$cdir/bin/npx"
if [ -x "$cdir/bin/node" ]; then
echo " node: $("$cdir/bin/node" --version)"
fi
# 6. Fix auto-assign created_by in CRUD dspys (xls2ui overwritten)
for d in sd_projects sd_iterations; do
for t in add update; do
f="$cdir/wwwroot/pipeline-sdlc/$d/${t}_${d}.dspy"
[ -f "$f" ] && grep -q 'created_by' "$f" || sed -i "s/ns\['org_id'\] = userorgid/ns['org_id'] = userorgid\nns['created_by'] = userorgid/" "$f"
done
done
# 6b. Inject session-current-project filter into generated get dspys (迭代/Bug/测试用例 用会话当前项目,无项目报错)
if [ -f "$cdir/scripts/inject_project_filter.py" ]; then
"$cdir/py3/bin/python" "$cdir/scripts/inject_project_filter.py" "$cdir/wwwroot/pipeline-sdlc" || echo " WARN: inject_project_filter.py failed"
fi
# 10.6 Create module tables (models -> DDL -> execute)
echo "=== Module table creation ==="
if [ -f "$cdir/scripts/create_tables.py" ]; then
"$cdir/py3/bin/python" "$cdir/scripts/create_tables.py" || echo " WARN: create_tables.py failed (DB not ready?)"
else
echo " WARN: scripts/create_tables.py not found"
fi
# 10.7 Import module init data (appcodes dictionaries)
echo "=== Module init data import ==="
if [ -f "$cdir/scripts/import_init.py" ]; then
"$cdir/py3/bin/python" "$cdir/scripts/import_init.py" || echo " WARN: import_init.py failed (DB not ready?)"
else
echo " WARN: scripts/import_init.py not found"
fi
# 11. Import RBAC permissions from conf/rp.json (r:p 数据 -> permission + rolepermission)
echo "=== RBAC permission import ==="
if [ -f "$cdir/scripts/import_rp.py" ]; then
"$cdir/py3/bin/python" "$cdir/scripts/import_rp.py" || echo " WARN: import_rp.py failed (DB not ready?)"
else
echo " WARN: scripts/import_rp.py not found"
fi
# 11.5 汇率自动获取定时任务(每日 8:00 抓取中国银行外汇牌价)
# accounting 模块 fetch_forex_rates.dspyUSD/JPY/GBP → CNY幂等写入 exchange_rate
if [ -f "$cdir/pkgs/accounting/wwwroot/api/fetch_forex_rates.dspy" ]; then
forex_cron="0 8 * * * curl -s http://localhost:9090/accounting/api/fetch_forex_rates.dspy"
cc=$(crontab -l 2>/dev/null || true)
if ! echo "$cc" | grep -Fq "fetch_forex_rates"; then
(echo "$cc"; echo "$forex_cron") | crontab -
echo " cron: 汇率任务已添加(每日 8:00"
else
echo " cron: 汇率任务已存在,未重复添加"
fi
fi
chmod +x "$cdir/start.sh" "$cdir/stop.sh" 2>/dev/null || true
echo "=== Build complete ==="