Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| acb77a821c | |||
| 2fcd4d093a | |||
| fcecce0595 | |||
| fbe92a4e7c | |||
| 4df29b70cd |
234
README.md
234
README.md
@@ -1,31 +1,47 @@
|
||||
# DevOps Skills
|
||||

|
||||
|
||||
Issue-Driven DevOps 平台技能仓库,核心产品是 `gitea-issue-devops-agent`。
|
||||
# gitea-issue-devops-agent
|
||||
|
||||
它把交付流程固化为:
|
||||
|
||||
`Issue -> Branch -> Preview Slot -> Test Loop -> Human-Confirmed Merge`
|
||||
> **Issue-Driven DevOps 产品官网**
|
||||
> 把 `Issue -> Branch -> Preview Slot -> Test Loop -> Human-Confirmed Merge` 变成标准交付引擎。
|
||||
|
||||
## 公网产品页
|
||||
|
||||
- 产品官网:`https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/site/index.html`
|
||||
- 产品官网(独立前端渲染页,非 Wiki):`https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/site/index.svg`
|
||||
- 仓库入口:`https://fun-md.com/Fun_MD/devops-skills`
|
||||
- HTML 设计稿源码:`site/index.html`
|
||||
- SVG 官网文件:`site/index.svg`
|
||||
|
||||
## 核心价值
|
||||
|
||||
### 1) 分支隔离提测
|
||||
|
||||
每个 issue 固定独立分支和预览槽位,主干保持稳定回归,避免提测互相覆盖。
|
||||
|
||||
### 2) 智能节省资源
|
||||
|
||||
按改动自动识别部署策略:`skip / client_only / server_only / full_stack / infra_only`。
|
||||
**服务端未变更就不重启服务端**。
|
||||
|
||||
### 3) 证据化闭环
|
||||
|
||||
提测沉淀 commit、测试链接、环境 URL、验证步骤;最终合并必须工程师人工确认。
|
||||
|
||||
## 一键安装
|
||||
|
||||
Linux:
|
||||
### Linux
|
||||
|
||||
```bash
|
||||
curl -fsSL https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/install/install.sh | bash
|
||||
```
|
||||
|
||||
macOS:
|
||||
### macOS
|
||||
|
||||
```bash
|
||||
curl -fsSL https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/install/install.sh | bash
|
||||
```
|
||||
|
||||
Windows (PowerShell):
|
||||
### Windows (PowerShell)
|
||||
|
||||
```powershell
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/install/install.ps1 | iex"
|
||||
@@ -35,25 +51,199 @@ powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://fun-md
|
||||
|
||||
- `~/.codex/skills/gitea-issue-devops-agent`
|
||||
|
||||
## 工具使用说明
|
||||
|
||||
### issue_audit.py
|
||||
|
||||
```bash
|
||||
python skills/gitea-issue-devops-agent/scripts/issue_audit.py \
|
||||
--base-url https://fun-md.com \
|
||||
--repo FunMD/document-collab \
|
||||
--token <TOKEN> \
|
||||
--state all \
|
||||
--download-attachments \
|
||||
--output-dir .tmp/issue-audit
|
||||
```
|
||||
|
||||
### change_scope.py
|
||||
|
||||
```bash
|
||||
python skills/gitea-issue-devops-agent/scripts/change_scope.py --repo-path . --base-ref origin/main --head-ref HEAD
|
||||
```
|
||||
|
||||
### preview_slot_allocator.py
|
||||
|
||||
```bash
|
||||
python skills/gitea-issue-devops-agent/scripts/preview_slot_allocator.py --state-file .tmp/preview-slots.json --slots preview-a,preview-b --repo FunMD/document-collab --issue 48 --branch dev --ttl-hours 24 --url-template https://{slot}.qa.example.com --evict-oldest
|
||||
```
|
||||
|
||||
## 工作流模板
|
||||
|
||||
- `.gitea/workflows/issue-branch-preview.yml`
|
||||
- `.gitea/workflows/preview-slot-reclaim.yml`
|
||||
- `.gitea/workflows/publish-site.yml`
|
||||
|
||||
## Skills 调用前置信息(Claude Code / Codex / OpenCode)
|
||||
|
||||
统一建议先准备这组参数:
|
||||
|
||||
- `repo_url`
|
||||
- `api_key`(Gitea token,需 issue 读写权限)
|
||||
- `mode`(`automatic` / `semi-automatic` / `manual`)
|
||||
- 可选:`reviewers`、`test_entry`、`deploy_env`、`health_endpoint`、`min_quality_score`
|
||||
|
||||
### Claude Code
|
||||
|
||||
Skills 目录(官方支持):
|
||||
|
||||
- 用户级:`~/.claude/skills/<skill-name>/SKILL.md`
|
||||
- 项目级:`.claude/skills/<skill-name>/SKILL.md`
|
||||
|
||||
唤起方式:
|
||||
|
||||
- 显式调用:`/<skill-name> [args]`
|
||||
- 对话调用:直接说“使用某个 skill 处理任务”
|
||||
|
||||
示例:
|
||||
|
||||
```text
|
||||
/gitea-issue-devops-agent repo_url=https://fun-md.com/FunMD/document-collab mode=automatic
|
||||
```
|
||||
|
||||
```text
|
||||
请使用 gitea-issue-devops-agent,连接 repo_url=...,api_key=...,以 semi-automatic 模式处理 issue #48
|
||||
```
|
||||
|
||||
### Codex
|
||||
|
||||
Skills 安装目录(当前方案):
|
||||
|
||||
- `~/.codex/skills/gitea-issue-devops-agent`
|
||||
|
||||
唤起方式:
|
||||
|
||||
- 对话显式点名:`$gitea-issue-devops-agent`
|
||||
- 或自然语言明确要求:`使用 gitea-issue-devops-agent skill`
|
||||
|
||||
示例:
|
||||
|
||||
```text
|
||||
$gitea-issue-devops-agent
|
||||
repo_url: https://fun-md.com/FunMD/document-collab
|
||||
api_key: <TOKEN>
|
||||
mode: automatic
|
||||
```
|
||||
|
||||
### OpenCode
|
||||
|
||||
Skills 目录(Claude skill 兼容):
|
||||
|
||||
- 项目级:`.opencode/skills/<skill-name>/SKILL.md`
|
||||
- 全局级:`~/.config/opencode/skills/<skill-name>/SKILL.md`
|
||||
|
||||
唤起方式:
|
||||
|
||||
- 对话里明确要求使用目标 skill(推荐)
|
||||
- Agent 内部会通过原生 `skill` 工具加载(`skill({name: "..."})`)
|
||||
|
||||
示例:
|
||||
|
||||
```text
|
||||
Use skill gitea-issue-devops-agent.
|
||||
repo_url=https://fun-md.com/FunMD/document-collab
|
||||
api_key=<TOKEN>
|
||||
mode=manual
|
||||
```
|
||||
|
||||
## `skills` 命令参数释义(重点补充)
|
||||
|
||||
> 本节把“`skills` 命令”统一理解为:在 Claude/Codex/OpenCode 中显式调用 `gitea-issue-devops-agent` 时提交的参数块。
|
||||
> 建议参数名如下,便于团队协作时统一模板和自动化脚本对接。
|
||||
|
||||
### 必填参数
|
||||
|
||||
| 参数 | 说明 | 典型值 | 使用场景 |
|
||||
| --- | --- | --- | --- |
|
||||
| `repo_url` | 目标仓库完整地址。优先使用完整 URL。 | `https://fun-md.com/Fun_MD/devops-skills` | 常规接入,避免 `base_url + owner/repo` 组合歧义 |
|
||||
| `api_key` | Gitea token,至少具备 issue 读写权限。 | `gta_xxx` | 需要读取 issue、评论、附件并回写提测证据 |
|
||||
| `mode` | 执行模式:`automatic` / `semi-automatic` / `manual`。 | `automatic` | 决定自动化程度和人工审批点 |
|
||||
|
||||
### 重要可选参数
|
||||
|
||||
| 参数 | 说明 | 典型值 | 使用场景 |
|
||||
| --- | --- | --- | --- |
|
||||
| `reviewers` | 指定评审人列表(逗号分隔)。 | `alice,bob` | `semi-automatic` 模式下提交后等待人工评审 |
|
||||
| `test_entry` | 分支提测入口(CI 命令或 job 名)。 | `gitea workflow run issue-branch-preview` | 多条流水线并存时明确提测入口 |
|
||||
| `main_env_url` | 主干稳定环境 URL。 | `https://main.qa.example.com` | 回归对比、基线验证 |
|
||||
| `shared_qa_url` | 共享 QA 环境 URL(可选)。 | `https://qa.example.com` | 需要跨分支集成验证 |
|
||||
| `preview_slots` | 预览槽位池。 | `preview-a,preview-b` | 多 issue 并行时的环境隔离与复用 |
|
||||
| `preview_url_template` | 槽位 URL 模板。 | `https://{slot}.qa.example.com` | 自动生成 issue 分支预览地址 |
|
||||
| `deploy_env` | 部署环境标识。 | `k8s-staging` | 一套技能同时驱动多环境 |
|
||||
| `health_endpoint` | 健康检查接口。 | `/healthz` | 提测后自动做可用性验证 |
|
||||
| `min_quality_score` | issue 最低质量分(默认 70)。 | `70` | 低质量 issue 先补充信息再进入开发 |
|
||||
| `skip_asset_endpoints` | 跳过 `/issues/*/assets` 端点抓图。 | `true` | 自建 Gitea 禁用了 assets API 时兜底 |
|
||||
| `target_base` | 变更比较基线分支。 | `origin/main` | 用于 `change_scope` 判断部署范围 |
|
||||
|
||||
### 参数组合示例(按场景)
|
||||
|
||||
#### 场景 1:日常 bug 修复,端到端自动执行
|
||||
|
||||
```text
|
||||
/gitea-issue-devops-agent \
|
||||
repo_url=https://fun-md.com/Fun_MD/devops-skills \
|
||||
api_key=<TOKEN> \
|
||||
mode=automatic \
|
||||
test_entry="issue-branch-preview" \
|
||||
main_env_url=https://main.qa.example.com \
|
||||
preview_slots=preview-a,preview-b \
|
||||
preview_url_template=https://{slot}.qa.example.com \
|
||||
min_quality_score=70
|
||||
```
|
||||
|
||||
适用:问题描述完整、团队希望最大化自动化吞吐。
|
||||
|
||||
#### 场景 2:生产敏感仓库,人工确认每一步
|
||||
|
||||
```text
|
||||
$gitea-issue-devops-agent
|
||||
repo_url: https://fun-md.com/Fun_MD/devops-skills
|
||||
api_key: <TOKEN>
|
||||
mode: manual
|
||||
deploy_env: prod-like-staging
|
||||
health_endpoint: /healthz
|
||||
```
|
||||
|
||||
适用:高风险改动、强合规流程、需要逐步确认分支/提交/提测/关闭。
|
||||
|
||||
#### 场景 3:半自动协作,先评审后提测
|
||||
|
||||
```text
|
||||
Use skill gitea-issue-devops-agent.
|
||||
repo_url=https://fun-md.com/Fun_MD/devops-skills
|
||||
api_key=<TOKEN>
|
||||
mode=semi-automatic
|
||||
reviewers=alice,bob
|
||||
test_entry=issue-branch-preview
|
||||
shared_qa_url=https://qa.example.com
|
||||
preview_slots=preview-a,preview-b,preview-c
|
||||
```
|
||||
|
||||
适用:多人协作项目,需要评审人显式批准后再进入提测和环境分配。
|
||||
|
||||
#### 场景 4:仅文档改动或轻量改动,资源最省策略
|
||||
|
||||
```text
|
||||
/gitea-issue-devops-agent repo_url=... api_key=... mode=automatic target_base=origin/main
|
||||
```
|
||||
|
||||
配合 `change_scope.py` 可自动得到 `skip` 或 `client_only`,避免不必要的服务端重启和环境开销。
|
||||
|
||||
## 技能路径
|
||||
|
||||
- `skills/gitea-issue-devops-agent/SKILL.md`
|
||||
|
||||
## 核心能力
|
||||
|
||||
- 三种执行模式:`automatic` / `semi-automatic` / `manual`
|
||||
- issue 图片证据抓取(含 attachments/assets 三路兜底)
|
||||
- 按变更范围部署(`skip` / `client_only` / `server_only` / `full_stack` / `infra_only`)
|
||||
- 预览槽位池分配与自动回收(TTL + 关闭释放)
|
||||
- 最终代码合并必须人工确认
|
||||
|
||||
## 核心脚本
|
||||
|
||||
- `skills/gitea-issue-devops-agent/scripts/issue_audit.py`
|
||||
- `skills/gitea-issue-devops-agent/scripts/change_scope.py`
|
||||
- `skills/gitea-issue-devops-agent/scripts/preview_slot_allocator.py`
|
||||
|
||||
## .gitea/workflows 模板
|
||||
|
||||
- `.gitea/workflows/issue-branch-preview.yml`
|
||||
- `.gitea/workflows/preview-slot-reclaim.yml`
|
||||
|
||||
213
site/index.svg
Normal file
213
site/index.svg
Normal file
@@ -0,0 +1,213 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="2500" viewBox="0 0 1600 2500">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#070c19"/>
|
||||
<stop offset="55%" stop-color="#102347"/>
|
||||
<stop offset="100%" stop-color="#0a3a4f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="accentGrad" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#29d8ff"/>
|
||||
<stop offset="100%" stop-color="#49f2c7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="cardGrad" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stop-color="#122445" stop-opacity="0.95"/>
|
||||
<stop offset="100%" stop-color="#0f1d38" stop-opacity="0.95"/>
|
||||
</linearGradient>
|
||||
<filter id="softGlow" x="-40%" y="-40%" width="180%" height="180%">
|
||||
<feGaussianBlur stdDeviation="18" result="blur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="blur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
<style>
|
||||
.title {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #ecf4ff;
|
||||
font-weight: 700;
|
||||
}
|
||||
.subtitle {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #b8c9e9;
|
||||
font-size: 30px;
|
||||
}
|
||||
.section-title {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #e7f1ff;
|
||||
font-size: 44px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.card-title {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #def2ff;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.card-text {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #bad0ee;
|
||||
font-size: 24px;
|
||||
}
|
||||
.mono {
|
||||
font-family: "Cascadia Mono", Consolas, Menlo, monospace;
|
||||
fill: #d8f1ff;
|
||||
font-size: 21px;
|
||||
}
|
||||
.label {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #88a6d4;
|
||||
font-size: 20px;
|
||||
}
|
||||
.badge {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #0a2b3f;
|
||||
font-size: 21px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.btn {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #06253a;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.btn-muted {
|
||||
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
fill: #d2e8ff;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<rect x="0" y="0" width="1600" height="2500" fill="url(#bgGrad)"/>
|
||||
<circle cx="1350" cy="240" r="260" fill="#29d8ff" opacity="0.13" filter="url(#softGlow)"/>
|
||||
<circle cx="180" cy="320" r="220" fill="#49f2c7" opacity="0.11" filter="url(#softGlow)"/>
|
||||
<circle cx="420" cy="2100" r="260" fill="#2fd8f0" opacity="0.10" filter="url(#softGlow)"/>
|
||||
|
||||
<rect x="70" y="70" width="1460" height="500" rx="32" fill="url(#cardGrad)" stroke="#345a90" stroke-width="2"/>
|
||||
<rect x="110" y="120" width="390" height="56" rx="28" fill="url(#accentGrad)"/>
|
||||
<text x="145" y="158" class="badge">Issue-Driven DevOps Platform</text>
|
||||
|
||||
<text x="110" y="255" class="title" font-size="74">gitea-issue-devops-agent</text>
|
||||
<text x="110" y="325" class="subtitle">把 Issue → Branch → Preview Slot → Test Loop → Human-Confirmed Merge 变成标准交付引擎</text>
|
||||
<text x="110" y="372" class="subtitle">不是临时脚本,而是可规模化的研发基础设施产品。</text>
|
||||
|
||||
<rect x="110" y="415" width="260" height="82" rx="14" fill="url(#accentGrad)"/>
|
||||
<text x="152" y="468" class="btn">访问仓库</text>
|
||||
<a href="https://fun-md.com/Fun_MD/devops-skills">
|
||||
<rect x="110" y="415" width="260" height="82" rx="14" fill="#ffffff" opacity="0.001"/>
|
||||
</a>
|
||||
|
||||
<rect x="390" y="415" width="330" height="82" rx="14" fill="#1b3157" stroke="#4068a5"/>
|
||||
<text x="445" y="468" class="btn-muted">SKILL 规范文档</text>
|
||||
<a href="https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/skills/gitea-issue-devops-agent/SKILL.md">
|
||||
<rect x="390" y="415" width="330" height="82" rx="14" fill="#ffffff" opacity="0.001"/>
|
||||
</a>
|
||||
|
||||
<rect x="820" y="150" width="660" height="340" rx="22" fill="#0c1a34" stroke="#34598e"/>
|
||||
<text x="860" y="215" class="label">核心指标</text>
|
||||
<text x="860" y="285" class="title" font-size="58">3 Modes</text>
|
||||
<text x="860" y="325" class="label">automatic / semi-automatic / manual</text>
|
||||
<text x="1160" y="285" class="title" font-size="58">5 Scopes</text>
|
||||
<text x="1160" y="325" class="label">skip / client / server / full / infra</text>
|
||||
<text x="860" y="390" class="title" font-size="58">1 : 1 Binding</text>
|
||||
<text x="860" y="430" class="label">Issue - Branch - Preview Slot 精确绑定</text>
|
||||
<text x="1160" y="390" class="title" font-size="58">TTL Reclaim</text>
|
||||
<text x="1160" y="430" class="label">空闲槽位自动回收</text>
|
||||
|
||||
<text x="80" y="680" class="section-title">产品核心价值</text>
|
||||
<rect x="80" y="715" width="460" height="280" rx="20" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="110" y="785" class="card-title">1. 分支隔离提测</text>
|
||||
<text x="110" y="835" class="card-text">每个 issue 固定分支和预览环境,</text>
|
||||
<text x="110" y="872" class="card-text">主干环境稳定回归,提测互不覆盖。</text>
|
||||
<text x="110" y="909" class="card-text">团队并行效率显著提升。</text>
|
||||
|
||||
<rect x="570" y="715" width="460" height="280" rx="20" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="600" y="785" class="card-title">2. 资源智能节流</text>
|
||||
<text x="600" y="835" class="card-text">按改动自动识别部署范围,</text>
|
||||
<text x="600" y="872" class="card-text">前端-only 改动不重启服务端,</text>
|
||||
<text x="600" y="909" class="card-text">节省机器和运维成本。</text>
|
||||
|
||||
<rect x="1060" y="715" width="460" height="280" rx="20" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="1090" y="785" class="card-title">3. 证据化闭环</text>
|
||||
<text x="1090" y="835" class="card-text">提测结果、commit、环境链接、</text>
|
||||
<text x="1090" y="872" class="card-text">验证步骤统一沉淀,</text>
|
||||
<text x="1090" y="909" class="card-text">最终合并始终人工确认。</text>
|
||||
|
||||
<text x="80" y="1090" class="section-title">流程拓扑(Issue 到交付)</text>
|
||||
<rect x="80" y="1125" width="1440" height="220" rx="20" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<rect x="112" y="1170" width="250" height="130" rx="14" fill="#13284b" stroke="#3d639b"/>
|
||||
<text x="138" y="1223" class="card-title" font-size="26">1. 引导连接</text>
|
||||
<text x="138" y="1263" class="card-text" font-size="20">repo_url + api_key + mode</text>
|
||||
<rect x="402" y="1170" width="250" height="130" rx="14" fill="#13284b" stroke="#3d639b"/>
|
||||
<text x="430" y="1223" class="card-title" font-size="26">2. 质量审计</text>
|
||||
<text x="430" y="1263" class="card-text" font-size="20">Issue + 图片附件 + 去重评分</text>
|
||||
<rect x="692" y="1170" width="250" height="130" rx="14" fill="#13284b" stroke="#3d639b"/>
|
||||
<text x="720" y="1223" class="card-title" font-size="26">3. 分支修复</text>
|
||||
<text x="720" y="1263" class="card-text" font-size="20">严格在 issue 分支迭代</text>
|
||||
<rect x="982" y="1170" width="250" height="130" rx="14" fill="#13284b" stroke="#3d639b"/>
|
||||
<text x="1007" y="1223" class="card-title" font-size="26">4. 按范围部署</text>
|
||||
<text x="1007" y="1263" class="card-text" font-size="20">skip/client/server/full/infra</text>
|
||||
<rect x="1272" y="1170" width="216" height="130" rx="14" fill="#13284b" stroke="#3d639b"/>
|
||||
<text x="1300" y="1223" class="card-title" font-size="26">5. 自动回收</text>
|
||||
<text x="1300" y="1263" class="card-text" font-size="20">TTL + Close Release</text>
|
||||
|
||||
<line x1="362" y1="1235" x2="402" y2="1235" stroke="#58d8ff" stroke-width="4"/>
|
||||
<line x1="652" y1="1235" x2="692" y2="1235" stroke="#58d8ff" stroke-width="4"/>
|
||||
<line x1="942" y1="1235" x2="982" y2="1235" stroke="#58d8ff" stroke-width="4"/>
|
||||
<line x1="1232" y1="1235" x2="1272" y2="1235" stroke="#58d8ff" stroke-width="4"/>
|
||||
|
||||
<text x="80" y="1440" class="section-title">一键安装命令(Windows / macOS / Linux)</text>
|
||||
|
||||
<rect x="80" y="1480" width="470" height="300" rx="18" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="110" y="1542" class="card-title">Linux</text>
|
||||
<rect x="110" y="1568" width="410" height="178" rx="12" fill="#091327" stroke="#406aa6"/>
|
||||
<text x="130" y="1620" class="mono">curl -fsSL https://fun-md.com/Fun_MD/</text>
|
||||
<text x="130" y="1656" class="mono">devops-skills/raw/branch/main/install/</text>
|
||||
<text x="130" y="1692" class="mono">install.sh | bash</text>
|
||||
|
||||
<rect x="565" y="1480" width="470" height="300" rx="18" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="595" y="1542" class="card-title">macOS</text>
|
||||
<rect x="595" y="1568" width="410" height="178" rx="12" fill="#091327" stroke="#406aa6"/>
|
||||
<text x="615" y="1620" class="mono">curl -fsSL https://fun-md.com/Fun_MD/</text>
|
||||
<text x="615" y="1656" class="mono">devops-skills/raw/branch/main/install/</text>
|
||||
<text x="615" y="1692" class="mono">install.sh | bash</text>
|
||||
|
||||
<rect x="1050" y="1480" width="470" height="300" rx="18" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="1080" y="1542" class="card-title">Windows PowerShell</text>
|
||||
<rect x="1080" y="1568" width="410" height="178" rx="12" fill="#091327" stroke="#406aa6"/>
|
||||
<text x="1100" y="1610" class="mono">powershell -NoProfile -ExecutionPolicy</text>
|
||||
<text x="1100" y="1646" class="mono">Bypass -Command "iwr -useb https://</text>
|
||||
<text x="1100" y="1682" class="mono">fun-md.com/Fun_MD/devops-skills/raw/</text>
|
||||
<text x="1100" y="1718" class="mono">branch/main/install/install.ps1 | iex"</text>
|
||||
|
||||
<text x="80" y="1878" class="section-title">核心工具</text>
|
||||
<rect x="80" y="1915" width="470" height="360" rx="18" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="110" y="1976" class="card-title">issue_audit.py</text>
|
||||
<text x="110" y="2014" class="card-text">拉取 issue / 评论 / 图片附件,去重并评分。</text>
|
||||
<rect x="110" y="2042" width="410" height="205" rx="12" fill="#091327" stroke="#406aa6"/>
|
||||
<text x="130" y="2091" class="mono">python .../issue_audit.py --base-url</text>
|
||||
<text x="130" y="2127" class="mono">https://fun-md.com --repo FunMD/</text>
|
||||
<text x="130" y="2163" class="mono">document-collab --token <TOKEN></text>
|
||||
<text x="130" y="2199" class="mono">--download-attachments</text>
|
||||
|
||||
<rect x="565" y="1915" width="470" height="360" rx="18" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="595" y="1976" class="card-title">change_scope.py</text>
|
||||
<text x="595" y="2014" class="card-text">识别部署范围,决定是否重启服务端。</text>
|
||||
<rect x="595" y="2042" width="410" height="205" rx="12" fill="#091327" stroke="#406aa6"/>
|
||||
<text x="615" y="2091" class="mono">python .../change_scope.py</text>
|
||||
<text x="615" y="2127" class="mono">--repo-path . --base-ref origin/main</text>
|
||||
<text x="615" y="2163" class="mono">--head-ref HEAD</text>
|
||||
|
||||
<rect x="1050" y="1915" width="470" height="360" rx="18" fill="url(#cardGrad)" stroke="#35598f"/>
|
||||
<text x="1080" y="1976" class="card-title">preview_slot_allocator.py</text>
|
||||
<text x="1080" y="2014" class="card-text">分配 / 复用 / 释放预览槽位。</text>
|
||||
<rect x="1080" y="2042" width="410" height="205" rx="12" fill="#091327" stroke="#406aa6"/>
|
||||
<text x="1100" y="2091" class="mono">python .../preview_slot_allocator.py</text>
|
||||
<text x="1100" y="2127" class="mono">--state-file .tmp/preview-slots.json</text>
|
||||
<text x="1100" y="2163" class="mono">--slots preview-a,preview-b --evict-oldest</text>
|
||||
|
||||
<rect x="80" y="2330" width="1440" height="110" rx="18" fill="#0b1730" stroke="#395d96"/>
|
||||
<text x="120" y="2383" class="label">官网入口: https://fun-md.com/Fun_MD/devops-skills/raw/branch/main/site/index.svg</text>
|
||||
<text x="120" y="2418" class="label">仓库地址: https://fun-md.com/Fun_MD/devops-skills</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -25,6 +25,8 @@ Run this interaction before any coding or issue action:
|
||||
- optional shared QA URL
|
||||
- preview slot pool (for issue branches), e.g. `preview-a,preview-b`
|
||||
- preview URL template, e.g. `https://{slot}.qa.example.com`
|
||||
- public routing mode: `port-based` or `virtual-host`
|
||||
- websocket public entry: explicit WS URL (`wss://...`) or same-origin path (`/ws`)
|
||||
- deployment environment + health endpoint
|
||||
- minimum issue quality score (default `70`)
|
||||
5. Validate connectivity by running:
|
||||
@@ -93,6 +95,14 @@ Always avoid `main` and issue branches overwriting each other.
|
||||
|
||||
Never deploy different branches to the same fixed URL unless user explicitly approves override.
|
||||
|
||||
### Routing Strategy (Recommended)
|
||||
|
||||
- Prefer `virtual-host` over raw ports for multi-branch testing:
|
||||
- `main.example.com`, `preview-a.example.com`, `preview-b.example.com`
|
||||
- Keep internal process ports private; expose only 80/443.
|
||||
- Use same-origin WS path for frontend (`VITE_WS_URL=/ws`) and route `/ws/*` to the slot server.
|
||||
- If `port-based` is used, every active env must have unique client/server ports; never reuse one public URL for two branches.
|
||||
|
||||
## Issue -> Branch -> Environment Binding
|
||||
|
||||
- Binding key: `<repo>#<issue>#<branch>`
|
||||
@@ -171,6 +181,7 @@ Hard rule:
|
||||
- Submit testing on the issue branch (CI pipeline + branch preview env).
|
||||
- Allocate/reuse branch slot before submission.
|
||||
- Apply resource-aware deployment decision from change scope.
|
||||
- Verify websocket handshake is healthy on the published preview URL/path before asking QA to test.
|
||||
- Post evidence in issue comment:
|
||||
- commit SHA
|
||||
- test run URL and result
|
||||
@@ -232,3 +243,5 @@ Close issue only when all are true:
|
||||
- Never bypass engineer merge confirmation.
|
||||
- Never allow branch previews to overwrite main stable env.
|
||||
- Never start dedicated branch server when scope indicates client-only changes.
|
||||
- When changing public service ports under PM2, do not rely on `pm2 restart --update-env` alone; delete and recreate the process so CLI args (for example `--port`) actually change.
|
||||
- If a branch must be rebound to a specific preview slot (for example `preview-a`), release the existing issue allocation first, then redeploy; reuse logic otherwise keeps the previous slot by design.
|
||||
|
||||
Reference in New Issue
Block a user