3

CI プロセスが整っておらず (オーバーナイト ビルドでさえありません)、大雑把な開発プラクティスがいくつかあるチームに参加したばかりです。それを変えたいという願望があるので、私は今、オーバーナイト ビルドの作成を任されています。この一連の記事に沿って、次のことを行いました。すべてのプロジェクト (一部の Web アプリ、Web サービス、一部の Windows サービス、およびコマンド ライン実行可能ファイルにコンパイルするツールの組み合わせ) を含むマスター ソリューションを作成します。製品を自動的にビルド、パッケージ化、デプロイする MSBuild スクリプトを作成しました。ワンクリックですべてを実行する.cmdファイルを作成しました。これらすべての一環として、私が今達成しようとしているタスクは次のとおりです。

チームは現在、web.config および app.config ファイルをソース管理の外部に保持し、web.template.config および app.template.config と呼ばれるソース管理ファイルに入れるという慣習を持っています。その意図は、開発者が .template.config ファイルを .config にコピーしてすべての標準構成値を取得し、.config ファイルの値を編集して、ローカルでの開発/テストに必要なものにできるようにすることです。 . 明らかな理由から、.template.config ファイルの名前を .config に変更するプロセスを自動化したいと考えています。これを行う最良の方法は何ですか?

名前を変更する必要があるすべての個々のファイルをスクリプト内で規定することなく、ビルド スクリプト自体でこれを行うことは可能ですか (新しいプロジェクトがソリューションに追加されるたびにスクリプトのメンテナンスが必要になります)。それとも、スクリプトから実行するだけのバッチ ファイルを作成する必要があるのでしょうか。

さらに、このプロセス全体を不要にする、私が提案できるより良い開発ソリューションはありますか?

4

2 に答える 2

6

アイテム グループ、ターゲット、およびコピー タスクについて多くのことを読んだ後、必要なことを実行する方法がわかりました。

<ItemGroup>
    <FilesToCopy Include="..\**\app.template.config">
        <NewFilename>app.config</NewFilename>
    </FilesToCopy>
    <FilesToCopy Include="..\**\web.template.config">
        <NewFilename>web.config</NewFilename>
    </FilesToCopy>
    <FilesToCopy Include"..\Hibernate\hibernate.cfg.template.xml">
        <NewFilename>hibernate.cfg.xml</NewFilename>
    </FilesToCopy>
</ItemGroup>

<Target Name="CopyFiles"
        Inputs="@(FilesToCopy)"
        Outputs="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFilename)')">
    <Message Text="Copying *.template.config files to *.config"/>
<Copy SourceFiles="@(FilesToCopy)"
      DestinationFiles="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFilename)')"/>



コピーするファイルを含むアイテム グループを作成します。** 演算子は、指定された名前を持つすべてのファイルを見つけるために、ディレクトリ ツリー全体を再帰的に検索するように指示します。次に、"NewFilename" という名前の各ファイルにメタデータを追加します。これは、各ファイルの名前を変更するものです。

このスニペットは、app.template.config という名前のディレクトリ構造にすべてのファイルを追加し、新しいファイルに app.config という名前を付けることを指定します。

<FilesToCopy Include="..\**\app.template.config">
    <NewFilename>app.config</NewFilename>
</FilesToCopy>

次に、すべてのファイルをコピーするターゲットを作成します。このターゲットは最初は非常に単純で、常にファイルをコピーして上書きするために Copy タスクを呼び出すだけでした。コピー操作のソースとして FilesToCopy 項目グループを渡します。出力ファイル名、NewFilename メタデータ、既知のアイテム メタデータを指定するために変換を使用します。

次のスニペットは、たとえば、ファイル c:\Project\Subdir\app.template.config を c:\Project\Subdir\app.config に変換し、前者を後者にコピーします。

<Target Name="CopyFiles">
    <Copy SourceFiles="@(FilesToCopy)"
          DestinationFiles="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFileName)')"/>
</Target>

しかしその後、開発者は、スクリプトが実行されるたびにカスタマイズされた web.config ファイルが上書きされることを好まないかもしれないことに気付きました。ただし、リポジトリの web.template.config が変更され、コードに必要な新しい値が含まれている場合、開発者はおそらくローカル ファイルを上書きする必要があります。「Exist()」関数を使用して Copy 属性「SkipUnchangedFiles」を true に設定するなど、さまざまな方法でこれを試しましたが、役に立ちませんでした。

これに対する解決策は、段階的に構築することでした。これにより、app.template.config が新しい場合にのみファイルが上書きされるようになります。ファイルの名前をターゲット入力として渡し、新しいファイル名をターゲット出力として指定します。

<Target Name="CopyFiles"
        Input="@(FilesToCopy)"
        Output="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFileName)')">
      ...
</Target>

これには、現在の出力が入力に対して最新であるかどうかを確認するためのターゲット チェックがあります。そうでない場合、つまり、特定の .template.config ファイルに対応する .config ファイルよりも新しい変更がある場合、既存の web.config に web.template.config がコピーされます。そうしないと、開発者の web.config ファイルがそのまま残り、変更されません。指定されたファイルのいずれもコピーする必要がない場合、ターゲットは完全にスキップされます。クリーンなリポジトリのクローンの直後に、すべてのファイルがコピーされます。

MSBuild を使い始めたばかりで、その強力な機能に驚いているため、上記は満足のいく解決策であることがわかりました。私が気に入らない唯一のことは、まったく同じ変換を 2 か所で繰り返さなければならなかったことです。どんな種類のコードも複製するのは嫌いですが、これを避ける方法がわかりませんでした。誰かがヒントを持っていれば、それは大歓迎です。また、これを必要とする開発プラクティスは完全に最悪だと思いますが、これはその最悪の要因を軽減するのに役立ちます。

于 2012-12-03T19:13:41.643 に答える
1

簡単な答え:
はい、これを自動化できます (また自動化する必要があります)。MSBuild Move タスクを使用してファイルの名前を変更できるはずです。

長い回答:
手動プロセスから自動プロセスに変更したいという要望があるのは素晴らしいことです。通常、自動化しない本当の理由はほとんどありません。ビルド スクリプトは、ビルドとデプロイが実際にどのように機能するかについての生きたドキュメントとして機能します。私の謙虚な意見では、優れたビルド スクリプトは静的なドキュメントよりもはるかに価値があります (ただし、ドキュメントを作成する必要がないと言っているわけではありません。結局のところ、ドキュメントは相互に排他的ではありません)。ご質問は個別に対応させていただきます。

これを行う最良の方法は何ですか?

これらのファイルに保存されている構成を完全に理解しているわけではありませんが、その構成の多くは開発チーム全体で共有できると思います。

次の質問を提起することをお勧めします。

  • 開発者固有の設定はどれですか?
  • 設定を共有できるように、ローカルの開発者マシンを標準化する方法はありますか?

名前を変更する必要があるすべての個々のファイルをスクリプト内で規定することなく、ビルド スクリプト自体でこれを行うことは可能ですか?

はい、MSBuild Move taskをご覧ください。ファイルの名前を変更するために使用できるはずです。

...新しいプロジェクトがソリューションに追加されるたびに、スクリプトのメンテナンスが必要になるのはどれですか?

これは避けられません。ビルド スクリプトは、ソリューションと共に進化する必要があります。これを事実として受け入れ、ビルド スクリプトを変更する時間を見積もりに含めてください。

さらに、このプロセス全体を不要にする、私が提案できるより良い開発ソリューションはありますか?

私はすべての要件を認識しているわけではないので、非常に具体的なものを推奨することは困難です. 私はこれを提案すると言うことができます:

  • ソリューションの共有ビルド スクリプトを作成する
  • 手動タスクを可能な限り自動化する (合理的な範囲内で)
  • 何かを自動化するのに苦労している場合は、再考/再設計が必要な領域の指標である可能性があります
  • チーム メンバーがビルドの仕組みを理解し、自分で変更できるようにしてください。ビルドを「所有」してボトルネックにならないようにしてください。

ビルド スクリプトなしから完全自動化への移行は、一晩でできるプロセスではないことに注意してください。辛抱強く、まず最も苦痛を引き起こしている領域を自動化することに集中してください。

あなたの質問のいずれかを誤解している場合は、お知らせください。回答を更新します。

于 2012-10-18T17:01:49.363 に答える