빌드 프로세스 이해

작성자 : Jason Lee

이 항목에서는 엔터프라이즈 규모 빌드 및 배포 프로세스의 연습을 제공합니다. 이 항목에서 설명하는 접근 방식은 MSBuild(사용자 지정 Microsoft Build Engine) 프로젝트 파일을 사용하여 프로세스의 모든 측면에 대한 세분화된 제어를 제공합니다. 프로젝트 파일 내에서 사용자 지정 MSBuild 대상은 IIS(인터넷 정보 서비스) 웹 배포 도구(MSDeploy.exe) 및 데이터베이스 배포 유틸리티 VSDBCMD.exe 같은 배포 유틸리티를 실행하는 데 사용됩니다.

참고

이전 항목인 프로젝트 파일 이해에서는 MSBuild 프로젝트 파일의 주요 구성 요소를 설명하고 여러 대상 환경에 대한 배포를 지원하기 위해 프로젝트 파일을 분할하는 개념을 소개했습니다. 이러한 개념에 익숙하지 않은 경우 이 항목을 진행하기 전에 프로젝트 파일 이해를 검토해야 합니다.

이 항목은 Fabrikam, Inc.라는 가상 회사의 엔터프라이즈 배포 요구 사항을 기반으로 하는 일련의 자습서의 일부를 구성합니다. 이 자습서 시리즈에서는 샘플 솔루션인 Contact Manager 솔루션을 사용하여 ASP.NET MVC 3 애플리케이션, WCF(Windows Communication Foundation) 서비스 및 데이터베이스 프로젝트를 포함하여 현실적인 수준의 복잡성을 가진 웹 애플리케이션을 나타냅니다.

이 자습서의 핵심인 배포 방법은 프로젝트 파일 이해에 설명된 분할 프로젝트 파일 접근 방식을 기반으로 합니다. 이 방법은 빌드 프로세스가 모든 대상 환경에 적용되는 빌드 지침과 환경별 빌드 및 배포 설정을 포함하는 두 개의 프로젝트 파일에 의해 제어됩니다. 빌드 시 환경별 프로젝트 파일이 환경에 구애받지 않은 프로젝트 파일로 병합되어 전체 빌드 지침 집합을 형성합니다.

빌드 및 배포 개요

Contact Manager 솔루션에서 세 개의 파일이 빌드 및 배포 프로세스를 제어합니다.

  • 범용 프로젝트 파일(Publish.proj). 여기에는 대상 환경 간에 변경되지 않는 빌드 및 배포 지침이 포함됩니다.
  • 환경별 프로젝트 파일(Env-Dev.proj). 여기에는 특정 대상 환경과 관련된 빌드 및 배포 설정이 포함됩니다. 예를 들어 Env-Dev.proj 파일을 사용하여 개발자 또는 테스트 환경에 대한 설정을 제공하고 Env-Stage.proj 라는 대체 파일을 만들어 스테이징 환경에 대한 설정을 제공할 수 있습니다.
  • 명령 파일(Publish-Dev.cmd). 여기에는 실행할 프로젝트 파일을 지정하는 MSBuild.exe 명령이 포함되어 있습니다. 각 파일에 다른 환경별 프로젝트 파일을 지정하는 MSBuild.exe 명령이 포함된 모든 대상 환경에 대한 명령 파일을 만들 수 있습니다. 이렇게 하면 개발자가 적절한 명령 파일을 실행하여 다른 환경에 배포할 수 있습니다.

샘플 솔루션의 솔루션 게시 폴더에서 이러한 세 파일을 찾을 수 있습니다.

샘플 솔루션의 솔루션 게시 폴더에서 세 개의 파일을 찾을 수 있습니다.

이러한 파일을 좀 더 자세히 살펴보기 전에 이 방법을 사용할 때 전체 빌드 프로세스의 작동 방식을 살펴보겠습니다. 높은 수준에서 빌드 및 배포 프로세스는 다음과 같습니다.

높은 수준에서 빌드 및 배포 프로세스의 모양.

가장 먼저 발생하는 작업은 유니버설 빌드 및 배포 명령이 포함된 프로젝트 파일과 환경별 설정을 포함하는 두 개의 프로젝트 파일이 단일 프로젝트 파일로 병합된다는 것입니다. 그런 다음 MSBuild는 프로젝트 파일의 지침을 통해 작동합니다. 각 프로젝트에 대한 프로젝트 파일을 사용하여 솔루션의 각 프로젝트를 빌드합니다. 그런 다음 웹 배포(MSDeploy.exe) 및 VSDBCMD 유틸리티와 같은 다른 도구를 호출하여 웹 콘텐츠 및 데이터베이스를 대상 환경에 배포합니다.

처음부터 끝까지 빌드 및 배포 프로세스는 다음 작업을 수행합니다.

  1. 새 빌드를 준비하기 위해 출력 디렉터리의 내용을 삭제합니다.

  2. 솔루션에서 각 프로젝트를 빌드합니다.

    1. 웹 프로젝트의 경우(이 경우 ASP.NET MVC 웹 애플리케이션 및 WCF 웹 서비스) 빌드 프로세스는 각 프로젝트에 대한 웹 배포 패키지를 만듭니다.
    2. 데이터베이스 프로젝트의 경우 빌드 프로세스는 각 프로젝트에 대한 배포 매니페스트(.deploymanifest 파일)를 만듭니다.
  3. VSDBCMD.exe 유틸리티를 사용하여 .deploymanifest 파일과 함께 프로젝트 파일의 다양한 속성(대상 연결 문자열 및 데이터베이스 이름)을 사용하여 솔루션의 각 데이터베이스 프로젝트를 배포합니다.

  4. MSDeploy.exe 유틸리티를 사용하여 프로젝트 파일의 다양한 속성을 사용하여 배포 프로세스를 제어하여 솔루션의 각 웹 프로젝트를 배포합니다.

샘플 솔루션을 사용하여 이 프로세스를 더 자세히 추적할 수 있습니다.

참고

사용자 고유의 서버 환경에 대한 환경별 프로젝트 파일을 사용자 지정하는 방법에 대한 지침은 대상 환경에 대한 배포 속성 구성을 참조하세요.

빌드 및 배포 프로세스 호출

개발자 테스트 환경에 Contact Manager 솔루션을 배포하기 위해 개발자는 Publish-Dev.cmd 명령 파일을 실행합니다. 이렇게 하면 MSBuild.exe 호출하고 Publish.proj 를 실행할 프로젝트 파일로 지정하고 Env-Dev.proj 를 매개 변수 값으로 지정합니다.

msbuild.exe Publish.proj /fl /p:TargetEnvPropsFile=EnvConfig\Env-Dev.proj

참고

/fl 스위치(/fileLogger의 약어)는 빌드 출력을 현재 디렉터리의 msbuild.log라는 파일에 기록합니다. 자세한 내용은 MSBuild 명령줄 참조를 참조하세요.

이 시점에서 MSBuild는 실행을 시작하고 Publish.proj 파일을 로드하며 그 안에 있는 지침을 처리하기 시작합니다. 첫 번째 명령은 TARGETEnvPropsFile 매개 변수가 지정하는 프로젝트 파일을 가져오도록 MSBuild에 지시합니다.

<Import Project="$(TargetEnvPropsFile)" />

TargetEnvPropsFile 매개 변수는 Env-Dev.proj 파일을 지정하므로 MSBuild는 Env-Dev.proj 파일의 내용을 Publish.proj 파일에 병합합니다.

병합된 프로젝트 파일에서 MSBuild에서 발생하는 다음 요소는 속성 그룹입니다. 속성은 파일에 표시되는 순서대로 처리됩니다. MSBuild는 지정된 조건이 충족되도록 각 속성에 대해 키-값 쌍을 만듭니다. 파일의 뒷부분에서 정의된 속성은 파일의 앞부분에서 정의된 동일한 이름의 속성을 덮어씁 수 있습니다. 예를 들어 OutputRoot 속성을 고려합니다.

<OutputRoot Condition=" '$(OutputRoot)'=='' ">..\Publish\Out\</OutputRoot>
<OutputRoot Condition=" '$(BuildingInTeamBuild)'=='true' ">$(OutDir)</OutputRoot>

MSBuild가 첫 번째 OutputRoot 요소를 처리할 때 비슷한 이름의 매개 변수가 제공되지 않은 경우 OutputRoot 속성의 값을 로 설정합니다. \Publish\Out. 두 번째 OutputRoot 요소가 발견되면 조건이 true로 평가되면 OutputRoot 속성의 값을 OutDir 매개 변수 값으로 덮어씁니다.

MSBuild에서 발생하는 다음 요소는 ProjectsToBuild라는 항목을 포함하는 단일 항목 그룹입니다.

<ItemGroup>
   <ProjectsToBuild Include="$(SourceRoot)ContactManager-WCF.sln"/>
</ItemGroup>

MSBuild는 ProjectsToBuild라는 항목 목록을 빌드하여 이 명령을 처리합니다. 이 경우 항목 목록에는 솔루션 파일의 경로와 파일 이름이라는 단일 값이 포함됩니다.

이 시점에서 나머지 요소는 대상입니다. 대상은 속성 및 항목과 다르게 처리됩니다. 기본적으로 대상은 사용자가 명시적으로 지정하거나 프로젝트 파일 내의 다른 구문에 의해 호출되지 않는 한 처리되지 않습니다. 여는 프로젝트 태그에는 DefaultTargets 특성이 포함되어 있습니다.

<Project ToolsVersion="4.0" 
         DefaultTargets="FullPublish" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

그러면 MSBuild.exe 호출될 때 대상이 지정되지 않은 경우 MSBuild에서 FullPublish 대상을 호출하도록 지시합니다. FullPublish 대상에는 작업이 포함되지 않습니다. 대신 종속성 목록을 지정합니다.

<PropertyGroup>   
  <FullPublishDependsOn>
     Clean;
     BuildProjects;      
     GatherPackagesForPublishing;
     PublishDbPackages;
     PublishWebPackages;
  </FullPublishDependsOn>
</PropertyGroup>
<Target Name="FullPublish" DependsOnTargets="$(FullPublishDependsOn)" />

이 종속성은 FULLPublish 대상을 실행하기 위해 제공된 순서대로 이 대상 목록을 호출해야 함을 MSBuild에 알릴 수 있습니다.

  1. Clean 대상을 호출해야 합니다.
  2. BuildProjects 대상을 호출해야 합니다.
  3. GatherPackagesForPublishing 대상을 호출해야 합니다.
  4. PublishDbPackages 대상을 호출해야 합니다.
  5. PublishWebPackages 대상을 호출해야 합니다.

클린 대상

Clean 대상은 기본적으로 출력 디렉터리와 모든 내용을 새 빌드를 위한 준비로 삭제합니다.

<Target Name="Clean" Condition=" '$(BuildingInTeamBuild)'!='true' ">
  <Message Text="Cleaning up the output directory [$(OutputRoot)]"/>
  <ItemGroup>
     <_FilesToDelete Include="$(OutputRoot)**\*"/>
  </ItemGroup>
  <Delete Files="@(_FilesToDelete)"/>
  <RemoveDir Directories="$(OutputRoot)"/>
</Target>

대상에는 ItemGroup 요소가 포함됩니다. Target 요소 내에서 속성 또는 항목을 정의할 때 동적 속성 및 항목을 만듭니다. 즉, 속성 또는 항목은 대상이 실행될 때까지 처리되지 않습니다. 출력 디렉터리가 없거나 빌드 프로세스가 시작될 때까지 파일이 포함되지 않을 수 있으므로 _FilesToDelete 목록을 정적 항목으로 빌드할 수 없습니다. 실행이 진행될 때까지 기다려야 합니다. 따라서 목록을 대상 내에서 동적 항목으로 빌드합니다.

참고

이 경우 Clean 대상이 가장 먼저 실행되므로 동적 항목 그룹을 사용할 필요가 없습니다. 그러나 특정 시점에 다른 순서로 대상을 실행할 수 있으므로 이러한 유형의 시나리오에서 동적 속성 및 항목을 사용하는 것이 좋습니다.
또한 사용되지 않을 항목을 선언하지 않도록 해야 합니다. 특정 대상에서만 사용할 항목이 있는 경우 빌드 프로세스에서 불필요한 오버헤드를 제거하기 위해 대상 내에 배치하는 것이 좋습니다.

동적 항목을 제외하고 Clean 대상은 매우 간단하며 기본 제공 Message, DeleteRemoveDir 작업을 사용하여 다음을 수행합니다.

  1. 로거에 메시지를 보냅니다.
  2. 삭제할 파일 목록을 작성합니다.
  3. 파일을 삭제합니다.
  4. 출력 디렉터리를 제거합니다.

BuildProjects 대상

BuildProjects 대상은 기본적으로 샘플 솔루션의 모든 프로젝트를 빌드합니다.

<Target Name="BuildProjects" Condition=" '$(BuildingInTeamBuild)'!='true' ">
   <MSBuild Projects="@(ProjectsToBuild)"
            Properties="OutDir=$(OutputRoot);
                        Configuration=$(Configuration);
                        DeployOnBuild=true;
                        DeployTarget=Package"
            Targets="Build" />
  </Target>

이 대상은 작업 및 대상이 속성 및 항목을 참조하는 방법을 설명하기 위해 이전 항목인 프로젝트 파일 이해에서 자세히 설명되었습니다. 이 시점에서는 주로 MSBuild 작업에 관심이 있습니다. 이 작업을 사용하여 여러 프로젝트를 빌드할 수 있습니다. 작업은 MSBuild.exe 새 instance 만들지 않으며 현재 실행 중인 instance 사용하여 각 프로젝트를 빌드합니다. 이 예제의 주요 관심사는 배포 속성입니다.

  • DeployOnBuild 속성은 각 프로젝트의 빌드가 완료되면 프로젝트 설정에서 배포 지침을 실행하도록 MSBuild에 지시합니다.
  • DeployTarget 속성은 프로젝트가 빌드된 후 호출할 대상을 식별합니다. 이 경우 패키지 대상은 프로젝트 출력을 배포 가능한 웹 패키지로 빌드합니다.

참고

패키지 대상은 MSBuild와 웹 배포 간의 통합을 제공하는 WPP(웹 게시 파이프라인)를 호출합니다. WPP에서 제공하는 기본 제공 대상을 살펴보려면 %PROGRAMFILES(x86)%\MSBuild\Microsoft\VisualStudio\v10.0\Web 폴더에서 Microsoft.Web.Publishing.targets 파일을 검토합니다.

GatherPackagesForPublishing 대상

GatherPackagesForPublishing 대상을 연구하는 경우 실제로 작업이 포함되지 않습니다. 대신 세 개의 동적 항목을 정의하는 단일 항목 그룹이 포함됩니다.

<Target Name="GatherPackagesForPublishing">
   <ItemGroup>
      <PublishPackages 
         Include="$(_ContactManagerDest)ContactManager.Mvc.deploy.cmd">
         <WebPackage>true</WebPackage>
         <!-- More item metadata -->  
      </PublishPackages>
      <PublishPackages 
         Include="$(_ContactManagerSvcDest)ContactManager.Service.deploy.cmd">
         <WebPackage>true</WebPackage>
         <!-- More item metadata -->
      </PublishPackages>
      <DbPublishPackages Include="$(_DbDeployManifestPath)">
         <DbPackage>true</DbPackage>
         <!-- More item metadata -->
      </DbPublishPackages>
   </ItemGroup>
</Target>

이러한 항목은 BuildProjects 대상이 실행될 때 생성된 배포 패키지를 참조합니다. BuildProjects 대상이 실행될 때까지 항목이 참조하는 파일이 존재하지 않으므로 프로젝트 파일에서 이러한 항목을 정적으로 정의할 수 없습니다. 대신 BuildProjects 대상이 실행될 때까지 호출되지 않는 대상 내에서 항목을 동적으로 정의해야 합니다.

항목은 이 대상 내에서 사용되지 않습니다. 이 대상은 단순히 각 항목 값과 연결된 항목 및 메타데이터를 빌드합니다. 이러한 요소가 처리되면 PublishPackages 항목에는 ContactManager.Mvc.deploy.cmd 파일의 경로와 ContactManager.Service.deploy.cmd 파일의 경로의 두 값이 포함됩니다. 웹 배포는 각 프로젝트에 대한 웹 패키지의 일부로 이러한 파일을 만들고 패키지를 배포하기 위해 대상 서버에서 호출해야 하는 파일입니다. 이러한 파일 중 하나를 열면 기본적으로 다양한 빌드별 매개 변수 값이 있는 MSDeploy.exe 명령이 표시됩니다.

DbPublishPackages 항목에는 ContactManager.Database.deploymanifest 파일의 경로인 단일 값이 포함됩니다.

참고

.deploymanifest 파일은 데이터베이스 프로젝트를 빌드할 때 생성되며 MSBuild 프로젝트 파일과 동일한 스키마를 사용합니다. 여기에는 데이터베이스 스키마(.dbschema)의 위치와 배포 전 및 배포 후 스크립트의 세부 정보를 포함하여 데이터베이스를 배포하는 데 필요한 모든 정보가 포함됩니다. 자세한 내용은 데이터베이스 빌드 및 배포 개요를 참조하세요.

웹 애플리케이션 프로젝트 빌드 및 패키징 및 데이터베이스 프로젝트 배포에서 배포 패키지 및 데이터베이스 배포 매니페스트를 만들고 사용하는 방법에 대해 자세히 알아봅니.

PublishDbPackages 대상

간단히 말해 PublishDbPackages 대상은 VSDBCMD 유틸리티를 호출하여 ContactManager 데이터베이스를 대상 환경에 배포합니다. 데이터베이스 배포 구성에는 많은 결정과 뉘앙스가 포함되며, 데이터베이스 프로젝트 배포여러 환경에 대한 데이터베이스 배포 사용자 지정에서 이에 대해 자세히 알아봅니다. 이 항목에서는 이 대상이 실제로 작동하는 방식에 초점을 맞춥니다.

먼저 여는 태그에 Outputs 특성이 포함되어 있습니다.

<Target Name="PublishDbPackages" Outputs="%(DbPublishPackages.Identity)">

대상 일괄 처리의 예입니다. MSBuild 프로젝트 파일에서 일괄 처리는 컬렉션을 반복하는 기술입니다. Outputs 특성 "%(DbPublishPackages.Identity)"의 값은 DbPublishPackages 항목 목록의 ID 메타데이터 속성을 참조합니다. Outputs=%(ItemList.ItemMetadataName)라는 표기법은 다음과 같이 변환됩니다.

  • DbPublishPackages의 항목을 동일한 ID 메타데이터 값을 포함하는 항목의 일괄 처리로 분할합니다.
  • 일괄 처리당 한 번 대상을 실행합니다.

참고

ID 는 만들 때 모든 항목에 할당되는 기본 제공 메타데이터 값 중 하나입니다. Item 요소의 Include 특성 값을 참조합니다. 즉, 항목의 경로와 파일 이름을 참조합니다.

이 경우 경로와 파일 이름이 같은 항목이 두 개 이상 있으면 안 되므로 기본적으로 일괄 처리 크기로 작업합니다. 대상은 모든 데이터베이스 패키지에 대해 한 번 실행됩니다.

적절한 스위치를 사용하여 VSDBCMD 명령을 빌드하는 _Cmd 속성에서 유사한 표기법을 볼 수 있습니다.

<_Cmd>"$(VsdbCmdExe)" 
   /a:Deploy 
   /cs:"%(DbPublishPackages.DatabaseConnectionString)" 
   /p:TargetDatabase=%(DbPublishPackages.TargetDatabase)             
   /manifest:"%(DbPublishPackages.FullPath)" 
   /script:"$(_CmDbScriptPath)" 
   $(_DbDeployOrScript)
</_Cmd>

이 경우 %(DbPublishPackages.DatabaseConnectionString), %(DbPublishPackages.TargetDatabase)%(DbPublishPackages.FullPath)는 모두 DbPublishPackages 항목 컬렉션의 메타데이터 값을 참조 합니다 . _Cmd 속성은 명령을 호출하는 Exec 작업에서 사용됩니다.

<Exec Command="$(_Cmd)"/>

이 표기법의 결과로 Exec 작업은 DatabaseConnectionString, TargetDatabaseFullPath 메타데이터 값의 고유한 조합을 기반으로 일괄 처리를 만들고 각 일괄 처리에 대해 한 번씩 실행됩니다. 작업 일괄 처리의 예입니다. 그러나 대상 수준 일괄 처리는 이미 항목 컬렉션을 단일 항목 일괄 처리로 분할했으므로 Exec 작업은 대상의 각 반복에 대해 한 번만 실행됩니다. 즉, 이 작업은 솔루션의 각 데이터베이스 패키지에 대해 VSDBCMD 유틸리티를 한 번 호출합니다.

참고

대상 및 작업 일괄 처리에 대한 자세한 내용은 MSBuild 일괄 처리, 대상 일괄 처리의 항목 메타데이터작업 일괄 처리의 항목 메타데이터를 참조하세요.

PublishWebPackages 대상

이 시점까지 샘플 솔루션의 각 프로젝트에 대한 웹 배포 패키지를 생성하는 BuildProjects 대상을 호출했습니다. 각 패키지는 대상 환경에 패키지를 배포하는 데 필요한 MSDeploy.exe 명령과 대상 환경의 필요한 세부 정보를 지정하는 SetParameters.xml 파일이 포함된 deploy.cmd 파일입니다. 또한 GatherPackagesForPublishing 대상을 호출하여 관심 있는 deploy.cmd 파일이 포함된 항목 컬렉션을 생성했습니다. 기본적으로 PublishWebPackages 대상은 다음 함수를 수행합니다.

  • XmlPoke 작업을 사용하여 대상 환경에 대한 올바른 세부 정보를 포함하도록 각 패키지에 대한 SetParameters.xml 파일을 조작합니다.
  • 적절한 스위치를 사용하여 각 패키지에 대해 deploy.cmd 파일을 호출합니다.

PublishDbPackages 대상과 마찬가지로 PublishWebPackages 대상은 대상 일괄 처리를 사용하여 대상이 각 웹 패키지에 대해 한 번 실행되도록 합니다.

<Target Name="PublishWebPackages" Outputs="%(PublishPackages.Identity)">

대상 내에서 Exec 작업은 각 웹 패키지에 대해 deploy.cmd 파일을 실행하는 데 사용됩니다.

<PropertyGroup>
   <_Cmd>
      %(PublishPackages.FullPath) 
      $(_WhatifSwitch) 
      /M:$(MSDeployComputerName) 
      %(PublishPackages.AdditionalMSDeployParameters)
   </_Cmd>
</PropertyGroup>
<Exec Command="$(_Cmd)"/>

웹 패키지 배포를 구성하는 방법에 대한 자세한 내용은 웹 애플리케이션 프로젝트 빌드 및 패키징을 참조하세요.

결론

이 항목에서는 Contact Manager 샘플 솔루션에 대한 빌드 및 배포 프로세스를 처음부터 끝까지 제어하는 데 분할 프로젝트 파일을 사용하는 방법에 대한 연습을 제공했습니다. 이 방법을 사용하면 환경별 명령 파일을 실행하기만 하면 반복 가능한 단일 단계에서 복잡한 엔터프라이즈 규모 배포를 실행할 수 있습니다.

추가 정보

프로젝트 파일 및 WPP에 대한 자세한 소개는 Microsoft Build Engine 내부: Sayed Ibrahim Hashimi 및 William Bartholomew의 MSBuild 및 Team Foundation Build 사용, ISBN: 978-0-7356-4524-0을 참조하세요.