1

Visual Studio の C# ライブラリ プロジェクトを使用して、デプロイ アーティファクトとして必要な静的リソースを含めています。(私の場合、RoundhouseE と Octopus デプロイの組み合わせで実行される SQL ファイル)。慣例により、プロジェクト内のすべてのファイルは、「ビルド アクション」が「コンテンツ」、「出力ディレクトリにコピー」が「常にコピー」になるようにプロパティを設定する必要があります。

チームの誰かがファイルを追加したが、これらのプロパティを設定するのを忘れた場合、展開エラーが発生します。これは通常、内部環境で検出されますが、CI ビルドでこれを強制する方法を見つけたいと考えていました。

ビルドを失敗させるか、ビルド中にこれらのプロパティを MS Build タスクでオーバーライドする方法はありますか? 私はこれに間違った方法で取り組んでいますか? どんな提案も歓迎します。

4

3 に答える 3

3

プロジェクトファイルを解析し、に設定Contentせずにチェックする必要があります。別の方法があるとは思えません。CopyToOutputDirectoryAlways

これは、任意のスクリプト言語を使用して行うことができます。また、Microsoft.Build.Evaluation 名前空間のクラスを使用する小さな C# ツールを作成することもできます。これが可能な PowerShell 実装です。最も難しい部分は、正規表現を正しく取得することです。最初の 1 つはメタデータのないコンテンツをチェックし、2 つ目は CopyToOutputDirectory が「A」で始まらないコンテンツをチェックします (これは「常に」である必要があります。その単語全体を一致させる方法がわかりません)。

FindBadContentNodes.ps1 :

param([String]$inputDir)

Function FindBadContent()
{
  $lines = Get-Content $input
  $text = [string]::Join( "`n", $lines )
  if( $text -match "<Content Include.*/>" -Or
      $text -match "<Content Include.*`n\s*<CopyToOutputDirectory>[^A]\w*<.*" )
  {
    "Found file with bad content node"
    exit 1
  }
}

Get-ChildItem -Recurse -Include *.csproj -Path $inputDir | FindBadContent

MsBuild からこれを呼び出します。

<Target Name="FindBadContentNodes">
  <Exec Command="Powershell FindBadContentNodes.ps1 -inputDir path\to\sourceDir"/>
</Target>

ビルド中にこれらのプロパティについて言及するか、オーバーライドすることをお勧めします。私はそのような解決策には近づきません。問題を埋めて、正しいビルドを生成するために CI に依存しているだけなので、VS だけを使用するローカル ビルドは同じではありません。特にほとんどのCIシステムには、責任のある開発者に通知する方法があるため、ビルドを失敗させるImoの方が優れているため、修正を迅速に適用する必要があります。

もう 1 つの可能性は、CI に修正を適用させてから、変更をコミットして、少なくとも全員が正しいバージョンを使用できるようにすることです。

于 2014-03-10T09:49:10.033 に答える
2

IIRCには、.configファイルが常にコンテンツに設定され、出力ディレクトリにコピーされるように、デフォルトで特定のことを行うようにファイル拡張子を設定する方法がVisual Studioにあります。

したがって、.sql ファイル (およびこの方法で設定したい他のファイル) で同じことができます。簡単な検索でこれにたどり着きました:http://blog.andreloker.de/post/2010/07/02/Visual-Studio-default-build-action-for-non-default-file-types.aspx

関連する部分:

ファイルの種類の既定のビルド アクションは、レジストリで構成できます。ただし、レジストリを手動でハッキングする代わりに、はるかに優れたアプローチを使用します: pkgdef ファイル (pkgdef ファイルに関する良い記事)。本質的に、pkdef は、実際のレジストリの正しい場所に自動的にマージされるレジストリ キーと値を定義する .reg ファイルに似た構成ファイルです。pkgfile が削除されると、変更は自動的に取り消されます。したがって、何かを壊す危険を冒さずにレジストリを安全に変更できます。少なくとも、損傷を元に戻すのは簡単です。

最後に、ファイル タイプのデフォルトのビルド アクションを変更する方法の例を次に示します。

1: [$RootKey$\Projects{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\FileExtensions.spark]

2: "DefaultBuildAction"="Content" キーの Guid は、プロジェクトの種類を参照します。この場合、「{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}」は「C# プロジェクト」を意味します。プロジェクト タイプの GUID のかなり包括的なリストは、こちらにあります。Visual Studio 2010 を明示的にカバーしていませんが、Guid は現在のバージョンにも適用されます。ちなみに、C# ベースの MVC プロジェクトは実際には C# プロジェクト (および Web アプリケーション プロジェクト) であるため、ここではプロジェクト タイプとして C# を使用できます。Visual Basic の場合は、代わりに「{F184B08F-C81C-45F6-A57F-5ABD9991F28F}」を使用します。

$RootKey$ は、Visual Studio が構成を格納する実際のレジストリ キーを抽象化したものです: HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0_Config (注: このキーはいつでも上書きされる可能性があるため、手動で編集しないでください。 Visual Studio による)。

残りは一目瞭然です。このオプションは、.spark ファイルのデフォルトのビルド アクションを「コンテンツ」に設定するため、これらのファイルは公開プロセスに含まれます。

ここで行う必要があるのは、このテキストを拡張子 pkgdef のファイルに入れるか、%PROGRAMFILES(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\Extensions (64 ビット システムの場合) または%PROGRAMFILES(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\Extensions (32 ビット システムの場合) と Visual Studio は、次回の起動時に設定を自動的に読み込み、適用します。変更を元に戻すには、ファイルを削除するだけです。

最後に、.spark、.brail、.brailjs、および .less ファイルの C# および VB プロジェクトの「コンテンツ」デフォルト ビルド アクションを定義する、本番環境で使用される一連の pkgdef ファイルを添付しました。それらをダウンロードして、Extensions フォルダーのどこかに保存すれば、準備完了です。

著者はまた、これらすべてを実行するのに役立つユーティリティを作成したと述べています。

http://tools.andreloker.de/dbag

于 2014-03-10T15:55:20.663 に答える
0

@stijn の回答を拡張すると、正規表現を使用する代わりに、ネイティブ xml 解析を使用する方がはるかに簡単です。

これが私の提案したファイルです。ファイル名のみに正規表現を使用して、どのファイルを評価するかをカスタマイズする機能もサポートしています。

param([String]$Path, [string]$IncludeMatch, [switch]$AllowPreserve)

Function Test-BadContentExists
{
    param (
        [parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
        [Alias("FullName")]
        [string[]]$Path,
        [string]$IncludeMatch,
        [switch]$AllowPreserve
        )
  [xml]$proj = Get-Content -Path $Path
  $ContentNodes = ($proj | Select-Xml "//Content|//n:Content" -Namespace @{n='http://schemas.microsoft.com/developer/msbuild/2003'}).Node
  if (![string]::IsNullOrEmpty($IncludeMatch)) {
    $ContentNodes = $ContentNodes | Where-Object -Property Include -Match $IncludeMatch
  }
  #remove the always nodes
  $ContentNodes = $ContentNodes | Where-Object -Property CopyToOutputDirectory -ne 'Always'
  #optionally remove the preserve nodes
  if ($AllowPreserve) {
    $ContentNodes = $ContentNodes | Where-Object -Property CopyToOutputDirectory -ne 'PreserveNewest'
  }
  if($ContentNodes)
  {
    write-output "Found file with bad content node:"
    write-output ($ContentNodes | Select-Object Include,CopyToOutputDirectory | sort Include | Out-String)

    exit 1
  }
}

[hashtable]$Options = $PSBoundParameters
[void]$Options.Remove("Path")
Get-ChildItem -Recurse -Include *.csproj -Path $Path | Test-BadContentExists @Options

パラメータを指定して呼び出す:

<Target Name="FindBadContentNodes">
  <Exec Command="Powershell FindBadContentNodes.ps1 -inputDir path\to\sourceDir -IncludeMatch '^Upgrade.*\.(sql|xml)$'"/>
</Target>

代わりにビルド前のイベントを使用することになり、この ps1 ファイルをソリューション ディレクトリに配置して、複数のプロジェクトで使用できるようにしました。

echo "Build Dir: %cd%"
echo "Sol Dir: $(SolutionDir)"
echo "Proj Dir: '$(ProjectDir)"
echo.
Powershell -NoProfile -Command "& '$(SolutionDir)\FindBadContentNodes.ps1' -Path '$(ProjectDir)' -IncludeMatch '^Upgrade.*\.(sql|xml)$'"

ビルド出力の例:

1>  "Build Dir: C:\Source\RPS\MRM BI\MRMBI-Setup\MRMBI-Schema\bin\Debug"
1>  "Sol Dir: C:\Source\RPS\MRM BI\MRMBI-Setup\"
1>  "Proj Dir: 'C:\Source\RPS\MRM BI\MRMBI-Setup\MRMBI-Schema\"
1>  
1>  Found file with bad content node:
1>  
1>  Include                          CopyToOutputDirectory
1>  -------                          ----------------------
1>  Upgrades\V17.09\myfile1.sql                          
1>  Upgrades\V20.05\myfile2.sql      PreserveNewest       
1>  
于 2020-06-12T18:02:51.027 に答える