@jira-deploy/core 1.0.0
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/constants/defaults.js +111 -0
- package/constants/environments.js +37 -0
- package/constants/field-ids.js +63 -0
- package/constants/index.js +53 -0
- package/constants/issue-types.js +23 -0
- package/constants/modules.js +55 -0
- package/constants/repos.js +55 -0
- package/constants/server.js +100 -0
- package/constants/system-codes.js +79 -0
- package/constants/users.js +47 -0
- package/dry-run.js +691 -0
- package/index.js +6 -0
- package/jira-client.js +313 -0
- package/notifier.js +56 -0
- package/package.json +34 -0
- package/platform-config.js +64 -0
- package/poller.js +64 -0
- package/tools/cd.js +666 -0
- package/tools/ci.js +204 -0
- package/tools/ci.test.js +154 -0
- package/tools/grayrelease.js +296 -0
- package/tools/helpers.js +78 -0
- package/tools/index.js +1119 -0
- package/tools/jabber.js +97 -0
- package/tools/library.js +225 -0
- package/tools/release.js +320 -0
- package/tools/release.test.js +137 -0
- package/tools.test.js +1711 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* handleWaitForComment 單元測試
|
|
3
|
+
* 執行:node --test src/tools/release.test.js
|
|
4
|
+
*/
|
|
5
|
+
import { test } from 'node:test'
|
|
6
|
+
import assert from 'node:assert/strict'
|
|
7
|
+
import { handleWaitForComment } from './release.js'
|
|
8
|
+
|
|
9
|
+
// ── helpers ───────────────────────────────────────────────────────
|
|
10
|
+
// ok() → { content: [{ type:'text', text: JSON }] }
|
|
11
|
+
// error() → same shape but text starts with ❌
|
|
12
|
+
|
|
13
|
+
function parseOk(result) {
|
|
14
|
+
return JSON.parse(result.content[0].text)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function isError(result) {
|
|
18
|
+
return result.content[0].text.startsWith('❌')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function errorText(result) {
|
|
22
|
+
return result.content[0].text
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** 製作一個 jira mock,getComments 第 callsUntilMatch 次回傳含關鍵字的 comment */
|
|
26
|
+
function makeJira({ callsUntilMatch = 1, keyword = 'Approved', author = 'BK00178' } = {}) {
|
|
27
|
+
let calls = 0
|
|
28
|
+
return {
|
|
29
|
+
getComments: async () => {
|
|
30
|
+
calls++
|
|
31
|
+
if (calls >= callsUntilMatch) {
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
body: `${keyword} by manager`,
|
|
35
|
+
author: { name: author, displayName: 'James Yu' },
|
|
36
|
+
},
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
return []
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 製作永遠回空的 jira mock(用於 timeout 測試) */
|
|
45
|
+
function makeJiraEmpty() {
|
|
46
|
+
return { getComments: async () => [] }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const BASE_ARGS = {
|
|
50
|
+
issueKey: 'CID-9999',
|
|
51
|
+
keyword: 'Approved',
|
|
52
|
+
intervalMs: 0, // 零延遲,測試瞬間完成
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ── Tests ─────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
test('dryRun 模式 → 立即回傳 found:true,不呼叫 Jira', async () => {
|
|
58
|
+
let called = false
|
|
59
|
+
const jira = {
|
|
60
|
+
getComments: async () => {
|
|
61
|
+
called = true
|
|
62
|
+
return []
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
const result = await handleWaitForComment({ ...BASE_ARGS, dryRun: true }, { jira })
|
|
66
|
+
const data = parseOk(result)
|
|
67
|
+
assert.equal(data.found, true)
|
|
68
|
+
assert.equal(data.dryRun, true)
|
|
69
|
+
assert.equal(data.attempts, 1)
|
|
70
|
+
assert.equal(data.elapsedMs, 0)
|
|
71
|
+
assert.equal(called, false, 'dryRun 時不應呼叫 jira.getComments')
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
test('第一次 poll 就找到關鍵字 → found:true', async () => {
|
|
75
|
+
const result = await handleWaitForComment(BASE_ARGS, { jira: makeJira({ callsUntilMatch: 1 }) })
|
|
76
|
+
const data = parseOk(result)
|
|
77
|
+
assert.equal(data.found, true)
|
|
78
|
+
assert.equal(data.issueKey, 'CID-9999')
|
|
79
|
+
assert.equal(data.keyword, 'Approved')
|
|
80
|
+
assert.equal(data.attempts, 1)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
test('第 3 次 poll 才找到關鍵字 → found:true,attempts === 3', async () => {
|
|
84
|
+
const result = await handleWaitForComment(BASE_ARGS, {
|
|
85
|
+
jira: makeJira({ callsUntilMatch: 3 }),
|
|
86
|
+
})
|
|
87
|
+
const data = parseOk(result)
|
|
88
|
+
assert.equal(data.found, true)
|
|
89
|
+
assert.equal(data.attempts, 3)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
test('關鍵字大小寫不分 → 能匹配', async () => {
|
|
93
|
+
const jira = makeJira({ keyword: 'APPROVED' })
|
|
94
|
+
const result = await handleWaitForComment(
|
|
95
|
+
{ ...BASE_ARGS, keyword: 'approved' },
|
|
96
|
+
{ jira },
|
|
97
|
+
)
|
|
98
|
+
assert.equal(parseOk(result).found, true)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
test('author filter 相符 → found:true', async () => {
|
|
102
|
+
const result = await handleWaitForComment(
|
|
103
|
+
{ ...BASE_ARGS, authorAccountId: 'BK00178' },
|
|
104
|
+
{ jira: makeJira({ author: 'BK00178' }) },
|
|
105
|
+
)
|
|
106
|
+
assert.equal(parseOk(result).found, true)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
test('author filter 不相符 → timeout error(超短 timeout)', async () => {
|
|
110
|
+
// comment 存在但 author 不符,永遠匹配不到
|
|
111
|
+
const jira = makeJira({ author: 'SOMEONE_ELSE' })
|
|
112
|
+
const result = await handleWaitForComment(
|
|
113
|
+
{ ...BASE_ARGS, authorAccountId: 'BK00178', timeoutMs: 20, intervalMs: 5 },
|
|
114
|
+
{ jira },
|
|
115
|
+
)
|
|
116
|
+
assert.ok(isError(result), '應回傳 error')
|
|
117
|
+
assert.match(result.content[0].text, /Timeout/)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('永遠找不到關鍵字 → timeout error', async () => {
|
|
121
|
+
const result = await handleWaitForComment(
|
|
122
|
+
{ ...BASE_ARGS, timeoutMs: 20, intervalMs: 5 },
|
|
123
|
+
{ jira: makeJiraEmpty() },
|
|
124
|
+
)
|
|
125
|
+
assert.ok(isError(result), '應回傳 error')
|
|
126
|
+
assert.match(result.content[0].text, /Timeout/)
|
|
127
|
+
assert.match(result.content[0].text, /Approved/)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('timeout error 包含輪詢次數資訊', async () => {
|
|
131
|
+
const result = await handleWaitForComment(
|
|
132
|
+
{ ...BASE_ARGS, timeoutMs: 20, intervalMs: 5 },
|
|
133
|
+
{ jira: makeJiraEmpty() },
|
|
134
|
+
)
|
|
135
|
+
assert.ok(isError(result), '應回傳 error')
|
|
136
|
+
assert.match(errorText(result), /次輪詢/)
|
|
137
|
+
})
|