joy-cli/docs/ops/joy-forgejo-observe.md
feibisi 297c0ebc83 docs(ops): 神州 — joy web production/external plane design
Name production & external services 神州 (not 线上). Full IA: flywheel
vs code vs shenzhou, tab boundaries, data model, phased rollout,
read-only iron rules. Cross-link from forgejo observe doc.
2026-07-10 19:47:40 +08:00

102 lines
4.4 KiB
Markdown
Raw Permalink 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.

# joy web · 代码态势(三平面)
> Phase 3 · **态势而非仓库浏览器** · 2026-07-10
## 产品定义
| 是 | 否 |
|----|-----|
| CI 节点健康runner / zombie TASK | 自动清容器 / 重启 runner |
| 本地 Git dirty / ahead / behind | 在 joy 里 commit / push |
| 待处理 PR、CI 红、未读通知 | 迷你 GitHub 仓列表 |
| 镜像滞后/过期(供应链) | 1200 仓目录浏览 |
| 深链回 feicode.com | 替代 devops `fei` CLI |
**分工**feicode/Forgejo = 远程真源 · **本地 Git** = Mac 工作区 · **CI 节点** = devops + feicode-prod runner · **`fei`** = 代码操作 · **joy web 代码 tab** = 工程态势。
**与「神州」的边界**:公网站 SLA、生产主机磁盘/nginx、SSL → 见 [`joy-shenzhou.md`](./joy-shenzhou.md)(导航名 **神州**,不是「线上」)。同一台 `feicode-prod` 可两面切开——**runner/zombie 归代码**,站点与主机指标归神州。
## 三平面(一屏)
| # | 平面 | 数据源 | 看什么 |
|---|------|--------|--------|
| ① | CI/CD 节点 | SSH `devops` / `feicode-prod` | system unit / act_runner、zombie 归组workflow/image、recent task 镜像负载 |
| ② | 本地 Git | Mac `~/Projects/linuxjoy` + `joy-cli` | ahead/behind、dirty、linked worktrees |
| ③ | feicode API | `https://feicode.com/api/v1` | PR 人/机拆分、CI 红 streak/慢性、通知、镜像、自有热更新 |
### 深挖结论2026-07-10
| 信号 | 事实 | 处置边界 |
|------|------|----------|
| zombie ×7 | 全是 `Mautic-tests-and-validations` 留下的 mysql/mariadb service 容器Up 3 weeks | **只观察**;清理由 devops/change |
| runner 忙 | devops/feicode 日志大量 `mautic/*` `wp-cli/*`**镜像仓** `has_actions` 仍触发) | 策略:禁镜像 Actions 或限流(需 devops |
| open PR | listed 几乎全是 Renovate Configure`open_prs_human=0` 常见 | UI 人/机拆分bot 降权 |
| CI 红 | `feibisi/linuxjoy` `syntax` **连续失败 ≥5慢性** | 修 workflow / shellcheck非 runner 挂 |
| 本地 | main ahead 未推 + dirtylinuxjoy 多 worktree | 观察;不在 joy 里 push |
## 数据字段 `dashboard.forgejo`
```text
view: situation
planes: [feicode, ci_nodes, local_git]
ci_nodes: {
nodes[{ zombie_groups, recent_load{top,mirror_heavy}, ... }],
zombie_groups[], summary{runners_*, zombie_total, mirror_heavy_nodes}
}
local_git: { repos[{ worktrees{linked,paths} }], summary{dirty,ahead,linked_worktrees,...} }
attention: {
open_prs[], open_prs_human[], open_prs_bot[],
ci_red[{ streak, chronic, head_branch, age_hours }],
notifications[]
}
summary: {
open_prs_human, open_prs_bot, ci_red, ci_chronic,
ci_runners_*, ci_zombie, ci_mirror_heavy,
local_*, local_worktrees, attention_score
}
```
## 配置
- Token`~/.config/forgejo/token``JOY_FORGEJO_TOKEN`
- 白名单:`~/.config/joy/forgejo.yml`(见 `configs/forgejo.example.yml`
- `first_party_orgs` / `pinned_repos`
- `local_repos`:本地仓列表(默认 linuxjoy + joy-cli
- HTTP **强制不走系统代理**Mac 代理会导致 feicode 超时)
- CI 节点依赖 SSH 别名:`devops``feicode-prod`ProxyJump 见 linuxjoy SSH config
## 实测基线2026-07-10
| 节点 | 状态 |
|------|------|
| devops `forgejo-runner` system unit | activeuser unit 可能 inactive以 system 为准) |
| feicode-prod `forgejo-runner-01` | Upact_runner daemon |
| feicode-prod zombie TASK | 常见Mautic 相关 `GITEA-ACTIONS-TASK-*` 长期 Up |
zombie **只观察不清理**;清理属 change/control走 devops。
## 与 fei CLI
devops `~/bin/fei`clone / pr / issue / release / notify / admin / push…
Agent 写代码走 **fei**;人在飞轮里看 **joy 代码 tab**
## 验收
```bash
PYTHONPATH=~/Projects/joy-cli/src python3 -c "
from joy.dashboard.forgejo import collect_forgejo
import json
d=collect_forgejo()
print('ok', d.get('ok'), 'planes', d.get('planes'))
print('summary', json.dumps(d.get('summary'), ensure_ascii=False)[:400])
ci=d.get('ci_nodes') or {}
print('ci', (ci.get('summary') or {}))
for n in (ci.get('nodes') or []):
print(' ', n.get('id'), n.get('status'), 'zombie', n.get('zombie_count'))
lg=d.get('local_git') or {}
print('git', (lg.get('summary') or {}))
for r in (lg.get('repos') or []):
print(' ', r.get('id'), r.get('status'), 'ahead', r.get('ahead'), 'dirty', r.get('dirty'))
"
# 浏览器 → 代码 → 态势:应见 ① CI 节点 ② 本地 Git ③ PR/镜像
```