๋ธ”๋กœ๊ทธ

๐Ÿ’๐Ÿปโ€โ™€๏ธ Gato GraphQL์ด ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ์ด์œ ์™€ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•

Leonardo Losoviz
์ž‘์„ฑ์ž: Leonardo Losoviz ยท

๋ฉฐ์น  ์ „, Hosting all your PHP packages together in a monorepo ๋ผ๋Š” ๊ธ€์„ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ๊ธ€์—์„œ๋Š” PHP ์ฝ”๋“œ๋ฒ ์ด์Šค ๊ด€๋ฆฌ์— ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํ™œ์šฉํ•˜๊ณ  ์‹ถ์€ ์ด์œ ์™€, Monorepo Builder๋ฅผ ํ†ตํ•ด ์ด๋ฅผ ์‹คํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” ๊ทธ ๊ธ€์„ ๋ณด์™„ํ•˜๋Š” ํ˜•ํƒœ๋กœ, GatoGraphQL/GatoGraphQL ์ฝ”๋“œ๋ฒ ์ด์Šค๏ผˆGato GraphQL, ๊ทธ ๊ธฐ๋ฐ˜์ด ๋˜๋Š” GraphQL ์—”์ง„, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์œ„์— ๊ตฌ์ถ•๋œ ์ปดํฌ๋„ŒํŠธ ๋ชจ๋ธ ์•„ํ‚คํ…์ฒ˜๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค๏ผ‰๊ฐ€ ๋ชจ๋…ธ๋ ˆํฌ์—์„œ ํ˜ธ์ŠคํŒ…๋˜์–ด์•ผ ํ•˜๋Š” ์ด์œ ์™€, ์ œ๊ฐ€ ์ˆ˜ํ–‰ํ•œ ์ตœ์ ํ™”์— ๋Œ€ํ•ด ์ข€ ๋” ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Gato GraphQL์ด ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ์ด์œ 

CMS ๋น„์ข…์†์„ฑ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด, Gato GraphQL ๋ฐ ๊ด€๋ จ ํ”„๋กœ์ ํŠธ์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค๋Š” Composer๋กœ ๊ด€๋ฆฌ๋˜๋Š” ์ˆ˜๋งŽ์€ ํŒจํ‚ค์ง€๋กœ ๋ถ„๋ฆฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด 100๊ฐœ ์ด์ƒ์˜ ํŒจํ‚ค์ง€๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค๏ผ๏ผˆํ˜„์žฌ๋Š” 200๊ฐœ ์ด์ƒ์ž…๋‹ˆ๋‹ค.๏ผ‰

ํŒจํ‚ค์ง€ ์ˆ˜๊ฐ€ ๋งŽ์•„๋„ Composer๋กœ ๋ชจ๋‘ ์กฐํ•ฉํ•˜๋Š” ๋ฐ ์ถ”๊ฐ€์ ์ธ ๋ณต์žกํ•จ์€ ์—†์Šต๋‹ˆ๋‹ค. composer install์„ ์‹คํ–‰ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ ํŒจํ‚ค์ง€๊ฐ€ ๊ฐœ๋ณ„ ์ €์žฅ์†Œ์— ์กด์žฌํ•˜๋ฉด ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ฌธ์ œ๋กœ ์ธํ•ด ๊ฐœ๋ฐœ์ด ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.

๊ฐ ํŒจํ‚ค์ง€๋Š” ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ์–ด๋–ค ํŒจํ‚ค์ง€์˜ ๋ชจ๋“  ๋ฒ„์ „์€ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€์˜ ํŠน์ • ๋ฒ„์ „์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋งŽ์€ ํŒจํ‚ค์ง€๊ฐ€ ์žˆ์œผ๋ฉด, PR ์ƒ์„ฑ ์‹œ ๋ชจ๋“  ๋ฒ„์ „์ด ์„œ๋กœ ์–ด๋–ป๊ฒŒ ์˜์กดํ•˜๋Š”์ง€ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์•…๋ชฝ์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งˆ์น˜ ์ŠคํŒŒ๊ฒŒํ‹ฐ ์ฝ”๋“œ ํ•œ ์ ‘์‹œ์ฒ˜๋Ÿผ ๋ฉด์˜ ํ•œ์ชฝ ๋์€ ๋ณด์ด์ง€๋งŒ ์–ด๋””์„œ ๋๋‚˜๋Š”์ง€๋Š” ์•Œ ์ˆ˜ ์—†๋Š” ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ชฝ ๋์„ ์ฐพ์•„์„œ

์‹ค์ œ๋กœ, ๊ด€๋ จ๋œ ๋ชจ๋“  ์ €์žฅ์†Œ์˜ ์—ฌ๋Ÿฌ ๋ธŒ๋žœ์น˜์— ๊ฑธ์นœ ๋ฒ„์ „์„ ๋ชจ๋‘ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ์–ด๋ ค์›Œ์ ธ์„œ, ์ด ๊ณผ์ •์„ ์™„์ „ํžˆ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๊ฐ ์ €์žฅ์†Œ์˜ master ๋ธŒ๋žœ์น˜์— ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ํ‘ธ์‹œํ•˜๊ณ  ๊ฐ๊ฐ์—์„œ dev-master ๋ฒ„์ „์— ์˜์กดํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” ์ ์ ˆํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ GatoGraphQL/GatoGraphQL์— ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๋ชจ๋…ธ๋ ˆํฌ ๋ชจ๋ธ๋กœ ์ „ํ™˜ํ•จ์œผ๋กœ์จ, ๊ทธ ๋ฌธ์ œ๊ฐ€ ํšจ๊ณผ์ ์œผ๋กœ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ™˜์˜ํ•  ๋งŒํ•œ ๋ถ€์ž‘์šฉ: ๊ธฐ์—ฌ์˜ ์ง„์ž… ์žฅ๋ฒฝ ๋‚ฎ์ถ”๊ธฐ

๊ธ€์—์„œ๋„ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด, ํ”„๋กœ์ ํŠธ๊ฐ€ ํŒจํ‚ค์ง€๋งˆ๋‹ค ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋˜ ์‹œ์ ˆ, ํ•œ ๊ธฐ์—ฌ์ž๊ฐ€ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •์— ์‹คํŒจํ•˜์—ฌ ์ฐธ์—ฌํ•˜๊ธฐ๋„ ์ „์— ํ”„๋กœ์ ํŠธ๋ฅผ ๋– ๋‚œ ์ผ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋…ธ๋ ˆํฌ๋กœ ์ „ํ™˜ํ•˜๊ธฐ ์ „์—๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •์ด ๋งค์šฐ ์–ด๋ ค์› ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ž‘์„ฑ์ž์˜€๊ธฐ ๋•Œ๋ฌธ์—, ๋ชจ๋“  ์ €์žฅ์†Œ๋ฅผ ํด๋ก ํ•˜๊ณ  ๋‹จ์ผ VSCode ์›Œํฌ์ŠคํŽ˜์ด์Šค์— ๋ชจ๋‘ ์ถ”๊ฐ€ํ•˜์—ฌ ์–ด๋–ป๊ฒŒ๋“  ์ž‘๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ž ์žฌ์ ์ธ ๊ธฐ์—ฌ์ž๋“ค์ด ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ธฐ ์‰ฝ๋„๋ก ์ด bash ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์†”์งํžˆ, ๊ทธ๊ฒƒ์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ผ์ด์—ˆ๊ณ , ์•„๋ฌด๋„ ํ”„๋กœ์ ํŠธ์— ๊ธฐ์—ฌ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋…ธ๋ ˆํฌ ๋•๋ถ„์—, ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์ฐธ์—ฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ ๋ถˆํ•ฉ๋ฆฌํ•œ ๊ด€๋ฃŒ์ฃผ์˜๋กœ ๊ธฐ์—ฌ์ž๋ฅผ ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ํ™•์‹ ์„ ๊ฐ€์ง€๊ณ  ๋ฐค์— ํŽธ์•ˆํžˆ ์ž ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋…ธ๋ ˆํฌ ์ตœ์ ํ™”

๊ธ€์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด, ๋Œ€์•ˆ๋“ค๊ณผ ๋น„๊ตํ•˜์—ฌ Monorepo Builder ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์žฅ์ ์€ PHP๋กœ ๊ตฌ์ถ•๋˜์–ด ์žˆ์–ด ํ™•์žฅ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, master์— ํ‘ธ์‹œํ•˜๊ณ  ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ๋ถ„ํ• ํ•  ๋•Œ, GitHub Action์˜ ๋งคํŠธ๋ฆญ์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ ํŒจํ‚ค์ง€์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ๋Ÿฌ๋„ˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ž์ฒด ์ €์žฅ์†Œ์™€ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค๏ผˆPackagist๋ฅผ ํ†ตํ•œ ๋ฐฐํฌ๋ฅผ ์œ„ํ•ด๏ผ‰.

GatoGraphQL/GatoGraphQL์—๋Š” 200๊ฐœ ์ด์ƒ์˜ ํŒจํ‚ค์ง€๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์–ด, 200๊ฐœ ์ด์ƒ์˜ ๋Ÿฌ๋„ˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

200๊ฐœ ์ด์ƒ์˜ ํŒจํ‚ค์ง€ ์ฒ˜๋ฆฌ ์ค‘

์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” GitHub๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ž‘์—… ์ˆ˜๋ฅผ 20๊ฐœ๋กœ ์ œํ•œํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ์•ก์…˜์ด ํ์— ๋ฐฐ์น˜๋˜๋ฏ€๋กœ, ๋‹ค๋ฅธ ์•ก์…˜์„ ๊ณ„์† ์‹คํ–‰ํ•˜๋ ค๋ฉด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฒŒ๋‹ค๊ฐ€, GitHub๊ฐ€ ๋Ÿฌ๋„ˆ๋ฅผ ์ฆ‰์‹œ ํ”„๋กœ๋น„์ €๋‹ํ•˜์ง€ ์•Š๊ณ  ๋‚˜์ค‘์œผ๋กœ ๋ฏธ๋ฃจ๋Š” ๊ฒฝ์šฐ๋„ ์ข…์ข… ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค:

๋Ÿฌ๋„ˆ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ ์ค‘

์ด ๋ชจ๋“  ๊ฒƒ์ด ๋Œ€๊ธฐ ์‹œ๊ฐ„์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. 200๊ฐœ ์ด์ƒ์˜ ํŒจํ‚ค์ง€๊ฐ€ ์žˆ์œผ๋ฉด, ๋‹จ ํ•˜๋‚˜์˜ PR์„ ๋ณ‘ํ•ฉํ•˜๋Š” ๋ฐ ์ตœ๋Œ€ 1์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค๏ผ ์ด๋Š” ํ•ด๊ฒฐ์ด ํ•„์š”ํ•œ ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.

์ปค์Šคํ…€ ๋ช…๋ น์œผ๋กœ ๋ชจ๋…ธ๋ ˆํฌ๋ฅผ ํ™•์žฅํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Monorepo Builder ํ™•์žฅํ•˜๊ธฐ

์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด ์ €์žฅ์†Œ์˜ ๋ชจ๋“  ํŒจํ‚ค์ง€ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

vendor/bin/monorepo-builder packages-json

์ €์žฅ์†Œ์˜ ๋ชจ๋“  ํŒจํ‚ค์ง€ ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ

๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค: ๋ชจ๋“  ํŒจํ‚ค์ง€๋ฅผ ๋™๊ธฐํ™”ํ•  ํ•„์š”๋Š” ์—†๊ณ , PR์—์„œ ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋œ ํŒจํ‚ค์ง€๋งŒ ๋™๊ธฐํ™”ํ•˜๋ฉด ๋œ๋‹ค๊ณ ์š”.

๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๋ชฉ๋ก์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ํ•ด๋‹น ํŒŒ์ผ์„ ํฌํ•จํ•˜๋Š” ๋ณ€๊ฒฝ๋œ ํŒจํ‚ค์ง€๋ฅผ ํŠน์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, git diff๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ filter ์ž…๋ ฅ์œผ๋กœ packages-json ๋ช…๋ น์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด:

vendor/bin/monorepo-builder packages-json --filter=modified_file_1 --filter=modified_file_2 --filter=...

๊ทธ๋Ÿฐ๋ฐ Monorepo Builder์— ํฌํ•จ๋œ packages-json ๋ช…๋ น์€ filter ์ž…๋ ฅ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์ด ๋ถ€๋ถ„์ด ์ปค์Šคํ…€ ๋ช…๋ น์œผ๋กœ ํ™•์žฅํ•ด์•ผ ํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

Monorepo Builder๋Š” Symfony์˜ DependencyInjection์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์ปจํ…Œ์ด๋„ˆ์— ์ƒˆ ์„œ๋น„์Šค๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ, ์„ค์ • ํŒŒ์ผ monorepo-builder.php๋Š” ์ด๋ฏธ ์„œ๋น„์Šค ์ปจํ”ผ๊ทœ๋ ˆ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ €๋Š” filter ์ž…๋ ฅ์„ ์ง€์›ํ•˜๋Š” package-entries-json์ด๋ผ๋Š” ์ƒˆ ๋ช…๋ น์œผ๋กœ Monorepo Builder๋ฅผ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค:

final class PackageEntriesJsonCommand extends AbstractSymplifyCommand
{
  private PackageEntriesJsonProvider $packageEntriesJsonProvider;
 
  public function __construct(PackageEntriesJsonProvider $packageEntriesJsonProvider)
  {
    $this->packageEntriesJsonProvider = $packageEntriesJsonProvider;
 
    parent::__construct();
  }
 
  protected function configure(): void
  {
    $this->setDescription('Provides package entries in json format. Useful for GitHub Actions Workflow');
    $this->addOption(
      Option::FILTER,
      null,
      InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
      'Filter the packages to those from the list of files. Useful to split monorepo on modified packages only',
      []
    );
  }
 
  protected function execute(InputInterface $input, OutputInterface $output): int
  {
    /** @var string[] $fileFilter */
    $fileFilter = $input->getOption(Option::FILTER);
 
    $packageEntries = $this->packageEntriesJsonProvider->providePackageEntries($fileFilter);
 
    // must be without spaces, otherwise it breaks GitHub Actions json
    $json = Json::encode($packageEntries);
    $this->symfonyStyle->writeln($json);
 
    return ShellCode::SUCCESS;
  }
}

์„œ๋น„์Šค ์ปจํ…Œ์ด๋„ˆ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค:

return static function (ContainerConfigurator $containerConfigurator): void {
    $services = $containerConfigurator->services();
    $services->defaults()->autowire()->autoconfigure();
    $services->set(PackageEntriesJsonCommand::class);
}

์ด์ œ package-entries-json์ด๋ผ๋Š” ์ƒˆ ๋ช…๋ น์„ GitHub Action ์›Œํฌํ”Œ๋กœ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

GitHub Action์—์„œ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ

์ด์ œ ์›Œํฌํ”Œ๋กœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ํŽธ๋ฆฌํ•˜๊ฒŒ๋„ technote-space/get-diff-action ์•ก์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์•ก์…˜์€ PR์—์„œ ๋ณ€๊ฒฝ๋œ ๋ชจ๋“  ํŒŒ์ผ์˜ git diff๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

# git diff to generate matrix with modified packages only
- uses: technote-space/get-diff-action@v4
  with:
    PATTERNS: layers/*/*/*/**

์ด ๊ฒฐ๊ณผ๏ผˆ${{ env.GIT_DIFF }}์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค๏ผ‰๋กœ๋ถ€ํ„ฐ ์ปค์Šคํ…€ ๋ช…๋ น package-entries-json ํ˜ธ์ถœ์„ ์ƒ์„ฑํ•˜๊ณ , ์ถœ๋ ฅ์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค:

- id: output_data
  name: Calculate matrix for packages
  run: |
    quote=\'
    clean_diff="$(echo "${{ env.GIT_DIFF }}" | sed -e s/$quote//g)"
    packages_in_diff="$(echo $clean_diff | grep -E -o 'layers/[A-Za-z0-9_\-]*/[A-Za-z0-9_\-]*/[A-Za-z0-9_\-]*/' | sort -u)"
    echo "[Packages in diff] $(echo $packages_in_diff | tr '\n' ' ')"
    filter_arg="--filter=$(echo $packages_in_diff | sed -e 's/ / --filter=/g')"
    echo "::set-output name=matrix::$(vendor/bin/monorepo-builder package-entries-json $(echo $filter_arg))"

๊ฒฐ๊ณผ๋กœ ์–ป์€ ํŒจํ‚ค์ง€๋Š” ๋งคํŠธ๋ฆญ์Šค ์ƒ์„ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค:

outputs:
  matrix: ${{ steps.output_data.outputs.matrix }}

์ •๋ง ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค๏ผ ์ด ์˜ˆ์‹œ์—์„œ๋Š” ๋ณ€๊ฒฝ๋œ ํŒจํ‚ค์ง€๊ฐ€ 2๊ฐœ๋ฟ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋งคํŠธ๋ฆญ์Šค์—์„œ ์‹คํ–‰๋œ ์ธ์Šคํ„ด์Šค๋„ 2๊ฐœ๋ฟ์ด์—ˆ์Šต๋‹ˆ๋‹ค:

๋ณ€๊ฒฝ๋œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ

์ด์ œ PR ๋ณ‘ํ•ฉ์ด 1์‹œ๊ฐ„์—์„œ ๋‹จ ๋ช‡ ๋ถ„์œผ๋กœ ์ค„์–ด๋“ค์–ด, ๋‹ค์‹œ ํ–‰๋ณตํ•œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ์ตœ์ ํ™” ๋ฐ ๊ณผ์ œ

GitHub Action์—์„œ ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค: PHPUnit ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์‹œ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ๋Š” ์ƒˆ ์ฝ”๋“œ๊ฐ€ ์—…๋กœ๋“œ๋  ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ํŒจํ‚ค์ง€์˜ ์ „์ฒด ํ…Œ์ŠคํŠธ ๋ฐฐํ„ฐ๋ฆฌ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ์—ญ์‹œ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋…ธ๋ ˆํฌ์— A, B, C ์„ธ ๊ฐœ์˜ ํŒจํ‚ค์ง€๊ฐ€ ์žˆ๊ณ , B๊ฐ€ A์— ์˜์กดํ•˜๋ฉฐ C๊ฐ€ B์— ์˜์กดํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.

์ด ๊ฒฝ์šฐ, ๋‹จ์ผ ํŒจํ‚ค์ง€์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์‹คํ–‰์ด ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค:

  • A์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ: A, B, C๋ฅผ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  • B์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ: B์™€ C๋ฅผ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
  • C์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ: C๋งŒ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

์ตœ์ ํ™”๋Š” ๋ณ€๊ฒฝ๋œ ํŒจํ‚ค์ง€ ๋ชฉ๋ก๏ผˆ์•ž์„  ์ตœ์ ํ™”์™€ ๋™์ผ๏ผ‰์„ ๊ฐ€์ ธ์™€์„œ, ํ•ด๋‹น ํŒจํ‚ค์ง€๋“ค๊ณผ ๊ทธ๊ฒƒ๋“ค์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ํŒจํ‚ค์ง€์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ํ˜„์žฌ ์ €๋Š” ๋ชจ๋…ธ๋ ˆํฌ ๋‚ด ๊ฐ ํŒจํ‚ค์ง€๊ฐ€ ์„œ๋กœ ์–ด๋–ป๊ฒŒ ์˜์กดํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฃจํŠธ composer.json์—๋Š” ๋ชจ๋“  ๋กœ์ปฌ ํŒจํ‚ค์ง€๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€๋งŒ, require๊ฐ€ ์•„๋‹Œ replace ์„น์…˜์— ์ •์˜๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— composer info ${ package_name }์„ ์‹คํ–‰ํ•˜์—ฌ Composer๋ฅผ ํ†ตํ•ด ์˜์กด์„ฑ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋Œ€์•ˆ์œผ๋กœ, ๊ฐ ํŒจํ‚ค์ง€์˜ ์„œ๋ธŒํด๋”๋กœ ์ด๋™ํ•˜์—ฌ composer install์„ ์‹คํ–‰ํ•œ ํ›„ composer info๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ composer install์„ 200๋ฒˆ ์ด์ƒ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์™„์ „ํžˆ ๋น„ํ˜„์‹ค์ ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ์•„์ง ์ตœ์ ํ™”ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์ด์Šˆ๋ฅผ ์ƒ์„ฑํ•ด ๋‘์—ˆ์œผ๋ฉฐ, ์–ธ์  ๊ฐ€ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ๊ธฐ๋ฅผ ๋ฐ”๋ผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ์น˜๋ฉฐ

Monorepo Builder๋ฅผ ๋ฐœ๊ฒฌํ•œ ๊ฒƒ์ด ์ •๋ง ๊ธฐ์ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ ์—†์ด๋Š” Gato GraphQL์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์—†์—ˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ €์ฒ˜๋Ÿผ 200๊ฐœ ์ด์ƒ์˜ ํŒจํ‚ค์ง€๊ฐ€ ์žˆ๊ฑฐ๋‚˜, ์•„๋งˆ๋„ 20๊ฐœ ์ด์ƒ์ธ ๊ฒฝ์šฐ๋ผ๋ฉด, ๋ถ„๋ช…ํžˆ ์‚ถ์ด ํ›จ์”ฌ ํŽธํ•ด์ง‘๋‹ˆ๋‹ค.

๋ชจ๋…ธ๋ ˆํฌ ๊ด€๋ฆฌ์—๋Š” ์„ค์ •๊ณผ ์œ ์ง€์— ์•ฝ๊ฐ„์˜ ์‹œ๊ฐ„๊ณผ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•˜์ง€๋งŒ, ์ผ์ƒ์ ์ธ ๊ฐœ๋ฐœ๋งŒ์œผ๋กœ๋„ ๊ทธ ์‹œ๊ฐ„๊ณผ ๋…ธ๋ ฅ์„ ๋ช‡ ๋ฐฐ๋กœ ๋Œ๋ ค๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๋‰ด์Šค๋ ˆํ„ฐ ๊ตฌ๋…ํ•˜๊ธฐ

Gato GraphQL์˜ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋ฅผ ๋†“์น˜์ง€ ๋งˆ์„ธ์š”.