κ·Έλλ€ λΉλ λΌμ΄νμ¬μ΄ν΄
μλ νμΈμ Mambo μ λλ€.
μ€λ μμλ³Ό λ΄μ©μ κ·Έλλ€ λΉλμ λΌμ΄νμ¬μ΄ν΄μ λλ€.
μΌλ§μ μ λ¨μΌ μ ν리μΌμ΄μ νλ‘μ νΈμμ λ€μν λ°°ν¬ νκ²½μ λν κΈ°λ₯μ λ³λλ‘ μ§μν΄μΌνλ μꡬμ¬νμΌλ‘ μΈνμ¬ κ·Έλλ€ λ©ν° λͺ¨λ νλ‘μ νΈλ‘ μ ννκ² λλ©΄μ λ°°ν¬ κ³Όμ μμ λ¬Έμ κ° λ°μνμμλλ°μ. κ·Έ λ¬Έμ λ ν¬λ¦¬ν°μ»¬ν μ΄μλ μλμ§λ§ νμ€ν¬ μν ν λ§λ€μ΄μ§ μμΆ νμΌμ νλ‘μ νΈ λ²μ μ΄ ν¬ν¨λμ§ μλ μν©μ΄μμ΅λλ€. μ΄λ¬ν λ¬Έμ κ° λ°μν μ΄μ λ κ·Έλλ€ νμ€ν¬λ₯Ό μ μν λ κ·Έλλ€ λΉλ λΌμ΄νμ¬μ΄ν΄μ κ³ λ €νμ§ μμκΈ° λλ¬Έμ λλ€.
κ·Έλλ€ νμ€ν¬
λ¨Όμ κΈ°μ‘΄μ μ μλ νμ€ν¬λ beanstalk-deploy-sampleμ build.gradleμ μ μλ zipBeanstalk νμ€ν¬μ κ°μ΄ Zip μ νμ νμ€ν¬λ‘ μμ±λμ΄μμ΅λλ€.
task zipBeanstalk(type: Zip, dependsOn: 'procfile') {
from ('.ebextensions') { into '.ebextensions' }
from ('.platform') { into '.platform' }
from ('build/libs') {
println bootWar.archiveName
include(bootWar.archiveName)
include("Procfile")
}
baseName = 'beanstalk'
}
μ μν νμ€ν¬μ²λΌ λ¨μΌ μ ν리μΌμ΄μ νλ‘μ νΈμμ μ μλ νμ€ν¬λ λ¬Έμ κ° λ°μν κ°λ₯μ±μ΄ μ μ΅λλ€. κ·Έ μ΄μ λ λ°°ν¬λ₯Ό μν΄μ μ¬λ¬κ°μ§ νμ€ν¬λ₯Ό μ μνμ§ μκΈ° λλ¬ΈμΈλ°μ. κ·Έλ¬λ©΄ μ νμ€ν¬λ₯Ό μννλ©΄ μ΄λ€ κ²°κ³Όλ₯Ό μ 곡νλμ§ νλ² νμΈν΄λ³ΌκΉμ?
νμ€ν¬ κ²°κ³Ό
νλ‘μ νΈ ν΄λμ μλ Gradle Wrapperλ₯Ό μ¬μ©νμ¬ zipBeanstalk νμ€ν¬λ₯Ό μννλ©΄μ νλ‘μ νΈ λ²μ μ λͺ μν΄λ³΄κ² μ΅λλ€.
./gradlew clean zipBeanstalk -x test -Pversion=1.0.0-hotfix.11
ν¨ν€μ§λ WAR νμΌκ³Ό zipBeanstalk νμ€ν¬μ μν΄ λ§λ€μ΄μ§λ μμΉ΄μ΄λΈ νμΌμ νλ‘μ νΈ λ²μ μ΄ ν¬ν¨λ¨μ νμΈν μ μμ΅λλ€.
μλ λ°°ν¬ νκ²½μ μν νμ€ν¬
μ¬μ€ zipBeanstalk νμ€ν¬λ μλ§μ‘΄ μΉ μλΉμ€μ λΉμ€ν‘ νκ²½μΌλ‘ λ°°ν¬νκΈ° μν μ ν리μΌμ΄μ λ²λ€ νμΌμ λ§λλ νμ€ν¬μ λλ€. λ§μ½, μλμΌλ‘ λ°°ν¬νμ¬μΌνλ νκ²½μ΄ μΆκ°λλ€λ©΄ λΉμ€ν‘ νκ²½μμ μ¬μ©νλ Procfileκ³Ό νκ²½ κ΅¬μ± νμΌλ€μ ν¬ν¨ν νμκ° μμΌλ©° νΉμ νκ²½μ μν νλ‘νΌν° νμΌλ§ λ³λλ‘ μΆκ°νλ©΄ λ©λλ€.
task zipManually(type: Zip, dependsOn: 'bootWar') {
println 'Build Version: ' + project.version
from ('.conf') { into 'application-prod.yml'}
from ('build/libs') {
include(bootWar.archiveName)
}
baseName = 'app-bundle'
}
zipManually νμ€ν¬μλ application-prod.ymlμ ν¨ν€μ§λ μ ν리μΌμ΄μ WAR νμΌκ³Ό ν¨κ» ν¬ν¨μν€λλ‘ μ μνμ΅λλ€. μμλ λΆλ€λ μκ² μ§λ§ μ€νλ§ λΆνΈ μ ν리μΌμ΄μ μ WAR νμΌκ³Ό λμΌν μμΉμ μλ μ ν리μΌμ΄μ νλ‘νΌν° νμΌμ μ½μ μ μμ΅λλ€. λ§μ½, λͺ¨λ₯΄μλ λΆλ€μ΄λΌλ©΄ νλ‘νΌν° κ΅¬μ± μ°μ μμμ λν λ¬Έμλ₯Ό νμΈνμκΈ° λ°λλλ€.
λμΌνκ² zipManually νμ€ν¬λ₯Ό μ€νν΄λ³΄λλ‘ νκ² μ΅λλ€.
./gradlew clean zipManually -x test -Pversion=1.0.0-hotfix.11
> Configure project :
JDK info: 11
Build Version: 1.0.0-hotfix.11
Build Version: 1.0.0-hotfix.11
> Task :bootBuildInfo
> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes
> Task :bootWarMainClassName
> Task :bootWar
> Task :procfile
> Task :zipManually
zipManually νμ€ν¬ κ²°κ³Όλ μ μμΌλ‘ 보μ λλ€λ§β¦ μ΄μν λΆλΆμ λμΉμ±μ λΆλ€μ΄ μμΌμκ² μ£ ? λ°λ‘ Build Versionμ΄ λλ² μΆλ ₯λμλ€λ μ μΈλ°μ. μ°λ¦¬λ λΆλͺ ν λ³λμ νμ€ν¬λ‘ μ μνκ³ νμ€ν¬ λΈλ‘ λ΄μμ νμ¬ Build Versionμ μΆλ ₯νλλ‘ μμ±νμ΅λλ€. μ΄λ κ² Build Version λ²μ μ΄ λλ² μΆλ ₯λλ μ΄μ λ μ΄ κΈμ μ£Όμ λ΄μ©μΈ κ·Έλλ€ λΉλ λΌμ΄νμ¬μ΄ν΄μ λν κ°λ κ³Ό κ΄λ ¨μ΄ μμ΅λλ€.
κ·Έλλ€ λΉλ λΌμ΄νμ¬μ΄ν΄
μ¬μ€ μ μ΄λ¬ν λ¬Έμ λ₯Ό κ²½ννλ μ΄μ λ κ·Έλλ€μ λΉλ λΌμ΄νμ¬μ΄ν΄μ λν κ°λ μ λͺ¨λ₯΄κΈ° λλ¬ΈμΈλ°μ. 20λ μ°¨μ΄μ νμ₯λ μ‘°μ°¨λ μ λͺ¨λ₯΄λ λΆλΆμ΄μλ€κ³ ν μ μμ΅λλ€. λΉλ λΌμ΄νμ¬μ΄ν΄ μ‘΄μ¬λ₯Ό λͺ¨λ₯΄λ μν©μ΄μκΈ°μ μ΄λ κ² λλ μ΄μ λ₯Ό κ²μνκ³ νμ₯λκ»μ Gradle executes all tasks?μ΄λΌλ μ€νμ€λ²νλ‘μ° μ§λ¬Έμ 곡μ ν΄μ£Όμ ¨μ΅λλ€.
μ΄ μ§λ¬Έμ λν λ΅λ³μμλ κ·Έλλ€μλ configuration λ¨κ³μ execution λ¨κ³κ° μκ³ μ΄κ²μ μ€μν κ°λ μ΄λΌκ³ μ€λͺ νκ³ μμμ΅λλ€. κ·Έλ¬λ©΄ κ·Έλλ€ κ³΅μ λ¬Έμμ μλ Build Lifecycleλ₯Ό μ΄ν΄λ³΄λλ‘ νκ² μ΅λλ€.
Gradle builds the complete dependency graph before any task is executed.
β¦ Your build scripts configure this dependency graph.
κ·Έλλ€μ νμ€ν¬λ₯Ό μννκΈ° μ μ μμ‘΄μ± κ·Έλνλ₯Ό λΉλνκ³ λΉλ μ€ν¬λ¦½νΈλ μμ‘΄μ± κ·Έλνλ₯Ό ꡬμ±νλ€κ³ μ€λͺ νλ©° λΉλ λ¨κ³μ λν΄μ μ€λͺ ν©λλ€.
λΉλ λ¨κ³
κ·Έλλ€μ λΉλ λ¨κ³λ 3κ°μ§λ‘ ꡬλΆλλ€κ³ νλ©° μ΄κΈ°ν(Initialization), ꡬμ±(Configuration), μν(Execution)μ λλ€.
Initialization
Gradle supports single and multi-project builds. During the initialization phase, Gradle determines which projects are going to take part in the build, and creates a Project instance for each of these projects.Configuration
During this phase the project objects are configured. The build scripts of all projects which are part of the build are executed.Execution
Gradle determines the subset of the tasks, created and configured during the configuration phase, to be executed. The subset is determined by the task name arguments passed to the gradle command and the current directory. Gradle then executes each of the selected tasks.
μΈκ°μ§μ λ¨κ³ μ€ κ΅¬μ± λ¨κ³μμλ λͺ¨λ νλ‘μ νΈμ λΉλ μ€ν¬λ¦½νΈκ° μ€νλλ€λ μ€λͺ μ΄ μμ΅λλ€. μ΄ λΆλΆμ΄ μ κ° κ²½νν λ¬Έμ μ μμΈμ΄λΌκ³ ν μ μλλ° νμ€ν¬ λ΄μμ μμ±νλ μ½λλ κ΅¬μ± λ¨κ³μ ν¬ν¨λλ©° doFirstμ doLast λΈλ‘μ΄ μν λ¨κ³μ ν¬ν¨λκΈ° λλ¬Έμ λλ€.
μ λ λͺ¨λ₯΄λ λΆλΆμ΄μκ³ μκ°λ³΄λ€ λ§μ λΈλ‘κ·Έμμλ κ·Έλλ€ νμ€ν¬ μ μλ₯Ό μ€λͺ ν λ κ΅¬μ± λ¨κ³μ ν΄λΉλλ κ³³μ printlnμ μμ±νλ μμλ₯Ό 보μ¬μ£Όλλ°μ. μκ°λ³΄λ€ λ§μ λΆλ€μ΄ μ΄ κ°λ μ λν΄μ λͺ¨λ₯Έλ€κ³ ν μ μμ΅λλ€. λ¬Όλ‘ λ¨μΌ μ ν리μΌμ΄μ νλ‘μ νΈμμλ λͺ°λΌλ μκ΄μλ€κ³ ν μ μκ² λ€μ.
ν μ€νΈλ₯Ό μν νμ€ν¬
κ·Έλ¬λ©΄ μ΄λ»κ² νμκΈ°μ νλ‘μ νΈ λ²μ μ΄ ν¬ν¨λμ§ μμμ μ§ λ€μμ νμ€ν¬λ₯Ό μ΄ν΄λ³΄λλ‘ νκ² μ΅λλ€.
task zipBeanstalk(type: Zip, dependsOn: 'procfile') {}
task zipManually(type: Zip, dependsOn: 'bootWar') {}
task k8sbuild(dependsOn: bootWar) {
project.version ''
}
μΆκ°ν k8sbuild νμ€ν¬λ μΏ λ²λ€ν°μ€ λ°°ν¬ νκ²½ ν μ€νΈλ₯Ό μν΄ ν¨ν€μ§λ μ ν리μΌμ΄μ WAR νμΌμ ν¬ν¨λλ νλ‘μ νΈ λ²μ μ μλ΅νκΈ° μν΄μ project.versionμ λΉ κ°μΌλ‘ μ€μ νλλ‘ μμ±νκ² νκ·Όμ΄μμ΅λλ€. μ΄ μνλ‘ zipManually νμ€ν¬λ₯Ό λ€μ νλ² μννλ©΄ μ΄λ»κ² λλμ§ νμΈν΄λ΄ μλ€.
./gradlew clean zipManually -x test -Pversion=1.0.0-hotfix.11
k8sbuild νμ€ν¬μ μμ±λ project.versionμ μ€μ νλ νμλ κ΅¬μ± λ¨κ³μ ν΄λΉνκΈ° λλ¬Έμ λͺ¨λ νμ€ν¬λ₯Ό μννκΈ° μ΄μ μ μ μ©λμ΄ zipManually νμ€ν¬λ₯Ό μννμμλ λΆκ΅¬νκ³ νλ‘μ νΈ λ²μ μ΄ ν¬ν¨λμ§ μμμμ 보μ¬μ€λλ€.
ν΄κ²°λ°©μ
κ·Έλ¬λ©΄ μ΄λ»κ² ν΄κ²°νλκ² μ’μμ§ λ°©μμ μ°Ύμ보λλ‘ νκ² μ΅λλ€.
νλ‘μ νΈ λ²μ μ¬μ μνλ κ²½μ°
k8sbuild νμ€ν¬μ²λΌ νΉμ νμ€ν¬μμ νλ‘μ νΈ λ²μ μ μ¬μ μ νκ³ μΆμ κ²½μ°μλ doFirstμ κ°μ ν΄λ‘μ λ₯Ό νμ©ν΄μΌν©λλ€.
task k8sbuild(dependsOn: bootWar) {
doFirst {
project.version ''
}
}
νλ‘μ νΈ λ²μ μ νμΈνκ³ μΆμ κ²½μ°
zipBeanstalkμ zipManually νμ€ν¬μ²λΌ μ ν리μΌμ΄μ μ WARλ‘ ν¨ν€μ§νλ κ²½μ° νμ¬ νλ‘μ νΈ λ²μ μ μΆλ ₯νκ³ μΆμ κ²½μ° gradle.taskGraph.whenReadyλ₯Ό νμ©ν¨μΌλ‘μ¨ ν΄κ²°ν μ μμ΅λλ€.
task zipBeanstalk(type: Zip, dependsOn: 'procfile') {
from ('.ebextensions') { into '.ebextensions' }
from ('.platform') { into '.platform' }
from ('build/libs') {
include(bootWar.archiveName)
include("Procfile")
}
baseName = 'beanstalk'
}
task zipManually(type: Zip, dependsOn: 'bootWar') {
from ('.conf') { into 'application-prod.yml'}
from ('build/libs') {
include(bootWar.archiveName)
}
baseName = 'app-bundle'
}
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(bootWar)) {
println 'Build Version: ' + project.version
}
}
λΆνμν νμΌμ μ κ±°ν΄μΌνλ κ²½μ°
κ²½μ°μ λ°λΌμλ νλ‘μ νΈ λΉλ μ ν¨ν€μ§λ μ ν리μΌμ΄μ WAR νμΌμ ν¬ν¨λμ§ μλλ‘ ν΄μΌν μ μμ΅λλ€. μλ₯Ό λ€μ΄, λ‘컬 νκ²½μμ μ¬μ©νλ μ ν리μΌμ΄μ νλ‘νΌν° νμΌμ΄λ νΉμ λλ©μΈμ λν μΈμ¦μ λλ μΈμ¦ν€λ₯Ό ν¬ν¨νμ§μλλ‘ μ μΈν΄μΌν μ μμ΅λλ€.
gradle.taskGraph.whenReady { graph ->
if (graph.hasTask(build_for_customer)) {
processResources {
exclude('**/config/**.yml')
exclude('**/certs/**')
}
}
}
μ μμλ κ΅¬μ± λ¨κ³μμ μμ‘΄μ± κ·Έλν ꡬμ±μ΄ μλ£λ μ΄νμ build_for_customer νμ€ν¬κ° μνλλ κ²½μ°μ κ³ κ° νκ²½μΌλ‘ λ°°ν¬νλ μ ν리μΌμ΄μ WAR νμΌμ μ체μ μΌλ‘ μ¬μ©νλ μ ν리μΌμ΄μ νλ‘νΌν° νμΌλ€κ³Ό μΈμ¦μλ₯Ό ν¬ν¨νμ§ μλλ‘ processResourcesλ₯Ό μ¬μ μν¨μ 보μ¬μ€λλ€.
κ·Έλλ€ λΉλ λΌμ΄νμ¬μ΄ν΄ κ°λ κ³Ό ν¨κ» κ²½ννμλ λ¬Έμ μ λνμ¬ μ΄λ»κ² ν΄κ²°ν μ μλμ§ μμ보μμ΅λλ€. μ΄λ€ κΈ°μ μ μ¬μ©ν¨μ μμ΄μ μ£Όμ κ°λ μ μ΄ν΄νκ³ μλ κ²μ΄ μ€μν¨μ λ€μνλ² κΉ¨λ«κ² λλ μ’μ κ²½νμ΄μμ΅λλ€. μ¬λ¬λΆμ κ·Έλλ€ λΉλ μ€ν¬λ¦½νΈμμλ μν λ¨κ³μμ μνλμ΄μΌν μ½λλ₯Ό κ΅¬μ± λ¨κ³μμ λμνλλ‘ μμ±λμ§ μμλμ§ κ²ν ν΄λ³΄μκΈ°λ₯Ό λ°λλλ€.
κ°μ¬ν©λλ€.