IndexNow 部署发现
当前实现与已确认缺口
公开站点已经提供 robots.txt、生成的 sitemap.xml,以及 IndexNow 密钥文件 7c5062acbc32b8a88d2e6b627d65cbfa.txt。本次变更之前,没有部署流程向 IndexNow 端点提交更新网址,因此参与的搜索引擎只能被动发现变更。
目标
每次向站点仓库成功提交发布内容后,将生成 sitemap 中的全部 canonical URL 通知给参与的搜索引擎。
边界
- 提交网址仍以 sitemap 为唯一依据。
- 现有公开 IndexNow 密钥及密钥位置文件保持不变。
- 搜索通知采用尽力而为方式,不得阻塞或回滚已成功的站点发布。
- 源码工作流等待站点仓库的发布 action,不等待该独立仓库下游的 GitHub Pages 部署。因此通知可能在 GitHub Pages 仍处理相同内容时到达。
- Google 不使用 IndexNow,因此 Google Search Console 验证及 sitemap 提交仍单独进行。
协议选择
工作流在站点仓库发布 action 成功后使用 IndexNow 批量端点。Python 标准库模块读取 _publish/sitemap.xml,提取属于 openprogram.io 的唯一 HTTPS URL,并生成协议规定的 JSON 请求。请求包含主机、公开密钥、密钥位置及 URL 列表。超过 10,000 个网址时拆分为多个请求,符合协议的单请求限制。
信任边界与数据流
- 受信任的文档构建器生成
_publish/sitemap.xml. - 载荷构建器仅读取严格匹配 sitemap 0.9 的
loc元素,只接受主机精确为openprogram.io的 HTTPS URL;空输入和其他主机输入在网络提交前失败。 - 工作流将验证后的请求批次写入 runner 临时目录。
- 标准库 HTTP 客户端将每批发送至
https://api.indexnow.org/indexnow,设置有限超时和重试次数。失败批次会被记录,但不跳过后续批次;全部批次尝试完毕后步骤才报告失败。
备选方案
| 机制 | 覆盖范围 | 选择 |
|---|---|---|
| 被动 sitemap 发现 | 所有支持 sitemap 的爬虫 | 保留;它不会在部署变化时主动通知爬虫。 |
| IndexNow 批量提交 | 参与的搜索引擎 | 每次成功发布后采用。 |
| Google Search Console | 保留为单独验证的服务;不增加部署凭据。 |
失败处理
提交步骤使用有限 HTTP 超时和 continue-on-error。无效 sitemap URL、载荷构建错误和端点失败会使通知步骤失败,但不影响已完成的站点仓库发布。IndexNow 所有权由公开密钥文件证明,无需仓库 secret。
兼容性与排除范围
- 实现使用 Python 3.12 标准库模块,不增加包依赖。
- 现有 sitemap、robots、Google 验证及 GitHub Pages 行为保持不变。
- 不等待下游
openprogram-sitePages 部署,因为它属于独立仓库工作流,而通知只是非阻塞的发现元数据。 - 搜索排名、抓取时机和索引收录不受系统控制,不作为验收标准。
验证
- 回归测试要求发布先于通知。
- 可执行测试要求协议中的 JSON 字段、稳定去重、10,001 个 URL 的分批、精确 sitemap 标签、旧批次清理、前批失败后继续提交,以及拒绝 HTTP 或其他主机 URL。
- 工作流回归要求官方端点、生成的 sitemap 输入及非阻塞失败策略。
- 线上密钥 URL 和每个提交的 sitemap URL 均使用 HTTPS,主机为
openprogram.io。 - 2026-08-13 手动批量提交当时的 499 个 sitemap URL,返回 HTTP 200。
实现证据
已审查的实现提交 f458791e8c245e642b563a5ffc9074c9758683ab 增加标准库载荷构建器、批量提交、部署钩子及八个聚焦回归用例。独立规格与质量审查在各自记录的修复后均达到 PASS。命令及最终门禁结果记录在 任务台账.