Files
gitea-jira-task-bot/README.md
2026-01-29 15:44:24 +08:00

396 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gitea-Jira工单同步系统
## 部署指南
### 第一步:环境准备
#### 1.1 系统要求
- Node.js版本: 14.0.0或更高
- npm版本: 6.0.0或更高
- SQLite: 3.0或更高
#### 1.2 依赖安装
```bash
cd /path/to/gitea-jira-sync
npm install
```
该命令将安装以下依赖:
- hono (4.x): 轻量级Web框架
- @hono/node-server (1.x): Hono Node.js服务器适配器
- axios (1.13.x): HTTP客户端库
- better-sqlite3 (12.x): SQLite数据库驱动
- dotenv (17.x): 环境变量加载
- j2m (1.1.x): Markdown与Jira格式转换库
### 第二步:环境变量配置
#### 2.1 创建.env文件
```bash
cp .env.example .env
```
#### 2.2 配置SQLite数据库
```
SQLITE_PATH=./data/gitea_jira_sync.db
```
获取方法:
- SQLITE_PATH: SQLite数据库文件路径默认./data/gitea_jira_sync.db
注意: 数据库文件和表会自动创建,无需手动初始化
#### 2.3 配置Gitea信息
```
GITEA_URL=https://gitea.example.com
GITEA_TOKEN=your_gitea_api_token
GITEA_BOT_ID=your_bot_user_id
GITEA_BOT_NAME=your_bot_username
```
获取方法:
- GITEA_URL: Gitea服务器地址
- GITEA_TOKEN: 登录Gitea后访问设置->应用->创建新令牌api_token
- GITEA_BOT_ID: 登录机器人账号访问API /api/v1/user 获取id字段
- GITEA_BOT_NAME: 机器人的用户名
#### 2.4 配置Jira信息
```
JIRA_URL=https://jira.example.com
JIRA_USERNAME=your_jira_username
JIRA_PASSWORD=your_jira_password_or_pat
JIRA_PROJECT_ID_1=10000
JIRA_PROJECT_KEY_1=TEST
JIRA_BOT_ID=jira_bot_id
JIRA_BOT_NAME=jira_bot_name
```
获取方法:
- JIRA_URL: Jira服务器地址
- JIRA_USERNAME: Jira用户名
- JIRA_PASSWORD: Jira密码或个人访问令牌推荐使用PAT
- JIRA_PROJECT_ID_1: 访问/rest/api/2/project获取id
- JIRA_PROJECT_KEY_1: 项目的英文标识符如TEST、PROJ等
- JIRA_BOT_ID: 机器人账号的ID或Key
- JIRA_BOT_NAME: 机器人显示名称
#### 2.5 配置Webhook签名密钥
```
GITEA_WEBHOOK_SECRET=your_webhook_secret_key
JIRA_WEBHOOK_SECRET=your_jira_webhook_secret
```
#### 2.6 配置熔断器参数(可选)
```
CIRCUIT_BREAKER_LIMIT=20
CIRCUIT_BREAKER_WINDOW=10000
DEBUG_MODE=false
```
参数说明:
- CIRCUIT_BREAKER_LIMIT: 时间窗口内允许的最大请求数默认20
- CIRCUIT_BREAKER_WINDOW: 时间窗口大小单位毫秒默认10000ms=10秒
- DEBUG_MODE: 是否启用调试模式默认false启用后熔断器不会强制退出
### 第三步:映射配置
#### 3.1 编辑mappings.json
配置需要同步的仓库及其字段映射
目前已经开发了图形化配置工具无需再手动配置但是遇到特殊情况比如json损坏、扫不出流转状态和sprint还是要手动实测发生概率不大
#### 3.2 获取Jira映射ID
**获取Priority ID**:
```bash
curl -u username:password https://jira.example.com/rest/api/2/priority
```
返回JSON中查看id字段
**获取Issue Type ID**:
```bash
curl -u username:password https://jira.example.com/rest/api/2/issuetype
```
返回JSON中查看id字段
**获取Sprint ID**:
```bash
curl -u username:password https://jira.example.com/rest/api/2/issue/TEST-1
```
搜索customfield_10105字段格式[id=37,name=Sprint Name,...]
**获取Transition ID**:
```bash
curl -u username:password https://jira.example.com/rest/api/2/issue/TEST-1/transitions
```
查看transitions数组中的id字段
### 第四步:启动服务
#### 4.1 直接运行
```bash
node index.js
```
输出示例:
```
Server running on http://localhost:3000
Database initialized: issue_mapping table ready
Webhook endpoints ready:
POST /webhook/gitea
POST /webhook/jira
```
#### 4.2 后台运行使用pm2
```bash
npm install -g pm2
pm2 start index.js --name "gitea-jira-sync"
pm2 save
pm2 startup
```
#### 4.3 使用systemd服务Linux
创建/etc/systemd/system/gitea-jira-sync.service:
```ini
[Unit]
Description=Gitea-Jira Sync Service
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/gitea-jira-sync
ExecStart=/usr/bin/node index.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
启动服务:
```bash
sudo systemctl start gitea-jira-sync
sudo systemctl enable gitea-jira-sync
```
### 第五步配置Webhook
#### 5.1 Gitea端配置
1. 进入仓库设置 -> 设置 -> Web Hooks -> Gitea
2. 点击"添加Webhook"
3. 填写以下信息:
- 推送地址: http://your_server:3000/webhook/gitea
- HTTP方法: POST
- POST内容类型: application/json
- 密钥: 与.env中GITEA_WEBHOOK_SECRET一致
- 触发事件: Issue和Comment必选
4. 测试Webhook确保连接正常
#### 5.2 Jira端配置
1. 访问Jira管理界面 -> 系统 -> Webhooks
2. 点击"创建webhook"
3. 填写以下信息:
- 名称: Gitea Sync Webhook
- URL: http://your_server:3000/webhook/jira
- 事件类型: jira:issue_created, jira:issue_updated, jira:issue_deleted
- 认证: Basic auth或Bearer token与.env配置一致
4. 点击"创建"
### 第六步:验证部署
#### 6.1 检查服务状态
```bash
curl http://localhost:3000/health
```
预期输出: 200状态码表示服务运行正常
#### 6.2 查看日志
```bash
tail -f logs/$(date +%Y-%m-%d).log
```
观察同步操作的日志记录
#### 6.3 测试同步
**测试Gitea->Jira**:
1. 在Gitea中新建工单
2. 观察logs中出现同步日志
3. 检查Jira中是否创建了对应问题
**测试Jira->Gitea**:
1. 在Jira中新建问题
2. 观察logs中出现同步日志
3. 检查Gitea中是否创建了对应工单
## 使用指南
### 场景一:新建工单自动同步
**Gitea新建工单**:
1. 进入Gitea仓库
2. 点击Issues -> 新建Issue
3. 填写标题、描述、指派人、标签(优先级、类型)、里程碑
4. 点击提交
5. 系统自动在Jira创建对应问题
6. Gitea工单中添加评论包含Jira问题链接
**Jira新建问题**:
1. 进入Jira项目
2. 点击创建按钮
3. 填写摘要、描述、经办人、优先级、问题类型、迭代
4. 点击创建
5. 系统自动在Gitea创建对应工单
6. Jira问题中添加评论包含Gitea工单链接
### 场景二:更新工单字段
**修改优先级**:
1. 在任何一端修改优先级
2. 系统自动更新对方平台的对应标签
3. 对应标签根据mappings.js中的优先级映射进行转换
**修改工单类型**:
1. 在任何一端修改工单类型
2. 系统自动更新对方平台的对应标签
3. 对应标签根据mappings.js中的类型映射进行转换
**修改迭代/里程碑**:
1. 在任何一端修改迭代或里程碑
2. 系统自动更新对方平台
3. 里程碑名称与Sprint ID根据mappings.js进行映射
**重开操作**:
1. 在Gitea关闭工单 -> Jira问题自动转至完成状态
2. 在Jira完成问题 -> Gitea工单自动关闭
3. 重开操作会将对方平台状态改为处理中/打开
### 场景三:跨平台手动同步
**使用/resync命令**:
1. 在Gitea或Jira工单评论中输入`/resync`
2. 系统会强制重新同步所有字段
3. 如果对方平台不存在对应工单,会自动创建
4. 如果已存在,会更新所有字段
**#不同步标记**:
1. 在工单标题中添加`#不同步`标记
2. 该工单不会自动同步到对方平台
3. 使用`/resync`命令可以强制同步带有`#不同步`标记的工单
### 场景四:类型过滤
**类型未配置的工单不同步**:
1. 如果工单的类型标签在mappings.json中没有配置对应关系
2. 且mappings.json中没有设置`defaultType`
3. 该工单不会被同步,日志会记录跳过原因
### 启用DEBUG模式
用于开发和故障诊断:
```bash
DEBUG_MODE=true node index.js
```
DEBUG模式下:
- 打印所有webhook payload
- 打印API调用详情
- 跳过熔断器强制退出
- 输出详细的转换过程
## 性能优化
### 1. 连接池配置
- axios客户端使用keep-alive连接
- 自动复用TCP连接减少握手开销
### 2. 数据库优化
- SQLite支持并发访问和连接优化
- 映射表创建了repo_key、gitea_id、jira_key索引加速查询
- 支持事务和完整的ACID特性
### 3. 异步处理
- 日志写入使用异步队列
- Webhook响应立即返回实际处理异步进行
### 4. 缓存策略
- 标签、优先级、工单类型信息在mappings.json中缓存
- 避免每次处理都请求Jira API
## 安全考虑
### 1. Webhook签名验证
- 所有webhook请求都经过HMAC签名验证
- 未通过验证的请求被直接拒绝
### 2. API认证
- Gitea使用token认证
- Jira支持Basic Auth和PAT认证
### 3. 敏感信息保护
- 环境变量不在代码中硬编码
- 日志不记录password和token字段
- SQLite数据库文件应该在安全位置存储
### 4. 防无限循环
- 机器人识别防止自己操作的无限循环
- 熔断机制防止恶意攻击导致的无限请求
- 内存锁防止重复处理同一工单
## 代码结构
```
gitea-jira-sync/
├── index.js - 主程序Hono应用入口
├── mappings.json - 映射配置文件
├── package.json - 项目依赖配置
├── README.md - 本文档
├── how-to-use.md - 使用指南
├── data/ - 数据目录
├── logs/ - 日志目录
├── public/ - 前端资源目录
│ ├── app.js - 配置编辑器应用脚本
│ ├── dashboard-app.js - 仪表板应用脚本
│ ├── dashboard.html - 仪表板页面
│ ├── editor.html - 配置编辑器页面
│ └── error.html - 错误页面
└── src/
├── config/ - 配置模块
│ ├── env.js - 环境变量加载
│ └── mappings.js - 字段映射配置管理
├── db/ - 数据库模块
│ ├── connection.js - 数据库连接管理
│ └── issueMap.js - 工单映射表操作
├── logic/ - 业务逻辑模块
│ ├── converter.js - 字段数据转换
│ ├── syncManager.js - Gitea->Jira同步管理
│ └── jiraSyncManager.js - Jira->Gitea同步管理
├── routes/ - 路由模块
│ └── editor.js - 配置编辑器路由
├── services/ - 第三方API服务
│ ├── gitea.js - Gitea API客户端
│ └── jira.js - Jira API客户端
└── utils/ - 工具函数
├── logger.js - 日志模块
├── circuitBreaker.js - 熔断器实现
└── tests_created_by_claude/
├── cleanup-test-issues.js
└── comprehensive-test.js
```
## 技术栈
- **Web框架**: Hono 4.x轻量级、高性能
- **服务器**: Node.js + @hono/node-server
- **数据库**: SQLite 3.xbetter-sqlite3驱动
- **HTTP客户端**: Axios
- **环境管理**: dotenv
- **格式转换**: j2mMarkdown↔Jira格式
- **前端**: Vanilla JS无框架依赖