# 安装 SVN Server

SVN Server

# 创建仓库

在控制面板创建一个仓库与 User 后配置完成

C:\Program Files\VisualSVN Server\bin\VisualSVN Server.msc

# 安装 Tortoise SVN

Tortoise SVN

# Checkout 仓库

从远程端 Checkout 刚才生成的仓库,并将要自动构建的工程放入其中。Commit 后配置完成

# 安装 Jenkins

  • jenkins
  • JDK
    按照 Jenkins 需要 Java17 - Java21

建议进行后续步骤的乱码解决步骤之后再进行以后的操作

# 额外插件

插件商城安装 SubVersionMSBuildMSTest

# 配置 Token

导航至 Dashboard - Manage Jenkins - User - 选择当前用户 - Security ,创建一个 Token,记录生成的 Token 与 Token 名称

# 配置 MSBuild

  1. 导航至 Dashboard - Manage Jenkins - Tools
  2. 滚动至 MSBuild 安装 ,点击 MSBuild 安装 ,点击新建
  3. 输入可用名称,此名称没有要求。取消勾选 Install automatically ,在新增的框中添加本机 MSBuild.exe 绝对路径

MSBuild.exe 位于 Visual Studio 的安装目录中
例如:D:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe

  1. 点击底部的 Save 按钮

# 新建持续集成项目

  1. 导航至 Dashboard - 新建Item
  2. 输入一个项目名称,并选择 FreeStyle project
  3. 由于我们按照了 SVN 扩展,在源码管理一栏能看到 Subversion 选项
  4. 填入 SVN 仓库的地址
    20250403162404.png
  5. Credentials 如果之前没有添加过,请点击下方的添加按钮,填入 SVN 账户与密码,之后在这里选中刚添加的用户。
  6. 滚动至 Triggers 部分,选择 触发远程构建 ,并在框内填入之前记录的 Token 名称
  7. 滚动至 Build Steps 部分,点击增加构建步骤,选择 Execute Windows batch command ,在下方框中填入,其中 cd 后的路径需要按需填写
1
2
cd trunk\WebApp1\
dotnet restore

dotnet restore 用于还原 Nuget 包

  1. 选择 Build a Visual Studio project or solution using MSBuild
  2. 选择上一步中添加的 MSBuild 名称 ,在 Project File 填入 sln 文件的相对路径
    20250403163223.png
  3. 如果需要构建完成后启动,可以在再添加一个新的步骤
1
2
cd trunk\WebApp1\WebApp1\bin\Debug\net9.0
start WebApp1.exe

start 指令用于启动项目,不阻塞脚本运行

  1. 点击底部的 Save 按钮
  2. 点击左侧的 Build Item 测试构建过程是否出错

# 修复控制台输出的中文乱码

此步骤需要更改 Jenkins 的运行方式从 Windows 服务改为终端启动,且会丢失原始的配置,若不能满足需求还请自行寻找解决方案。

  1. 通过任务管理器的服务一栏,终止 Jenkins 服务
    20250403163759.png
  2. 打开 Jenkins 安装路径

C:\Program Files\Jenkins

  1. 新建脚本,填入以下内容,并更改文件扩展名为 .bat
1
java -Dfile.encoding=UTF-8 -jar Jenkins.war
  1. 使用管理员权限启动脚本,并重新配置 Jenkins

# 自动构建

# 定时构建

Jenkins 会定时拉取 SVN 版本号,当版本号变化时,会触发一次构建

# 配置

Triggers - Poll SCM - 日程表 输入 corn 表达式

# SVN 钩子自动构建

# 配置 SVN post-commit 钩子

  1. 打开 SVN 的创建仓库路径

D:\Repositories\TestRepo

  1. 打开 hook 文件夹,在此处放置 post-commit 脚本来实现提交后通知 Jenkins 进行构建。脚本文件可以是 .bat .vbs .exe

# 请求步骤

  1. {jenkinsUrl}/crumbIssuer/api/json 发送请求
    • 添加鉴权 Header, key = Authorization, Value = Base64 ( {username}:{token} )
    • Json 解析返回结果,获取 crumbRequestFieldcrumb
    • 记录 Cookie
  2. {jenkinsUrl}/job/{jobName}/build?token={tokenName} 发送请求
    • 添加鉴权 Header, key = crumbRequestField , Value = crumb
    • 添加上一步获取的 Cookie
    • 200 返回码为成功,前往 Jenkins 查看是否创建了构建任务
# C# 示例脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using Newtonsoft.Json.Linq;
using System;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
static void Main(string[] args)
{
// 从 app.config 中读取配置
string jenkinsUrl = ConfigurationManager.AppSettings["JenkinsUrl"];
string jobName = ConfigurationManager.AppSettings["JobName"];
string token = ConfigurationManager.AppSettings["Token"];
string username = ConfigurationManager.AppSettings["Username"];
string tokenName = ConfigurationManager.AppSettings["TokenName"];

try
{
using (HttpClientHandler handler = new HttpClientHandler())
using (HttpClient client = new HttpClient(handler))
{
handler.CookieContainer = new System.Net.CookieContainer();

var byteArray = System.Text.Encoding.ASCII.GetBytes($"{username}:{token}");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

// 获取 crumb
HttpResponseMessage crumbResponse = client.GetAsync($"{jenkinsUrl}/crumbIssuer/api/json").Result;
crumbResponse.EnsureSuccessStatusCode();
dynamic crumbData = JObject.Parse(crumbResponse.Content.ReadAsStringAsync().Result);
string crumb = crumbData.crumb;
string crumbRequestField = crumbData.crumbRequestField;

var request = new HttpRequestMessage(HttpMethod.Post, $"{jenkinsUrl}/job/{jobName}/build?token={tokenName}");
request.Headers.Add(crumbRequestField, crumb);

var cookies = handler.CookieContainer.GetCookies(new Uri(jenkinsUrl));
foreach (System.Net.Cookie cookie in cookies)
{
request.Headers.Add("Cookie", $"{cookie.Name}={cookie.Value}");
}

HttpResponseMessage buildResponse = client.SendAsync(request).Result;
buildResponse.EnsureSuccessStatusCode();

Console.WriteLine("Jenkins build triggered successfully");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
Environment.ExitCode = -1;
}
}
}

使用 Fody 生成单一文件后,放置在 hook 文件夹中并改名为 post-commit.exe
Commit 后,检查 Jenkins 是否开始构建任务