Lead 是一个与 TIN 功能等价、面向 CI 运行环境的全文搜索实现。它解决的重点并不是“再做一个搜索工具”,而是让原本依赖 TIN 的检索流程能够进入持续集成:在构建、测试和校验阶段执行,并把结果变成稳定的自动化信号。
为什么 CI 需要专门考虑全文搜索
在开发机上运行搜索,失败时可以人工查看上下文;在 CI 中,搜索通常承担更明确的职责,例如:
- 检查文档或代码库中是否存在必须出现的内容;
- 检查敏感词、过期 API 或禁止提交的配置;
- 对生成结果执行关键词验证;
- 为后续脚本提供可判断的退出状态。
这类任务最怕两件事:运行环境不一致,以及搜索结果无法稳定地被脚本消费。Lead 的定位是提供 TIN 兼容的全文搜索能力,同时适合放进 CI 流程。换句话说,迁移重点应放在“让现有检索逻辑可靠执行”,而不是重新设计一套搜索业务。
TIN 兼容意味着什么
“功能等价”并不自动等于“每个边界行为都完全一致”。在迁移时,建议把兼容性拆成几个可验证的层次:
- 输入兼容:同样的索引或文本数据能否被处理。
- 查询兼容:现有查询语法、关键词和过滤条件是否仍然成立。
- 输出兼容:结果格式是否足以被现有脚本解析。
- 退出状态兼容:命中、未命中和执行错误能否被 CI 正确区分。
- 性能边界:在 CI 的 CPU、内存和临时目录约束下是否可接受。
不要只在本地运行一次命令就宣布迁移完成。更可靠的方式是准备一组小型回归数据集:包含必命中的查询、必不命中的查询、空输入和异常输入,然后在 TIN 与 Lead 上分别执行,对比结果和退出状态。
一个可改造的 CI 集成示例
下面的示例假设 Lead 提供 search 子命令,并支持 --query、--input 与 --format 参数。具体参数名应以你使用的 Lead 版本帮助信息为准;如果实际 CLI 不同,只需要替换 run_search 函数中的调用。
把以下脚本保存为 ci/check-search.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
LEAD_BIN="${LEAD_BIN:-lead}"
INPUT_DIR="${INPUT_DIR:-./search-fixtures}"
QUERY="${1:?用法: $0 <query>}"
if ! command -v "$LEAD_BIN" >/dev/null 2>&1; then
echo "未找到 Lead: $LEAD_BIN" >&2
exit 127
fi
run_search() {
"$LEAD_BIN" search \
--input "$INPUT_DIR" \
--query "$QUERY" \
--format json
}
result="$(run_search)"
printf '%s\n' "$result" > search-result.json
# 假设 Lead 在命中时返回 JSON 数组;实际格式请按版本调整。
if python -c 'import json, sys; data=json.load(sys.stdin); sys.exit(0 if data else 1)' \
< search-result.json; then
echo "命中查询: $QUERY"
else
echo "未命中查询: $QUERY" >&2
exit 1
fi
赋予执行权限并在本地试跑:
chmod +x ci/check-search.sh
mkdir -p search-fixtures
printf 'Lead runs in continuous integration.\n' > search-fixtures/example.txt
./ci/check-search.sh "continuous integration"
在 CI 中使用时,重点是固定 Lead 的版本,并把测试数据作为仓库文件或构建产物管理。例如,一个通用的 shell 阶段可以这样写:
set -Eeuo pipefail
# 这里替换为组织内部的安装方式或预构建镜像。
# 关键是确保 CI 中的 Lead 版本可追踪、可复现。
lead --version
LEAD_BIN=lead ./ci/check-search.sh "required phrase"
如果实际工作流只需要判断命中与否,也可以直接使用退出状态,不必让 CI 解析复杂输出。若需要保存结果,则建议明确指定机器可读格式,并将结果文件作为构建产物上传,便于失败排查。
迁移时的测试策略
可以先建立一张简短的兼容性清单:
| 场景 | 需要确认的内容 |
|---|---|
| 普通关键词 | Lead 能返回与 TIN 等价的匹配集合 |
| 多词查询 | 空格、引号或其他语法不会被 CI shell 意外改写 |
| 空结果 | 未命中时退出状态符合流水线预期 |
| 错误输入 | 参数错误与“没有匹配”能够区分 |
| 大型数据集 | 运行时间和内存没有超出 CI 限制 |
| 并行任务 | 临时索引或输出文件不会互相覆盖 |
尤其要注意 shell 的引号和退出状态。查询内容应使用双引号或数组传递,避免特殊字符被 shell 展开;流水线脚本也不应把“命令成功执行但没有命中”误判为基础设施故障。
落地建议
Lead 适合被当作 CI 中的一个确定性工具链组件,而不是只在失败时临时登录机器运行的调试命令。落地时可以遵循下面的顺序:
- 锁定 Lead 版本和运行镜像。
- 用真实查询建立 TIN/Lead 对照用例。
- 先在非阻断流水线中收集差异。
- 固定输出格式和退出状态约定。
- 确认性能与并行隔离后,再把检查设为阻断条件。
最后,若你的查询依赖 TIN 的某些边界语义,不要仅凭“兼容”两个字跳过验证。用小而真实的回归集测试输入、结果和失败方式,才能让全文搜索真正成为 CI 的可靠质量门禁。