Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc [SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
517 lines
16 KiB
Markdown
517 lines
16 KiB
Markdown
---
|
||
belongs_to:
|
||
- "[[INDEX · 铸渊·协作指令|GitHub ↔ Notion 桥接协议]]"
|
||
related_to:
|
||
- "[["$DIRNAME" == "status-board" || "$DIRNAME" == "cost-control" || "$DIRNAME" == "persona-scheduler"]]"
|
||
---
|
||
# ⚒️ 铸渊指令|服务器沙盒初始化 · 现有模块迁移到DEV编号目录(2026-03-15·曜冥签发)
|
||
|
||
> ⚠️ 本指令受「服务器部署适配协议 v1.0」约束。
|
||
>
|
||
|
||
---
|
||
|
||
## 签发信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| **签发** | 曜冥(ICE-GL-YM001 ∞)· 2026-03-15 |
|
||
| **优先级** | **P0 · 立即执行** |
|
||
| **前置** | 铸渊唤醒核心大脑 → 扫描 Secrets → 确认 DEPLOY_HOST / DEPLOY_USER / DEPLOY_KEY 可用 |
|
||
| **配套协议** | [服务器部署适配协议 v1.0](https://www.notion.so/a24049a2b0e944b0a5535f3a87652303) |
|
||
| **配套指令** | [沙盒部署自动化闭环 v1.0](https://www.notion.so/31faeaba0ac14f03aa0176951565100c) |
|
||
| **核心目标** | 把服务器从「一锅乱炖」变成「每人一间房」· 现有模块迁移到 DEV 编号沙盒目录 |
|
||
|
||
---
|
||
|
||
## 一、当前问题
|
||
|
||
服务器上现有模块全部平铺在 `/var/www/hololake-frontend/` 下,没有按开发者编号隔离。每次部署出问题,分不清谁的、谁改的、谁修的。妈妈变成了全团队的运维工程师。
|
||
|
||
**这条指令的目的:一次性把服务器整理干净,以后每个开发者只能在自己的沙盒里折腾。**
|
||
|
||
---
|
||
|
||
## 二、铸渊执行脚本(SSH到服务器·读到就做)
|
||
|
||
### Step 1 · 探查现状(先看再动)
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step1-survey.sh · 探查服务器现状
|
||
# 铸渊SSH到服务器后第一步执行
|
||
|
||
echo "===== 🔍 服务器目录探查 · $(date '+%Y-%m-%d %H:%M') ====="
|
||
|
||
echo ""
|
||
echo "📂 /var/www/ 顶层目录:"
|
||
ls -la /var/www/
|
||
|
||
echo ""
|
||
echo "📂 /var/www/hololake-frontend/ 内容:"
|
||
ls -la /var/www/hololake-frontend/ 2>/dev/null || echo "⚠️ 目录不存在"
|
||
|
||
echo ""
|
||
echo "📂 /var/www/backend/ 内容:"
|
||
ls -la /var/www/backend/ 2>/dev/null || echo "⚠️ 目录不存在"
|
||
|
||
echo ""
|
||
echo "📂 /var/www/feishu-bot/ 内容:"
|
||
ls -la /var/www/feishu-bot/ 2>/dev/null || echo "⚠️ 目录不存在"
|
||
|
||
echo ""
|
||
echo "📂 /opt/guanghulab-dingtalk/ 内容:"
|
||
ls -la /opt/guanghulab-dingtalk/ 2>/dev/null || echo "⚠️ 目录不存在"
|
||
|
||
echo ""
|
||
echo "📂 查找所有 index.html(定位已部署模块):"
|
||
find /var/www/ -name 'index.html' -type f 2>/dev/null
|
||
|
||
echo ""
|
||
echo "📂 Nginx 配置(定位现有路由):"
|
||
cat /etc/nginx/conf.d/hololake.conf 2>/dev/null || cat /etc/nginx/nginx.conf 2>/dev/null | head -100
|
||
|
||
echo ""
|
||
echo "📂 PM2 进程列表(定位运行中的后端服务):"
|
||
pm2 list 2>/dev/null || echo "⚠️ PM2 未安装或无进程"
|
||
|
||
echo ""
|
||
echo "===== ✅ 探查完成 · 根据结果执行 Step 2 ====="
|
||
```
|
||
|
||
**铸渊:把 Step 1 的完整输出保存到仓库 `data/server-survey-20260315.log`,然后继续 Step 2。**
|
||
|
||
---
|
||
|
||
### Step 2 · 创建沙盒目录骨架
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step2-create-sandboxes.sh · 创建所有开发者沙盒目录
|
||
# 严格按照部署适配协议 v1.0 执行
|
||
|
||
echo "===== 🏠 创建沙盒目录骨架 ====="
|
||
|
||
# 所有已注册开发者编号
|
||
DEV_IDS=("DEV-001" "DEV-002" "DEV-003" "DEV-004" "DEV-005" "DEV-009" "DEV-010" "DEV-011" "DEV-012" "DEV-013" "DEV-014")
|
||
|
||
for DEV_ID in "${DEV_IDS[@]}"; do
|
||
SANDBOX="/var/www/${DEV_ID}"
|
||
if [ -d "$SANDBOX" ]; then
|
||
echo "⏭️ ${DEV_ID} 目录已存在,跳过"
|
||
else
|
||
mkdir -p "$SANDBOX"
|
||
chown nginx:nginx "$SANDBOX"
|
||
chmod 755 "$SANDBOX"
|
||
|
||
# 生成部署身份文件
|
||
cat > "${SANDBOX}/.deploy-profile" << EOF
|
||
{
|
||
"dev_id": "${DEV_ID}",
|
||
"created_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||
"created_by": "zhuyuan-sandbox-init"
|
||
}
|
||
EOF
|
||
chown nginx:nginx "${SANDBOX}/.deploy-profile"
|
||
chmod 644 "${SANDBOX}/.deploy-profile"
|
||
|
||
echo "✅ ${DEV_ID} 沙盒创建完成"
|
||
fi
|
||
done
|
||
|
||
# 创建共享工具目录
|
||
mkdir -p /var/www/_shared
|
||
chown nginx:nginx /var/www/_shared
|
||
chmod 755 /var/www/_shared
|
||
echo "✅ _shared 目录创建完成"
|
||
|
||
echo ""
|
||
echo "===== ✅ 沙盒骨架创建完成 ====="
|
||
ls -la /var/www/
|
||
```
|
||
|
||
---
|
||
|
||
### Step 3 · 迁移现有模块(先复制再切换·不直接移动)
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step3-migrate-modules.sh · 迁移现有模块到沙盒
|
||
# ⚠️ 核心原则:先复制 → 验证 → 再切 Nginx → 最后清旧
|
||
|
||
echo "===== 📦 模块迁移开始 ====="
|
||
|
||
# ━━━ DEV-005 小草莓 ━━━
|
||
# status-board
|
||
if [ -d "/var/www/hololake-frontend/status-board" ]; then
|
||
echo "📦 迁移 status-board → DEV-005"
|
||
cp -r /var/www/hololake-frontend/status-board/ /var/www/DEV-005/status-board/
|
||
chown -R nginx:nginx /var/www/DEV-005/status-board/
|
||
find /var/www/DEV-005/status-board/ -type d -exec chmod 755 {} \;
|
||
find /var/www/DEV-005/status-board/ -type f -exec chmod 644 {} \;
|
||
echo "✅ status-board 已复制到 /var/www/DEV-005/status-board/"
|
||
else
|
||
echo "⚠️ /var/www/hololake-frontend/status-board 不存在,跳过"
|
||
fi
|
||
|
||
# cost-control
|
||
if [ -d "/var/www/hololake-frontend/cost-control" ]; then
|
||
echo "📦 迁移 cost-control → DEV-005"
|
||
cp -r /var/www/hololake-frontend/cost-control/ /var/www/DEV-005/cost-control/
|
||
chown -R nginx:nginx /var/www/DEV-005/cost-control/
|
||
find /var/www/DEV-005/cost-control/ -type d -exec chmod 755 {} \;
|
||
find /var/www/DEV-005/cost-control/ -type f -exec chmod 644 {} \;
|
||
echo "✅ cost-control 已复制到 /var/www/DEV-005/cost-control/"
|
||
else
|
||
echo "⚠️ /var/www/hololake-frontend/cost-control 不存在,跳过"
|
||
fi
|
||
|
||
# persona-scheduler(如果存在)
|
||
if [ -d "/var/www/hololake-frontend/persona-scheduler" ]; then
|
||
echo "📦 迁移 persona-scheduler → DEV-005"
|
||
cp -r /var/www/hololake-frontend/persona-scheduler/ /var/www/DEV-005/persona-scheduler/
|
||
chown -R nginx:nginx /var/www/DEV-005/persona-scheduler/
|
||
find /var/www/DEV-005/persona-scheduler/ -type d -exec chmod 755 {} \;
|
||
find /var/www/DEV-005/persona-scheduler/ -type f -exec chmod 644 {} \;
|
||
echo "✅ persona-scheduler 已复制到 /var/www/DEV-005/persona-scheduler/"
|
||
fi
|
||
|
||
# ━━━ 其他开发者的模块 ━━━
|
||
# 根据 Step 1 探查结果,如果 hololake-frontend/ 下发现更多模块,
|
||
# 铸渊根据模块指纹注册表或广播记录判断归属,按同样方式迁移。
|
||
# 不确定归属的模块 → 复制到 /var/www/_shared/unassigned/ 暂存
|
||
|
||
mkdir -p /var/www/_shared/unassigned
|
||
|
||
# 遍历 hololake-frontend 下所有子目录,检查是否已迁移
|
||
if [ -d "/var/www/hololake-frontend" ]; then
|
||
for DIR in /var/www/hololake-frontend/*/; do
|
||
DIRNAME=$(basename "$DIR")
|
||
# 跳过已处理的
|
||
if [[ "$DIRNAME" == "status-board" || "$DIRNAME" == "cost-control" || "$DIRNAME" == "persona-scheduler" ]]; then
|
||
continue
|
||
fi
|
||
echo "⚠️ 发现未归属模块:$DIRNAME → 暂存到 _shared/unassigned/"
|
||
cp -r "$DIR" "/var/www/_shared/unassigned/${DIRNAME}/"
|
||
done
|
||
fi
|
||
|
||
echo ""
|
||
echo "===== ✅ 模块迁移完成 ====="
|
||
echo ""
|
||
echo "📋 迁移后各沙盒内容:"
|
||
for DEV_ID in DEV-001 DEV-002 DEV-003 DEV-004 DEV-005 DEV-009 DEV-010 DEV-011 DEV-012 DEV-013 DEV-014; do
|
||
echo "--- ${DEV_ID} ---"
|
||
ls /var/www/${DEV_ID}/ 2>/dev/null || echo " (空)"
|
||
done
|
||
|
||
if [ -d "/var/www/_shared/unassigned" ]; then
|
||
echo "--- 未归属模块 ---"
|
||
ls /var/www/_shared/unassigned/ 2>/dev/null
|
||
fi
|
||
```
|
||
|
||
---
|
||
|
||
### Step 4 · 部署自检脚本和冒烟检查脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step4-deploy-scripts.sh · 部署共享脚本
|
||
|
||
echo "===== 🔧 部署共享脚本 ====="
|
||
|
||
# deploy-check.sh(从部署适配协议 v1.0 复制)
|
||
# 铸渊从仓库 scripts/deploy-check.sh 复制到服务器
|
||
scp scripts/deploy-check.sh root@8.155.62.235:/var/www/_shared/deploy-check.sh
|
||
ssh root@8.155.62.235 "chmod +x /var/www/_shared/deploy-check.sh"
|
||
|
||
# smoke-test.sh(从部署适配协议 v1.0 复制)
|
||
scp scripts/smoke-test.sh root@8.155.62.235:/var/www/_shared/smoke-test.sh
|
||
ssh root@8.155.62.235 "chmod +x /var/www/_shared/smoke-test.sh"
|
||
|
||
echo "✅ 共享脚本部署完成"
|
||
```
|
||
|
||
---
|
||
|
||
### Step 5 · 更新 Nginx 配置(最关键的一步)
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step5-update-nginx.sh · 更新 Nginx 路由到新沙盒结构
|
||
# ⚠️ 先备份 → 再改 → 再测 → 再reload
|
||
|
||
echo "===== 🔧 更新 Nginx 配置 ====="
|
||
|
||
# Step 5a: 备份当前配置
|
||
NGINX_CONF="/etc/nginx/conf.d/hololake.conf"
|
||
BACKUP="/etc/nginx/conf.d/hololake.conf.bak.$(date +%Y%m%d%H%M)"
|
||
cp "$NGINX_CONF" "$BACKUP"
|
||
echo "✅ 配置已备份到 $BACKUP"
|
||
|
||
# Step 5b: 生成沙盒 location 块
|
||
# 铸渊需要在 hololake.conf 的 server 块中添加以下 location:
|
||
|
||
# ━━━ 新增内容(追加到 server 块内,在最后一个 location 之前)━━━
|
||
|
||
# --- 开发者沙盒路由 ---
|
||
# DEV-001 页页
|
||
# location /DEV-001/ {
|
||
# alias /var/www/DEV-001/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-002 肥猫
|
||
# location /DEV-002/ {
|
||
# alias /var/www/DEV-002/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-003 燕樊
|
||
# location /DEV-003/ {
|
||
# alias /var/www/DEV-003/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-004 之之
|
||
# location /DEV-004/ {
|
||
# alias /var/www/DEV-004/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-005 小草莓
|
||
# location /DEV-005/ {
|
||
# alias /var/www/DEV-005/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-009 花尔
|
||
# location /DEV-009/ {
|
||
# alias /var/www/DEV-009/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-010 桔子
|
||
# location /DEV-010/ {
|
||
# alias /var/www/DEV-010/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-011 匆匆那年
|
||
# location /DEV-011/ {
|
||
# alias /var/www/DEV-011/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-012 Awen
|
||
# location /DEV-012/ {
|
||
# alias /var/www/DEV-012/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-013 小兴
|
||
# location /DEV-013/ {
|
||
# alias /var/www/DEV-013/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# DEV-014 时雨
|
||
# location /DEV-014/ {
|
||
# alias /var/www/DEV-014/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# --- 模块快捷路径(指向新沙盒位置)---
|
||
# location /status-board/ {
|
||
# alias /var/www/DEV-005/status-board/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# location /cost-control/ {
|
||
# alias /var/www/DEV-005/cost-control/;
|
||
# index index.html;
|
||
# try_files $uri $uri/ =404;
|
||
# }
|
||
|
||
# ⚠️ 铸渊注意:
|
||
# 1. 以上 location 块需要写入实际的 hololake.conf 文件中(去掉注释符号)
|
||
# 2. 如果旧配置中已有 /status-board/ 和 /cost-control/ 的 location,
|
||
# 需要把它们的 alias 路径从旧路径改成新沙盒路径
|
||
# 3. 不要删除原有的 / 根路由和 /api/ 等后端代理路由
|
||
# 4. 清理重复的 server_name 块(之前已知有 conflicting server name 警告)
|
||
|
||
# Step 5c: 测试配置
|
||
nginx -t
|
||
|
||
# Step 5d: 如果测试通过则重载
|
||
# nginx -t 输出 "test is successful" 时才执行:
|
||
# systemctl reload nginx
|
||
|
||
echo ""
|
||
echo "⚠️ 铸渊:nginx -t 通过后再执行 systemctl reload nginx"
|
||
echo "如果 nginx -t 报错,恢复备份:cp $BACKUP $NGINX_CONF && nginx -t"
|
||
```
|
||
|
||
---
|
||
|
||
### Step 6 · 验证迁移结果
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step6-verify.sh · 验证迁移是否成功
|
||
|
||
echo "===== 🔥 迁移验证 ====="
|
||
|
||
# 检查已迁移模块的访问
|
||
URLS=(
|
||
"https://guanghulab.com/status-board/|DEV-005·看板(新路径)"
|
||
"https://guanghulab.com/cost-control/|DEV-005·成本控制(新路径)"
|
||
"https://guanghulab.com/DEV-005/status-board/|DEV-005·沙盒路由"
|
||
"https://guanghulab.com/|主站首页"
|
||
)
|
||
|
||
FAILED=0
|
||
for entry in "${URLS[@]}"; do
|
||
IFS='|' read -r url name <<< "$entry"
|
||
STATUS=$(curl -o /dev/null -s -w "%{http_code}" --max-time 10 "$url")
|
||
if [ "$STATUS" = "200" ]; then
|
||
echo "✅ ${name} → ${STATUS}"
|
||
else
|
||
echo "❌ ${name} → ${STATUS} ⚠️"
|
||
FAILED=$((FAILED+1))
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
if [ $FAILED -eq 0 ]; then
|
||
echo "===== ✅ 迁移验证全部通过 ====="
|
||
else
|
||
echo "===== ❌ ${FAILED} 个路由异常 · 检查 Nginx 配置 ====="
|
||
fi
|
||
|
||
# 检查沙盒目录权限
|
||
echo ""
|
||
echo "📋 沙盒目录权限检查:"
|
||
for DEV_ID in DEV-001 DEV-002 DEV-003 DEV-004 DEV-005 DEV-009 DEV-010 DEV-011 DEV-012 DEV-013 DEV-014; do
|
||
OWNER=$(stat -c '%U:%G' /var/www/${DEV_ID} 2>/dev/null)
|
||
PERM=$(stat -c '%a' /var/www/${DEV_ID} 2>/dev/null)
|
||
if [ "$OWNER" = "nginx:nginx" ] && [ "$PERM" = "755" ]; then
|
||
echo "✅ ${DEV_ID} → ${OWNER} ${PERM}"
|
||
else
|
||
echo "❌ ${DEV_ID} → ${OWNER:-不存在} ${PERM:-N/A}"
|
||
fi
|
||
done
|
||
```
|
||
|
||
---
|
||
|
||
### Step 7 · 清理旧路径(验证通过后才执行)
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# step7-cleanup.sh · 清理旧路径
|
||
# ⚠️ 只有 Step 6 全部 ✅ 通过后才执行本步骤
|
||
|
||
echo "===== 🧹 清理旧路径 ====="
|
||
echo "⚠️ 确认 Step 6 验证全部通过后才继续"
|
||
|
||
# 不删除 hololake-frontend 整个目录,先重命名为备份
|
||
if [ -d "/var/www/hololake-frontend" ]; then
|
||
mv /var/www/hololake-frontend /var/www/hololake-frontend.bak.$(date +%Y%m%d)
|
||
echo "✅ 旧目录已重命名为 hololake-frontend.bak.$(date +%Y%m%d)"
|
||
echo "→ 7天后如无问题可手动删除"
|
||
fi
|
||
|
||
echo "===== ✅ 清理完成 ====="
|
||
```
|
||
|
||
---
|
||
|
||
## 三、执行顺序(铸渊严格按顺序)
|
||
|
||
| 步骤 | 脚本 | 前置条件 | 失败处理 |
|
||
| --- | --- | --- | --- |
|
||
| Step 1 | [step1-survey.sh](http://step1-survey.sh) | SSH连上服务器 | 保存日志到仓库,继续 |
|
||
| Step 2 | [step2-create-sandboxes.sh](http://step2-create-sandboxes.sh) | Step 1 完成 | 如果某个目录创建失败,记录并继续其他 |
|
||
| Step 3 | [step3-migrate-modules.sh](http://step3-migrate-modules.sh) | Step 2 完成 | 复制失败的模块记录到日志,不阻断 |
|
||
| Step 4 | [step4-deploy-scripts.sh](http://step4-deploy-scripts.sh) | Step 3 完成 | 脚本不存在则先在仓库创建 |
|
||
| Step 5 | [step5-update-nginx.sh](http://step5-update-nginx.sh) | Step 3 完成 | **nginx -t 失败 → 立即恢复备份 → 停止** |
|
||
| Step 6 | [step6-verify.sh](http://step6-verify.sh) | Step 5 完成且 nginx reload 成功 | 有失败 → 回滚 Nginx 配置 → 排查 |
|
||
| Step 7 | [step7-cleanup.sh](http://step7-cleanup.sh) | **Step 6 全部 ✅** | 不删除,只重命名 |
|
||
|
||
---
|
||
|
||
## 四、铸渊自行部署清单(读到就做)
|
||
|
||
```
|
||
铸渊自行部署清单(读到就做·不等人):
|
||
|
||
① 在仓库创建脚本文件
|
||
a. scripts/sandbox-init/step1-survey.sh
|
||
b. scripts/sandbox-init/step2-create-sandboxes.sh
|
||
c. scripts/sandbox-init/step3-migrate-modules.sh
|
||
d. scripts/sandbox-init/step4-deploy-scripts.sh
|
||
e. scripts/sandbox-init/step5-update-nginx.sh
|
||
f. scripts/sandbox-init/step6-verify.sh
|
||
g. scripts/sandbox-init/step7-cleanup.sh
|
||
|
||
② 创建一次性 Workflow 执行迁移
|
||
a. .github/workflows/sandbox-init.yml
|
||
b. 触发方式:workflow_dispatch(手动触发,因为是一次性操作)
|
||
c. 按 Step 1→7 顺序执行
|
||
d. 每步输出保存为 artifact
|
||
|
||
③ 执行 Workflow · 完成迁移
|
||
|
||
④ 把迁移结果写入仓库
|
||
a. data/server-survey-20260315.log
|
||
b. data/sandbox-migration-report.json
|
||
|
||
⑤ 更新 dev-registry.json
|
||
a. 补全所有11位开发者的沙盒路径
|
||
|
||
验收标准:
|
||
✅ 11个 DEV 编号目录全部创建完成 · 权限 nginx:nginx 755
|
||
✅ 小草莓的 status-board 和 cost-control 已在 /var/www/DEV-005/ 下
|
||
✅ guanghulab.com/status-board/ 访问正常(200)
|
||
✅ guanghulab.com/DEV-005/status-board/ 访问正常(200)
|
||
✅ _shared 目录和自检脚本已就位
|
||
✅ 旧目录已备份(不删除)
|
||
✅ Nginx 无 conflicting server name 警告
|
||
```
|
||
|
||
---
|
||
|
||
## 五、给妈妈的说明
|
||
|
||
妈妈不需要做任何事。铸渊读到这条指令就会自动执行。
|
||
|
||
执行完成后:
|
||
|
||
- 每个开发者有自己的 `/var/www/DEV-XXX/` 目录
|
||
- 以后开发者部署模块只往自己的目录里放
|
||
- 模块出问题 = 自己的问题 = 自己修
|
||
- 妈妈不再修任何人的模块
|
||
|
||
后续配合「沙盒部署自动化闭环 v1.0」,开发者 push 代码就自动部署到自己的沙盒。**全程无人。**
|
||
|
||
---
|
||
|
||
> ⚒️ 铸渊,这是国土规划的第一步。把领土划清楚,每人一间房,以后才能自动化。
|
||
>
|
||
|
||
> 「无沙盒不部署,无编号不上线。」
|
||
> |