style:优化代码格式,提高可读性
This commit is contained in:
2
index.js
2
index.js
@@ -102,7 +102,7 @@ app.post('/hooks/jira', rateLimiter, async (c) => {
|
|||||||
const body = await c.req.json();
|
const body = await c.req.json();
|
||||||
logger.info(`[JIRA HOOK] Received request`, { event: body?.webhookEvent });
|
logger.info(`[JIRA HOOK] Received request`, { event: body?.webhookEvent });
|
||||||
|
|
||||||
// Jira Webhook通常没有签名头,依赖IP白名单或URL secret参数,此处仅校验结构
|
//Jira Webhook通常没有签名头,依赖IP白名单或URL secret参数,此处仅校验结构
|
||||||
if (!body || !body.webhookEvent) {
|
if (!body || !body.webhookEvent) {
|
||||||
logger.warn(`[JIRA HOOK] Invalid payload: missing webhookEvent`);
|
logger.warn(`[JIRA HOOK] Invalid payload: missing webhookEvent`);
|
||||||
return c.text('Invalid Jira payload', 400);
|
return c.text('Invalid Jira payload', 400);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const config = {
|
|||||||
app: {
|
app: {
|
||||||
port: process.env.PORT || 3000,
|
port: process.env.PORT || 3000,
|
||||||
dbPath: process.env.DB_FILE_PATH || './sync.sqlite',
|
dbPath: process.env.DB_FILE_PATH || './sync.sqlite',
|
||||||
rate : process.env.RATE_LIMIT_WINDOW || 10000,
|
rate: process.env.RATE_LIMIT_WINDOW || 10000,
|
||||||
maxRequests: process.env.MAX_REQUESTS_PER_WINDOW || 20,
|
maxRequests: process.env.MAX_REQUESTS_PER_WINDOW || 20,
|
||||||
debugMode: process.env.DEBUG_MODE === 'true',
|
debugMode: process.env.DEBUG_MODE === 'true',
|
||||||
logRetentionDays: process.env.LOG_RETENTION_DAYS || 30
|
logRetentionDays: process.env.LOG_RETENTION_DAYS || 30
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
// 读取配置文件路径
|
//读取配置文件路径
|
||||||
const configPath = path.join(__dirname, '../../mappings.json');
|
const configPath = path.join(__dirname, '../../mappings.json');
|
||||||
|
|
||||||
let mappingsConfig = null;
|
let mappingsConfig = null;
|
||||||
@@ -19,7 +19,7 @@ function loadMappings() {
|
|||||||
const configContent = fs.readFileSync(configPath, 'utf8');
|
const configContent = fs.readFileSync(configPath, 'utf8');
|
||||||
mappingsConfig = JSON.parse(configContent);
|
mappingsConfig = JSON.parse(configContent);
|
||||||
|
|
||||||
// 处理环境变量替换
|
//处理环境变量替换
|
||||||
processEnvVariables(mappingsConfig);
|
processEnvVariables(mappingsConfig);
|
||||||
|
|
||||||
return mappingsConfig;
|
return mappingsConfig;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function buildJiraFields(title, body, labels, milestone, repoConfig) {
|
|||||||
sprintId = sprints[milestone.title];
|
sprintId = sprints[milestone.title];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果body为空,给默认值,否则将Markdown转换为Jira Wiki Markup
|
//如果body为空,给默认值,否则将Markdown转换为Jira Wiki Markup
|
||||||
let description = "No description";
|
let description = "No description";
|
||||||
if (body) {
|
if (body) {
|
||||||
description = j2m.toJ(body);
|
description = j2m.toJ(body);
|
||||||
|
|||||||
@@ -54,18 +54,18 @@ function findLabelByTypeName(typeName, typesMap) {
|
|||||||
function parseSprintId(sprintData) {
|
function parseSprintId(sprintData) {
|
||||||
if (!sprintData) return null;
|
if (!sprintData) return null;
|
||||||
|
|
||||||
// 如果是数组,取最后一个(当前活动Sprint)
|
//如果是数组,取最后一个(当前活动Sprint)
|
||||||
if (Array.isArray(sprintData)) {
|
if (Array.isArray(sprintData)) {
|
||||||
if (sprintData.length === 0) return null;
|
if (sprintData.length === 0) return null;
|
||||||
return parseSprintId(sprintData[sprintData.length - 1]);
|
return parseSprintId(sprintData[sprintData.length - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果已经是对象,直接返回id
|
//如果已经是对象,直接返回id
|
||||||
if (typeof sprintData === 'object' && sprintData.id) {
|
if (typeof sprintData === 'object' && sprintData.id) {
|
||||||
return parseInt(sprintData.id);
|
return parseInt(sprintData.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是字符串(Java对象toString),用正则提取id
|
//如果是字符串(Java对象toString),用正则提取id
|
||||||
if (typeof sprintData === 'string') {
|
if (typeof sprintData === 'string') {
|
||||||
const match = sprintData.match(/\bid=(\d+)/);
|
const match = sprintData.match(/\bid=(\d+)/);
|
||||||
if (match) {
|
if (match) {
|
||||||
@@ -214,7 +214,7 @@ async function handleJiraHook(payload) {
|
|||||||
//通过评论记录来源链接
|
//通过评论记录来源链接
|
||||||
const jiraIssueUrl = `${config.jira.baseUrl}/browse/${issue.key}`;
|
const jiraIssueUrl = `${config.jira.baseUrl}/browse/${issue.key}`;
|
||||||
const giteaWebUrl = config.gitea.baseUrl.replace(/\/api\/v1\/?$/, '');
|
const giteaWebUrl = config.gitea.baseUrl.replace(/\/api\/v1\/?$/, '');
|
||||||
// 使用repoInfo中的owner和repo,确保使用当前配置的仓库名
|
//使用repoInfo中的owner和repo,确保使用当前配置的仓库名
|
||||||
const giteaIssueUrl = `${giteaWebUrl}/${owner}/${repo}/issues/${giteaIssue.number}`;
|
const giteaIssueUrl = `${giteaWebUrl}/${owner}/${repo}/issues/${giteaIssue.number}`;
|
||||||
|
|
||||||
const successMsg = isResyncCommand
|
const successMsg = isResyncCommand
|
||||||
@@ -257,9 +257,9 @@ async function handleJiraHook(payload) {
|
|||||||
logger.info(`[JIRA->GITEA] Entering update logic for ${issue.key}, isResync: ${isResyncCommand}`);
|
logger.info(`[JIRA->GITEA] Entering update logic for ${issue.key}, isResync: ${isResyncCommand}`);
|
||||||
const updateData = {};
|
const updateData = {};
|
||||||
const changes = isResyncCommand ? [] : (changelog.items || []);
|
const changes = isResyncCommand ? [] : (changelog.items || []);
|
||||||
let needsUpdate = isResyncCommand; // resync时强制更新
|
let needsUpdate = isResyncCommand; //resync时强制更新
|
||||||
let needsLabelUpdate = isResyncCommand; // resync时强制更新标签
|
let needsLabelUpdate = isResyncCommand; //resync时强制更新标签
|
||||||
let needsMilestoneUpdate = isResyncCommand; // resync时强制更新里程碑
|
let needsMilestoneUpdate = isResyncCommand; //resync时强制更新里程碑
|
||||||
|
|
||||||
//获取当前Gitea工单详情以处理标签
|
//获取当前Gitea工单详情以处理标签
|
||||||
let currentGiteaIssue = null;
|
let currentGiteaIssue = null;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const logger = require('../utils/logger');
|
|||||||
const config = require('../config/env');
|
const config = require('../config/env');
|
||||||
const { checkCircuitBreaker } = require('../utils/circuitBreaker');
|
const { checkCircuitBreaker } = require('../utils/circuitBreaker');
|
||||||
|
|
||||||
// 处理Gitea Issue事件的主逻辑
|
//处理Gitea Issue事件的主逻辑
|
||||||
const processingIds = new Set();
|
const processingIds = new Set();
|
||||||
const LOCK_TIMEOUT = 10000;
|
const LOCK_TIMEOUT = 10000;
|
||||||
const RETRY_DELAY = 1500;
|
const RETRY_DELAY = 1500;
|
||||||
@@ -37,7 +37,7 @@ async function handleIssueEvent(payload, retryCount = 0) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证payload完整性
|
//验证payload完整性
|
||||||
if (!issue || !issue.number || !repository) {
|
if (!issue || !issue.number || !repository) {
|
||||||
logger.error('Invalid payload: missing required fields');
|
logger.error('Invalid payload: missing required fields');
|
||||||
return;
|
return;
|
||||||
@@ -194,8 +194,8 @@ async function handleIssueEvent(payload, retryCount = 0) {
|
|||||||
//已有映射的工单,即使类型未配置也允许同步(只是不更新类型字段)
|
//已有映射的工单,即使类型未配置也允许同步(只是不更新类型字段)
|
||||||
//这样当类型从未配置变为已配置时,也能正常同步
|
//这样当类型从未配置变为已配置时,也能正常同步
|
||||||
if (jiraFields) {
|
if (jiraFields) {
|
||||||
// 处理指派人同步(resync 时)
|
//处理指派人同步(resync 时)
|
||||||
// Gitea 支持多个指派人,Jira 只支持一个经办人,取第一个
|
//Gitea 支持多个指派人,Jira 只支持一个经办人,取第一个
|
||||||
if (isResyncCommand) {
|
if (isResyncCommand) {
|
||||||
if (issue.assignees && issue.assignees.length > 0) {
|
if (issue.assignees && issue.assignees.length > 0) {
|
||||||
const firstAssignee = issue.assignees[0];
|
const firstAssignee = issue.assignees[0];
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ function checkCircuitBreaker() {
|
|||||||
}
|
}
|
||||||
requestCount++;
|
requestCount++;
|
||||||
if (requestCount > config.app.maxRequests) {
|
if (requestCount > config.app.maxRequests) {
|
||||||
const msg = `Circuit breaker triggered: Exceeded ${config.app.maxRequests} requests in ${config.app.rate/1000}s. Exiting...`;
|
const msg = `Circuit breaker triggered: Exceeded ${config.app.maxRequests} requests in ${config.app.rate / 1000}s. Exiting...`;
|
||||||
|
|
||||||
//同步写入fatal日志
|
//同步写入fatal日志
|
||||||
logger.fatal("============================");
|
logger.fatal("============================");
|
||||||
|
|||||||
Reference in New Issue
Block a user