如果字符串存在于解决方案中的任何文件中,MBBuild 将失败
MBBuild fail if string exists in any file in the solution
如果解决方案中包含的任何文件中包含特定字符串,是否有办法让 MSBuild 失败?
在这种特定情况下,我们使用 DbUp 和 Ocotpus Deploy 以 .sql 文件的形式部署 SQL 脚本。在我们的部署过程中,我们专门直接针对每个数据库。有时,会创建包含 USE [devDatabase]
的脚本。如果此字符串存在于作为构建一部分的任何 .sql 文件中,我希望构建失败。
这可能吗?
一个可能的解决方案是使用额外的 Octopus 步骤来进行此检查,如果存在类似文件则部署失败。
只是一个 PowerShell 脚本步骤:
$Files = @(Get-ChildItem -Path C:\Projects\SQL -Filter *.sql -Recurse | Select-String -Pattern "use " | group path | select name)
if ($Files.length -eq 0) {
write-host "no SQL files with 'USE'"
} else {
foreach ($file in $Files) {
write-host $file.Name
}
Exit 1
}
鉴于您的下一步具有以下条件,它应该会失败:
这是一个 MsBuild 解决方案,将其添加到项目文件中:
<Target Name="CheckSqlFiles" BeforeTargets="Build">
<ItemGroup>
<SqlFiles Include="$(MSBuildThisFileDirectory)**\*.sql" />
</ItemGroup>
<MSBuild Projects="$(MSBuildThisFile)" Targets="ErrorIfDevDataBaseUsed" Properties="SqlFileToCheck=%(SqlFiles.Identity)" />
</Target>
<Target Name="ErrorIfDevDataBaseUsed">
<ReadLinesFromFile File="$(SqlFileToCheck)">
<Output TaskParameter="Lines" ItemName="Sql" />
</ReadLinesFromFile>
<Error Text="Found devDatabase in $(SqlFileToCheck)"
Condition="$([System.String]::Copy('%(Sql.Identity)').Contains('USE [devDatabase]'))" />
</Target>
它将 运行 在 Build 目标之前。还有许多其他目标,所以如果这个目标太迟或太早,运行 msbuild with the /v:d flag 并在之前(或之后,使用 AfterTargets=...
)找出你想要它的目标运行。如果它很慢,或者您更喜欢 PowerShell,您当然可以应用相同的原则并在 CheckSqlFiles 目标中调用 Powershell,例如使用<Exec command="PowerShell checksql.ps1 $(MsBuildThisFileDirectory)"/>
其中 checksql.ps1 类似于 AlexM 的答案,但将目录作为参数添加到 运行。
正如@AlexM 所展示的那样,完全可以使用 Octopus 步骤进行此检查,但似乎 Octopus 并不是进行此类检查的最佳场所。
我的意思是,有没有您想按原样部署脚本的情况?
如果答案是否定的,那么此检查属于您的构建服务器(TeamCity、Jenkins 等)并且构建应该失败如果脚本包含您的字符串正在寻找,并且您根本不应该将工件发送到 Octopus - 这意味着它无论如何都无法部署。
有很多方法可以在构建服务器上执行此操作...使用 Powershell、MSBuild(正如@stijn 指出的那样)等
您可以编写一个单元测试来读取所有嵌入的 SQL 文件并检查该语句。
也可以看看https://github.com/andrewabest/Conventional,可以作为开始类似测试的基础。
如果解决方案中包含的任何文件中包含特定字符串,是否有办法让 MSBuild 失败?
在这种特定情况下,我们使用 DbUp 和 Ocotpus Deploy 以 .sql 文件的形式部署 SQL 脚本。在我们的部署过程中,我们专门直接针对每个数据库。有时,会创建包含 USE [devDatabase]
的脚本。如果此字符串存在于作为构建一部分的任何 .sql 文件中,我希望构建失败。
这可能吗?
一个可能的解决方案是使用额外的 Octopus 步骤来进行此检查,如果存在类似文件则部署失败。
只是一个 PowerShell 脚本步骤:
$Files = @(Get-ChildItem -Path C:\Projects\SQL -Filter *.sql -Recurse | Select-String -Pattern "use " | group path | select name)
if ($Files.length -eq 0) {
write-host "no SQL files with 'USE'"
} else {
foreach ($file in $Files) {
write-host $file.Name
}
Exit 1
}
鉴于您的下一步具有以下条件,它应该会失败:
这是一个 MsBuild 解决方案,将其添加到项目文件中:
<Target Name="CheckSqlFiles" BeforeTargets="Build">
<ItemGroup>
<SqlFiles Include="$(MSBuildThisFileDirectory)**\*.sql" />
</ItemGroup>
<MSBuild Projects="$(MSBuildThisFile)" Targets="ErrorIfDevDataBaseUsed" Properties="SqlFileToCheck=%(SqlFiles.Identity)" />
</Target>
<Target Name="ErrorIfDevDataBaseUsed">
<ReadLinesFromFile File="$(SqlFileToCheck)">
<Output TaskParameter="Lines" ItemName="Sql" />
</ReadLinesFromFile>
<Error Text="Found devDatabase in $(SqlFileToCheck)"
Condition="$([System.String]::Copy('%(Sql.Identity)').Contains('USE [devDatabase]'))" />
</Target>
它将 运行 在 Build 目标之前。还有许多其他目标,所以如果这个目标太迟或太早,运行 msbuild with the /v:d flag 并在之前(或之后,使用 AfterTargets=...
)找出你想要它的目标运行。如果它很慢,或者您更喜欢 PowerShell,您当然可以应用相同的原则并在 CheckSqlFiles 目标中调用 Powershell,例如使用<Exec command="PowerShell checksql.ps1 $(MsBuildThisFileDirectory)"/>
其中 checksql.ps1 类似于 AlexM 的答案,但将目录作为参数添加到 运行。
正如@AlexM 所展示的那样,完全可以使用 Octopus 步骤进行此检查,但似乎 Octopus 并不是进行此类检查的最佳场所。
我的意思是,有没有您想按原样部署脚本的情况?
如果答案是否定的,那么此检查属于您的构建服务器(TeamCity、Jenkins 等)并且构建应该失败如果脚本包含您的字符串正在寻找,并且您根本不应该将工件发送到 Octopus - 这意味着它无论如何都无法部署。
有很多方法可以在构建服务器上执行此操作...使用 Powershell、MSBuild(正如@stijn 指出的那样)等
您可以编写一个单元测试来读取所有嵌入的 SQL 文件并检查该语句。
也可以看看https://github.com/andrewabest/Conventional,可以作为开始类似测试的基础。