首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

CCNET + MSBuild + SVN 實時構建優化實戰:大型倉庫下的增量編譯策略

     編輯:關於.NET

SVN 倉庫增長至 10G+,自動構建速度急劇下降,微小提交需等待數小時。本文不介紹基礎搭建,專注優化實戰總結。

效能瓶頸分析

  1. SVN 倉庫過大,更新耗時極長
  2. 任何檔案更新觸發全專案編譯(含無需編譯的 Python 腳本等)
  3. 專案數量增多,全量編譯時間線性增長

前兩點可優化,第三點屬硬性限制。

優化策略一:加速 SVN 更新——縮小監控範圍

CCNET 透過 multi 型別 sourcecontrol 僅監控需編譯的專案路徑:

<sourcecontrol type="multi">
  <sourceControls>
    <svn>
      <trunkUrl>https://xxx/projectA</trunkUrl>
      <workingDirectory>x:\ccnet\svn\projectA</workingDirectory>
      <username>name</username> <password>pwd</password>
      <executable>x:\ccnet\Subversion\svn.exe</executable>
    </svn>
    <svn> ... projectB ... </svn>
    <svn> ... projectC ... </svn>
  </sourceControls>
</sourcecontrol>

效果:排除無需編譯的巨大非代碼目錄,更新速度質的飛躍。

優化策略二:減少不必要編譯——依賴感知的增量建置

需求:提交 FrameworkA 觸發 A/B/C 全編;提交 ProjectA 僅編 A。

方案:擴展 MSBuild 自定義 Task,讀取 CCNET 產生的 mods.xml 判斷變更專案,依預設依賴關係決定編譯目標。

1. CCNET 記錄變更清單

<prebuild>
  <modificationWriter>
    <filename>mods.xml</filename>
    <path>x:\ccnet\svn\build</path>
  </modificationWriter>
</prebuild>

mods.xml 格式:

<Modification>
  <Type>Modified</Type>
  <FileName>xxx.cs</FileName>
  <FolderName>/trunk/ProjectA/</FolderName>
  <ModifiedTime>...</ModifiedTime>
  <UserName>coderzh</UserName>
  <ChangeNumber>8888</ChangeNumber>
  <Comment>...</Comment>
</Modification>

2. MSBuild 定義專案路徑與依賴關係

<PropertyGroup>
  <FrameworkAPath>\trunk\Framework</FrameworkAPath>
  <ProjectAPath>\trunk\ProjectA</ProjectAPath> ...
</PropertyGroup>
<ItemGroup>
  <SvnFolder Include="$(FrameworkAPath);"> <ProjectName>FrameworkA</ProjectName> </SvnFolder>
  <SvnFolder Include="$(ProjectAPath);"> <ProjectName>ProjectA</ProjectName> </SvnFolder> ...
</ItemGroup>

<Target Name="FrameworkA">
  <MSBuild Projects="$(FrameworkAPath)\FrameworkA.sln" Properties="Configuration=Release"/>
  <CallTarget Targets="ProjectA;ProjectB;ProjectC" />
</Target>
<Target Name="ProjectA"> <MSBuild Projects="$(ProjectAPath)\ProjectA.sln" .../> </Target>
...

3. 自定義 Task:MyTask 核心邏輯

public class MyTask : Task {
    [Output] public ITaskItem[] Targets { get; set; }
    [Required] public ITaskItem[] Projects { get; set; }
    [Required] public string SvnModifyFile { get; set; }  // mods.xml
    [Required] public string StateFile { get; set; }      // CCNET state.xml

    public override bool Execute() {
        ReadLastBuildStatus();  // 讀取上次構建時間/結果
        if (!lastBuildResult || lastBuildTime.Day != DateTime.Now.Day) {
            SetAllTargetsToRun();  // 失敗或跨天 → 全量構建
        } else {
            SetTargetsToRunBySvnModify();  // 解析mods.xml決定增量目標
        }
        return true;
    }
    // 解析mods.xml獲取變更資料夾,匹配專案路徑,回傳Target清單
}

4. 整合至建置流程

<UsingTask AssemblyFile="CoderZh.MyTask.dll" TaskName="MyTask"/>
<Target Name="Build">
  <MyTask SvnModifyFile="$(SvnModifyFile)" StateFile="$(CCNetStateFile)" Projects="@(SvnFolder)">
    <Output TaskParameter="Targets" ItemName="TargetNames"/>
  </MyTask>
  <Message Text="Targets to be call:@(TargetNames)"/>
  <CallTarget Targets="@(TargetNames)"/>
</Target>

優化成果總結

  1. CCNET 僅更新需編譯專案代碼,大幅縮短 SVN 更新時間
  2. 實現「改哪編哪 + 依賴傳遞」,大幅縮小編譯範圍與時間
  3. 方案可擴展、可維護,歡迎社群討論更優方案

相關配置檔與代碼:mybuild.txt、ccnet.txt。出處:https://coderzh.cnblogs.com/

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved