Steam에 게임을 출시해보자 (4편) - 스팀게임 CD(배포 자동화) 파이프라인 구축 (ver. Unity)

배포 자동화 (CD - Continuous Deployment)
왜? 배포까지 자동화해야 할까?
이전 포스팅에서 Jenkins를 통해 게임 빌드 과정을 자동화했습니다. 이제는 유니티를 열지 않아도, 코드가 갱신되면 Jenkins가 알아서 게임을 빌드해 줍니다. 하지만 아직 한 가지 과정이 남아 있습니다. 바로 빌드된 게임을 스팀에 업로드하는 과정입니다.
지금 상황을 정리해 보면 아래와 같습니다.
- Jenkins가 게임 빌드를 완료합니다.
- 개발자가 빌드 PC에서 SteamPipeGUI를 엽니다.
- Generate VDFs → Upload를 눌러 업로드를 진행합니다.
- 업로드 중 Steam Guard 승인 요청이 오면 확인하고 승인합니다.
- Steamworks에 접속해 test 브랜치를 새 빌드로 지정합니다.
빌드는 자동으로 진행되지만, 그 이후의 과정은 여전히 사람이 직접 처리해야 합니다. 결국 업데이트를 할 때마다 개발자가 작업을 멈추고 업로드를 챙겨야 하는 상황이 반복됩니다. 이 과정에서 업로드를 깜빡하거나, 이전 빌드를 잘못 올리거나, 브랜치를 잘못 지정하는 등의 실수도 생기기 쉽습니다.
이번 포스팅에서는 이 업로드 과정까지 Jenkins에 맡기도록 하겠습니다. 3편에서 다룬 CI/CD 중 CD(지속적 배포) 에 해당하는 부분입니다. 배포까지 자동화가 완료된다면 코드를 올리는 것만으로 빌드부터 스팀 업로드까지 한 번에 진행되며, 개발자는 테스트 버전이 올라왔는지만 확인하면 됩니다.
전체 흐름
이번 포스팅까지 완료했을 때의 전체 흐름은 아래와 같습니다.
- Git Push → Jenkins 트리거 → Unity 빌드(3편) → SteamCMD 업로드(이번 글) → test 브랜치 반영
- Git Push : 개발자가 작업한 코드를 GitHub에 올립니다.
- Jenkins 트리거 : 3편에서 설정한 빌드 트리거(GitHub hook 또는 Poll SCM)가 변경사항을 감지하고 빌드를 시작합니다.
- Unity 빌드 : 3편에서 작성한 빌드 스크립트를 배치모드로 실행하여 게임을 빌드합니다.
- SteamCMD 업로드 : 빌드가 성공하면 이어서 SteamCMD가 빌드 결과물을 스팀에 업로드합니다. 이번 포스팅에서 추가하는 부분입니다.
- test 브랜치 반영 : 업로드된 빌드가 자동으로 test 브랜치에 지정되어, 테스터들이 바로 최신 버전을 플레이할 수 있게 됩니다.
여기서 중요한 점은 빌드가 실패하면 업로드도 진행되지 않는다는 것입니다. Jenkins는 앞 단계가 성공한 경우에만 다음 단계를 진행하기 때문에, 빌드에 실패한 게임이 스팀에 올라가는 일은 발생하지 않습니다.
SteamCMD 설정과 최초 로그인
SteamPipeGUI와 SteamCMD의 관계
2편에서 SteamPipeGUI의 Upload 버튼을 눌렀을 때 콘솔창이 나타나며 업로드가 진행되는 것을 확인했습니다. 사실 이 콘솔창이 바로 SteamCMD입니다.


SteamCMD는 스팀에서 제공하는 명령어 기반의 스팀 클라이언트로, 스팀 로그인과 게임 업로드 등의 작업을 명령어로 수행할 수 있습니다. SteamPipeGUI는 우리가 화면에 입력한 정보로 설정파일(VDF)을 만들어 주고, 그 설정파일로 SteamCMD를 대신 실행해 주는 역할을 했던 것입니다.
- SteamPipeGUI : 정보 입력 → VDF 생성 → SteamCMD 실행 (사람이 버튼을 눌러야 함)
- SteamCMD : 명령어 한 줄로 로그인 → 업로드 실행 (사람이 개입하지 않아도 됨)
3편에서 유니티 빌드 메뉴를 클릭하는 대신 배치모드 명령어로 빌드했던 것과 같은 원리입니다. Jenkins는 버튼을 누를 수 없기 때문에, 이번 포스팅에서는 GUI를 거치지 않고 SteamCMD를 직접 명령어로 실행하도록 구성하겠습니다.
SteamCMD 실행 확인
SteamCMD는 따로 설치할 필요 없이, 2편에서 다운로드한 SDK 안에 이미 포함되어 있습니다. SteamCMD는 SDK > Tools > ContentBuilder > builder 폴더의 steamcmd.exe 입니다.

steamcmd.exe를 실행하면 처음에는 스팀 클라이언트의 최신 버전을 내려받는 업데이트 과정이 진행됩니다. 업데이트가 완료될 때까지 잠시 기다립니다.

업데이트가 완료되면 Steam> 입력창이 나타납니다. 이 상태가 되었다면 SteamCMD를 사용할 준비가 완료된 것입니다.

최초 실행 시 업데이트 과정이 진행되지 않는다면, 이미 2편에서 SteamPipeGUI로 업로드할 때 업데이트가 완료된 상태입니다.
Steam Guard 처리
⚠️ 2편에서 업로드 중 Steam Guard 승인을 요청받았던 것처럼, SteamCMD도 로그인 시 인증을 요구합니다. Jenkins는 빌드 중에 이 인증을 처리할 수 없기 때문에, 빌드 PC에서 미리 한 번 로그인해 인증 정보를 저장해 두어야 합니다.
Jenkins가 업로드를 진행하는 도중 Steam Guard 인증을 요구받는다면, 코드를 입력하거나 승인해 줄 사람이 없기 때문에 업로드가 실패하게 됩니다. 따라서 빌드 PC에서 미리 한 번 직접 로그인하여, 이 PC가 신뢰할 수 있는 기기라는 것을 스팀에 인증받아 두어야 합니다.
SteamCMD의 Steam> 입력창에 아래 명령어를 입력합니다. ({아이디}는 업로드 권한이 있는 스팀 계정의 아이디를 입력합니다)
login {아이디}
비밀번호를 입력합니다. (보안상 입력한 비밀번호는 화면에 표시되지 않습니다)

Steam Guard 인증을 요청받습니다. 계정에 설정된 인증 방식(이메일 또는 스팀 모바일 앱)에 따라 인증 코드를 입력하거나 승인을 진행합니다. 로그인에 성공하면 인증 정보가 SteamCMD 폴더에 저장됩니다. 이후부터는 같은 PC의 같은 SteamCMD로 로그인할 때 Steam Guard 인증을 다시 요구하지 않습니다.
스팀 계정의 비밀번호를 변경하거나 오랜 기간 로그인하지 않은 경우에는 저장된 인증 정보가 만료될 수 있습니다.
Jenkins 업로드가 갑자기 로그인 단계에서 실패한다면, 위 과정을 다시 진행하여 인증 정보를 갱신해 주시면 됩니다.
업로드 스크립트(VDF) 작성
SteamCMD로 업로드를 하려면 무엇을, 어디에, 어떻게 올릴지를 알려주는 설정파일이 필요합니다. 이 설정파일을 VDF(Valve Data Format) 파일이라고 합니다. 업로드에는 두 종류의 VDF 파일이 사용됩니다.
- app_build_{AppID}.vdf : 어떤 게임(App)에, 어떤 디팟들을, 어떤 브랜치로 올릴지 설정합니다.
- depot_build_{DepotID}.vdf : 하나의 디폿에 어떤 폴더의 어떤 파일들을 담을지 설정합니다.
쉽게 말해 app_build는 업로드 전체 계획서, depot_build는 디폿별 포장 목록이라고 생각하시면 됩니다.
SteamPipeGUI를 활용한 VDF 초안 작성
VDF 파일의 경우에는 공식 메뉴얼의 구조에 맞게 설정해야 정상적인 업로드 과정이 가능합니다. 스크립트 구조에 맞추어 내용을 작성하는 경우에 작성된 규칙에 맞추어 업로드 과정이 진행됩니다.
Steamworks 업로드 배포 공식 메뉴얼
하지만 이번 방법으로는 VDF 파일을 처음부터 작성하지 않고 SteamPipeGUI를 활용할 생각입니다. SteamPipeGUI의 Generate VDFs 을 진행하는 경우에 VDF 초안을 생성할 수 있습니다.

SDK > Tools > ContentBuilder > scripts폴더로 이동합니다.app_build_{AppID}.vdf,depot_build_{DepotID}.vdf파일이 생성되어 있는 것을 확인할 수 있습니다.

- 두 파일은 메모장 등 텍스트 편집기로 열어서 수정할 수 있습니다. 이번 포스팅에서는 이 파일들을 SteamCMD로 업로드 하고, Jenkins 자동 업로드에 맞게 수정하겠습니다.
SteamPipeGUI 버전에 따라 생성된 파일의 형태가 아래 예시와 조금 다를 수 있습니다.
항목의 이름과 역할은 같으니, 아래 설명을 참고하여 자신의 파일에 맞게 수정해 주시면 됩니다.
app_build_{AppID}.vdf
app_build 파일은 업로드 전체를 설정하는 파일입니다. 해당 파일은 업로드를 진행할 때 필요한 정보들을 포함하고 있습니다.
"AppBuild"
{
"AppID" "{AppID}"
"Desc" "{Desc}"
"BuildOutput" "{Log directory}"
"SetLive" "{Branch name}"
"Depots"
{
"{DepotID}" "depot_build_{DepotID}.vdf"
}
}
각 항목의 의미는 아래와 같습니다.
- AppID : 업로드할 게임의 고유 번호입니다. 스팀 페이지의 게임 이름 옆 괄호에서 확인할 수 있습니다.
- Desc : 업로드한 빌드에 붙는 설명입니다. Steamworks 빌드 목록에서 설명을 작성하는 내용으로 업로드한 빌드의 설명을 작성합니다. Steamworks 페이지에서는 설명을 토대로 빌드의 구성을 파악합니다. 지금은 임시로 작성해 두고, Jenkins에서 설명을 작성하도록 바꾸겠습니다.
- BuildOutput : 업로드 과정의 로그와 캐시 파일이 저장되는 경로입니다. ContentBuilder의
output폴더를 그대로 사용합니다. 만약 업로드 중 오류가 발생했다면 로그를 통해서 에러를 확인할 수 있습니다. - SetLive : 업로드가 끝나면 이 빌드를 지정할 브랜치입니다. 이번 포스팅에서 가장 중요한 항목으로, 2편에서 만든
test브랜치 이름을 입력합니다. 이 항목 덕분에 업로드와 동시에 test 브랜치가 최신 빌드로 바뀌게 됩니다. - Depots : 이번 업로드에 포함할 디폿 목록입니다. 디폿 번호와, 그 디폿을 설정한 depot_build 파일 이름을 짝지어 작성합니다.
⚠️ 주의 SetLive에
default를 입력해도 default 브랜치에는 반영되지 않습니다. 스팀은 정식 배포 브랜치를 자동으로 변경하지 못하도록 막아 두었기 때문입니다. (5장에서 다시 다루겠습니다)또한 SetLive에 입력하는 브랜치는 Steamworks에 미리 만들어져 있어야 합니다. 브랜치 이름의 대소문자까지 정확히 일치하는지 확인해 주세요.
VDF 파일 안의 상대 경로(
..\output\등)는 VDF 파일이 있는 위치를 기준으로 계산됩니다.즉,
scripts폴더 기준으로 한 단계 위인 ContentBuilder 폴더의output폴더를 의미합니다.
depot_build_{DepotID}.vdf
depot_build 파일은 디폿에 담을 파일들을 설정합니다. 2편에서는 SteamPipeGUI에서 게임 폴더를 직접 선택했지만, 이번에는 3편에서 Jenkins가 빌드한 결과물 폴더를 지정해야 합니다.
"DepotBuild"
{
"DepotID" "{DepotID}"
"ContentRoot" "{Build File Directory}"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"Recursive" "1"
}
"FileExclusion" "*.pdb"
}
각 항목의 의미는 아래와 같습니다.
- DepotID : 파일을 담을 디폿 번호입니다.
- ContentRoot : 업로드할 게임 파일이 있는 폴더입니다. 자동 빌드 후 결과물이 나오는 지정된 폴더를 입력합니다. 이렇게 하면 Jenkins가 빌드를 마친 폴더가 그대로 업로드 대상이 됩니다.
- FileMapping : ContentRoot 안의 어떤 파일을, 디폿의 어디에 넣을지 설정합니다.
- LocalPath : 업로드할 파일입니다.
*는 모든 파일을 의미합니다. - DepotPath : 유저 PC에 설치될 위치입니다.
.은 게임 설치 폴더 바로 아래를 의미합니다. - Recursive :
1로 설정하면 하위 폴더까지 모두 포함합니다.
- LocalPath : 업로드할 파일입니다.
- FileExclusion : 업로드에서 제외할 파일입니다. 필요한 만큼 여러 줄 작성할 수 있으며, 업로드에 포함하지 않을 설정 파일 등을 지정합니다.
빌드 결과물 폴더 이름(
ProjectDC_...)은 3편 빌드 스크립트의 실행파일 이름(ProjectDC.exe)에 따라 정해집니다.실행파일 이름을 다르게 지정했다면, FileExclusion의 폴더 이름도 그에 맞게 바꿔 주세요.
커맨드 라인으로 업로드 테스트
VDF 파일 작성이 완료되었다면, Jenkins에 연결하기 전에 명령어로 먼저 업로드가 되는지 확인합니다. 유니티에서 빌드 자동화를 위해 커맨드 라인을 통해 작업을 진행했던 것과 동일하게, Jenkins에 넣기 전에 배치모드 명령어로 빌드를 먼저 테스트했던 것과 같은 과정입니다.
이 단계는 이번 포스팅에서 가장 중요한 과정입니다. Jenkins는 결국 여기서 테스트한 명령어를 그대로 대신 실행해 주는 역할을 하기 때문입니다. 즉, 명령 프롬프트에서 업로드가 성공한다면 Jenkins에서도 성공하고, 여기서 실패한다면 Jenkins에서도 실패합니다. Jenkins에서 오류가 발생하면 원인을 찾기가 더 어렵기 때문에, 이 단계에서 모든 문제를 해결하고 넘어가는 것을 권장합니다.
업로드 명령어 구성
업로드 명령어는 아래와 같은 형태입니다.
- {SteamCMD 경로} : steamcmd.exe의 전체 경로를 입력합니다.
- +login {아이디} : 업로드 권한이 있는 스팀 계정으로 로그인합니다.
- run_app_build {VDF 경로} : 작성한 app_build 파일의 전체 경로를 입력하여 업로드를 진행합니다.
- quit : 업로드를 마친 후 SteamCMD를 종료합니다.
{SteamCMD 경로} +login {아이디} +run_app_build {VDF 경로} +quit
저의 상황에서 진행하는 명령어는 아래와 같습니다. (여러분들도 SDK 경로와 AppID에 따라 상황이 다를 수 있으므로 자신의 컴퓨터 상황에 맞추어 작성할 필요가 있습니다)
"C:\steamworks_sdk_165\sdk\tools\ContentBuilder\builder\steamcmd.exe" +login {아이디} +run_app_build "C:\steamworks_sdk_165\sdk\tools\ContentBuilder\scripts\app_3829210.vdf" +quit

업로드 결과 확인
명령 프롬프트에 성공 메시지가 나왔다면, Steamworks에서 실제로 반영되었는지 확인합니다.
Steamworks의 게임 빌드 페이지로 이동합니다.
방금 업로드한 빌드가 목록에 추가되어 있는지 확인합니다. 명령 프롬프트에 출력된 BuildID와 VDF의 Desc에 작성한 설명으로 구분할 수 있습니다.

해당 빌드가 test 브랜치로 지정되어 있는지 확인합니다. SetLive를 설정했기 때문에, 직접 브랜치를 선택하지 않아도 자동으로 지정됩니다.
이는 곧 Steam의 test 브랜치를 통해 빌드를 테스트하고 있는 구성원들에게 바로 배포가 진행된다는 뜻과 동일합니다. 조직 내 구성원이라면 test 브랜치 등 테스트용 브랜치를 활용하여 빌드의 안정성을 테스트합니다. 만약 test 브랜치에서 정상동작을 확인했다면 그 경우에 default 브랜치를 최신 버전으로 변경하여 정식 출시를 진행할 수 있습니다.
⚠️ 주의 SetLive에
default를 입력해도 default 브랜치에는 반영되지 않습니다. 스팀은 정식 배포 브랜치를 자동으로 변경하지 못하도록 막아 두었기 때문입니다. 정식 출시만큼은 직접 손으로 변경하여 위험성을 줄이고자 하는 의도입니다.

만약 스팀에서 업데이트가 바로 확인되지 않는 경우에는 게임의 설정에서 업데이트 설정을 변경해주시기 바랍니다.

여기까지 확인되었다면 명령어 한 줄로 업로드부터 test 브랜치 지정까지 완료할 수 있게 된 것입니다. 즉, steamworks의 업로드를 수행하고 test 브랜치를 지정하기 때문에, 조직 구성원의 입장에서는 스팀에서 바로 test 버전의 게임을 다운로드하고 플레이가 가능합니다. 이제 남은 것은 이 명령어를 Jenkins가 대신 실행하도록 연결하는것 뿐입니다.
Jenkins 연동
이제 명령어 한 줄로 업로드부터 test 브랜치 지정까지 완료할 수 있게 되었습니다. 이 명령어를 Jenkins Item에 추가하여, 빌드가 끝나면 자동으로 업로드까지 진행되도록 구성하겠습니다. 그렇다면 비로소 유니티의 버전관리를 위해 깃에 변경사항을 커밋하는 것만으로도 빌드를 자동으로 수행하고 배포까지 전달되는 결과를 얻을 수 있습니다.
업로드 빌드 스텝 추가
이제 Jenkins Item에 업로드 명령어를 추가하도록 하겠습니다.
Jenkins 메인 화면에서 Item을 선택하고 구성으로 들어갑니다.

Build Steps 항목에 Unity 빌드 스텝이 있는 것을 확인합니다. 그 아래에 Add build step → Execute Windows batch command를 선택하여 새로운 빌드 스텝을 추가합니다.

추가된 입력창에 배포 자동화 명령어를 작성합니다.
{SteamCMD 경로} +login {아이디} +run_app_build {VDF 경로} +quit

빌드 스텝은 위에서부터 순서대로 실행됩니다. 반드시 Unity 빌드 스텝 아래에 업로드 스텝이 위치해야 빌드가 끝난 결과물을 업로드하게 됩니다.
빌드 정보 자동 기록
지금 상태로도 업로드는 진행되지만, Steamworks의 빌드 목록에서는 모든 빌드가 VDF에 작성한 같은 설명(Jenkins Auto Upload)으로 표시됩니다. 빌드가 쌓이다 보면 어떤 빌드가 어떤 Jenkins 빌드에서 올라온 것인지 구분하기 어려워집니다.
이를 해결하기 위해 업로드할 때마다 Jenkins 빌드 번호를 설명에 자동으로 넣도록 하겠습니다.
Jenkins는 빌드마다 %BUILD_NUMBER%라는 변수에 빌드 번호를 담아 줍니다. (Jenkins 빌드 기록에 표시되는 #1, #2 같은 번호입니다) +run_app_build 뒤에 -desc "설명"을 추가하면, VDF의 Desc 대신 입력한 설명이 사용됩니다.
명령어를 아래와 같이 수정합니다.
"C:\SteamSDK\tools\ContentBuilder\builder\steamcmd.exe" +login {아이디} +run_app_build -desc "Jenkins Build #%BUILD_NUMBER%" "C:\SteamSDK\tools\ContentBuilder\scripts\app_build_{AppID}.vdf" +quit
이제 Steamworks 빌드 목록에서 Jenkins Build #12처럼 표시되어, Jenkins의 빌드 기록과 1:1로 비교할 수 있습니다. 문제가 생긴 빌드를 발견했을 때 Jenkins에서 해당 번호의 빌드 로그를 바로 찾아볼 수 있어 매우 편리합니다.
빌드 시간 제한 설정
빌드 자동화 방식은 편리하지만 한 가지 주의할 점이 있습니다. 저장된 로그인 정보는 비밀번호를 변경하거나 오랜 기간이 지나면 만료될 수 있습니다.
로그인 정보가 만료된 상태에서 Jenkins가 업로드를 진행하면, SteamCMD는 비밀번호 입력을 기다리며 멈추게 됩니다. 하지만 Jenkins에서는 아무도 입력해 줄 수 없기 때문에, 빌드가 끝나지 않고 계속 멈춰 있는 상황이 발생합니다. 이를 방지하기 위해 빌드 시간 제한을 설정합니다.
Item 구성의 빌드 환경(Build Environment) 항목에서 Terminate a build if it's stuck를 체크합니다.

Time-out strategy를 Absolute로 선택하고, 제한 시간(분)을 입력합니다. 평소 빌드와 업로드에 걸리는 시간보다 넉넉하게 설정합니다. Time-out actions에서 Fail the build를 추가하면, 제한 시간이 지났을 때 빌드가 실패로 처리됩니다.

빌드가 시간 초과로 실패한다면 대부분 로그인 정보 만료가 원인입니다. 로그인 과정을 다시 한 번 진행하여 로그인 정보를 갱신하면 해결됩니다.
배포 자동화 결과 확인
지금까지의 여정을 통해서 어떤 결과를 얻을 수 있는지 확인해보도록 하겠습니다.
[수동] 유니티 프로젝트를 개발하고 변경사항을 Git으로 커밋하고 push 합니다.


[자동] Jenkins가 자동으로 게임 빌드의 변경사항을 감지하여 빌드를 수행합니다

[자동] 빌드가 성공하면 SteamCMD를 통해서 Steamworks에 업로드와 test 브랜치 배포를 진행합니다.

[자동] 스팀에서 최신 버전의 업데이트가 다운로드 됩니다.

이로서 결국 게임 개발자는 오로지 게임 프로젝트를 개발하고 Git을 통해 버전관리만 진행하면 됩니다. 모든 빌드 과정, 배포 과정은 Jenkins를 통해서 자동화로 수행되기 때문에 스팀에서 바로 플레이가 가능합니다. 개발자가 CI/CD 환경을 구축한다면 오로지 게임개발에만 집중할 수 있는 환경을 구성할 수 있습니다.

핵심 효과를 정리하자면 아래와 같습니다.
- 개발에만 집중할 수 있는 환경
코드를 올리기만 하면 빌드부터 스팀 업로드까지 자동으로 진행됩니다. 빌드 설정을 열고, SteamPipeGUI를 실행하고, 업로드를 기다리는 시간이 사라져 그만큼 게임 개발에 시간을 쓸 수 있습니다.
- 사람의 실수 감소
업로드 누락, 이전 빌드를 잘못 올리는 실수, 브랜치 지정 실수처럼 반복 작업에서 생기기 쉬운 실수가 줄어듭니다. 매번 같은 명령어가 같은 순서로 실행되기 때문에 결과가 항상 일정합니다.
- 빠른 테스트와 피드백
업로드와 동시에 test 브랜치가 최신 빌드로 지정되기 때문에, 테스터는 스팀 클라이언트에서 업데이트만 받으면 바로 새 버전을 확인할 수 있습니다. 개발 → 테스트 → 수정의 주기가 짧아져 문제를 더 빨리 발견하고 고칠 수 있습니다.
- 빌드 이력 추적
Jenkins 빌드 번호가 Steamworks 빌드 설명에 기록되므로, 스팀에 올라간 빌드가 어떤 Jenkins 빌드에서 왔는지 바로 찾을 수 있습니다. 문제가 생긴 버전을 발견했을 때 해당 빌드의 로그와 코드 변경 내역을 쉽게 확인할 수 있습니다.
- 안정적인 배포 구조
테스트 버전 배포까지는 자동으로, 정식 배포(default 브랜치)는 사람이 확인한 뒤에 진행합니다. 자동화의 편리함과 사람의 최종 확인이라는 안전장치를 함께 가져갈 수 있습니다.
- 팀 작업에 유리한 환경
빌드와 배포가 특정 개발자의 PC나 손에 의존하지 않습니다. 누가 코드를 올리든 같은 과정으로 빌드되고 배포되기 때문에, 팀원이 늘어나거나 담당자가 바뀌어도 배포 과정이 흔들리지 않습니다.
- 확장의 기반
한 번 파이프라인을 갖춰 두면 Discord·Slack 빌드 알림, 여러 플랫폼(Windows·Mac) 동시 빌드, 자동 테스트 추가처럼 원하는 기능을 단계적으로 붙여 나갈 수 있습니다.






팔로우 했습니다~ 이런글 좋아요 잘 보고갑니다~!