๐Ÿช„GitHub Actions๋ฅผ ์ด์šฉํ•ด์„œ CI/CD๋ฅผ ๊ตฌ์ถ•ํ•ด๋ณด์ž!

GitHub Actions

๋ธ”๋กœ๊ทธ๋ฅผ ์ƒˆ๋กœ ํŒŒ์„œ ๊ธ€์„ ์ž‘์„ฑ์„ ํ•˜๋ฉด์„œ ์•„์ฃผ ์น˜๋ช…์ ์œผ๋กœ ๊ท€์ฐฎ์€ ๋ฌธ์ œ๊ฐ€ ํ•˜๋‚˜ ์ƒ๊ฒผ๋‹ค. ๋ฐ”๋กœ deploy!! ํฌ์ŠคํŒ…์„ ํ•˜๋‚˜ ์“ธ ๋•Œ๋งˆ๋‹ค ์ผ์ผํžˆ ๋ฐฐํฌ๋ฅผ ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์น˜๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ๊ท€์ฐฎ์•˜๋˜ ๋‚˜๋Š” ์ž๋™ํ™”์˜ ๊ฐ„์ ˆํ•จ์„ ๋А๋‚€๋‹ค. ๊ตฌ๊ธ€์—์„œ ์—ด์‹ฌํžˆ ์„œ์น˜๋ฅผ ํ•œ ๊ฒฐ๊ณผ Jenkins์™€ GitHub Actions์ด๋ผ๋Š” ํˆด์„ ๋ฐœ๊ฒฌํ–ˆ๊ณ  โ€ฆ ๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ๊ฒฐ๊ตญ GitHub Actions๋ผ๋Š” ๋ฐฉ๋ฒ•์„ ์ฑ„ํƒํ•˜๊ธฐ๋กœ ๊ฒฐ์‹ฌ์„ ํ•˜๋Š”๋ฐ โ€ฆ๋”๋ณด๊ธฐ

์ž ๊น๋งŒ ๊ทธ๋Ÿฐ๋ฐ CI/CD๊ฐ€ ๋ญ”๋ฐ?

CI/CD๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ๋‹จ๊ณ„๋ฅผ ์ž๋™ํ™”์‹œ์ผœ์„œ ์งง์€ ์ฃผ๊ธฐ๋กœ ๊ณ ๊ฐ์—๊ฒŒ ์ œ๊ณต์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

CI : Continuous Integration(์ง€์†์  ํ†ตํ•ฉ)

CD : Continuous Delivery(์ง€์†์  ์ œ๊ณต)/ Continuous Deployment(์ง€์†์  ๋ฐฐํฌ)

์˜ ์ค„์ž„๋ง์ด์ง€๋งŒโ€ฆ๋ฌด์Šจ ๋ง์ธ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค ๋” ์•Œ์•„๋ณด์ž

CI๋ž€?

ํ•œ ์ค„๋กœ ์š”์•ฝํ•˜๋ฉด ํ†ตํ•ฉ์„ ์œ„ํ•œ ๋‹จ๊ณ„(๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋จธ์ง€)๋ฅผ ์ž๋™ํ™”ํ•˜๋Š” ๊ฒƒ์ด๋‹ค

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

CI์˜ ์žฅ์ 

  • ๊ฐœ๋ฐœ์˜ ํŽธ์˜์„ฑ์ด ์ฆ๊ฐ€
    • ๋””๋ฒ„๊น…์ด ์‰ฌ์›Œ์ง€๊ธฐ ๋•Œ๋ฌธ
  • ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ฆ‰๊ฐ์  ํ”ผ๋“œ๋ฐฑ๊ณผ ๊ฒ€์ฆ ๊ฐ€๋Šฅ
  • ์ข‹์€ ์ฝ”๋“œ ํ€„๋ฆฌํ‹ฐ ์œ ์ง€ ๊ฐ€๋Šฅ
    • ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๋Š” ์ฝ”๋“œ๋งŒ ๊ณต์œ  ๋ ˆํฌ์ง€ํ„ฐ๋ฆฌ์— ์˜ฌ๋ผ๊ฐˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ
  • ์†Œ์Šค์ฝ”๋“œ์˜ ํ†ตํ•ฉ๊ณผ ๊ฒ€์ฆ์— ๋“ค์–ด๊ฐ€๋Š” ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋œ๋‹ค

CD๋ž€?

์ œ๊ณต๊ณผ ๋ฐฐํฌ์˜ ์ฐจ์ด

์ง€์†์  ์ œ๊ณต

  • CI๋ฅผ ๊ฑฐ์นœ ์ดํ›„์— ๋ฐฐํฌ๋ฅผ ํ•  ์ค€๋น„๋ฅผ ํ•˜๊ณ , ์ด ๊ณผ์ •์—์„œ ๋ฐฐํฌ๊ฐ€ ๋  ๊ฒƒ์ด ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†๋Š”์ง€ ๊ฐœ๋ฐœ์ž/๊ฒ€์ฆ ํŒ€์ด ๊ฒ€์ฆ์„ ํ•œ ๋’ค์— ์ˆ˜๋™์œผ๋กœ ๋ฐฐํฌ๋ฅผ ํ•œ๋‹ค

์ง€์†์  ๋ฐฐํฌ

  • ๋ฐฐํฌ๋ฅผ ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๋ฉด ์ž๋™์ ์œผ๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ๊นŒ์ง€ ๋ฐฐํฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋„๋ก ์ž๋™ํ™”๋ฅผ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์ผ๋ จ์˜ ๊ณผ์ •์„ ์ง€์†์  ๋ฐฐํฌ๋ผ๊ณ  ๋งํ•œ๋‹ค

CD์˜ ์žฅ์ 

  • ๊ฐœ๋ฐœ๋ถ€ํ„ฐ ๋ฐฐํฌ๊นŒ์ง€ ๊ณผ์ •์ด ๋ฒˆ๊ฑฐ๋กญ์ง€ ์•Š๊ณ  ๊ฐ„์†Œํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์„ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋‹ค
    • ์ฆ‰, ์žฅ์•  ๋Œ€์‘์ด ๋นจ๋ผ์ง„๋‹ค

CI/CD์˜ ํ๋ฆ„

  • CI

    1. ๊ฐœ๋ฐœ์ž๋Š” ์ž์‹ ์ด ๊ฐœ๋ฐœํ•œ ์†Œํ”„ํŠธ์›จ์–ด์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๊ณตํ†ต๋œ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ(ex.GitHub)์— ์ €์žฅํ•œ๋‹ค.
    2. ์†Œ์Šค์ฝ”๋“œ์ƒ์—์„œ ๋ณ€๋™์ด ์ƒ๊ธฐ๋ฉด ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์—์„œ๋Š” CI ํˆด๋กœ ์ฝ”๋“œ์˜ ๋ณ€๊ฒฝ์„ ์•Œ๋ฆฐ๋‹ค
    3. CIํˆด์—์„œ๋Š” ๋ณ€๊ฒฝ๋œ ์ฝ”๋“œ๋ฅผ ๋นŒ๋“œ, ํ…Œ์ŠคํŠธ, ๋จธ์ง€๋ฅผ ํ•œ๋‹ค.
  • CD

    1. CI๋ฅผ ํ†ตํ•ด ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๊ฒ€์ฆํ•œ๋‹ค
    2. ๊ฒ€์ฆ๋œ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์‹ค์ œ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์œผ๋กœ ๋ฐฐํฌํ•œ๋‹ค.

ยฟยฟGitHub Actions??

  • GitHub์—์„œ ์ œ๊ณตํ•˜๋Š” ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ž๋™ํ™”ํ•˜๋„๋ก ๋„์™€์ฃผ๋Š” ๋„๊ตฌ์ด๋‹ค.

  • Github์—์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ workflow ํ…œํ”Œ๋ฆฟ์„ ์ถ”์ฒœํ•ด์ฃผ๋Š”๋ฐ, ์ด๊ฑธ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ ํ…Œ์ŠคํŠธ/๋นŒ๋“œ/๋ฐฐํฌ ๋“ฑ ๋‹ค์–‘ํ•œ ์ž‘์—…๋“ค์„ ์ž๋™ํ™”ํ•˜์—ฌ ๋š๋”ฑ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

GitHub Actions์„ ์„ ํƒํ•œ ์ด์œ 

  1. Jenkins์ฒ˜๋Ÿผ ์„ค์น˜ ํ›„ ๋”ฐ๋กœ ์„œ๋ฒ„๋ฅผ ํŒ” ํ•„์š”๊ฐ€ ์—†๋‹ค
  2. ๊ธฐ์™•์ด๋ฉด GitHub ํ•˜๋‚˜๋กœ ์ž๋™ํ™”๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค.

GitHub Actions์˜ ๊ตฌ์„ฑ

Workflow(์›Œํฌ ํ”Œ๋กœ์šฐ)

  • ์ €์žฅ์†Œ์— ์ถ”๊ฐ€ํ•˜๋Š” ์ž๋™ํ™”๋œ ํ”„๋กœ์„ธ์Šค. ํ•˜๋‚˜ ์ด์ƒ์˜ job์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์œผ๋ฉฐ, ์ด๋ฒคํŠธ์— ์˜ํ•ด ์‹คํ–‰๋œ๋‹ค.
  • Workflow ํŒŒ์ผ์€ YAML์œผ๋กœ ์ž‘์„ฑ๋˜๊ณ , .github/workflowsํด๋” ์•„๋ž˜์— ์ €์žฅ๋œ๋‹ค.

Event(์ด๋ฒคํŠธ)

  • ์›Œํฌ ํ”Œ๋กœ์šฐ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ํŠน์ • ํ™œ๋™์ด๋‚˜ ๊ทœ์น™.
  • ์ปค๋ฐ‹์˜ push/pull request๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„ ๋•Œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, GitHub ์™ธ๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํ™œ๋™์œผ๋กœ๋„ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ๋‹ค.

ex)

# push๋‚˜ PR์ด ๋ฐœ์ƒํ•  ๋•Œ ์›Œํฌํ”Œ๋กœ์šฐ ์‹คํ–‰
on: [push, pull_request]

๊ฒŒ๋‹ค๊ฐ€ cron ๋ฌธ๋ฒ•์œผ๋กœ schedule ์ด๋ฒคํŠธ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค!

ex)

# ์›”-๊ธˆ ์˜ค์ „ 9์‹œ
on:
  schedule:
    - cron: '0 9 * * 1-5'

Job(์ž‘์—…)

  • ์›Œํฌํ”Œ๋กœ์šฐ์˜ ๊ธฐ๋ณธ ๋‹จ์œ„. ์—ฌ๋Ÿฌ Step์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.
  • ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋ณ‘๋ ฌ์ ์œผ๋กœ ์‹คํ–‰ํ•˜์ง€๋งŒ, ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Step(์Šคํ…)

  • Job์•ˆ์—์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ํ”„๋กœ์„ธ์Šค์˜ ๋‹จ์œ„. ์—ฌ๊ธฐ์„œ ๋ช…๋ น์„ ๋‚ด๋ฆฌ๊ฑฐ๋‚˜, action์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํ•œ job์˜ ๊ฐ ์Šคํ…๋“ค์€ ๋™์ผํ•œ ๋Ÿฌ๋„ˆ์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ์ž‘์—…์˜ ์•ก์…˜๋“ค์€ ์„œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋œ๋‹ค.

Runner(๋Ÿฌ๋„ˆ)

  • GitHub Actions Runner Application์ด ์„ค์น˜๋œ ์„œ๋ฒ„.
  • GitHub์—์„œ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๋Ÿฌ๋„ˆ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์ง์ ‘ ํ˜ธ์ŠคํŒ…์„ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ ์‹คํ–‰๋  ์ธ์Šคํ„ด์Šค์ด๋‹ค.

๋ฐฐํฌ ์ž๋™ํ™” ๊ฐ€๋ณด์ž๊ณ .

Access Token ์ƒ์„ฑ

GitHub Actions๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Access Token์ด ํ•„์š”ํ•˜๋‹ค. ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผ์„ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ!!

์—ฌ๊ธฐ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

Generate New Token ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์„œ Note์˜ ๋ถ€๋ถ„์— ํ† ํฐ ์ด๋ฆ„์„ ์ ๊ณ , Select scopes์˜ Repo๋ถ€๋ถ„์„ ์ „๋ถ€ ์ฒดํฌํ•ด์ค€๋‹ค. newtoken

Generate Token ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํ† ํฐ์ด ์ƒ์„ฑ๋œ๋‹ค! ๊ทธ๋Ÿฐ๋ฐ ํ† ํฐ์€ ๋‹ค์Œ์— ๋‹ค์‹œ ํ™•์ธํ•  ์ˆ˜ ์—†์œผ๋‹ˆ๊นŒ ๊ผฌ์˜ฅ..๋ณต์‚ฌํ•ด์„œ ์–ด๋”” ์ ์–ด๋†”์•ผํ•œ๋‹ค..

Access Token ํ• ๋‹น

์œ„์—์„œ ๋ฐœํ–‰ํ•œ ํ† ํฐ์„ ๋ ˆํฌ์ง€ํ† ๋ฆฌ์— ํ• ๋‹น์„ ํ•ด์ฃผ์ž.

๋ ˆํฌ์ง€ํ† ๋ฆฌ์˜ ์„ค์ •์— ๋“ค์–ด๊ฐ€ Secretsํƒญ์— ์žˆ๋Š” New repository secret ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด์„œ Name์—๋Š” ํ† ํฐ ์ด๋ฆ„(์œ„์˜ ํ† ํฐ ์ด๋ฆ„๊ณผ ๋‹ฌ๋ผ๋„ ๋จ!), Value์—๋Š” ์œ„์—์„œ ๋ฐœํ–‰ํ•œ ํ† ํฐ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ณ  ์ถ”๊ฐ€๋ฅผ ํ•˜๋ฉด ๋!

Workflow ์ƒ์„ฑ

์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € .github/workflows ๋ฐ‘์— main.yml ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

# GitHub Action์˜ workflow ์ด๋ฆ„
name: Gatsby Publish

# gh-pages๋ผ๋Š” ๋ธŒ๋žœ์น˜์— push๋ฅผ ํ•  ๋•Œ๋งˆ๋‹ค jobs๋ฅผ ์‹คํ–‰
on:
  push:
    branches:
      - gh-pages
jobs:
  build_gatsby:
    name: build
    # ์‹คํ–‰ ํ™˜๊ฒฝ์ด ubuntu-latest
    runs-on: ubuntu-latest
    steps:
      # checkout์„ ํ•ด์ฃผ๋Š” ์•ก์…˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉ
      - uses: actions/checkout@v2

      - name: packages install๐Ÿ›ธ
        run: yarn install

      - name: gatsby build๐Ÿš€
        run: yarn build
        env:
          # GH_API_KEY์— secret์„ ์ƒ์„ฑํ•  ๋•Œ ์„ค์ •ํ•œ ์ด๋ฆ„์œผ๋กœ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค
          GH_API_KEY: ${{secrets.TOKEN_KEY}}

      - name: deploy๐Ÿ›ฐ
        uses: maxheld83/ghpages@v0.2.1
        env:
          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
          # ์—ฌ๊ธฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€! TOKEN_KEY ๋Œ€์‹  ์ž์‹ ์ด ์„ค์ •ํ•œ ์ด๋ฆ„์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค
          GH_PAT: ${{secrets.TOKEN_KEY}}
          BUILD_DIR: 'public/'

์œ„ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ๋’ค์— ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œ๋ฅผ ํ•ด์ฃผ๋ฉด, repository์˜ Actionsํƒญ์— ์›Œํฌํ”Œ๋กœ์šฐ๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค!

๋™์ž‘ํ™•์ธ

๋ธŒ๋žœ์น˜์— push๋ฅผ ํ•˜๋ฉด, ๋ฐ”๋กœ Github Action์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์›Œํฌํ”Œ๋กœ์šฐ์ฒดํฌ ์š”๋ ‡๊ฒŒ!

๋งŒ์•ฝ ์ € ์ผ๋ จ์˜ ๊ณผ์ •์„ ์‹คํ–‰ํ•˜๊ณ , ๋ฐฐํฌ๊นŒ์ง€ ์„ฑ๊ณต์ ์œผ๋กœ ๋˜์—ˆ๋‹ค๋ฉด ์ด๋Ÿฐ ํ™”๋ฉด์ด ๋œฐ ๊ฒƒ์ด๋‹ค.

์™„๋ฃŒ ์•ˆ-์ •์˜ ์ดˆ๋ก๋ถˆโ€ฆ

๋ธ”๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด, ๋งค์šฐ๋งค์šฐ ์ž˜ ํฌ์ŠคํŒ…์ด ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค! ์„ฑ๊ณต

ํžˆํžˆํž‰..! ์ด์ œ ๋”์ด์ƒ ๊ท€์ฐฎ๊ฒŒ npm run deploy์•ˆํ•ด๋„ ๋œ๋‹คโ€ฆ! ํžˆํžˆํž‰..!


์•„์ง ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ๋ฐฑํผ์„ผํŠธ ์ดํ•ดํ•˜์ง€๋Š” ๋ชปํ–ˆ์ง€๋งŒ, ์‹ค์ œ๋กœ ์ด๋ ‡๊ฒŒ ๋Œ๋ ค๋ณด๋‹ˆ๊นŒ ๋„ˆ๋ฌด ํŽธํ•˜๊ณ โ€ฆ์งœ๋ฆฟํ•ดโ€ฆ! ๋‹ค์Œ์— ํ˜น์‹œ๋‚˜ ์ž๋™ํ™”ํ•ด์•ผํ•  ์ผ์ด ์žˆ๋‹ค๋ฉด ๋˜ ์ฃผ์ €์—†์ด GitHub Actions๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค..! ๋ฌผ๋ก  ์  ํ‚จ์Šค๋„ ๊ผญ ์‚ฌ์šฉํ•ด๋ณด๋Š”๊ฑธ๋กœ >_^


Written by@UndefinedP
๊ธฐ๋ก์„ ์ž˜ ํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ  ์‹ถ์–ด์š”

GitHub