Microsoft MVP성태의 닷넷 이야기
Team Foundation Server: 39. 배치 파일로 팀 빌드 구성 [링크 복사], [링크+제목 복사],
조회: 28696
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 4개 있습니다.)
배치 파일로 팀 빌드 구성


제품을 개발하다 보니, "빌드" 작업이 만만치 않게 복잡해져 가고 있습니다. 변경 사항이 너무 많아서 TFS의 정형화된 팀 빌드를 이용하기보다는 초기부터 배치 파일을 통한 팀 빌드 작업을 구성했습니다.

현재 제가 담당하고 있는 제품은 다음과 같은 팀 빌드 작업이 배치 파일에 의해서 이뤄지고 있습니다.

  1. 최신 버전을 내려받고,
  2. 전체 프로젝트의 DLL 어셈블리 버전을 증가시키기 위해 "공통 GlobalAssemblyInfo.cs 버전 정보를 수정"하고, 다시 체크인.
  3. 현재 시점의 TFS Label 자동 지정
  4. 기존 코드에서 .NET 1.0 프로젝트로 변환
  5. .NET 1.0, 2.0, 3.0 배포환경에 맞는 바이너리를 각각 생성(빌드)하고,
  6. Source 서버 동작을 위한 인덱싱 작업
  7. Symbol 서버에 PDB 배포
  8. EXE/DLL에 대해 인증서로 코드 서명,
  9. .NET 1.0, 2.0, 3.0 바이너리를 테스트하는 웹 사이트, WCF 예제, .NET 리모팅 예제, COM+ 예제를 빌드
  10. Windows 2003 32/64bit, Windows Server 2008, Windows Server 2008 R2 테스트 머신에 모든 바이너리 배포

몇 개 안 되어 보이지만, 세세한 작업까지 해서 배치 파일 크기만 800라인 정도 됩니다. 이 중에서, 일반적인 환경에서도 공통적으로 적용될 수 있는 작업 몇 개를 골라서 배치 파일 예제로 만들어 볼 텐데요. 대략, 다음과 같은 작업이 되겠습니다.

  1. 최신 버전을 내려받고,
  2. 전체 프로젝트의 DLL 어셈블리 버전을 증가시키기 위해 "공통 GlobalAssemblyInfo.cs 버전 정보를 수정"하고, 다시 체크인.
  3. 현재 시점의 TFS Label 자동 지정
  4. 빌드
  5. Source 서버 동작을 위한 인덱싱 작업
  6. Symbol 서버에 PDB 배포
  7. EXE/DLL에 대해 인증서로 코드 서명

자... 그럼 하나씩 구현해 볼까요? ^^




0. 경로 설정


현재, 다음과 같은 환경으로 설정된 팀 프로젝트를 대상으로 사용자 정의 팀 빌드를 만드는 것을 가정합니다. (이 환경은 여러분의 경우 달라질 수 있습니다.)

팀 프로젝트 솔루션 파일이 있는 폴더 경로: D:\Settings\desktop\project_apply\TestSolution
빌드 배치 파일 위치: D:\Settings\desktop\project_apply\build.bat

이제부터 build.bat 파일에 하나씩 내용을 추가해 나갈 텐데요. 빌드 작업 관련해서 여러 가지 환경 변수를 미리 설정해 주는 작업부터 진행해 보겠습니다. 대충 다음과 같은 정도면 팀 빌드 관련해서 문제없이 동작합니다.

REM ======== 1. From Visual Studio Command Prompt (2010) batch file 
SET DevEnvDir=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\
SET Framework35Version=v3.5
SET FrameworkDir=C:\Windows\Microsoft.NET\Framework\
SET FrameworkDIR32=C:\Windows\Microsoft.NET\Framework\
SET FrameworkVersion=v4.0.30319
SET FrameworkVersion32=v4.0.30319 
SET INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\INCLUDE;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include;
SET LIB=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\LIB;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib;
SET LIBPATH=C:\Windows\Microsoft.NET\Framework\%FrameworkVersion%;C:\Windows\Microsoft.NET\Framework\v3.5;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\LIB;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ATLMFC\LIB;

SET PATH=C:\Program Files (x86)\Microsoft F#\v4.0\;C:\Program Files (x86)\MicrosoftVisual Studio 10.0\VSTSDB\Deploy;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools;C:\Windows\Microsoft.NET\Framework\%FrameworkVersion%;C:\Windows\Microsoft.NET\Framework\v3.5;C:\ProgramFiles (x86)\Microsoft Visual Studio 10.0\VC\VCPackages;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files (x86)\Microsoft Visual Studio 10.0\\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;D:\Tools\SysInternals;

SET PATH=C:\Program Files\Debugging Tools for Windows (x64);C:\Program Files\Debugging Tools for Windows (x64)\srcsrv;%PATH%
SET PATH=C:\Perl64\site\bin;C:\Perl64\bin;%PATH%

SET VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\
SET VSINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 10.0\
SET WindowsSdkDir=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\

REM ======== 2. current working folder
FOR /F %%I IN ("%0") DO SET CURRENTDIR=%%~dpI

REM ======== 3. build configuration
SET SOLUTIONDIR=%CURRENTDIR%\TestSolution\
SET BUILDCONFIG=Release
SET TARGET_PLATFORM=AnyCPU

2번과 3번 영역은 여기서 굳이 설명이 필요 없을 것 같고요.

위에서 1번 작업 영역은 대부분의 내용을 "Visual Studio Command Prompt" 배치 파일에서 복사한 것입니다. 그런데, 중간 부분에 보면 Perl과 "Debugging Tools for Windows"에 대한 경로가 잡혀 있는데요. 나중에 소스 인덱싱을 위해 필요하기 때문에 추가시켜 줘야 합니다. 다운로드는 다음에서 받을 수 있습니다.

ActivePerl
; http://www.activestate.com/activeperl

윈도우 32비트 5.10.1
; http://downloads.activestate.com/ActivePerl/releases/5.10.1.1007/ActivePerl-5.10.1.1007-MSWin32-x86-291969.msi

윈도우 64비트 5.10.1
; http://downloads.activestate.com/ActivePerl/releases/5.10.1.1007/ActivePerl-5.10.1.1007-MSWin32-x64-291969.msi

Debugging Tools for Windows
; https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools

1. 최신 버전을 내려받기


TFS 형상관리 서버로부터 최신 버전을 받는 방법은 간단합니다. 이미 팀 프로젝트가 구성되어 Workspace가 할당된 상태이기 때문에 Visual Studio에서도 할 수 있지만 자동화된 빌드를 만들어야 하기 때문에 tf.exe를 이용해서 다음과 같이 명령을 내려줄 수 있습니다.

tf get . /version:T /force /overwrite /recursive /all



전체 솔루션에 포함된 프로젝트들은 단일한 GlobalAssemblyInfo.cs 파일을 "Add as Link" 형태로 추가하고 있습니다. 따라서 이 파일 하나만 수정해 주면 모든 프로젝트의 "AssemblyInformationalVersion" 번호가 바뀌게 되는데요. 현재 이 작업은 cmd batch 명령어로는 해결이 안됩니다. 따라서, "GlobalAssemblyInfo.cs" 파일을 입력으로 받아 그 안의 버전 번호를 증가시켜 주고 증가된 버전 번호를 반환해 줄 사용자 정의 프로그램이 필요합니다. (TFS 같은 경우에는 Custom Build Task를 만들어야 합니다.)

크게 어렵지 않은 프로그램이고 본론과 상관없기 때문에 제가 만들어 놓은 버전 증가 IncrementVersionInfo.exe 파일을 첨부해 놓겠습니다. (물론, 만드셔도 됩니다.)

이를 다음과 같이 사용하면, 해당 파일의 버전 번호를 바꿔서 저장하고,

IncrementVersionInfo.exe %SOLUTIONDIR%\GlobalAssemblyInfo.cs

다음과 같이 응용하면 변수에 증가된 버전 번호의 값을 "GLOBAL_VERSION" 환경 변수에 저장해 둘 수 있습니다.

for /f %%i in ('IncrementVersionInfo %SOLUTIONDIR%\GlobalAssemblyInfo.cs') do set GLOBAL_VERSION=%%i

위의 단계에서 한 가지 문제가 있는데요. 해당 Workspace는 TFS의 버전관리를 받기 때문에 기본적으로 모든 파일이 read-only로 되어 있어서 GlobalAssemblyInfo.cs 파일이 잠겨 있다는 것입니다.

이 때문에, 위의 과정 전/후에 check-out/check-in을 해주어야 합니다.

체크 아웃: tf checkout %SOLUTIONDIR%\GlobalAssemblyInfo.cs
체크 인: tf checkin /comment:"Increment Version: %GLOBAL_VERSION%" /noprompt %SOLUTIONDIR%\GlobalAssemblyInfo.cs

종합해 보면, 다음과 같이 추가해 줄 수 있습니다.

tf checkout %SOLUTIONDIR%\GlobalAssemblyInfo.cs
for /f %%i in ('IncrementVersionInfo %SOLUTIONDIR%\GlobalAssemblyInfo.cs') do set GLOBAL_VERSION=%%i
tf checkin /comment:"Increment Version: %GLOBAL_VERSION%" /noprompt %SOLUTIONDIR%\GlobalAssemblyInfo.cs

3. 소스 컨트롤의 "Label" 자동 지정


자, Label은 모든 팀 빌드에 해줄 필요는 없습니다. 이건 프로젝트 개발 성격에 따라서 달라질 수 있는데요. 하루 한 번 자동 빌드되는 경우 해주거나, 배포를 위한 최종 빌드를 해주는 경우에만 Label을 해줄 수 있습니다. 어쨌든, 명령행에서 지정하는 방법은 매우 간단합니다.

tf label "%GLOBAL_VERSION%_DeployBuild" %SOLUTIONDIR% /recursive

이렇게 실행되면 다음과 같이 "Labels" 기록을 확인할 수 있습니다.

tfs_source_server_1.png

4. 빌드

빌드 작업은 간단하지요. ^^ msbuild라서! 예제로 사용될 솔루션에는 프로젝트가 두 개만 있기 때문에 다음과 같이 추가될 수 있습니다.

msbuild %SOLUTIONDIR%\TestLibrary\TestLibrary.csproj /property:Platform=%TARGET_PLATFORM%;Configuration=%BUILDCONFIG%;SolutionDir=%SOLUTIONDIR%
msbuild %SOLUTIONDIR%\ConsoleApplication1\ConsoleApplication1.csproj /property:Platform=%TARGET_PLATFORM%;Configuration=%BUILDCONFIG%;SolutionDir=%SOLUTIONDIR%

이 때, 저 같은 경우에는 빌드 결과물들을 하나의 폴더에 모으는 것을 선호합니다. 그래서, 각각의 csproj 파일의 OutputPath를 직접 다음과 같이 메모장에서 미리 수정해서 체크인을 합니다. (참고: Output 경로에 매크로 상수 사용하는 방법)

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ... [생략] ...
    <OutputPath>$(SolutionDir)\bin\$(Configuration)</OutputPath>
    ... [생략] ...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    ... [생략] ...
    <OutputPath>$(SolutionDir)\bin\$(Configuration)</OutputPath>
    ... [생략] ...
</PropertyGroup>

그래서 빌드 작업까지 모두 완료하면 다음과 같이 출력 폴더가 구성됩니다.

tfs_source_server_2.png

부가적으로, TFS 2010부터는 C++도 msbuild로 관리되는 등의 편이성이 더욱 향상되었습니다.

(참고로, 아래의 글들은 msbuild 관련해서 제가 써놓은 글들을 나열한 것입니다.)

MSBuild를 이용한 VC++ 프로젝트 빌드
; https://www.sysnet.pe.kr/2/0/871

TFS - 팀 빌드 오류 확인 방법
; https://www.sysnet.pe.kr/2/0/732

Output 경로에 매크로 상수 사용하는 방법
; https://www.sysnet.pe.kr/2/0/688

C#에서 아쉬운 __DATE__, __TIME__ 매크로
; https://www.sysnet.pe.kr/2/0/587

XmlSerializer 생성자의 실행 속도를 올리는 방법 - 두 번째 이야기
; https://www.sysnet.pe.kr/2/0/521

Team Build에 사용되는 각종 Property 값
; https://www.sysnet.pe.kr/2/0/508

PDB 파일과 소스 코드
; https://www.sysnet.pe.kr/2/0/324

하위 폴더의 모든 프로젝트의 출력물을 제거 (Clean)
; https://www.sysnet.pe.kr/2/0/304

.NET에서의 신뢰도 등급 조정 - Manifest 파일 이용 
; https://www.sysnet.pe.kr/2/0/450

5. Source 서버 동작을 위한 인덱싱 작업


자, 드디어 ^^ 기다리던 소스 서버 작업입니다. 이를 위해 처음 부분에서 설명한 "ActivePerl"과 "Debugging Tools for Windows"를 설치해 두었어야 하고, 여기서는 두 가지 모두 64비트 제품으로 설치해서 다음과 같은 경로에 설치되었다고 가정합니다.

ActivePerl: C:\Perl64
Debugging Tools for Windows: C:\Program Files\Debugging Tools for Windows (x64)

먼저, "C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\srcsrv.ini" 파일을 메모장으로 열어서 MYSERVER 값을 자신의 TFS 환경에 맞게 바꿔줍니다.

[variables]
MYSERVER=http://tfs2010:8080/tfs/defaultcollection

* 위의 MYSERVER의 http 주소값을 알아내는 방법은 "예전 글"의 3번 내용을 참고합니다.

그리고, TFS 2010을 사용하시는 분들은 "C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\ssindex.cmd" 파일을 편집해 주어야 하는데, 이에 대해서는 다음의 글을 참고하십시오. (이 글에서는 TFS 2010 기준으로 설명합니다.)

TFS 2010의 소스 서버 수작업 구성
; https://www.sysnet.pe.kr/2/0/902

지난번의 TFS 2008 팀 빌드에 통합했던 작업에서는 tfsindex.cmd를 호출해서 처리했는데, 이번에는 그럴 수가 없습니다. 왜냐하면, batch 파일 작업이기 때문에 그 안에서 또 다른 배치 파일인 tfsindex.cmd를 호출하면 제어를 잃어버리기 때문입니다. 따라서, 응용 프로그램을 곧바로 호출해야 하는 식으로 바꿔야 하는데요.

ssindex.cmd 안을 확인해 보니, 다음과 같이 호출하는 것으로 해결이 가능합니다.

perl -w -x "ssindex.cmd 경로" -SYSTEM=TFS -SYMBOLS="PDB 파일들 경로" -SOURCE="소스 파일 루트 경로"

이 글의 예제로 사용되고 있는 "TestSolution"의 구조를 이에 반영하면 아래와 같습니다.

perl -w -x "C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\ssindex.cmd" -SYSTEM=TFS -SYMBOLS="%SOLUTIONDIR%\bin\%BUILDCONFIG%" -SOURCE="%SOLUTIONDIR%"



그래서, 정상적으로 실행되고 나면 다음과 같은 출력 결과를 얻을 수 있습니다.

D:\...>perl -w -x "C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\ssindex.cmd" -SYSTEM=TFS -SYMBOLS="D:\Settings\desktop\project_apply\TestSolution\bin\Release" -SOURCE="D:\Settings\desktop\project_apply\TestSolution"
--------------------------------------------------------------------------------

ssindex.cmd [STATUS] : Server ini file: C:\Program Files\Debugging Tools for Windows (x64)\srcsrv\srcsrv.ini
ssindex.cmd [STATUS] : Source root    : D:\Settings\desktop\project_apply\TestSolution
ssindex.cmd [STATUS] : Symbols root   : D:\Settings\desktop\project_apply\TestSolution\bin\Release
ssindex.cmd [STATUS] : Control system : TFS
ssindex.cmd [STATUS] : TFS program name: tf.exe
ssindex.cmd [STATUS] : TFS Label      : <N/A>
ssindex.cmd [STATUS] : Old path root  : <N/A>
ssindex.cmd [STATUS] : New path root  : <N/A>
--------------------------------------------------------------------------------

ssindex.cmd [STATUS] : Running... this will take some time...

정상적으로 소스 코드의 파일 다운로드 정보가 PDB 파일에 반영되었는지 다음과 같은 명령어를 통해서 확인이 가능합니다.

D:\...>srctool D:\Settings\desktop\project_apply\TestSolution\bin\Release\ConsoleApplication1.pdb

[d:\Settings\desktop\project_apply\TestSolution\ConsoleApplication1\Program.cs]
cmd: tf.exe view /version:74 /noprompt "$/TestSolution/TestSolution/ConsoleApplication1/Program.cs" /server:http://tfs2010:8080/tfs/defaultcollection /console >"D:\Settings\desktop\project_apply\MYSERVER\TestSolution\TestSolution\ConsoleApp
lication1\Program.cs\74\Program.cs"

D:\Settings\desktop\project_apply\TestSolution\bin\Release\ConsoleApplication1.pdb: 1 source files are indexed

즉, PDB를 로드한 디버거가 소스 코드가 필요하면 /server:http://tfs2010:8080... 으로 지정된 서버로 Program.cs 파일을 요청하는 것입니다. 이 때문에 소스 코드가 복사되어 있지 않은 어떠한 컴퓨터에서도 디버깅 시에 (바이너리가 빌드된 당시의) 소스 코드를 직접 다루는 것이 가능합니다. (Break Point까지 모두!)

6. Symbol 서버에 PDB 배포


디버거가 Source Server와 정상적으로 연동하기 위해서는 소스 코드가 인덱싱된 정보를 바이너리와 일치해서 가지고 있는 바로 그 PDB 파일들을 찾을 수 있어야 합니다. 대부분의 경우, PDB 파일을 바이너리와 함께 배포하면 쉽게 해결이 되지만 그래도 회사 차원에서 적절한 Symbol 서버를 구성하고 있는 것은 지난 버전들에 대한 PDB 파일까지 모두 충돌없이 보관되기 때문에 관리가 쉽다는 장점이 있습니다.

개인적으로, Symbol 서버와 Source Server의 올바른 구성과 Visual Studio의 "원격 디버깅"이 만나면 적어도 자사 제품에 한해서의 버그 수정에 대해서 엄청난 시간과 비용을 절약할 수 있다고 보기 때문에, 모든 상용 프로젝트라면 기본 구성 사항이라고 주장하고 싶을 정도입니다.

또한, 비싼 Team Foundation Server와 같은 형상관리 시스템이 그 값어치를 할 수 있는 활용 사례 중의 하나도 바로 "Symbol Server"와 "소스 서버"의 구성이겠고. (물론, CVS/Visual SourceSafe 등에도 Symbol/Source 서버 구성이 가능합니다.)

Symbol 서버와 Source 서버의 적당한 사용예는 마이크로소프트의 .NET Framework 소스 코드 디버깅을 들 수 있습니다. 지난 글에서도 이런 설명과 함께 TFS 2008 팀 빌드로 Symbol/Source 서버를 구성하는 예를 보여드렸는데요.

TFS Team Build + Source Server = 소스 코드 디버깅
; https://www.sysnet.pe.kr/2/0/600

TFS Team Build + Symbol Server
; https://www.sysnet.pe.kr/2/0/599

Symbol Server 생성
; https://www.sysnet.pe.kr/2/0/323

위의 내용에서 소스 서버 구성은 이미 5번에서 설명드렸고, Symbol 서버 구성은 바뀐 점이 없습니다. 단순하게 다음과 같이 추가해 주면 됩니다.

symstore add /r /f %SOLUTIONDIR%\bin\%BUILDCONFIG%\*.* /s \\web2008\TestSymbols /t "TestSolution" /v %GLOBAL_VERSION%

위의 "\\web2008\TestSymbols"는 제 경험으로 TFS 2010의 App Tier가 설치된 서버에 "http://tfs2010:8080/tfs"와 동일한 사이트에 "가상 디렉터리"로 추가해 주는 것을 권장합니다. 그래서, "http://tfs2010:8080/TestSymbols"와 같은 식의 경로로 접근할 수 있게 열어줍니다. (자세한 사항은 "Symbol Server 생성" 글을 참고합니다.)

아래는 제가 구성한 환경의 예입니다.

tfs_source_server_3.png

7. EXE/DLL에 대해 인증서로 코드 서명


마지막으로, 배포될 바이너리 파일들에 대한 서명을 해줄 수 있습니다. 이 작업은 코드 서명을 위한 인증서가 있는 경우에 한해서 해주시면 되고, 없는 경우에는 어쩔 수 없이 생략될 수 있습니다.

개인적으로, 왜 이 작업이 중요하냐고 생각하냐면?
코드 서명을 해줌으로써 바이너리 파일이 변조되지 않았다는 확인을 쉽게 할 수 있는 장점이 있기 때문입니다. 또한, 가끔 USB 등을 통한 모듈 전달시 정상적으로 복사되지 않은 문제들 역시 쉽게 잡아낼 수 있습니다.

예를 들어, 혹시나 바이너리가 변조된 것이 아닐까... 의심이 되는 상황이라면 signtool과 같은 도구를 이용해서 검증이 가능합니다.

아래는 테스트 인증서로 서명한 후 헥사 에디터에서 바이트 하나를 변경한 exe를 signtool로 확인했을 때의 결과입니다.

D:\...>signtool verify /pa .\TestSolution\bin\Release\ConsoleApplication1.exe
SignTool Error: WinVerifyTrust returned error: 0x80096010
        The digital signature of the object did not verify.

Number of errors: 1

아래에 보는 것처럼 Process Explorer에서도 가능한데,,, 수 차례 테스트를 해보면서 가끔씩 판단에 오류가 발생하는 것을 발견할 수 있었습니다. (signtool.exe가 가장 확실합니다.)

tfs_source_server_4.png
tfs_source_server_5.png

자, 그럼 마지막 단계이니 힘 좀 내볼까요? ^^
우선, 여기서는 예를 들기 위한 것이니 테스트 인증서를 사용해야 할 텐데, 이전에 만들어 둔 것으로 사용하겠습니다.

인증서 관련(CER, PVK, SPC, PFX) 파일 만드는 방법
; https://www.sysnet.pe.kr/2/0/863
; 예제 인증서 다운로드 (비밀 번호: 0000) 

위의 경로에서 다운로드 받은 mytest.pfx 파일을 "Local Machine" 영역의 "MY"에 인증서를 등록합니다. 이를 위해 "인증서 MMC 관리자"를 사용해야 하는데, 다음의 글을 참고하세요.

인증서 관리 - 인증서 MMC 관리자
; https://www.sysnet.pe.kr/2/0/395

그래서, 최종적으로 다음과 같이 서명을 해줄 수 있습니다.

signtool sign /v /sm /n "mytest" %SOLUTIONDIR%\bin\%BUILDCONFIG%\ConsoleApplication1.exe
signtool sign /v /sm /n "mytest" %SOLUTIONDIR%\bin\%BUILDCONFIG%\TestLibrary.dll

참고로, 인증서를 등록하지 않고 pfx 파일을 그대로 입력으로 받아서 서명하는 방법도 있습니다.

ActiveX 서명 과정 자동화 
; https://www.sysnet.pe.kr/2/0/327
(위와 같이 해주면, 배치 파일에 인증서의 비밀 번호가 노출된다는 문제 외에도 "작업 스케줄러"와 같은 곳에 배치 작업으로 등록되어 실행될 때 UI 팝업창이 하나 뜬 체로 더 이상 실행이 안되는 문제가 있습니다. 즉, 로그인 세션을 가지고 있는 경우에 한해서 정상적으로 배치 작업이 완료될 수 있습니다.)




자, 이렇게 해서 상용 프로젝트에서 가져야 할 프로젝트 빌드 관리에 대해서는 하나의 사이클을 돌아본 것 같습니다. 어떠세요? 여러분들의 프로젝트도 이 정도는 되어야 하지 않을까요? 처음 배치 파일을 구성할 때는 귀찮을 수 있지만 점점 프로젝트가 진행될수록 별도의 "빌드 서버"에서 위와 같은 배치 파일을 실행해 주는 것으로 테스트 서버까지 모두 자동 배포되는 것이 얼마나 시간 절약이 되는지를 체감할 수 있습니다. (가급적 개발자 PC보다는 빌드를 위한 PC를 하나 만들어두시길 권장합니다.)

사실, 지난 TFS 소개 글들은 위의 기능을 소개하기 위해 작성된 것이었습니다. 즉, TFS를 단순 Check-out/in 저장소로만 활용하기에는 너무 아깝다는 생각에서! ^^

TFS 소스 코드 관리 기능 (1) - Changeset 
; https://www.sysnet.pe.kr/2/0/899

TFS 소스 코드 관리 기능 (2) - Shelveset 
; https://www.sysnet.pe.kr/2/0/900

TFS 소스 코드 관리 기능 (3) - Label 
; https://www.sysnet.pe.kr/2/0/901

TFS 소스 코드 관리 기능 (4) - Branch 
; https://www.sysnet.pe.kr/2/0/903

TFS 2010의 소스 서버 수작업 구성 
; https://www.sysnet.pe.kr/2/0/902

* 첨부된 파일은 위의 예제 배치 파일과 VS 2010 솔루션을 포함하고 있습니다.



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/30/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2010-08-09 09시42분
[ryujh] 안녕하십니까? 처음으로 글을 남깁니다.

지금까지 SourceSafe 를 체크인/체크아웃 으로만 사용하다보니 제가 잘몰라서 SourceSafe 는 뭔가 부족하다는 느낌만 갖고 있었는데
이글에서 Visual SourceSafe 에서도 Symbol 서버 구성이 된다고 하셔서 TFS는 사용하지도 않았고 하니
SourceSafe 만으로도 TFS 처럼 위의 팀빌드 구성이 가능한지요? 그렇지 않다면 TFS 밖에 사용할 수 없는지.

감사합니다.
[guest]
2010-08-12 11시03분
넵. 동일하게 가능합니다. 위의 1번 ~ 7번 동작을 모두 할 수 있습니다.
kevin25

... 46  47  48  49  50  51  52  53  54  55  56  57  58  [59]  60  ...
NoWriterDateCnt.TitleFile(s)
12338정성태9/21/202012685오류 유형: 654. 우분투 설치 시 "CHS: Error 2001 reading sector ..." 오류 발생
12337정성태9/21/202014139오류 유형: 653. Windows - Time zone 설정을 바꿔도 반영이 안 되는 경우
12336정성태9/21/202017309.NET Framework: 942. C# - WOL(Wake On Lan) 구현
12335정성태9/21/202025979Linux: 31. 우분투 20.04 초기 설정 - 고정 IP 및 SSH 설치
12334정성태9/21/202010870오류 유형: 652. windbg - !py 확장 명령어 실행 시 "failed to find python interpreter"
12333정성태9/20/202011245.NET Framework: 941. C# - 전위/후위 증감 연산자에 대한 오버로딩 구현 (2)
12332정성태9/18/202014064.NET Framework: 940. C# - Windows Forms ListView와 DataGridView의 예제 코드파일 다운로드1
12331정성태9/18/202012819오류 유형: 651. repadmin /syncall - 0x80090322 The target principal name is incorrect.
12330정성태9/18/202014062.NET Framework: 939. C# - 전위/후위 증감 연산자에 대한 오버로딩 구현 [2]파일 다운로드1
12329정성태9/16/202016070오류 유형: 650. ASUS 메인보드 관련 소프트웨어 설치 후 ArmouryCrate.UserSessionHelper.exe 프로세스 무한 종료 현상
12328정성태9/16/202016145VS.NET IDE: 150. TFS의 이력에서 "Get This Version"과 같은 기능을 Git으로 처리한다면?
12327정성태9/12/202013794.NET Framework: 938. C# - ICS(Internet Connection Sharing) 제어파일 다운로드1
12326정성태9/12/202013273개발 환경 구성: 516. Azure VM의 Network Adapter를 실수로 비활성화한 경우
12325정성태9/12/202012643개발 환경 구성: 515. OpenVPN - 재부팅 후 ICS(Internet Connection Sharing) 기능이 동작 안하는 문제
12324정성태9/11/202013773개발 환경 구성: 514. smigdeploy.exe를 이용한 Windows Server 2016에서 2019로 마이그레이션 방법
12323정성태9/11/202012812오류 유형: 649. Copy Database Wizard - The job failed. Check the event log on the destination server for details.
12322정성태9/11/202014738개발 환경 구성: 513. Azure VM의 RDP 접속 위치 제한 [1]
12321정성태9/11/202011892오류 유형: 648. netsh http add urlacl - Error: 183 Cannot create a file when that file already exists.
12320정성태9/11/202013439개발 환경 구성: 512. RDP(원격 데스크톱) 접속 시 비밀 번호를 한 번 더 입력해야 하는 경우
12319정성태9/10/202013185오류 유형: 647. smigdeploy.exe를 Windows Server 2016에서 실행할 때 .NET Framework 미설치 오류 발생
12318정성태9/9/202012422오류 유형: 646. OpenVPN - "TAP-Windows Adapter V9" 어댑터의 "Network cable unplugged" 현상
12317정성태9/9/202015123개발 환경 구성: 511. Beats용 Kibana 기본 대시 보드 구성 방법
12316정성태9/8/202013242디버깅 기술: 170. WinDbg Preview 버전부터 닷넷 코어 3.0 이후의 메모리 덤프에 대해 sos.dll 자동 로드
12315정성태9/7/202015641개발 환경 구성: 510. Logstash - FileBeat을 이용한 IIS 로그 처리 [2]
12314정성태9/7/202015040오류 유형: 645. IIS HTTPERR - Timer_MinBytesPerSecond, Timer_ConnectionIdle 로그
12313정성태9/6/202015238개발 환경 구성: 509. Logstash - 사용자 정의 grok 패턴 추가를 이용한 IIS 로그 처리
... 46  47  48  49  50  51  52  53  54  55  56  57  58  [59]  60  ...