Focalboard Jira 导入器实战:从 Jira XML 导出到 Focalboard 归档的完整迁移指南 Focalboard Jira 导入器实战从 Jira XML 导出到 Focalboard 归档的完整迁移指南【免费下载链接】focalboardFocalboard is an open source, self-hosted alternative to Trello, Notion, and Asana.项目地址: https://gitcode.com/GitHub_Trending/fo/focalboard导读Focalboard 的import/jira目录下内置了一个基于 Node.js 的命令行导入器它能把 Jira 通过高级搜索 XML 导出得到的数据文件转换成一个可在 Focalboard 中直接导入归档的.boardarchive文件从而实现从 Jira 到 Focalboard 的自托管迁移。本文以仓库中的 import/jira/README.md 为主体结合 importJira.ts、jiraImporter.ts 等源码完整讲解环境准备、命令行用法、字段映射规则、归档格式原理与已知限制让你读完即可独立完成一次 Jira 数据迁移。一、迁移原理与整体流程Jira 导入器是一个独立于 Focalboard 服务端与 WebApp 的 Node 命令行程序核心入口为 importJira.ts。它不直接访问 Jira API而是消费 Jira 官方Export XML功能生成的标准 RSS/XML 文件。整条链路可以分为四个阶段导出在 Jira 高级搜索Advanced Search中筛选出所有需要迁移的 Issue通过Export → Export XML得到本地 XML 文件解析导入器使用xml2js把 XML 解析为 JavaScript 对象遍历channel下的每一个item对应一条 Jira Issue转换将每条 Issue 映射为 Focalboard 的 Card卡片并为整批数据创建一个 Board看板与一个 Board View视图归档通过ArchiveUtils.buildBlockArchive把 Board 与 Block 序列化为 Focalboard 的标准归档格式.boardarchive最后在 Focalboard 界面执行导入归档即可。从源码看jiraImporter.ts 的run(inputFile, outputFile)函数完整实现了读取输入 → 校验 → 解析 → 转换 → 写出的主流程其返回值为导出的 Block 数量这也是 jiraImporter.test.ts 断言blockCount 4的依据2 张卡片 1 个视图 1 个文本块等。二、环境准备与依赖安装导入器依赖仓库内两处npm install缺一不可WebApp 依赖导入器直接 import 了../../webapp/src/blocks/下的类型与工厂函数如createBoard、createCard、createTextBlock因此需要先在focalboard/webapp下安装依赖导入器自身依赖import/jira/package.json声明了minimist命令行参数解析、xml2jsXML 解析、turndownHTML 转 Markdown三个运行时依赖以及ts-node、typescript、jest等开发依赖。安装命令建议按顺序执行cd focalboard/webapp npm install cd focalboard/import/jira npm installimport/jira/tsconfig.json使用module: commonjs、target: es2019并开启strict严格模式说明该工具按 CommonJS 模块体系在 Node 环境中运行配合ts-node可以直接执行 TypeScript 源码无需预先编译。三、使用步骤与命令行参数3.1 在 Jira 中导出 XML打开 Jira 的高级搜索Advanced Search用 JQL 筛选出需要迁移的所有 Issue点击搜索结果页的Export选择Export XML将文件保存到本地例如jira_export.xml。仓库中的测试样例 test/jira-export.xml 展示了 Jira XML 导出的真实结构根节点为rss version0.92包含channel其中每条 Issue 是一个item内含title、summary、type、priority、status、resolution、assignee、reporter、created、link、description、comments、attachments与customfields等元素。文件头部的注释还提示可以通过fieldkeyfieldsummary之类的参数限制导出字段。3.2 执行导入命令在focalboard/import/jira目录下运行npx ts-node importJira.ts -i path-to-jira.xml -o archive.boardarchive参数说明对应 importJira.ts 的minimist解析逻辑参数含义默认值说明-i输入 Jira XML 文件路径无必填缺失时打印用法并退出文件不存在时以错误码 2 退出-o输出归档文件路径archive.boardarchive可省略默认写到当前目录命令行帮助信息在 jiraImporter.ts 的showHelp()中定义为import -i input.xml -o [output.boardarchive]。若输入文件不存在或 XML 中缺少rsschannel结构程序会打印File not found、No channels in xml等错误并退出。3.3 在 Focalboard 中导入归档打开 Focalboard 应用点击Settings设置选择Import archive导入归档选中生成的archive.boardarchive文件。导入后即可看到一个名为Jira import的看板其中每条 Jira Issue 对应一张卡片。3.4 测试与调试脚本import/jira/package.json提供了两条便捷脚本可用于验证环境与流程npm test # 运行 jest 测试使用 test/jira-export.xml 执行完整导入 npm run testRun # ts-node importJira.ts -i test/jira_export.xml -o test/jira-import.focalboard其中npm run debug:test会以node --inspect5858的方式启动调试端口方便在 IDE 中逐步跟踪转换逻辑。四、字段映射规则Jira Issue → Focalboard Card转换的核心逻辑集中在 jiraImporter.ts 的convert()函数中。迁移后看板名为Jira import并创建一个名为Board View的看板视图boardView.ts 中定义viewType: board。4.1 标准属性映射导入器为看板预置了 8 个卡片属性其中 6 个为 Select单选类型2 个为 URL / 日期类型Jira XML 字段Focalboard 属性名属性类型说明priorityPriorityselect优先级如 MediumstatusStatusselect状态如 In Progress、To DoresolutionResolutionselect解决结果如 UnresolvedtypeTypeselect问题类型如 Task、EpicassigneeAssigneeselect经办人reporterReporterselect报告人linkOriginal URLurl原始 Issue 链接createdCreated Datedate创建时间毫秒时间戳Select 属性的选项Option由buildCardPropertyFromValues动态生成先对全部 Issue 的取值去重再为每个取值生成一个带颜色的 Option。颜色取自optionColors数组propColorGray到propColorRed共 9 色循环分配见 jiraImporter.ts 与 board.ts 中IPropertyOption的定义。设置卡片属性值时setSelectProperty通过optionForPropertyValue按值查找对应 Option 的 ID 写入卡片Created Date则由Date.parse转换为毫秒时间戳后存储。4.2 描述文本转换Jira 的description字段会通过turndownService.turndown()从 HTML 转换为 Markdown然后创建一个text类型的文本块挂在卡片下并通过card.fields.contentOrder指定其在卡片内容区的顺序对应 card.ts 中CardFields.contentOrder字段。转换后的描述文本会同步打印到控制台便于核对。4.3 未导入的内容按 README.md 的说明与源码中的// TODO: Map custom properties注释以下内容当前不会被导入自定义属性Custom propertiescustomfields下的 Development、Sprint、Rank、Start date 等自定义字段均被忽略评论Commentscomments元素不会被转换内嵌文件Embedded filesattachments附件不会被转换。此外README 明确提醒Jira 的 XML 导出单次上限为 1000 条 Issue超过后需要分批导出再分别导入。从实现看jiraImporter.ts 中buildCardPropertyFromValues只读取了priority、status等标准元素确实未解析customfields子节点与文档所述限制一致。五、输出归档格式.boardarchive 的结构原理导出的.boardarchive并非二进制而是一种基于 JSON Lines 的文本归档格式由 import/util/archive.ts 中的ArchiveUtils.buildBlockArchive生成首行为版本头{version:1,date:时间戳}后续每行是一条记录格式为{type:board|block,data:{...}}其中board行承载看板定义含cardPropertiesblock行承载视图、卡片、文本块等行与行之间以换行符分隔末尾空行会被忽略。对应的ArchiveUtils.parseBlockArchive负责反向解析它要求首行版本号 1且包含date否则抛出ERROR parsing header解析时按line.type分发目前仅处理block类型。正是这套格式保证了导入器生成的归档可以被 Focalboard 的导入归档功能无缝识别。六、验证方式与测试用例仓库提供了可独立运行的 Jest 测试 jiraImporter.test.ts它使用test/jira-export.xml作为输入、test/jira.focalboard作为输出完成两件事数量断言expect(blockCount 4)验证导入生成了 4 个 Block内容断言通过ArchiveUtils.parseBlockArchive读回归档断言其中包含Board View类型view、Investigate feature area与Investigate feature类型card。运行npm test即可复现这一验证流程。测试还展示了run()返回 Block 数量这一返回值契约以及归档文件可被parseBlockArchive完整读回的特性。七、已知限制与扩展方向综合 README 与源码当前版本的导入器存在以下边界规划迁移前应提前评估单看板迁移所有 Issue 被导入到名为Jira import的单个看板不会按项目Project或 Epic 拆分多个看板1000 条上限Jira XML 导出单次最多 1000 条 Issue大数据量需分批导出、多次导入用户以文本形式呈现Assignee、Reporter 仅作为 Select 属性选项存在不映射为 Focalboard 的成员Person属性三类内容缺失自定义属性、评论、附件当前不在导入范围内描述仅限单文本块每条 Issue 的多个描述段落会合并进一个 text 块不会按段落拆分成多个内容块。对于自定义属性等缺口源码在convert()中预留了// TODO: Map custom properties的扩展点buildCardPropertyFromValues也提供了从取值集合自动生成 Select 属性的通用模式可作为自行扩展 Jira 导入能力的参考起点。【免费下载链接】focalboardFocalboard is an open source, self-hosted alternative to Trello, Notion, and Asana.项目地址: https://gitcode.com/GitHub_Trending/fo/focalboard创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考