CI 환경에서 Docker build 시 csproj의 Link 파일에 대한 빌드 오류
하나의 솔루션에 포함된 다중 프로젝트에서 소스 코드를 관리할 때, 가끔씩 공통 소스 코드는 하나의 프로젝트에 추가한 다음, 다른 프로젝트에서 LINK로 연결해서 쓰는 경우가 있습니다.
<ItemGroup>
<Compile Include="..\test_prj\MyStruct.cs" Link="MyStruct.cs" />
</ItemGroup>
이게 CI 빌드 환경의 dockerfile에서는 이런 식의 오류가 발생하는군요. ^^
...[생략]...
Step 10/16 : RUN dotnet build "current_prj.csproj" -c Release -o /app/build
---> Running in ad1801f1a0fd
Microsoft (R) Build Engine version 17.1.0+ae57d105c for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
CSC : error CS2001: Source file '/src/current_prj/../test_prj/MyStruct.cs' could not be found. [/src/current_prj/current_prj.csproj]
Build FAILED.
CSC : error CS2001: Source file '/src/current_prj/../test_prj/MyStruct.cs' could not be found. [/src/current_prj/current_prj.csproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:02.57
The command '/bin/sh -c dotnet build "current_prj.csproj" -c Release -o /app/build' returned a non-zero code: 1
Cleaning up project directory and file based variables
원래 프로젝트가 다음과 같은 구조인데,
./my/test_prj
./my/current_prj
./my/current_prj가 CI Build 디렉터리의 루트가 되는 상황에서 "COPY ../test_prj ./test_prj"와 같은 식으로 상위 my 디렉터리를 경유해 접근하고 싶어도 다음과 같은 식의 오류가 발생합니다.
Step 8/17 : COPY ./../test_prj ./test_prj
COPY failed: Forbidden path outside the build context: ../test_prj ()
어쩔 수 없습니다. 이 오류를 해결하고 싶다면, 2개의 프로젝트를 모두 포함하는 상위 디렉터리에서 CI 빌드 문맥을 시작해야 합니다.
또 다른 우회 방법으로는, 빌드 이벤트를 활용해 대상 파일을 미리 복사해 프로젝트에 포함하는 방법으로 처리를 해야 합니다.
<Project Sdk="Microsoft.NET.Sdk.Web">
// ...[생략]...
<Target Name="PreBuild" Condition="$(Configuration) == 'Debug'" BeforeTargets="PreBuildEvent">
<Exec Command="robocopy ..\test_prj . MyStruct.cs
exit 0" />
</Target>
</Project>
저렇게 Debug 시에만 복사하도록 지정하고, 평소 로컬에서 개발 시 소스 코드가 부지런히 반영되도록 한 다음, 아래의 설정을 포함시키면,
<ItemGroup Condition="$(Configuration) == 'Debug'">
<Compile Include="..\test_prj\MyStruct.cs" Link="MyStruct.cs" />
<Compile Remove="MyStruct.cs" />
</ItemGroup>
Debug 상황에서만 LINK 경로의 파일을 사용하게 하고, CI 빌드 시에는 로컬 경로의 소스 코드를 참조하게 만드는 것입니다. 그런데, 사실 이미 robocopy로 로컬에 복사를 했기 때문에 저렇게 굳이 LINK 연결을 보존해야 할 필요는 없습니다. ^^;
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]