工具
MSBuild v14
Visual Studio 2013
在Windows Server 2012上运行的Jenkins v2.111
Git(本地文件服务器上的裸仓库)
Windows Batch
我的目标
使用MSBuild构建一个c#Visual Studio项目,该项目从项目AssemblyInfo.cs中提取主要和次要版本号,以便在构建期间使用。构建将产生类似1.2。$ BUILD_NUMBER的东西,产生类似1.2.121,1.2.122,1.2.123等等。一旦用户选择“发布”'在构建中,文件夹名称中具有正确版本的clickonce部署将复制到其目标目标,并将标记应用于Git存储库。
管道示例
以下是正在进行的工作'我所做的一切。欢迎提出任何改进建议。对于那些想知道为什么我要将代码库复制到临时文件夹的人。我在Jenkins中使用多分支作业,并且自动生成的文件夹非常长!这给了我错误,我的文件名,项目名称或两者都太长(因为整个路径高于255左右的字符长度)。所以解决这个问题的唯一方法就是复制内容,这样构建和发布就可以了。
pipeline {
agent none
stages {
stage ('Checkout'){
agent any
steps
{
checkout scm
}
}
stage ('Nuget Restore'){
agent any
steps
{
bat 'nuget restore "%WORKSPACE%\\src\\Test\\MyTestSolution.sln"'
}
}
stage('Build Debug') {
agent any
steps
{
bat "xcopy %WORKSPACE%\\src\\* /ey d:\\temp\\"
bat "\"${tool 'MSBuild'}\" d:\\temp\\Test\\MyTestSolution.sln /p:Configuration=Debug /target:publish /property:PublishUrl=d:\\temp\\ /p:OutputPath=d:\\temp\\build\\ /p:GenerateBootstrapperSdkPath=\"C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v8.1A\\Bootstrapper\" /p:VersionAssembly=1.0.$BUILD_NUMBER /p:ApplicationVersion=1.0.$BUILD_NUMBER"
}
}
stage('Deploy to Dev'){
agent none
steps {
script {
env.DEPLOY_TO_DEV = input message: 'Deploy to dev?',
parameters: [choice(name: 'Deploy to dev staging area?', choices: 'no\nyes', description: 'Choose "yes" if you want to deploy this build')]
}
}
}
stage ('Deploying to Dev')
{
agent any
when {
environment name: 'DEPLOY_TO_DEV', value: 'yes'
}
steps {
echo 'Deploying debug build...'
}
}
stage ('Git tagging')
{
agent any
steps
{
bat 'd:\\BuildTargets\\TagGit.bat %WORKSPACE% master v1.0.%BUILD_NUMBER%.0(DEV) "DEV: Build deployed."'
}
}
}
}
目前,我已在上述脚本中对主要版本和次要版本进行了硬编码。我想从AssemblyInfo.cs中提取这些值,以便开发人员可以从那里控制它而无需编辑Jenkins文件。有任何建议/最佳实践来实现这一目标吗?
因为我正在为winforms应用程序进行clickonce部署,所以我必须使用MSBuild的VersionAssembly和ApplicationVersion交换机来传递版本。这似乎有助于在MSBuild发布文件时正确标记文件夹。我的设置中是否遗漏了哪些内容会使这些开关无效并使生活更简单?
我的管道中的最后一个操作是触发.bat文件以将标记添加回存储库的主分支。这是我需要使管道脚本可以访问主要版本和次要版本的另一个原因。
用于编辑AssemblyInfo.cs的MSBuild目标
此代码来自此处:http://www.lionhack.com/2014/02/13/msbuild-override-assembly-version/
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CompileDependsOn>
CommonBuildDefineModifiedAssemblyVersion;
$(CompileDependsOn);
</CompileDependsOn>
</PropertyGroup>
<Target Name="CommonBuildDefineModifiedAssemblyVersion" Condition="'$(VersionAssembly)' != ''">
<!-- Find AssemblyInfo.cs or AssemblyInfo.vb in the "Compile" Items. Remove it from "Compile" Items because we will use a modified version instead. -->
<ItemGroup>
<OriginalAssemblyInfo Include="@(Compile)" Condition="%(Filename) == 'AssemblyInfo' And (%(Extension) == '.vb' Or %(Extension) == '.cs')" />
<Compile Remove="**/AssemblyInfo.vb" />
<Compile Remove="**/AssemblyInfo.cs" />
</ItemGroup>
<!-- Copy the original AssemblyInfo.cs/.vb to obj\ folder, i.e. $(IntermediateOutputPath). The copied filepath is saved into @(ModifiedAssemblyInfo) Item. -->
<Copy SourceFiles="@(OriginalAssemblyInfo)"
DestinationFiles="@(OriginalAssemblyInfo->'$(IntermediateOutputPath)%(Identity)')">
<Output TaskParameter="DestinationFiles" ItemName="ModifiedAssemblyInfo"/>
</Copy>
<!-- Replace the version bit (in AssemblyVersion and AssemblyFileVersion attributes) using regular expression. Use the defined property: $(VersionAssembly). -->
<Message Text="Setting AssemblyVersion to $(VersionAssembly)" />
<RegexUpdateFile Files="@(ModifiedAssemblyInfo)"
Regex="Version\("(\d+)\.(\d+)(\.(\d+)\.(\d+)|\.*)"\)"
ReplacementText="Version("$(VersionAssembly)")"
/>
<!-- Include the modified AssemblyInfo.cs/.vb file in "Compile" items (instead of the original). -->
<ItemGroup>
<Compile Include="@(ModifiedAssemblyInfo)" />
</ItemGroup>
</Target>
<UsingTask TaskName="RegexUpdateFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Regex ParameterType="System.String" Required="true" />
<ReplacementText ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Core" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Text.RegularExpressions" />
<Using Namespace="Microsoft.Build.Framework" />
<Using Namespace="Microsoft.Build.Utilities" />
<Code Type="Fragment" Language="cs">
<![CDATA[
try {
var rx = new System.Text.RegularExpressions.Regex(this.Regex);
for (int i = 0; i < Files.Length; ++i)
{
var path = Files[i].GetMetadata("FullPath");
if (!File.Exists(path)) continue;
var txt = File.ReadAllText(path);
txt = rx.Replace(txt, this.ReplacementText);
File.WriteAllText(path, txt);
}
return true;
}
catch (Exception ex) {
Log.LogErrorFromException(ex);
return false;
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
Git标记
启动此bat文件并传递用于创建标记并将标记推送到定义的存储库的值。
echo off
set gitPath=%1
set gitBranchName=%2
set gitTag=%3
set gitMessage=%4
@echo on
@echo Adding tag to %gitBranchName% branch.
@echo Working at path %gitPath%
@echo Tagging with %gitTag%
@echo Using commit message: %gitMessage%
d:
cd %gitPath%
git checkout %gitBranchName%
git pull
git tag -a %gitTag% -m %gitMessage%
git push origin %gitBranchName% %gitTag%
如果还有其他任何有助于简化或改进整体工作流程的淘金网,那么也欢迎这些!
答案 0 :(得分:3)
我最近遇到了与创建Windows脚本相同的问题。
for /f delims^=^"^ tokens^=2 %%i in ('findstr "AssemblyFileVersion" %1\\AssemblyFile.cs') DO SET VERSION=%%i
此脚本从AssemblyInfo.cs中提取版本号并将其放在变量中,以便以后可以用它来标记提交(尽管在同一步骤中):
CALL FindAssemblyVersion .\Properties
git tag %VERSION%
git push http://%gitCredentials%@url:port/repo.git %VERSION%
答案 1 :(得分:0)
并非完全来自汇编文件,而是一个非常方便的解决方法,可在与Jenkins一起使用并使用批处理(或powershell
)命令时从DLL获取文件版本:
转到DLL所在的目录[CD Foo / Bar]
FOR /F "USEBACKQ" %F IN (`powershell -NoLogo -NoProfile -Command (Get-Item "myApi.dll").VersionInfo.FileVersion`) DO (SET fileVersion=%F )
echo File version: %fileVersion%