@jira-deploy/core 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tools/grayrelease.js +16 -15
- package/tools/index.js +2 -2
package/package.json
CHANGED
package/tools/grayrelease.js
CHANGED
|
@@ -570,7 +570,7 @@ export async function handleAutoGrayRelease(args, ctx) {
|
|
|
570
570
|
});
|
|
571
571
|
await notifier.notify(issueKey, '開始自動執行 GrayRelease 流程');
|
|
572
572
|
|
|
573
|
-
const result = await
|
|
573
|
+
const result = await executeAutoGrayReleaseFlow(
|
|
574
574
|
issueKey,
|
|
575
575
|
{
|
|
576
576
|
maxBuildRetries: args.maxBuildRetries ?? 3,
|
|
@@ -655,7 +655,7 @@ export async function handleContinueGrayRelease(args, ctx) {
|
|
|
655
655
|
currentStatus: status.currentStatus,
|
|
656
656
|
});
|
|
657
657
|
|
|
658
|
-
const result = await
|
|
658
|
+
const result = await executeAutoGrayReleaseFlow(
|
|
659
659
|
issueKey,
|
|
660
660
|
{
|
|
661
661
|
maxBuildRetries: args.maxBuildRetries ?? 3,
|
|
@@ -830,7 +830,7 @@ async function executeGrayReleaseDeployFlow(issueKey, ctx) {
|
|
|
830
830
|
/**
|
|
831
831
|
* 主執行流程:從當前狀態開始,自動執行到完成或需要人工介入
|
|
832
832
|
*/
|
|
833
|
-
async function
|
|
833
|
+
async function executeAutoGrayReleaseFlow(issueKey, options, ctx) {
|
|
834
834
|
const { jira, notifier } = ctx;
|
|
835
835
|
const log = [];
|
|
836
836
|
let buildAttempts = 0;
|
|
@@ -1007,16 +1007,16 @@ async function runGrayReleaseDeployStep(issueKey, systemCode, ctx, log) {
|
|
|
1007
1007
|
await notifier.notify(issueKey, '觸發 GrayRelease Deploy');
|
|
1008
1008
|
|
|
1009
1009
|
// 等待部署完成:優先輪詢 deploy result、VERIFY 狀態,
|
|
1010
|
-
//
|
|
1011
|
-
// 最多等待 3 分鐘(避免 MCP client timeout),
|
|
1010
|
+
// 最多等待 10 分鐘(避免 MCP client timeout),
|
|
1012
1011
|
// 若超時則回傳「部署中」訊息,請使用者稍後繼續。
|
|
1013
|
-
|
|
1014
|
-
const
|
|
1012
|
+
// 每 3 分鐘 輪詢一次
|
|
1013
|
+
const DEPLOY_WAIT_MS = Math.min(getPollTimeoutMs(), 10 * 60 * 1000);
|
|
1014
|
+
const DEPLOY_POLL_MS = Math.min(getPollIntervalMs(), 3 * 60 * 1000);
|
|
1015
1015
|
const deployDeadline = Date.now() + DEPLOY_WAIT_MS;
|
|
1016
1016
|
let deployCompleted = false;
|
|
1017
1017
|
let attempts = 0;
|
|
1018
1018
|
|
|
1019
|
-
log.push(' ⏳ 等待部署完成(最多
|
|
1019
|
+
log.push(' ⏳ 等待部署完成(最多 10 分鐘)...');
|
|
1020
1020
|
while (Date.now() <= deployDeadline) {
|
|
1021
1021
|
attempts++;
|
|
1022
1022
|
const issue = await jira.getIssue(issueKey);
|
|
@@ -1037,10 +1037,10 @@ async function runGrayReleaseDeployStep(issueKey, systemCode, ctx, log) {
|
|
|
1037
1037
|
nextPollMs: DEPLOY_POLL_MS,
|
|
1038
1038
|
});
|
|
1039
1039
|
|
|
1040
|
-
if (statusNow === 'VERIFY') {
|
|
1040
|
+
if (statusNow === 'VERIFY' && isPassingResult(deployResult)) {
|
|
1041
1041
|
// Jira automation 或 Jenkins 已自動切到 VERIFY
|
|
1042
1042
|
deployCompleted = true;
|
|
1043
|
-
log.push(' ✅
|
|
1043
|
+
log.push(' ✅ Deploy 完成,狀態已進入 VERIFY(cid jira worker 自動切換),進入驗證階段');
|
|
1044
1044
|
break;
|
|
1045
1045
|
}
|
|
1046
1046
|
|
|
@@ -1071,8 +1071,9 @@ async function runGrayReleaseDeployStep(issueKey, systemCode, ctx, log) {
|
|
|
1071
1071
|
await sleep(DEPLOY_POLL_MS);
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
|
+
|
|
1074
1075
|
if (!deployCompleted) {
|
|
1075
|
-
log.push(' ⚠️
|
|
1076
|
+
log.push(' ⚠️ 10 分鐘內未看到部署結果,部署可能仍在進行中');
|
|
1076
1077
|
log.push(' 請稍後使用 get_grayrelease_status 或 deploy_grayrelease 繼續');
|
|
1077
1078
|
await notifier.notify(issueKey, '部署仍在進行中,請稍後查詢狀態');
|
|
1078
1079
|
return false;
|
|
@@ -1246,8 +1247,7 @@ async function handleGrayReleaseApproval(issueKey, environment, systemCode, ctx)
|
|
|
1246
1247
|
|
|
1247
1248
|
/**
|
|
1248
1249
|
* 判斷是否需要執行 Switch Execution Node
|
|
1249
|
-
* 規則:查詢同系統上次 CD 部署的環境群組,若與本次不同則需切換
|
|
1250
|
-
* 注意:不查詢 GrayRelease 歷史,因為 GrayRelease 永遠是 nonPrd
|
|
1250
|
+
* 規則:查詢同系統上次 CD or GrayRelease 部署的環境群組,若與本次不同則需切換
|
|
1251
1251
|
*/
|
|
1252
1252
|
async function needSwitchExecutionNode(issueKey, systemCode, jira) {
|
|
1253
1253
|
if (await hasRecentSwitchExecutionNodeComment(issueKey, systemCode, jira)) {
|
|
@@ -1260,12 +1260,13 @@ async function needSwitchExecutionNode(issueKey, systemCode, jira) {
|
|
|
1260
1260
|
// 只查詢 CD 單的部署歷史(不包含 GrayRelease)
|
|
1261
1261
|
const isPrdEnv = (env) => ['prd', 'dr', 'prd/dr', 'prd&dr'].includes(env?.toLowerCase()?.trim());
|
|
1262
1262
|
|
|
1263
|
-
const jql_cd = `project = CID AND issuetype = CD
|
|
1263
|
+
const jql_cd = `project = CID AND (issuetype = CD OR issuetype = GrayRelease) AND text ~ "${systemCode}" AND status = Done AND issueKey != "${issueKey}" ORDER BY updated DESC`;
|
|
1264
1264
|
|
|
1265
1265
|
try {
|
|
1266
1266
|
const cdResults = await jira.searchIssues(jql_cd, ['customfield_13436', 'updated'], 1);
|
|
1267
1267
|
const cdIssue = cdResults[0] ?? null;
|
|
1268
1268
|
|
|
1269
|
+
|
|
1269
1270
|
// 查不到歷史 → 保守執行 Switch
|
|
1270
1271
|
if (!cdIssue) {
|
|
1271
1272
|
return true;
|
|
@@ -1311,7 +1312,7 @@ async function hasRecentSwitchExecutionNodeComment(issueKey, systemCode, jira) {
|
|
|
1311
1312
|
const lowerSystemCode = String(systemCode ?? '').toLowerCase();
|
|
1312
1313
|
return comments.some((comment) => {
|
|
1313
1314
|
const body = String(comment.body ?? '').toLowerCase();
|
|
1314
|
-
const author = String(comment.author?.displayName ??
|
|
1315
|
+
const author = String(comment.author?.displayName ?? '').toLowerCase();
|
|
1315
1316
|
return author === 'cid jira worker'
|
|
1316
1317
|
&& body.includes('instance_group')
|
|
1317
1318
|
&& body.includes('nonprd_executionnode')
|
package/tools/index.js
CHANGED
|
@@ -727,8 +727,8 @@ export async function executeTool(name, args, deps) {
|
|
|
727
727
|
|
|
728
728
|
// 查詢同系統最近一筆已完成的部署(CD 或 GrayRelease),回傳 'prd' | 'nonPrd' | null
|
|
729
729
|
const getLastDeployEnvGroup = async (systemCode, excludeKey) => {
|
|
730
|
-
const jql_cd = `project = CID AND issuetype = CD AND
|
|
731
|
-
const jql_gr = `project = CID AND issuetype = GrayRelease AND
|
|
730
|
+
const jql_cd = `project = CID AND issuetype = CD AND text ~ "${systemCode}" AND status = Done AND issueKey != "${excludeKey}" ORDER BY updated DESC`;
|
|
731
|
+
const jql_gr = `project = CID AND issuetype = GrayRelease AND text ~ "${systemCode}" AND status = Done ORDER BY updated DESC`;
|
|
732
732
|
|
|
733
733
|
const [cdResults, grResults] = await Promise.all([
|
|
734
734
|
jira.searchIssues(jql_cd, ['customfield_13436', 'updated'], 1).catch(() => []),
|