Skip to content

Jenkins Pipeline 使用 MSBuild 发布 ASP.NET 项目

🏷️ Jenkins

在之前的博客(使用 Jenkins 自动编译 C# 项目Jenkins 发布.NET 项目)中有讲到使用 MSBuild 插件来编译和发布 ASP.NET 项目,这里使用 Pipeline 来实现同样的功能。

这里分成三步来实现。

  1. 更新代码

    为了获取 Git 的分支名,这里安装了 List Git Branches Parameter 插件,之后添加一个 List Git branches (and more) 类型的参数。
    这个插件获取的分支名是 refs/heads/BranchName 这种格式的,所以通过 "${BranchName}"[11..-1] 截取了字符串。
    之后通过 git 工具获取代码,如果设置了密码可以通过 credentialsId 参数设置,值为在 Jenkins 凭据中设置的凭据 ID。
    我这里使用的是 SSH Username with private key 类型的凭证,具体方法可以参考 这篇博客2.5 从版本库拉取 pipeline

  2. 创建发布配置文件

    这里使用通过 Pipeline 脚本创建一个发布用的配置文件。

  3. 编译并发布

    调用 msbuild 通过指定 PublishProfileDeployOnBuild 属性来编译和发布项目。
    关于 MSBuild 命令参数的详细情况可以参考 这篇博客

下面是具体的 Pipeline 脚本代码(示例代码均为 Windows 环境)。

groovy
pipeline {
    agent any
    stages {
        stage('Update Source') {
            steps{
                script {
                    echo "${BranchName}"
                    def branchName = "${BranchName}"[11..-1]
                    echo branchName
                    git branch: branchName, credentialsId: 'JiaJia', url: '${RepositoryUrl}'
                }
            }
        }
        stage("Create Pubxml") {
            steps{
                script {
                    write_file_path = "\\${ProjectName}\\Properties\\PublishProfiles\\publish_by_jenkins.pubxml"
                    file_contents = """<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>True</ExcludeApp_Data>
    <publishUrl>${PublishFolder}</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
  </PropertyGroup>
</Project>"""
                    writeFile file: write_file_path, text: file_contents, encoding: "UTF-8"
                    fileContents = readFile file: write_file_path, encoding: "UTF-8"
                    println fileContents
                }
            }
        }
        stage('Publish') {
            steps {
                bat """call "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\VsMSBuildCmd.bat"
                echo "building ${ProjectName}"
                msbuild "${env.WORKSPACE}\\${ProjectName}\\${ProjectName}.csproj" -p:Configuration=Release;Platform=AnyCPU;PublishProfile=publish_by_jenkins;DeployOnBuild=true
                """
            }
        }
    }
}

使用发布配置文件(.pubxml)的方式时遇到了一种会导致发布失败的情况。当项目引用了另一个可以发布的工程时,也会触发这个工程的发布,而且同样需要有参数中指定的发布配置文件(.pubxml),否则就会报如下错误。

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.targets(4364,5): error : PublishProfile 的值已设置为“publish_by_jenkins”,需要在“D:\Program Files (x86)\Jenkins\workspace\JenkinsJobName\ProjectName\Properties\PublishProfiles\publish_by_jenkins.pubxml”位置找到该文件,但并未找到。

有两种方案可以避免该错误,一是在对应的工程下再创建一个同名的配置文件,另一个是使用 _WPPCopyWebApplication 目标来发布项目。
下面是示例的脚本代码,第二步修改为 删除发布目录 处理。

groovy
pipeline {
    agent any
    stages {
        stage('Update Source') {
            steps{
                script {
                    echo "${BranchName}"
                    def branchName = "${BranchName}"[11..-1]
                    echo branchName
                    git branch: branchName, credentialsId: 'JiaJia', url: '${RepositoryUrl}'
                }
            }
        }
        stage('Remove Publish Folder') {
            steps {
                bat """if exist "${PublishFolder}" (
                    rmdir "${PublishFolder}" /s/q
                )"""
            }
        }
        stage('Publish') {
            steps {
                bat """call "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\Tools\\VsMSBuildCmd.bat"
                echo "building ${ProjectName}"
                msbuild "${env.WORKSPACE}\\${ProjectName}\\${ProjectName}.csproj" /t:Clean;Build;_WPPCopyWebApplication /p:Configuration=Release;Platform=AnyCPU;VisualStudioVersion=14.0;WebProjectOutputDir="${PublishFolder}"
                """
            }
        }
    }
}

另外还发现了一个比较奇怪的问题需要注意。

在使用 Visual Studio 2017 或 2019 的 开发人员命令提示工具 时,同样的 MSBuild 命令,但发布的文件有些区别:bin 目录下会生成 .config.pdb 文件。
使用 Visual Studio 2015 的 VS2015 开发人员命令提示VS2015 的 MSBuild 命令提示符 就不会发布这两种文件。