从 Jira 导出¶
导出会读取你指定的项目并写出一个导入包。先小规模试一下,检查结果没问题,再做正式导出。
试运行¶
--limit 20 只导出每个项目的前 20 个工作项(按工作项编号从旧到新)。这是检查凭据、权限以及文本和字段转换效果最快的方法。
--validate 会在导入包写完后检查它,所用的检查与 Specivo 导入时相同。工具会输出导入包的路径和一行写入内容的摘要,一切顺利时以 0 退出。
整站导出为一个包¶
列出你要导出的每个项目:
(写成 --project ACME,OPS,SUP 效果相同。)结果是一个 目录,内含 manifest.json、lookups.json、每种记录各一个 .jsonl 文件,以及存放附件内容的 files/。加上 --zip,或者让 --out 以 .zip 结尾,就会改为写出单个压缩包。
按项目分批导出¶
大站点分批迁移更省事,各部分还可以在不同时间导出。对每个项目(或一组项目)各运行一次工具,每次使用 相同的站点名称:
specivo-jira-migration --project ACME --out exports/acme --validate
specivo-jira-migration --project OPS --out exports/ops --validate
分属不同导入包的项目之间的链接、父工作项和工作项提及,会写进持有其中一端的每个导入包里,另一端的工作项以其 Jira id 标识。无论先加载哪个包,Specivo 都会在两端的工作项都导入后再建立这些关系。要让这一机制生效:
- 每个部分都用相同的
--instance导出(默认值是站点主机名,本来就相同); - 把各部分依次加载到同一个 Specivo 中,从第二个起加上
--continue-import; - 每次加载都传入相同的
--links-file,或者把所有导入包放在同一个目录下,让默认位置共用。参见校验与加载。
--validate 会把这类跨包引用报告为 external_ref 警告。对分批导出的部分来说,这是正常现象。
选项¶
| 选项 | 含义 |
|---|---|
--url URL |
Jira 站点地址(默认:$JIRA_URL)。 |
--email、--api-token |
Jira Cloud 凭据(默认:$JIRA_EMAIL、$JIRA_API_TOKEN)。 |
--pat TOKEN |
Jira Data Center 个人访问令牌(默认:$JIRA_PAT)。 |
--project KEY |
要导出的项目。可重复指定,也可用逗号分隔(默认:$JIRA_PROJECTS)。 |
--instance NAME |
站点在导入包中的名称(默认:站点主机名)。 |
--out PATH |
新目录或空目录,或者一个 .zip 路径。必填。 |
--zip |
写出 .zip 而不是目录。 |
--status-category-map NAME=CATEGORY,... |
把状态归入 Specivo 的 backlog / active / done / closed 四类。默认由 Jira 的状态类别决定:待办(To Do)归入 backlog,进行中(In Progress)归入 active,完成(Done)归入 closed。 |
--max-attachment-size SIZE |
跳过大于此大小的附件,例如 500M 或 2G;0 表示不限制。默认 100M。被跳过的文件数会记录在 manifest 中。 |
--no-resolve-keys |
不向 Jira 查询导入包之外的工作项编号(出现在文本和 Epic Link 字段中的)。它们保持为纯文本。 |
--limit N |
每个项目最多导出 N 个工作项,按工作项编号从旧到新。用于试运行。 |
--page-size N |
列表请求的每页条目数(默认 100)。 |
--keep-state |
运行成功后保留状态目录。 |
--restart |
丢弃上一次未完成运行的状态,重新开始。 |
--validate |
导入包写完后按 Specivo 的方式检查它。 |
--quiet |
只输出错误。进度信息写到 stderr,导入包路径写到 stdout。 |
--version |
输出工具版本。 |
退出状态:成功为 0;导出失败或 --validate 发现问题为 1;用法错误(包括项目不存在)为 2。
映射状态¶
Specivo 把每个状态归入四个类别之一(backlog、active、done、closed),看板和报表都依据这些类别。工具默认沿用 Jira 自身的状态类别。可按名称覆盖单个状态:
specivo-jira-migration --project ACME --out jira-export \
--status-category-map "In Review=active,Won't Do=closed"
运行中断时¶
工具从 Jira 读到的所有内容都会随到随存,放在输出路径旁的 状态目录 中(jira-export.jira-state/)。如果运行中断(网络故障、限流后放弃重试、Ctrl-C),再运行一次同样的命令 即可:
- 已列出的项目不再重新列出,已读取的工作项不再重新读取;
- 已获取的关注者不再重新请求;
- 已下载且哈希值仍与记录一致的附件不再重新下载。正在下载的文件以临时名写入,运行中断时丢弃;
- 用更大的
--max-attachment-size再运行一次,会补下载之前因大小限制跳过的附件。
用其他选项(另一个站点、其他项目、不同的 --limit)生成的状态会被拒绝使用;传 --restart 可丢弃它。由本工具其他版本写入的状态同样会被拒绝。
导入包仅由状态生成,且顺序固定,因此同一状态总会产生逐字节相同的导入包。
状态目录保存的是 Jira 返回的原始内容
其中包括人员的电子邮件地址。该目录创建时只有你本人可读,导入包写完后会被删除,除非你传了 --keep-state。用完后请自行删除。
限流¶
Jira Cloud 会限制客户端的调用频率。工具请求过快时,Jira 会返回 429 Too Many Requests(有时是 503),且不一定带 Retry-After 头。工具对这类请求最多重试六次:至少等待 Retry-After 要求的时间(上限十分钟),没有该头时则按指数退避并加入随机抖动,每次等待都会记录日志。如果重试后请求仍然失败,运行会停止,可按上文所述续跑。
附件逐个下载,不并行。
附件与凭据¶
在 Jira Cloud 上,文件通过附件内容端点读取,该端点会重定向到一个媒体主机,地址中带有短期有效的令牌。工具自行逐跳跟随重定向,只向 --url 指定的站点(协议、主机和端口均相同)发送你的凭据。跳转到任何其他主机时,使用不带凭据、不带 cookie 的独立客户端;从 https 到 http 的重定向会被拒绝。媒体令牌不会写入日志。在 Data Center 上,如果附件地址在站点内,就直接使用附件自身的地址。
每个文件边下载边写入磁盘并计算哈希。大小限制会先根据 Jira 报告的大小检查,收到数据后再根据实际字节数检查一次。