发布可以跟上只多了文档的测试环境头
四个生产工作流改用同一条发布修订:最近一次代码门禁成功的提交可以发布,后面只多文档不再挡住。生产环境拒绝测试验证码。63 个还没上生产的迁移写了分级、演练脚本和首发步骤。没有点任何生产按钮。 自测:发布修订 7 通过,演练安全 3 通过,tsc 0 错,lint 0 error。本机空库演练在服务角色读人物表处按设计停止(退出码 4,其他人物已确认行数为 0)。 Co-Authored-By: Grok (agent loop)
This commit is contained in:
co-authored by
Grok (agent loop)
parent
f4c53e7f9f
commit
00e6efdbfa
@@ -17930,3 +17930,33 @@
|
||||
- 复发自:无。
|
||||
- 修复版本:分支 `codex/node-runtime-resources-20261013`,尚未合入 staging。
|
||||
|
||||
## BUG-1348 | 测试环境后面多了文档,生产就发不出去
|
||||
|
||||
- 状态:fixed-pending-verify(代码和合同测试已有;生产按钮还没点,不能标 resolved)。
|
||||
- 首次发现 / 最近更新:2026-10-14 / 2026-10-14
|
||||
- 来源:issue #74。产品 2026-10-14 授权改四个生产工作流。
|
||||
- 现象:测试环境只要在最后一次代码提交后再推了文档,四个生产发布按钮全部拒绝。
|
||||
- 触发条件:要发布的提交没有自己的代码门禁记录,或者它不等于测试环境当前的头。
|
||||
- 根因:生产工作流仍要求「被发布的提交等于测试环境头,并且这个头自己有一次代码门禁」。文档提交不跑那道门禁。测试环境侧早就允许「最近一次门禁提交之后只前进文档」,生产侧没有跟上。
|
||||
- 修复:发布修订改成最近一次代码门禁成功的提交。测试环境头可以在它后面只多文档。四个生产工作流共用同一个判断。回滚仍要明确确认,并且目标必须在已审查的 main 历史里。
|
||||
- 验证:`tests/test_resolve_release_revision.py` 7 通过。工作流文本合同改去要求非回滚时「提交必须等于测试环境头」。生产还没实跑。
|
||||
- 防复发:上述测试锁住「中间改了代码就拒绝」「不是祖先就拒绝」「没有门禁运行就拒绝」「两个分支不一致就拒绝」「接口失败退出 2」。
|
||||
- 相关记录:无。
|
||||
- 复发自:无。
|
||||
- 修复版本:分支 `codex/release-path-production-20261014`。本树最大号原来是 BUG-1346。BUG-1347 在另一条尚未合入的分支上,所以这里用 1348,避免两条分支以后撞号。
|
||||
|
||||
## BUG-1349 | 生产环境如果配了测试验证码,任何人都能用固定码登录
|
||||
|
||||
- 状态:fixed-pending-verify(代码和测试已有;生产环境文件还没在主机上复检,不能标 resolved)。
|
||||
- 首次发现 / 最近更新:2026-10-14 / 2026-10-14
|
||||
- 来源:issue #74。
|
||||
- 现象:只要服务器配了 6 位测试验证码,登录就不区分是不是生产站。
|
||||
- 触发条件:生产环境变量里出现测试验证码,包括写成空值。
|
||||
- 根因:读取测试码时只检查位数,不看站点;生产环境校验脚本也没把它列为禁止项。
|
||||
- 修复:站点正好是生产域名时,配了测试码就拒绝启动。生产环境校验只要看见这个变量就失败。测试环境的行为不变。
|
||||
- 验证:身份配置测试覆盖生产站抛错、测试站仍返回验证码、未设置返回空。环境校验测试覆盖有值、空值都失败,没有这个变量则通过。
|
||||
- 防复发:上述两处测试。
|
||||
- 相关记录:BUG-1348。
|
||||
- 复发自:无。
|
||||
- 修复版本:分支 `codex/release-path-production-20261014`。编号跳过 BUG-1347,原因见 BUG-1348。
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# 生产待上线迁移(2026-10-14)
|
||||
|
||||
对照 `origin/main` 与本分支基线,`frontend/supabase/migrations` 新增 63 个文件,没有修改或删除。`frontend/db/migrations` 在这之间是 0 个。迁移文件本身不改。
|
||||
|
||||
分级看的是去掉函数体之后还留在文件顶层的语句。`A` 是用户能直接看见的改写或删除。`B` 是范围有限的改写。`C` 是顶层还有收回权限。`D` 是只加表、列、函数或授权。
|
||||
|
||||
任务书初筛是 A 2、B 5、C 约 45、D 其余。复核后是 A 2、B 7、C 42、D 12。多出来的两条 B 是写在匿名代码块里的标题修补,机械筛会把它们看成没有顶层更新。
|
||||
|
||||
重复的时间戳只记录、不改名:`20260816010000` 有两个文件,`20260920010000` 有两个文件。仓库里另外还有 `20260806010000` 和 `frontend/db/migrations` 的 `20260807010000`,不在这 63 个里面。
|
||||
|
||||
## 产品需知
|
||||
|
||||
- `20260921010000`:以前归档的会话会全部回到列表。这是取消归档功能时已经定过的。
|
||||
- `20260925020000`:人物表里「本人」那一行会删掉,本人资料只留在账户资料里。
|
||||
- `20260816010000_accept_exact_family_birth_times`:家人整点时间会变成已采用。
|
||||
- `20260822010000`:只知道时段的,会补上开始和结束钟点。
|
||||
- `20260823010000`:没有日期的职业、外貌、胎记证据会变成已确认。
|
||||
- `20260906030000`:时间完全未知且还没采用的校正,会先进入时段比较。
|
||||
- `20260916020000`:校正标题修补。生产上预期是 0 行。NOTICE 不是 0 就停下,只报两个数字。
|
||||
- `20260925010000`:自动校正标题会改成带结果。只看 NOTICE 的行数。
|
||||
- `20260925030000`:他人档案里已采用或已确认的时间会退回已申报。演练在跑这个文件之前先数行,预期 0。不是 0 就停下,只把数字报给产品,不要继续。
|
||||
|
||||
服务角色读人物表的授权不在这 63 个文件里(BUG-1063)。演练冒烟到这一项会停下。那笔授权进入这一批之前,不要点生产迁移。
|
||||
|
||||
## 63 条
|
||||
|
||||
| 文件 | 级 | 作用 | 对生产用户 | 演练要看 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `20260816010000_accept_exact_family_birth_times.sql` | B | 家人给出的整点时间,从「已申报」改成「已采用」。 | 只动还没做过校正、并且本来就是整点的家人时间。 | 迁移前后数 public.profiles 里被这条命中的行。 |
|
||||
| `20260816010000_admin_redemption_admin_access.sql` | C | 兑换码管理改成普通后台能力,并收紧权限。 | 不改用户已有的点数或兑换记录。 | 迁移无报错;后台仍只有管理员能进。 |
|
||||
| `20260817010000_billing_catalog_admin_runtime_read_policies.sql` | D | 给后台只读价格目录加策略。 | 用户看不到新入口,也不改已有订单。 | 迁移无报错。 |
|
||||
| `20260818010000_admin_product_catalog_mutations.sql` | C | 后台改价格目录的权限收紧。 | 不改用户已购内容。 | 迁移无报错。 |
|
||||
| `20260819010000_rectification_ingest_precision_plateau.sql` | C | 校正录入的精度判断收紧。 | 不改已填写的出生时间。 | 迁移无报错。 |
|
||||
| `20260820010000_rectification_family_appearance_d12.sql` | C | 校正增加家人外貌相关判断,并收紧函数权限。 | 不改已保存的档案。 | 迁移无报错。 |
|
||||
| `20260820020000_rectification_d5_d7_precision.sql` | C | 校正增加两类分盘精度,并收紧函数权限。 | 不改已保存的档案。 | 迁移无报错。 |
|
||||
| `20260820030000_rectification_d3_family.sql` | C | 校正增加家人分盘,并收紧函数权限。 | 不改已保存的档案。 | 迁移无报错。 |
|
||||
| `20260820040000_rectification_occupation_horary.sql` | C | 校正增加职业问事,并收紧函数权限。 | 不改已保存的档案。 | 迁移无报错。 |
|
||||
| `20260822010000_declared_birth_window_clocks.sql` | B | 把「只知道大概时段」回填成开始和结束钟点。 | 只填原来空白的时段列,不改已经写上的时间。 | 数 public.profiles 里时段来源且两列仍空的行,迁移后应变少。 |
|
||||
| `20260823010000_rectification_occupation_dateless.sql` | B | 没有日期的职业、外貌、胎记证据可以记成已确认。 | 只改这三类证据的确认状态,不改出生时间。 | 数这三类证据在迁移前后的确认行数。 |
|
||||
| `20260823020000_rectification_inference_choice_write.sql` | C | 校正选择题的写入权限收紧。 | 不改已有答案。 | 迁移无报错。 |
|
||||
| `20260824010000_rectification_inference_transition_ledger.sql` | C | 校正推断过程改成只追加的记录,并收紧权限。 | 旧的推断结果仍在,不删。 | 迁移无报错。 |
|
||||
| `20260824020000_rectification_choice_action.sql` | C | 校正点选和停止改成一次写完,并收紧权限。 | 不改已有对话。 | 迁移无报错。 |
|
||||
| `20260824030000_rectification_turn_origin.sql` | C | 校正每句话记下是打字、点选、语音还是重试,并收紧权限。 | 不改已有对话正文。 | 迁移无报错。 |
|
||||
| `20260825010000_rectification_evidence_kind_date_dedup.sql` | C | 同类又同日的校正证据去重规则收紧。 | 不删除用户原文。 | 迁移无报错。 |
|
||||
| `20260826010000_rectification_inference_round_audit.sql` | C | 校正每一轮多记审计字段,并收紧权限。 | 不改已有结论。 | 迁移无报错。 |
|
||||
| `20260826020000_rectification_choice_focus_identity.sql` | C | 校正选项卡用服务器保存的编号认身份,并收紧权限。 | 刚发出的卡不会因为编号对不上而被拒绝。 | 迁移无报错。 |
|
||||
| `20260826030000_rectification_migration_ledger_health.sql` | C | 网页角色不能再直接读迁移账本,健康检查改走只返回文件名的函数。 | 用户界面不变。 | 迁移无报错。 |
|
||||
| `20260827010000_rectification_candidate_profile_freshness.sql` | C | 校正候选和档案是否还新鲜的判断收紧。 | 不改已采用的时间。 | 迁移无报错。 |
|
||||
| `20260827020000_rectification_vedastro_validation_retry.sql` | C | 校正外部核对失败后可以重试,并收紧权限。 | 不改已采用的时间。 | 迁移无报错。 |
|
||||
| `20260830010000_chat_session_chart_profile_binding.sql` | D | 会话可以绑定到某一位已保存的人。 | 旧会话不改内容。 | 迁移无报错。 |
|
||||
| `20260830020000_personal_report_sections.sql` | C | 个人报告按章节保存进度,并收紧权限。 | 已生成的报告正文还在。 | 迁移无报错。 |
|
||||
| `20260831010000_feature_pricing.sql` | C | 功能价格表收紧权限。 | 不改用户余额。 | 迁移无报错。 |
|
||||
| `20260831020000_feature_pricing_admin_runtime_read_policy.sql` | D | 后台可以只读功能价格。 | 用户侧不变。 | 迁移无报错。 |
|
||||
| `20260901010000_append_consultation_question.sql` | C | 咨询提问的写入函数收紧。 | 不改已有对话。 | 迁移无报错。 |
|
||||
| `20260901020000_chat_session_pin_archive.sql` | D | 会话增加置顶和归档用的列。 | 这一步还不把归档会话放回列表。 | 迁移无报错。 |
|
||||
| `20260902010000_rectification_question_on_turn.sql` | C | 校正把问过的题和选中的项记在当轮上,并收紧权限。 | 刷新后还能看到刚才那道题。 | 迁移无报错。 |
|
||||
| `20260902020000_rectification_tool_activity_timing.sql` | C | 校正工具耗时从已有记录推算,并收紧权限。 | 不新增用户能看到的个人资料。 | 迁移无报错。 |
|
||||
| `20260903010000_profile_ayanamsa.sql` | D | 本人资料增加岁差设置。 | 不改已有星盘结论。 | 迁移无报错。 |
|
||||
| `20260904010000_read_report_candidate_range.sql` | C | 报告只通过一个只读函数看校正窗口,表权限保持收回。 | 找不到时按未找到处理,不编一个窗口。 | 迁移无报错。 |
|
||||
| `20260905010000_personal_report_longform_appendices.sql` | C | 长报告附录单独缓存,失败不影响报告本身,并收紧权限。 | 已完成的报告不会因为附录失败被改成失败。 | 迁移无报错。 |
|
||||
| `20260906010000_chat_session_context_summary.sql` | D | 会话增加一段上下文摘要列。 | 旧对话正文不变。 | 迁移无报错。 |
|
||||
| `20260906020000_adopted_credible_range.sql` | C | 采用校正结果时另存当时的可信窗口,并收紧权限。 | 原来的搜索起点不被改写。 | 迁移无报错。 |
|
||||
| `20260906030000_rectification_block_scan_stage.sql` | B | 出生时间完全未知、而且尚未采用的校正,阶段改成先比较时段。 | 已经确认、关闭或已有具体时间的不改。 | 数 public.agentic_rectification_cases 里被改成 block_scan 的行。 |
|
||||
| `20260907010000_personal_report_card_summary.sql` | D | 报告列表增加一段纯文字摘要。 | 不改报告正文。 | 迁移无报错。 |
|
||||
| `20260907020000_rectification_declared_uncertainty.sql` | C | 校正可以按用户说的不确定范围收窄或放宽,并收紧权限。 | 不改已经采用的时间。 | 迁移无报错。 |
|
||||
| `20260909010000_profile_ayanamsa_service_role_grants.sql` | D | 补岁差列给服务角色的读取权。 | 不改用户设置。 | 迁移无报错。 |
|
||||
| `20260910010000_rectification_host_fallback_phase.sql` | C | 校正在模型没写出答案时记下宿主兜底,并收紧权限。 | 不改已有答案。 | 迁移无报错。 |
|
||||
| `20260915010000_rectification_touch_chat_session.sql` | C | 校正有进展时,会话的更新时间跟着前进,并收紧权限。 | 只打开或改标题不会刷新这个时间。 | 迁移无报错。 |
|
||||
| `20260916010000_consultation_session_capacity.sql` | C | 咨询字数上限只数用户看得到的正文,并收紧权限。 | 思考过程仍保存,但不占那一档额度。 | 迁移无报错。 |
|
||||
| `20260916020000_rectification_session_title_repair.sql` | B | 校正会话标题里对不上的月日会按创建时间改回;更新时间只向前补。 | 生产停在 08-16 时标题是固定的「生时校正」,预期改 0 行。 | 只看两条 NOTICE 的数字。不是 0 就停下,不记录标题文字。 |
|
||||
| `20260920010000_consultation_free_completion.sql` | C | 咨询完成时的免费收尾规则收紧。 | 不改已扣的点数。 | 迁移无报错。 |
|
||||
| `20260920010000_rectification_receipt_result_identity.sql` | C | 校正回执改用最后一次完成结果的来源,并收紧权限。 | 不改已展示的结论形状。 | 迁移无报错。 |
|
||||
| `20260920020000_adopted_birth_date.sql` | C | 增加采用后的日期和时区列,并收紧权限。 | 原来申报的日期不改。 | 迁移无报错。 |
|
||||
| `20260920030000_rectification_dated_windows.sql` | C | 校正窗口可以带公历日期,并收紧权限。 | 已有结果和原始日期不改写。 | 迁移无报错。 |
|
||||
| `20260921010000_retire_chat_session_archive.sql` | A | 所有已归档会话的归档标记清空,会话回到列表。 | 用户会重新看到以前归档的会话。列先留着,以后再删。 | 数 public.chat_sessions 里归档标记非空的行,迁移后应为 0。 |
|
||||
| `20260925010000_rectification_session_title_result.sql` | B | 自动生成的校正标题改成带结果,并回填已有自动标题。 | 手改过的标题不动。 | 只看 NOTICE 的行数,不记录标题文字。 |
|
||||
| `20260925020000_chart_subject_typed_columns.sql` | A | 他人档案改用单独的列;本人在人物表里的镜像行删除。 | 本人资料改由账户资料承载。他人档案还在。 | 数 role 为 self 的人物行,迁移后应为 0。不要打印行内容。 |
|
||||
| `20260925030000_chart_subject_trust_and_limit.sql` | B | 他人档案里已采用或已确认的时间退回「已申报」,并清空采用列。 | 每人最多再保存 4 位他人。生产预期受影响行数是 0。 | 本文件之前先数命中行。不是 0 就停下,只报数字。 |
|
||||
| `20260925040000_deleted_report_release.sql` | C | 已删除报告的释放规则收紧。 | 不把已删除报告重新公开。 | 迁移无报错。 |
|
||||
| `20260926010000_rectification_telemetry.sql` | C | 校正交付时写一行不含身份的汇总,并收紧权限。 | 不保存出生时间或对话原文。 | 迁移无报错。 |
|
||||
| `20260927010000_profile_gender.sql` | D | 账户和已保存的人增加可选性别。 | 不填也能继续用。 | 迁移无报错。 |
|
||||
| `20260927020000_profile_adopted_birth_service_role_select.sql` | D | 补服务角色读取已采用日期列的权限。 | 不改已有日期。 | 迁移无报错。 |
|
||||
| `20260928010000_profile_ayanamsa_six.sql` | D | 岁差选项从四种扩成六种。 | 原来的设置仍然有效。 | 迁移无报错。 |
|
||||
| `20260930010000_user_consents.sql` | C | 增加用户协议和隐私政策的同意记录,并收紧权限。 | 只追加,不改写旧同意。 | 迁移无报错。 |
|
||||
| `20260930020000_account_deletion_requests.sql` | C | 增加 7 天冷静期的注销申请,并收紧权限。 | 申请当时会退出全部登录。不立刻删资料。 | 迁移无报错。 |
|
||||
| `20260930030000_user_feedback.sql` | C | 增加应用内反馈和回复评价的表,并收紧权限。 | 旧对话不改。 | 迁移无报错。 |
|
||||
| `20260930040000_moderation_events.sql` | C | 增加审核命中记录,并收紧权限。 | 只记类别和规则编号,不记原文。 | 迁移无报错。 |
|
||||
| `20260930050000_reply_quality_snapshots.sql` | C | 点了负向评价时保存那一轮的问题、回答和上下文,并收紧权限。 | 没有点评价的对话不写这份快照。 | 迁移无报错。演练输出不要带正文。 |
|
||||
| `20261001010000_rectification_segment_adoption.sql` | C | 校正可以把一段时间里的某一分钟记为采用结果,并收紧权限。 | 这不是新的引擎候选,也不等于最终确认。 | 迁移无报错。 |
|
||||
| `20261001020000_rectification_segment_checks.sql` | C | 校正时段结果的检查收紧。 | 不改已采用的时间。 | 迁移无报错。 |
|
||||
| `20261002010000_rectification_dated_algorithm_generation.sql` | D | 校正记下算法版本,方便以后区分新旧打分。 | 不改已经交付的结果。 | 迁移无报错。 |
|
||||
@@ -0,0 +1,111 @@
|
||||
# 生产首发步骤(2026-10-14)
|
||||
|
||||
给产品负责人照着点。本单合入测试环境并部署完成之后再做。执行人不要把出生资料、姓名、邮箱、会话、密钥写进仓库或评论。
|
||||
|
||||
发布用两个提交:
|
||||
|
||||
- `H`:当时的测试环境分支头。`main` 要快进到这一个,不能合并出新提交。
|
||||
- `R`:测试环境上最近一次「代码门禁成功」的提交。`H` 可以比 `R` 更靠前,但中间只能是文档。公网健康检查里的版本号必须等于 `R`。
|
||||
|
||||
四个按钮都在 Gitea Actions 里,要从 `main` 点。迁移演练没有第五个按钮。产品在生产主机上自己跑脚本,看下面第 5 步。
|
||||
|
||||
## 0. 前一天
|
||||
|
||||
冻结代码推送。文档可以继续推。确认测试环境健康检查的版本号仍是 `R`,并且从 `R` 到当前测试环境头没有代码改动。
|
||||
|
||||
## 1. 核对版本
|
||||
|
||||
打开 `https://staging.jyotisha.chat/api/health`。`deployment.gitCommit` 等于 `R`。
|
||||
|
||||
在仓库里执行 `deploy/is-docs-only-range.sh R <当前测试环境头>`。退出码 0 才继续。退出码 1 或 2 都停,不要发布。
|
||||
|
||||
## 2. 把 main 快进到测试环境头
|
||||
|
||||
用快进把 `main` 推到 `H`。不要做 merge。快进之后 `main` 和测试环境是同一个提交。
|
||||
|
||||
通过:Gitea 上两个分支指向同一个 40 位提交。
|
||||
|
||||
## 3. Release Quality Gate
|
||||
|
||||
Gitea → Jyotish Release Quality Gate → Use workflow from:`main`。不需要填发布提交。
|
||||
|
||||
通过:这一步成功,摘要里能看到 `release_sha`(这就是 `R`)和 `head_sha`(这就是 `H`),并写着相对 `R` 的后续改动只是文档。
|
||||
|
||||
失败:不要点后面的按钮。看失败那一行的原文,把原文交给验收,不要附带环境文件。
|
||||
|
||||
## 4. Create Production Recovery Point
|
||||
|
||||
Gitea → Create Production Recovery Point。Use workflow from:`main`。`deploy_sha` 填 `R`。
|
||||
|
||||
通过:成功结束,记下三样东西:`recovery_reference`、`recovery_created_at`、以及它已经写明还原验证通过。加密备份在生产主机的备份目录里,不要打开、不要把密钥贴出来。
|
||||
|
||||
失败:停。不要迁移。
|
||||
|
||||
## 5. 在主机上演练迁移
|
||||
|
||||
没有单独的 Gitea 按钮。用部署账号在生产主机上跑。主机上如果还没有这份代码,只读检出 `R`,不要在主机上构建镜像。备份文件要自己填进 `RECOVERY_DUMP`,脚本不会猜哪一个是最新的。
|
||||
|
||||
先看计划,不连数据库:
|
||||
|
||||
```text
|
||||
DEPLOY_PATH=/opt/jyotisha-production JYOTISHA_REHEARSAL_PLAN=1 bash deploy/rehearse-production-migrations.sh
|
||||
```
|
||||
|
||||
通过:输出里 `stop_in_before=no`,并且一次性库的名字以 `rehearse_` 开头。
|
||||
|
||||
再正式跑。把刚才那个备份文件路径放进 `RECOVERY_DUMP`,文件必须在 `/opt/jyotisha-production/backups/` 下面,并且是 `.dump.enc`:
|
||||
|
||||
```text
|
||||
DEPLOY_PATH=/opt/jyotisha-production RECOVERY_DUMP=/opt/jyotisha-production/backups/<刚才那个备份文件名> bash deploy/rehearse-production-migrations.sh
|
||||
```
|
||||
|
||||
脚本只还原到一次性库,不会改名为 `jyotisha` 的生产库。磁盘使用率要低于 70%。另一项生产变更正在进行时会停。跑完会删掉一次性库。
|
||||
|
||||
通过,要同时满足:
|
||||
|
||||
- 输出有 `other_person_accepted_rows=0`。这是 `20260925030000` 之前的人数。不是 0 就停,只把这个数字发给产品,不要继续,也不要写出任何一行的内容。
|
||||
- 两条会改用户能看见的数据:归档会话回到列表,人物表里的本人镜像被删掉。行数变化要和 `docs/operations/production-migrations-20261014.md` 的产品需知一致。
|
||||
- 权限冒烟三行都是 `true`:网页角色能读账户资料、能读会话列表,服务角色能读人物表。
|
||||
- 最后一行是 `rehearsal_ok=1`。
|
||||
|
||||
现在这一批里还没有「服务角色可读人物表」那一笔授权(BUG-1063,在另一条尚未合入的分支上)。冒烟因此会停,并退出码 4。这不是脚本坏了。在那一笔进入本次发布之前,不要点生产迁移。
|
||||
|
||||
失败时:脚本会删掉一次性库。生产库还没动。把退出码和它打印的那一句原因留下来。不要复制数据库口令或备份密钥。
|
||||
|
||||
## 6. Migrate Production Database
|
||||
|
||||
只在第 5 步 `rehearsal_ok=1` 之后点。
|
||||
|
||||
Gitea → Migrate Production Database。Use workflow from:`main`。
|
||||
|
||||
- `deploy_sha`:`R`
|
||||
- `recovery_reference`:第 4 步记下的引用
|
||||
- `recovery_created_at`:第 4 步记下的时间,24 小时内
|
||||
- `restore_verified`:true
|
||||
|
||||
通过:工作流成功,并且没有「恢复点超过 24 小时」或「版本对不上」的失败句。
|
||||
|
||||
失败:不要部署新代码。按下面的「失败后」整库还原。
|
||||
|
||||
## 7. Deploy production
|
||||
|
||||
Gitea → Deploy production。Use workflow from:`main`。
|
||||
|
||||
- `deploy_sha`:`R`
|
||||
- `allow_rollback`:false
|
||||
- `verification_mode`:public
|
||||
|
||||
通过:工作流成功。然后做 `docs/testing/production-first-release-20261014.md`。
|
||||
|
||||
## 失败后
|
||||
|
||||
接受整库还原到第 4 步那个恢复点。恢复点之后新写入的数据会丢掉。内测还没开放时,这个窗口里通常还没有新的用户数据。
|
||||
|
||||
旧代码读不了新的表结构。所以不能只把程序退回去。两件事都要做:
|
||||
|
||||
1. 用恢复点把数据库整库还原到发布前。
|
||||
2. 再点 Deploy production,`allow_rollback` 选 true,目标用发布前的生产版本 `7b620c7a`。
|
||||
|
||||
谁来点:产品负责人。不要让执行代理代点生产按钮。
|
||||
|
||||
还原之后再按核对清单看健康检查。版本号应回到 `7b620c7a`。
|
||||
@@ -0,0 +1,47 @@
|
||||
# PROGRESS · 发布通路改规则 + 生产首发(2026-10-14)
|
||||
|
||||
- 分支:`codex/release-path-production-20261014`
|
||||
- 基线:从 `origin/staging` 新建,开工 HEAD `f4c53e7f9fad1a3de08b613c3470f8e4a2f62116`。任务书里的 `48a2fadd` 是更早的记录;`74384be0` 是本基线的祖先。
|
||||
- 开工时测试环境健康检查的版本号与这个 HEAD 相同。收尾时公开健康检查已变成 `cb8004a188afd51ec440a7678f91be801fbd3147`,本分支没有变基到那个提交。本轮没有改测试环境。
|
||||
- 预检 `scripts/pre_work_check.py`:远端仓库可见,Python 可用。碎片扫描 90 秒超时,聚焦测试 45 秒超时。不能写成预检通过。
|
||||
- 编号:本树 `docs/BUG_HISTORY.md` 最大号原是 BUG-1346。BUG-1347 在另一条还没合入的分支上,本单用 BUG-1348、BUG-1349,避免以后撞号。
|
||||
|
||||
## 做了什么
|
||||
|
||||
1. 四个生产工作流共用 `deploy/resolve-release-revision.sh`。发布修订是最近一次代码门禁成功的提交。测试环境头可以在它后面只多文档。回滚仍走原来的确认和祖先检查。
|
||||
2. 生产环境拒绝测试验证码:环境校验看见这个变量就失败;运行时如果站点是生产域名并且配了验证码,就拒绝启动。
|
||||
3. 63 个新增迁移的清单、演练脚本、首发步骤和发布后核对都写好了。迁移演练没有单独的 Gitea 按钮,这是决策记录只授权四个工作流之后的做法。
|
||||
4. 没有点任何生产按钮,没有推 `staging` 或 `main`。
|
||||
|
||||
## 自测
|
||||
|
||||
| 命令 | 结果 |
|
||||
| --- | --- |
|
||||
| `tests/test_resolve_release_revision.py` | 7 通过 |
|
||||
| `tests/test_rehearse_production_migrations.py` | 3 通过。拒绝非生产路径、拒绝生产库名、计划输出把停止文件留在第二批 |
|
||||
| `tsc --noEmit -p frontend` | 0 错 |
|
||||
| `npm run lint --prefix frontend` | 0 error,125 条原有 warning |
|
||||
| 四个生产工作流 | `js-yaml` 能解析 |
|
||||
| 新脚本 `bash -n` | 通过(工作流测试里的语法检查那一条通过) |
|
||||
| 生产发布、恢复点、生产迁移、手动发布门的文本合同 | 通过 |
|
||||
| 生产站拒绝测试验证码的身份配置测试 | 通过 |
|
||||
|
||||
同一批前端测试文件里还有 8 条失败,0 条取消。它们是这台 Windows 机器的环境,不是把断言改弱:
|
||||
|
||||
- 环境文件校验要求 Unix 权限 `0600`。Git Bash 里 `chmod 600` 之后 `stat` 仍是 `644`,脚本在看到验证码检查之前就停了。
|
||||
- 工作流 YAML 检查找到的 `python` 是 Windows 占位程序,退出码 9009。四个生产文件另用项目里的 `js-yaml` 解析通过。
|
||||
- 两条同步测试缺 `rsync`。
|
||||
- 一条回滚测试在临时目录上 `install` 改权限被拒绝。
|
||||
- 纯文档范围脚本在这台机器上没有 `python3`,退出码 49。发布修订测试用仓库里的 Python 跑过了同一条判断。
|
||||
|
||||
## 迁移演练(本机一次性库)
|
||||
|
||||
空库,角色按主机引导脚本的名字建好,没有真实个人资料。`deploy/rehearse-production-migrations.sh` 在本地模式跑完:
|
||||
|
||||
- 停止文件之前 160 个迁移,全部应用后 174 个。
|
||||
- `other_person_accepted_rows=0`
|
||||
- 两条标题修补 NOTICE 都是 0
|
||||
- 网页角色读账户资料、读会话列表:true
|
||||
- 服务角色读人物表:false,退出码 4
|
||||
|
||||
这是预期停止。BUG-1063 的授权不在这 63 个文件里。演练库已删除。在那笔授权进入这一批之前,不要点生产迁移。主机上的正式演练仍由产品按 runbook 做,本机这次不能代替主机恢复点。
|
||||
@@ -333,7 +333,7 @@
|
||||
| `TASK-upstream-sync6-20261007.md` | [PROGRESS-upstream-sync6-20261007.md](PROGRESS-upstream-sync6-20261007.md) | **上游同步第六轮(`23be1807`)**:10-05 五个计算修正一行未合——D5/D6/D8/D11 映射(乔布斯盘四张分盘星座全不同)、Vimsopaka 权重、Yogini 顺序与出生余额、Panchadhikari 宫位参照、Narayana 并列、特殊上升、出生秒数、Neecha Bhanga 两条件、首段大运子运、岁差被覆盖;逐项对照原书核实;最先做 | 已验收(门禁补修 `2df6ee72`,已部署 staging) | [PROGRESS-upstream-sync6-20261007.md](PROGRESS-upstream-sync6-20261007.md) |
|
||||
| `TASK-upstream-sync7-20261014.md` | [PROGRESS-upstream-sync7-20261014.md](PROGRESS-upstream-sync7-20261014.md) | **上游同步第七轮(BUG-1318 起)**:婚恋评级断语改证据档位、DK「婚姻质量 X/100」改对;KP 宫头到宫头判宫;瑜伽宫主排序去重;api_server 大运年长 365.25;星历路径只核查。不动校正打分。Grok 执行(agent 循环) | 待验收 | `codex/upstream-sync7-20261014`(BUG-1318~1321 已改;BUG-1322 星历路径核查中,未改代码) |
|
||||
| `TASK-beta-main-path-20261014.md` | — | **内测主路径**:BUG-1063 他人报告 worker 读档案(逐列只读授权 + test:db);对话与报告「AI 生成,仅供参考」标识与免责;BUG-1080/283 状态;状态板按事实清账;冒烟清单 `docs/testing/beta-smoke-20261014.md`。与发布单并行 | 待执行 | — |
|
||||
| `TASK-release-path-production-20261014.md` | — | **发布通路 + 生产首发**:产品 10-14 授权改生产工作流(发布 SHA = 最近门禁成功提交 + 其后纯文档);63 个迁移清单与演练脚本、首发 runbook;生产拒绝测试验证码。Grok 不 dispatch 生产工作流 | 待执行 | — |
|
||||
| `TASK-release-path-production-20261014.md` | `PROGRESS-release-path-production-20261014.md` | **发布通路 + 生产首发**:产品 10-14 授权改生产工作流(发布 SHA = 最近门禁成功提交 + 其后纯文档);63 个迁移清单与演练脚本、首发 runbook;生产拒绝测试验证码。Grok 不 dispatch 生产工作流 | 待验收 | `codex/release-path-production-20261014`(BUG-1348、BUG-1349;BUG-1347 在另一条未合入分支) |
|
||||
| `TASK-beta-safety-net-20261014.md` | — | **内测安全网**:每日备份 + 恢复演练、探活告警、本地错误汇总、日志轮转、按 requestId 查日志。**等发布通路单合入、#58 合入后开工** | 待前置 | — |
|
||||
| `TASK-beta-capacity-20261014.md` | — | **内测容量**:按用户限流、重计算短排队与对话重试、兑换码当邀请码、staging 10/20 并发压测。**等 #58 合入后开工,压测等 #57 合入** | 待前置 | — |
|
||||
| `TASK-special-lagnas-native-20261008.md` | `PROGRESS-special-lagnas-native-20261008.md` | **特殊上升点原生计算(线上缺陷)**:sync6 U6 运行时调 PyJHora,生产镜像没有 PyJHora → staging 上 Hora/Ghati/Sree/Indu/Pranapada 全 blocked;原生实现、PyJHora 只作冻结对照、快速门禁止运行时 import jhora;最先做 | 已验收(已部署 staging `795b8845`,BUG-1273) | `codex/special-lagnas-native-20261008`(未上线;部署以 `/api/health` 为准) |
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# 生产首发后核对(2026-10-14)
|
||||
|
||||
产品发布完成后照着看。把「实际」一栏填成通过或没通过。不要把登录账号、页面正文、出生资料写进仓库。
|
||||
|
||||
`R` 是这次部署填的那个 40 位提交,也就是测试环境健康检查在发布前显示的版本。
|
||||
|
||||
| 核对 | 预期 | 实际 |
|
||||
| --- | --- | --- |
|
||||
| 打开 `https://jyotisha.chat/api/health` | 状态 200,`deployment.gitCommit` 等于 `R`,`apiGitCommit` 等于 `R` | |
|
||||
| 同一份健康检查里的数据库 | `database.requiredMigrationsPresent` 为 true,`latestMigration` 与测试环境同一字段相同 | |
|
||||
| 内部健康检查 | 状态 200,`swisseph_available` 为 true | |
|
||||
| 打开 `/login` | 状态 200,页面数据里的 `testOtp` 是 null | |
|
||||
| 未登录打开 `/api/account` | 状态 401 | |
|
||||
| 用受控账号登录 | 能登录 | |
|
||||
| 登录后建一张盘 | 盘能打开 | |
|
||||
| 发一轮对话 | 能收到回复 | |
|
||||
| 打开一份报告 | 报告页能打开 | |
|
||||
| 打开 `/admin` | 只有管理员能进,普通账号不能 | |
|
||||
|
||||
任何一行没通过:不要继续开放内测。按 runbook 的「失败后」做整库还原,并把应用退回 `7b620c7a`。
|
||||
@@ -0,0 +1,25 @@
|
||||
# 生产迁移演练报告(模板)
|
||||
|
||||
产品在主机上跑完 `deploy/rehearse-production-migrations.sh` 后填写。只写行数和通过/停止。不要写姓名、出生时间、邮箱、会话正文、密钥或任何一行的内容。
|
||||
|
||||
| 项 | 结果 |
|
||||
| --- | --- |
|
||||
| 日期 | |
|
||||
| 发布修订 R | |
|
||||
| 恢复点引用 | |
|
||||
| 一次性库名字(必须是 `rehearse_` 开头) | |
|
||||
| `other_person_accepted_rows` | 预期 0 |
|
||||
| 归档会话:迁移前非空行数 / 迁移后 | 迁移后应为 0 |
|
||||
| 人物表里本人镜像:迁移前 / 迁移后 | 迁移后应为 0 |
|
||||
| 标题修补两条 NOTICE | 生产上预期都是 0。不是 0 就停止 |
|
||||
| 自动标题回填 NOTICE | 只写数字 |
|
||||
| 未知时间改成时段比较的行数 | |
|
||||
| 家人整点改为已采用的行数 | |
|
||||
| 时段回填的行数 | |
|
||||
| 无日期证据改为已确认的行数 | |
|
||||
| 网页角色读账户资料 | true 才算过 |
|
||||
| 网页角色读会话列表 | true 才算过 |
|
||||
| 服务角色读人物表 | true 才算过。false 时停止,不要点生产迁移(BUG-1063 的授权还没进这一批) |
|
||||
| 最终一行 | `rehearsal_ok=1` 才算演练通过 |
|
||||
|
||||
停止时:生产库不应被修改。把脚本打印的那一句原因贴在这里,去掉任何连接地址。
|
||||
Reference in New Issue
Block a user