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.
4.4 KiB
4.4 KiB
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(导航名 神州,不是「线上」)。同一台 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 未推 + dirty;linuxjoy 多 worktree | 观察;不在 joy 里 push |
数据字段 dashboard.forgejo
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_reposlocal_repos:本地仓列表(默认 linuxjoy + joy-cli)
- HTTP 强制不走系统代理(Mac 代理会导致 feicode 超时)
- CI 节点依赖 SSH 别名:
devops、feicode-prod(ProxyJump 见 linuxjoy SSH config)
实测基线(2026-07-10)
| 节点 | 状态 |
|---|---|
devops forgejo-runner system unit |
active(user unit 可能 inactive,以 system 为准) |
feicode-prod forgejo-runner-01 |
Up(act_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。
验收
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/镜像