7

ステージング サーバーへのビルド プロセスを自動化しようとしていますが、かなりマイナーではありますが問題が発生しました。VS2010 に組み込まれた発行機能を使用して Subversion にコミットすると、サード パーティのアプリ (Beanstalk) が更新されたファイルを自動的にプルし、FTP でステージング サーバーに送信します。

私たちが遭遇した問題は、次の選択肢しかないように見えることです。

  • (2 つの悪の小さい方) 「一致するファイルをローカル コピーで置き換える」を使用することを選択した場合、これはうまく機能しますが、1 つの例外があります。このオプションは、プロジェクトから削除されたファイルを削除しません。これは、古くからの空っぽのファイルのジャンクおよび/またはセキュリティの問題につながります.
  • 「公開前にすべての既存のファイルを削除する」を選択すると、Subversion が更新の追跡などに使用する .SVN 隠しフォルダーを含むフォルダー構造全体が削除されます。この自動化の仲介者であるローカル SVN 環境を実際に破壊します。

私の質問: これに対する簡単な回避策はありますか、それとも私たちが見落としているまったく別の展開オプションはありますか (誰が/何を/いつ展開したかを追跡したいので、VS からサーバーに直接公開したくありません) )? 私が遭遇した唯一のことは、公開する前にファイルの内容を手動で削除し、フォルダー構造をそのままにしてから、「一致するファイルをローカルコピーに置き換える」で展開することです。残念ながら、これは「自動化」という言葉にまったく新しい意味をもたらします。

これを達成するための最善の方法についてのアイデアはありますか?

4

4 に答える 4

4

ビルドや Subversion への公開など、自動化したいタスクには NAnt などの使用を検討することをお勧めします。これは、Web アプリケーション プロジェクトのビルド ファイルのほとんどです。MVC の場合は異なる場合があります。もしそうなら、これを出発点として使用できると確信しています。私は決してNAntの専門家ではないので、いくつかの欠陥があるかもしれませんが、これは間違いなく私にとってはうまくいっています.

公開したい各 .csproj ファイルに PublishToFileSystem ターゲットを追加する必要がありました。そのソースはここにあります

ビルドファイルも Pastebin で入手可能

<?xml version="1.0"?>
<project name="deploy" default="all">
    <property name="nant.settings.currentframework" value="net-4.0" />  
    <!-- Any of these can be passed through the command line -->
    <property name="sourceDirectory" value="${project::get-base-directory()}" />
    <property name="publishDirectory" value="${sourceDirectory}\build" />
    <property name="MSBuildPath" value="${framework::get-assembly-directory(framework::get-target-framework())}\msbuild.exe" />
    <!-- The build configuration to use when publishing and transforming the web.config file. This is useful when you have multiple environments for which you create builds -->
    <property name="buildConfiguration" value="Release" /> 
    <!-- Set these as needed -->
    <property name="svn.username" value="" />
    <property name="svn.password" value="" />

    <target name="SvnPrep">
        <property name="svn.dir" value="${publishDirectory}\.svn" />
        <property name="svn.update" value="true" readonly="false" />
        <echo>env.svn.path = svn</echo>
        <echo>svn.dir = ${svn.dir}</echo>
        <mkdir dir="${publishDirectory}" unless="${directory::exists(publishDirectory)}" />
        <!-- Check if there's a .svn dir already. If not: checkout, else: update. -->
        <if test="${not directory::exists(svn.dir)}">
            <exec program='svn.exe' workingdir="${publishDirectory}" verbose="true">
                <arg line='co ${svn.builduri} --username ${svn.username} --password ${svn.password} --non-interactive ./' />
            </exec>
            <property name="svn.update" value="false" readonly="false" />
        </if>
        <if test="${svn.update}">
            <exec program='svn.exe' workingdir="${publishDirectory}\" verbose="true">
                <arg line='up --username ${svn.username} --password ${svn.password} --non-interactive --force ./' />
            </exec>
        </if>
        <!-- Force any conflicts to be resolved with the most recent code -->
        <exec program='svn.exe' workingdir="${publishDirectory}\" verbose="true">
            <arg line='resolve --accept theirs-full -R ./' />
        </exec>
    </target>   

    <target name="DeleteFiles">
        <!-- Delete only the files (retain directory structure) in the directory to which you are going to publish/build. NAnt excludes svn directories by default. -->
        <delete includeemptydirs="false">
            <fileset basedir="${publishDirectory}">
                <include name="**/*.*" /> 
            </fileset>
        </delete>
    </target>
    <target name="Publish">
        <!-- I know there's an MSBuild task, I don't know why I didn't use it, but this works. -->
        <!-- Build and publish frontend -->
        <exec program="${MSBuildPath}">
            <arg line='"${sourceDirectory}\YourProject.csproj"' />
            <arg value='"/p:Platform=AnyCPU;Configuration=${buildConfiguration};PublishDestination=${publishDirectory}"' />
            <arg value="/target:PublishToFileSystem" />
        </exec>
        <!-- Transform the correct web.config and copy it to the build folder. PublishToFileSystem doesn't transform the web.config, unfortunately. -->
        <exec program="${MSBuildPath}">
            <arg line='"${sourceDirectory}\YourProject.csproj"' />
            <arg value='"/p:Platform=AnyCPU;Configuration=${buildConfiguration};PublishDestination=${publishDirectory}"' />
            <arg value="/target:TransformWebConfig" />
        </exec>
        <copy file="${sourceDirectory}\YourProject\obj\${buildConfiguration}\TransformWebConfig\transformed\Web.config" tofile="${publishDirectory}\YourProject\web.config" overwrite="true" />     
    </target>

    <target name="SvnCommit">       
        <!-- add any new files -->
        <exec program='svn.exe' workingdir="${publishDirectory}" verbose="true">
            <arg line='add --force .' />
        </exec>
        <!-- delete any missing files, a modification of this http://stackoverflow.com/questions/1071857/how-do-i-svn-add-all-unversioned-files-to-svn -->
        <!-- When there's nothing to delete it looks like this fails (to NAnt) but it is actually fine, that's why failonerror is false -->     
        <exec program='cmd.exe' workingdir="${publishDirectory}\" verbose="true" failonerror="false" 
            commandline='/C for /f "usebackq tokens=2*" %i in (`svn status ^| findstr /r "^\!"`) do svn del "%i %j"' >
        </exec>
        <exec program='svn.exe' workingdir="${publishDirectory}" verbose="true">
            <arg line='commit -m "Automated commit from build runner"' />
        </exec>
    </target>

    <target name="ShowProperties">
        <script language="C#" prefix="util" >
            <code>
                <![CDATA[
                public static void ScriptMain(Project project) 
                {
                    foreach (DictionaryEntry entry in project.Properties)
                    {
                        Console.WriteLine("{0}={1}", entry.Key, entry.Value);
                    }
                }
                ]]>
            </code>
        </script>
    </target>

    <target name="all">
        <call target="ShowProperties" />
        <call target="SvnPrep" />
        <call target="DeleteFiles" />
        <call target="Publish" />
        <call target="SvnCommit" />
    </target>
</project>
于 2011-01-11T15:07:29.670 に答える
0

Subversion によって処理されるフォルダーにサイトを公開するのはなぜですか?

私が行う方法は、SVN で処理されたフォルダー内のファイルを直接操作することです。何かをコミットするとすぐに、豆の木によってステージング領域に引っ張られます。このように、削除されたファイルは常にリポジトリから削除されるため、心配する必要はありません。すべてが常に同期しています。

これによりステージング領域に配置されるファイルが多すぎると思われる場合でも、スクリプトと Visual Studio コマンドを使用してサイトを公開できます。しかし、Beanstalk がこのシナリオにどの程度うまく統合されているかはわかりません。CC.netや他の多くの代替手段がそうであることを私は知っています。

于 2011-01-05T09:16:42.750 に答える
0

「幸いなことに」、これは自動化という言葉にまったく新しい意味をもたらします:)あなたが説明しているのは、アプリケーションリリース自動化として知られているもので、展開自動化とも呼ばれます。誰がどこで何をしたか、結果はどうだったかなどを本当に知りたい場合は、Nolio ASAP (http://www.noliosoft.com) のような製品を探しています。あなたが説明していることから、それは完全に一致しているように見えるので、これが役立つかどうか教えてください.

+ダニエル

于 2011-01-04T09:16:09.020 に答える
0

また、SVN からデプロイしたところ、同じ問題が発生しました。私たちの解決策は、基本的に「重要な」アップグレードのためにプロジェクトを分岐することです。つまり、小さなバグを修正したり、通常は xcopy で処理できる微調整を行ったりするだけでなく、ファイルを追加および削除する状況です。Svn レイアウトは次のようになります。

--project
---production
----20100101
----20100213
[etc, etc]

手順に関しては、非常に単純です。十分に大きな変更がある場合は、必要に応じてビルド アーティファクトをチェックインします。

特にプロダクションビットを簡単にブランチを「切り替える」ことができない場合に試してみたいもう1つのことは、powershellなどのより洗練されたものを使用してファイル削除コマンドを実行し、* .svnフォルダーを除外することです。

于 2011-01-02T18:06:52.840 に答える