Jira REST API ํ† ํฐ ๋ฐœ๊ธ‰ ๋ฐ ์ด์Šˆ ์กฐํšŒ

2025. 3. 2. 19:55ยท๐Ÿ“‚ Quality Assurance Study/๐Ÿ“„ QA ๊ณต๋ถ€

๐Ÿ“Œ ๋ฌธ์ œ ์ƒํ™ฉ

์šฐ๋ฆฌ ์Šคํ„ฐ๋””์—์„œ๋Š” ์ฃผ์ฐจ๋ณ„๋กœ ์Šคํ”„๋ฆฐํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ๊ฐ ์ฃผ์ฐจ์— ๋งž๋Š” ์ด์Šˆ๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ์ผ์ •์„ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 1์ฃผ์ฐจ์— ํ•ด๋‹นํ•˜๋Š” ์ด์Šˆ๋“ค์€ '1์ฃผ์ฐจ' ์—ํ”ฝ์—, 2์ฃผ์ฐจ์— ํ•ด๋‹นํ•˜๋Š” ์ด์Šˆ๋“ค์€ '2์ฃผ์ฐจ' ์—ํ”ฝ์— ํ• ๋‹น๋œ๋‹ค. Confluence ๋ฌธ์„œ์— Jira์˜ ํŠน์ • ์ด์Šˆ๋ฅผ ์‚ฝ์ž…ํ•  ๊ฒฝ์šฐ ํŠน์ • ์—ํ”ฝ์„ ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์—†์–ด, ๋ชจ๋“  ์ฃผ์ฐจ์˜ ์ด์Šˆ๊ฐ€ ํ•œ๊บผ๋ฒˆ์— ๋ถˆ๋Ÿฌ์™€์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค. ์ด๋Š” JQL์—์„œ and parent = "์—ํ”ฝ ํ‚ค" ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

(์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋„๊ตฌ #1] Jira ๋ฐ Confluence ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ๊ธ€์˜ "๐Ÿ“Œ Confluence ์ฝ˜ํ…์ธ  ์ƒ์„ฑ (jira ์ด์Šˆ ์—ฐ๋™)" ์ฐธ๊ณ )

 

์œ„๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ, ์ด์Šˆ ์œ ํ˜•, ์ƒํƒœ, ๋‹ด๋‹น์ž ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ JQL์„ ์ˆ˜์ •ํ•˜์—ฌ ์—ํ”ฝ๊นŒ์ง€ ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ํŠน์ • ์—ํ”ฝ์˜ ์ด์Šˆ๋“ค์€ ์ •์ƒ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์™€์กŒ์ง€๋งŒ, ๊ทธ ์ด์Šˆ๋“ค์˜ ํ•˜์œ„ ์ด์Šˆ๋“ค์€ ํฌํ•จ๋˜์ง€ ์•Š์•˜๋‹ค. ์ด๋Š” JQL์—์„œ ํŠน์ • ์—ํ”ฝ์„ parent๋กœ ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฆ‰, ํ•˜์œ„ ์ด์Šˆ๋“ค์€ ํ•ด๋‹น ์—ํ”ฝ์ด ์•„๋‹Œ, ๊ทธ ์ƒ์œ„ ์ด์Šˆ๋ฅผ parent๋กœ ๊ฐ€์ง€๋ฏ€๋กœ ์ž๋™์œผ๋กœ ํฌํ•จ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. ํ•˜์œ„ ์ด์Šˆ๊นŒ์ง€ ํฌํ•จํ•˜๋ ค๋ฉด JQL์—์„œ parent in () ์กฐ๊ฑด์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ํ•˜์ง€๋งŒ, ์ด ๋ฐฉ๋ฒ•์€ ํ•˜์œ„ ์ด์Šˆ๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ์ด์Šˆ์˜ ํ‚ค๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€์ด ์žˆ๋‹ค.

 

[ ์˜ˆ์‹œ ]

๋”๋ณด๊ธฐ

์˜ˆ๋ฅผ ๋“ค์–ด, ํ™๊ธธ๋™ ๋‹ด๋‹น์ž์—๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์Šˆ๊ฐ€ ํ• ๋‹น๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•˜์ž.

  • A ์ด์Šˆ (parent: "3์ฃผ์ฐจ" ์—ํ”ฝ)
  • B ์ด์Šˆ (parent: "3์ฃผ์ฐจ" ์—ํ”ฝ / ํ•˜์œ„ ์ด์Šˆ: a, b, c)
  • C ์ด์Šˆ (parent "3์ฃผ์ฐจ" ์—ํ”ฝ / ํ•˜์œ„ ์ด์Šˆ: d)

์ด์Šˆ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ, A, B, C ์ด์Šˆ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ B์™€ C์˜ ํ•˜์œ„ ์ด์Šˆ๋“ค๊นŒ์ง€ ๋ชจ๋‘ ํฌํ•จํ•˜๋ ค๋ฉด, JQL์˜ parent๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

... and parent in ("3์ฃผ์ฐจ ์—ํ”ฝ ํ‚ค", "B ์ด์Šˆ ํ‚ค", "C ์ด์Šˆ ํ‚ค") ...

 

๐Ÿ“Œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์Šคํ„ฐ๋”” ์ฃผ์ฐจ๊ฐ€ ๋๋‚˜๋Š” ๋‚ , Confluence๋กœ ๋ฌธ์„œ๋ฅผ ์ทจํ•ฉํ•˜๋ฉด์„œ ๋ฌธ๋“ ๋– ์˜ค๋ฅธ ์ƒ๊ฐ์ด '์ตœ๊ทผ์— ๋ฐฐ์šด Selenium์„ ํ™œ์šฉํ•˜๋ฉด ์ด ์ž‘์—…์„ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ?' ์˜€๋‹ค. ์ฒ˜์Œ์—๋Š” Selenium์„ ์‚ฌ์šฉํ•ด ๋‹ด๋‹น์ž๋ณ„๋กœ ํ•˜์œ„ ์ด์Šˆ๋ฅผ ๊ฐ€์ง„ ์ด์Šˆ๋“ค์˜ ํ‚ค๋ฅผ ์ž๋™์œผ๋กœ ์ฐพ์•„์ฃผ๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ–ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ ๊ตฌํ˜„์„ ์‹œ๋„ํ•˜๋ฉด์„œ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

 

Selenium์„ ํ†ตํ•œ ์ž๋™ํ™”์˜ ๋ฌธ์ œ์ 

  1. Jira๋Š” SPA(Single Page Application) ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ๋งŒ ์ผ๋ถ€ ์š”์†Œ๋“ค์ด ๋กœ๋“œ๋œ๋‹ค.
  2. ๋Œ€๋ถ€๋ถ„์˜ ์ด์Šˆ ์ƒํƒœ ๋ณ€๊ฒฝ, ๊ฒ€์ƒ‰, ํ•„ํ„ฐ๋ง ๋“ฑ์€ AJAX ์š”์ฒญ์„ ํ†ตํ•ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ, Selenium์ด ์š”์†Œ๋ฅผ ๊ฐ์ง€ํ•˜๊ธฐ ์ „์— ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.
  3. ์ผ๋ถ€ UI ์š”์†Œ๊ฐ€ iframe ๋‚ด๋ถ€์— ์œ„์น˜ํ•˜์—ฌ, Selenium์—์„œ ๋ฐ”๋กœ ์ ‘๊ทผํ•˜๋ ค๋ฉด switch_to.frame()์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, ์ด๋กœ ์ธํ•ด ์ถ”๊ฐ€์ ์ธ ๋ณต์žก์„ฑ์ด ๋ฐœ์ƒํ•œ๋‹ค.
  4. HTML ๊ตฌ์กฐ๊ฐ€ ๋ณต์žกํ•˜๊ณ , ํด๋ž˜์Šค ๋„ค์ด๋ฐ์„ ๋‚œ๋…ํ™”ํ•˜์—ฌ ๋žœ๋คํ•œ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  5. jira์˜ ๋กœ๋”ฉ ์†๋„๊ฐ€ ์ผ์ •ํ•˜์ง€ ์•Š์•„ WebDriverWait์™€ time.sleep()์„ ์‚ฌ์šฉํ•ด๋„ ์˜ˆ์™ธ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค.

 

'๊ทธ๋ ‡๋‹ค๋ฉด Selenium ๋ง๊ณ  ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์—†์„๊นŒ?'์— ๋Œ€ํ•œ ๊ณ ๋ฏผ ๋์— ์ฐพ์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ๋ฐ”๋กœ Jira REST API ์˜€๋‹ค. Jira REST API๋ฅผ ํ™œ์šฉํ•˜๋ฉด, UI ์š”์†Œ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•ด ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด, Selenium๋ณด๋‹ค ํ›จ์”ฌ ์•ˆ์ •์ ์ด๊ณ  ํšจ์œจ์ ์ธ ์ž๋™ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

+ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์‚ฌ์‹ค Confluence์—์„œ๋Š” ํ•˜์œ„ ์ž‘์—…์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ–ˆ์ง€๋งŒ, ๋ณธ์ธ์€ ์ด๋ฅผ ์•Œ์ง€ ๋ชปํ–ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์—ด ๊ตฌ์„ฑ์—์„œ ํ•˜์œ„ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•ด๊ฒฐ๋˜๋Š” ๋ฌธ์ œ์˜€์ง€๋งŒ, JQL ์ƒ์„ฑ ์ž๋™ํ™” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“  ํ›„ ํ•ด๋‹น JQL์„ Confluence ๋ฌธ์„œ์— ์ ์šฉํ•ด๋ณด๋ฉด์„œ ์ด๋ฅผ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์–ด์ฐŒ ๋ณด๋ฉด ํ˜ผ์ž ์‚ฝ์งˆํ•œ ์…ˆ์ด์ง€๋งŒ, ๊ธ์ •์ ์œผ๋กœ ๋ณด๋ฉด ๋•๋ถ„์— Selenium์„ ์—ฐ์Šตํ•˜๊ณ  Jira REST API๋„ ํ™œ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. (์ž์„ธํ•œ ๋‚ด์šฉ์€ [๋„๊ตฌ #1] Jira ๋ฐ Confluence ์‚ฌ์šฉ ๋ฐฉ๋ฒ• ๊ธ€์˜ "๐Ÿ“Œ Confluence ์ฝ˜ํ…์ธ  ์ƒ์„ฑ (jira ์ด์Šˆ ์—ฐ๋™)" ์ฐธ๊ณ )

 

๐Ÿ“Œ Jira REST API๋ž€?

Jira REST API๋Š” HTTP ์š”์ฒญ์„ ํ†ตํ•ด Jira์˜ ๋ฐ์ดํ„ฐ(์ด์Šˆ, ํ”„๋กœ์ ํŠธ, ์‚ฌ์šฉ์ž ์ •๋ณด ๋“ฑ)์— ์ ‘๊ทผํ•˜๊ณ  ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณต๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ฆ‰, ๋ธŒ๋ผ์šฐ์ €์—์„œ UI๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์ด์Šˆ๋ฅผ ํ™•์ธํ•˜๋Š” ๋Œ€์‹ , API๋ฅผ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑ, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. Jira REST API๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ JSON ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์œผ๋ฉฐ, GET, POST, PUT, DELETE ๊ฐ™์€ HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ“Œ Jira API Token ๋ฐœ๊ธ‰ ๋ฐฉ๋ฒ•

Jira API Token์„ ๋ฐœ๊ธ‰ํ•˜๋ ค๋ฉด, ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ์˜ [ ํ”„๋กœํ•„ ๋ฐ ์„ค์ • ] > [ ๊ณ„์ • ๊ด€๋ฆฌ ] ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค.

๋‹ค์Œ์œผ๋กœ, [ API ํ† ํฐ ๋งŒ๋“ค๊ธฐ ๋ฐ ๊ด€๋ฆฌ ] ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค.

๋‹ค์Œ์œผ๋กœ, [ API ํ† ํฐ ๋งŒ๋“ค๊ธฐ ] ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค.

์ƒˆ๋กœ ์ƒ์„ฑํ•  API ํ† ํฐ์˜ ์ด๋ฆ„๊ณผ, ๋งŒ๋ฃŒ์ผ์„ ์„ค์ •ํ•œ ๋’ค [ ๋งŒ๋“ค๊ธฐ ] ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ์ƒˆ๋กœ์šด API ํ† ํฐ์„ ์ƒ์„ฑํ•œ๋‹ค.

API ํ† ํฐ์„ ์ƒ์„ฑํ•˜๋ฉด ์œ„์™€ ๊ฐ™์€ ์ฐฝ์ด ๋œจ๋Š”๋ฐ, ์ด ์ฐฝ์€ ํ•œ ๋ฒˆ๋งŒ ํ‘œ์‹œ๋˜๋ฏ€๋กœ ๋‹ซ์œผ๋ฉด ๋‹ค์‹œ ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค. ์ฆ‰, ๋ณต์‚ฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ดํ›„์— ํ•ด๋‹น ํ† ํฐ์„ ๋‹ค์‹œ ๋ณผ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜๋“œ์‹œ ์•ˆ์ „ํ•œ ๊ณณ์— ์ €์žฅํ•ด๋‘์–ด์•ผ ํ•œ๋‹ค.

 

๐Ÿ“Œ Jira REST API๋ฅผ ํ†ตํ•œ ์ด์Šˆ ์กฐํšŒ

ํ˜„์žฌ ์Šคํ„ฐ๋”” ํ”„๋กœ์ ํŠธ๋Š” Jira Cloud๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๋ฏ€๋กœ, Jira Cloud Platform REST API ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์˜€๋‹ค.

๋งŒ์•ฝ Jira Server(Data Center)๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๋ผ๋ฉด, Jira Server/Data Center REST API ๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ”„๋กœ์ ํŠธ์˜ REST API ๋ฒ„์ „์„ ํ™•์ธํ•˜๋ ค๋ฉด, ๋ธŒ๋ผ์šฐ์ € ์ฃผ์†Œ์ฐฝ์— "https://your-instance.atlassian.net/rest/api/3/serverInfo" URL์„ ์ž…๋ ฅํ•œ๋‹ค. ์ด๋•Œ, "your-instance.atlassian.net" ๋ถ€๋ถ„์„ ๋ณธ์ธ์˜ Jira ๋„๋ฉ”์ธ์œผ๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ ์‘๋‹ต์ด ์ •์ƒ์ ์œผ๋กœ JSON ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค๋ฉด, ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๋Š” REST API v3๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ฐ˜๋Œ€๋กœ, 404 Not Found ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, REST API v3๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. Jira REST API๋Š” ๋ฒ„์ „์— ๋”ฐ๋ผ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ณธ์ธ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ง€์›ํ•˜๋Š” REST API ๋ฒ„์ „์„ ๋จผ์ € ํ™•์ธํ•œ ํ›„, ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์ ์ ˆํ•œ ๋ฒ„์ „์„ ์„ ํƒํ•˜์—ฌ ๋ณธ์ธ์˜ ํ™˜๊ฒฝ์— ๋งž๋Š” ๋‚ด์šฉ์„ ์ฐธ๊ณ ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

 

[ ๊ตฌํ˜„ ์ฝ”๋“œ ]

๋”๋ณด๊ธฐ
import os
import requests

JIRA_URL = "jira ํ”„๋กœ์ ํŠธ ๋„๋ฉ”์ธ"
JIRA_API_TOKEN = "๋ฐœ๊ธ‰๋ฐ›์€ Jira API ํ† ํฐ"
JIRA_EMAIL = "๋ณธ์ธ์˜ ์ด๋ฉ”์ผ"

AUTH = (JIRA_EMAIL, JIRA_API_TOKEN)
HEADERS = {"Content-Type": "application/json"}

def getAccountID(userName): # ์‚ฌ์šฉ์ž Account ID ์กฐํšŒ ํ•จ์ˆ˜
    response = requests.get(f"{JIRA_URL}/rest/api/3/user/search", auth=AUTH, headers=HEADERS, params={"query": userName})
    return response.json()[0]["accountId"] if response.status_code == 200 and response.json() else None

def hasSubtasks(issueKey): # ํŠน์ • ์ด์Šˆ์— ํ•˜์œ„ ์ด์Šˆ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜
    jql = f'parent="{issueKey}"'
    response = requests.get(f"{JIRA_URL}/rest/api/3/search", auth=AUTH, headers=HEADERS, params={"jql": jql, "fields": "key"})
    return bool(response.json().get("issues", [])) if response.status_code == 200 else False

def getIssues(project, epicKey, userName): # ํŠน์ • Epic์— ์†ํ•œ ์‚ฌ์šฉ์ž์˜ ์ด์Šˆ & ํ•˜์œ„ ์ด์Šˆ ์กฐํšŒ
    assigneeID = getAccountID(userName)
    if not assigneeID:
        return print(f"โŒ '{userName}' ์‚ฌ์šฉ์ž๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")

    jql = f'project="{project}" AND assignee="{assigneeID}" AND parent="{epicKey}" ORDER BY created DESC'
    response = requests.get(f"{JIRA_URL}/rest/api/3/search", auth=AUTH, headers=HEADERS, params={"jql": jql, "fields": "key"})

    if response.status_code != 200:
        return print("โŒ API ์š”์ฒญ ์‹คํŒจ!")

    issues = [issue["key"] for issue in response.json().get("issues", [])]
    print(f"โœ… {userName}์˜ ์ด์Šˆ ํ‚ค:", issues)

    subtasks = [key for key in issues if hasSubtasks(key)]
    print(f"๐Ÿ“Œ ํ•˜์œ„ ์ด์Šˆ๊ฐ€ ์žˆ๋Š” ์ด์Šˆ ํ‚ค:", subtasks if subtasks else "์—†์Œ")

# ์‹คํ–‰
os.system('cls')
getIssues("STUDY", "STUDY-100", "๊ฐ•์—ฐ์ˆ˜")

 

์œ„์™€ ๊ฐ™์ด, Jira REST API๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ •์ƒ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์™”์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

+ ์ถ”๊ฐ€ ์ง€์‹

Jira Cloud vs Jira Server(Data Center)

๊ตฌ๋ถ„ Jira Cloud Jira Server(Data Center)
๋ฐฐํฌ ๋ฐฉ์‹ Atlassian์ด ํด๋ผ์šฐ๋“œ์—์„œ ์šด์˜ (SaaS) ์ž์ฒด ์„œ๋ฒ„์— ์„ค์น˜ ๋ฐ ์šด์˜ (On-Premise)
์œ ์ง€๋ณด์ˆ˜ Atlassian์ด ์ž๋™ ๊ด€๋ฆฌ (์—…๋ฐ์ดํŠธ, ๋ณด์•ˆ ๋“ฑ) ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์œ ์ง€๋ณด์ˆ˜ ๋ฐ ์—…๊ทธ๋ ˆ์ด๋“œ ์ˆ˜ํ–‰
ํ™•์žฅ์„ฑ ์ž๋™ ํ™•์žฅ ์ง€์› ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ธํ”„๋ผ ํ™•์žฅ ํ•„์š”
์—…๋ฐ์ดํŠธ ์ž๋™ ์—…๋ฐ์ดํŠธ ์ง์ ‘ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•„์š”
๋ฐฑ์—… ๋ฐ ๋ณต๊ตฌ Atlassian์ด ๊ด€๋ฆฌ (๊ธฐ๋ณธ 7์ผ ์œ ์ง€) ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๋ฐฑ์—… ๋ฐ ๋ณต๊ตฌ ์„ค์ •
์ปค์Šคํ„ฐ๋งˆ์ด์ง• ์ œํ•œ์  (Cloud์šฉ ์•ฑ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ) ๊ณ ๋„์˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• (ํ”Œ๋Ÿฌ๊ทธ์ธ, ์Šคํฌ๋ฆฝํŠธ ํ™œ์šฉ)
๋ณด์•ˆ ๋ฐ ๊ทœ์ • ์ค€์ˆ˜ Atlassian์ด SOC2, ISO27001 ๋“ฑ ๋ณด์•ˆ ์ธ์ฆ ๊ธฐ์—… ๋‚ด๋ถ€ ๋ณด์•ˆ ์ •์ฑ…์— ๋”ฐ๋ผ ์„ค์ • ๊ฐ€๋Šฅ
์‚ฌ์šฉ์ž ๊ด€๋ฆฌ Atlassian Access(SAML, SSO) ์ง€์› LDAP, Active Directory ์—ฐ๋™ ๊ฐ€๋Šฅ
๊ฐ€๊ฒฉ ๋ชจ๋ธ ์›”/์—ฐ ๊ตฌ๋…ํ˜• (์‚ฌ์šฉ์ž ์ˆ˜ ๊ธฐ๋ฐ˜) ์—ฐ๊ฐ„ ๋ผ์ด์„ผ์Šค ๊ตฌ๋งค (Data Center๋Š” ์ตœ์†Œ 500๋ช…)
๋ฌด๋ฃŒ ํ”Œ๋žœ ์ตœ๋Œ€ 10๋ช… ๋ฌด๋ฃŒ ์—†์Œ (์œ ๋ฃŒ ๋ผ์ด์„ ์Šค ํ•„์š”)
๋Œ€์ƒ ์Šคํƒ€ํŠธ์—…, ์ค‘์†Œ๊ธฐ์—…, ์œ ์ง€๋ณด์ˆ˜ ๋ถ€๋‹ด์ด ์ ์€ ์กฐ์ง ๋Œ€๊ธฐ์—…, ๋ณด์•ˆ์ด ์ค‘์š”ํ•œ ์กฐ์ง, ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ํ•„์š”ํ•œ ํŒ€

Jira REST API์˜ ์ธ์ฆ ๋ฐฉ์‹

1. Basic Authentication (๊ธฐ๋ณธ ์ธ์ฆ)

 ~> ์‚ฌ์šฉ ๋ฐฉ๋ฒ• (Jira Cloud Platform REST API ๊ณต์‹ ๋ฌธ์„œ)

  1. ์‚ฌ์šฉ์ž ID + API Token์„ Base64 ์ธ์ฝ”๋”ฉ ํ›„ Authorization ํ—ค๋”์— ์ถ”๊ฐ€

 ~> ํŠน์ง•

  • ๊ฐ„๋‹จํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

  • ๋ณด์•ˆ์ƒ ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ์–ด HTTPS ์‚ฌ์šฉ ํ•„์ˆ˜

  • Jira Cloud๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ ๋Œ€์‹  API Token ์‚ฌ์šฉ ํ•„์ˆ˜

2. OAuth 2.0 ์ธ์ฆ

 ~> ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

  1. OAuth ์•ฑ ์ƒ์„ฑ ํ›„ Client ID & Client Secret ํš๋“

  2. ์‚ฌ์šฉ์ž ์ธ์ฆ ํ›„ Access Token ๋ฐœ๊ธ‰

  3. API ์š”์ฒญ ์‹œ Authorization ํ—ค๋”์— Bearer ํ† ํฐ ์ถ”๊ฐ€

 ~> ํŠน์ง•

  • ๋ณด์•ˆ์ด ๊ฐ•๋ ฅํ•˜๊ณ , ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ

  • ์™ธ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ์˜ ์—ฐ๋™์— ์œ ๋ฆฌ

  • ์„ค์ • ๊ณผ์ •์ด ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Œ

3. Session-based Authentication (์ฟ ํ‚ค ์ธ์ฆ)

 ~> ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

  1.  ๋กœ๊ทธ์ธ API๋ฅผ ํ˜ธ์ถœํ•ด JSESSIONID ํš๋“

  2. API ์š”์ฒญ ์‹œ Cookie ํ—ค๋”์— ์ถ”๊ฐ€

 ~> ํŠน์ง•

  • Jira Server (On-Premise)์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • ๊ธฐ์กด ๋กœ๊ทธ์ธ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•˜์—ฌ ์นœ์ˆ™ํ•จ

  • Jira Cloud์—์„œ๋Š” ์ง€์›ํ•˜์ง€ ์•Š์Œ

 

๐Ÿ“Œ Jira REST API์˜ ์ถ”๊ฐ€ ํ™œ์šฉ ๋ฐฉ์•ˆ

์‚ฌ์‹ค ๋ณธ์ธ์€ Jira REST API๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์ด์Šˆ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ธฐ๋Šฅ๋งŒ์„ ๋‹ค๋ค˜์ง€๋งŒ, ์ด๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์€ ๋ฌด๊ถ๋ฌด์ง„ํ•˜๋‹ค๊ณ  ๋А๊ผˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Selenium์ด๋‚˜ ๊ธฐํƒ€ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•ด ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ–ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ Jira์— ๋ฒ„๊ทธ ํ‹ฐ์ผ“์„ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜, ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด ํ•ด๋‹น ์ด์Šˆ์˜ ์ƒํƒœ๋ฅผ ‘์ง„ํ–‰ ์ค‘’์—์„œ ‘์™„๋ฃŒ’๋กœ ์ž๋™ ๋ณ€๊ฒฝํ•˜๋Š” ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ๋˜ํ•œ, ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ์ด์Šˆ์˜ ๋Œ“๊ธ€๋กœ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜, ํŠน์ • ์ด์Šˆ ๋ฐœ์ƒ ์‹œ Slack์ด๋‚˜ Discord๋กœ ์•Œ๋ฆผ์„ ์ „์†กํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•  ๊ฒƒ์ด๋‹ค. ์•ž์œผ๋กœ๋Š” ์ด๋Ÿฌํ•œ ํ™•์žฅ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉฐ, Jira REST API๋ฅผ ๋ณด๋‹ค ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํฌ์ŠคํŒ…ํ•  ๊ณ„ํš์ด๋‹ค.

 

'๐Ÿ“‚ Quality Assurance Study > ๐Ÿ“„ QA ๊ณต๋ถ€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Jest + POM] ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ† ๋ง  (0) 2025.04.20
Unity์—์„œ์˜ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๋ฐ Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™”  (0) 2025.03.09
XPath์— ๋Œ€ํ•˜์—ฌ  (0) 2025.02.27
Jira ๋ฐ Confluence ์‚ฌ์šฉ ๋ฐฉ๋ฒ•  (2) 2025.02.20
BTS (Bug Tracking System)์— ๋Œ€ํ•˜์—ฌ  (3) 2025.01.13
'๐Ÿ“‚ Quality Assurance Study/๐Ÿ“„ QA ๊ณต๋ถ€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Jest + POM] ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•œ ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ† ๋ง
  • Unity์—์„œ์˜ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ๋ฐ Jira ์ด์Šˆ ๋“ฑ๋ก ์ž๋™ํ™”
  • XPath์— ๋Œ€ํ•˜์—ฌ
  • Jira ๋ฐ Confluence ์‚ฌ์šฉ ๋ฐฉ๋ฒ•
YeonSu02
YeonSu02
Email : rkddustn2519@naver.com
  • YeonSu02
    IsLiife2
    YeonSu02
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ
      • ๐Ÿ“‚ Computer Science
      • ๐Ÿ“‚ Unity Engine Study
        • ๐Ÿ“„ Unity ์ธํ”„๋Ÿฐ ๊ฐ•์˜
        • ๐Ÿ“„ Unity ์œ ํŠœ๋ธŒ ๊ฐ•์˜
        • ๐Ÿ“„ Unity ์ฐธ๊ณ 
        • ๐Ÿ’ป Game Development
      • ๐Ÿ“‚ Quality Assurance Study
        • ๐Ÿ”ฅ ์—˜๋ฆฌ์Šค SW QAํŠธ๋ž™
        • ๐Ÿ“„ QA ๊ณต๋ถ€
        • ๐Ÿ“š QA ์ฑ… ๋ฆฌ๋ทฐ
      • ๐Ÿ“‚ Program Language Study
        • ๐Ÿ“„ C# ๊ณต๋ถ€
        • ๐Ÿ“„ ํŒŒ์ด์ฌ ๊ณต๋ถ€
        • ๐Ÿ“„ JavaScript ๊ณต๋ถ€
        • ๐Ÿ“„ TypeScript ๊ณต๋ถ€
      • ๐Ÿ“‚ Additional Study
        • ๐Ÿ“„ Git
        • ๐Ÿ“„ Docker
        • ๐Ÿ“„ Jenkins
        • ๐Ÿ“„ Firebase
        • ๐Ÿ“„ Economy
        • ๐Ÿ“„ License
      • ๐Ÿ“‚ Experience
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
  • ๋งํฌ

    • GitHub
  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ์ž๊ฒฉ์ฆ
    qa ๋ถ€ํŠธ์บ ํ”„
    ์ปดํ™œ
    ๋ถ€ํŠธ์บ ํ”„ ์ถ”์ฒœ
    qa ์ฑ… ๋ฆฌ๋ทฐ
    ๊ตญ๋น„๋ถ€ํŠธ์บ ํ”„ ์ถ”์ฒœ
    ์—‘์…€
    ํ…Œ์ŠคํŒ…์ž๊ฒฉ์ฆ
    qa์ž๊ฒฉ์ฆ
    QA
    ์—˜๋ฆฌ์ŠคํŠธ๋ž™
    qa ๊ฐ•์˜
    ์ •์ฒ˜๊ธฐ ์‹ค๊ธฐ
    ์ •์ฒ˜๊ธฐ ํ•„๊ธฐ
    qa ์ฑ…
    istqb-ctfl
    qa ์ง๋ฌด ๊ต์œก
    ์ •์ฒ˜๊ธฐ ๋…ํ•™
    ์ปดํ“จํ„ฐํ™œ์šฉ๋Šฅ๋ ฅ
    ์—˜๋ฆฌ์ŠคํŠธ๋ž™ ํ›„๊ธฐ
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
YeonSu02
Jira REST API ํ† ํฐ ๋ฐœ๊ธ‰ ๋ฐ ์ด์Šˆ ์กฐํšŒ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”