<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56, comments - 77, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    ©Copyright 2008 Julian Simpson. All rights reserved.

    英文原文:   Bootstrap with a Bootstrapper

    I'm an Infrastructure Specialist at ThoughtWorks.  In my role I make sure that we are building our software so it can successfully be deployed to production.  In this series of blog posts I hope to pass on my top ten tips for using CruiseControl Enterprise effectively.  I'm writing these with the developers or systems administrators in mind: the people who most often manage CruiseControl.  However, I hope that anybody who is interested in Continuous Integration will get something from these articles.

    # 4:  Bootstrap with a Bootstrapper

    在我上次的文章中, 我演示了如何使用bootstrapper來確保CruiseControl的配置文件是最新的. 在這篇文章中我會繼續討論這個話題. 這里便是導致在CruiseControl中引入Bootstrapper的問題: 當你破壞了你的構建腳本時你如何修復你的構建?

    想象一下這種情形: 你歡天喜地的對構建腳本做了點修改來支持一個新的特性. 你的同事Bob走到你的桌旁想討論一下這個特性先. 但他并不能阻止你完成這個特性的熱情. 無論如何你都幾乎已經快做完了. 于是你迅速的check in, 然后轉過身在Bob提到釣魚之前拉著他聊工作.

    于是最終Bob逛到飲水機旁去誘陷別人, 而你回來繼續工作. 你看了一下顯示你構建結果的界面, 它居然是紅的!  "業余的家伙們", 你想. "他們總是弄壞構建". 你刷新了一下CruiseControl Dashboard來檢查一下這次構建中有哪些checkin (這里每個人都很頻繁的check in). 最終你發現構建在一秒鐘之內就失敗了, 因為 build.xml 是非法的.

    突然之間多了點對你的構建破壞者同事們的容忍, 你盯著那個 build.xml, 它依然顯示在你的IDE里面. 就是它了, 文件結尾處有一個多余的大大的 '#' 號. "詛咒這鍵盤布局", 你叫嚷著. 當你輸入文件的最后一行時, 你錯過了回車鍵而敲了個 '#'. 你匆匆忙忙check in的時候沒有發現它, 而現在構建腳本不會更新checkout了. 構建腳本根本就不會運行, 因為它是非法的. 通常情況下它做的第一件事就是更新CruiseControl服務器上的源代碼工作拷貝來得到最新的修改. 看起來你得check in你的修復, 然后到CruiseControl服務器上手動更新工作拷貝. 噢!

    曾經干過這些事(有時根本不需要假想一個同事來破壞構建腳本), 因此我可以為 "bootstrapper"這種方法做擔保: 

    <?xml version="1.0"?>

    <cruisecontrol>
      <project name="my_great_app">
        <bootstrappers>
          <svnbootstrapper localWorkingCopy="${working.dir}/${project.name}" file="build.xml">
          <svnbootstrapper localWorkingCopy="${working.dir}/${project.name}" file="ccbuild.xml">
        </bootstrappers>

        <modificationset quietperiod="30">
          <svn LocalWorkingCopy="${working.dir}/${project.name}"/>
        </modificationset>

        <schedule interval="60">
          <ant antWorkingDir="${working.dir}/${project.name}" antscript="${working.dir}/tools/apache-ant-1.6.5/bin/ant" />
        </schedule>
      </project>
    </cruisecontrol>

    在上面的例子中, bootstrapper會始終從Subversion中抓取最新的文件. Bootstrapper在構建發生之前運行, 不管構建是否必要, 但是如果project被暫停了則不會運行. 但何必到此為止呢? 這將確保你能拿到最新的構建腳本, 而后者將負責從你的版本控制系統中獲取最近的更新. 但是你的構建腳本需要做這些事嗎? No, Bootstrapper可以更新所有的工作拷貝, 如果你像這樣配置它的話:

    <bootstrappers>
      <svnbootstrapper localWorkingCopy="${working.dir}/${project.name}"/>
    </bootstrappers>

    現在CruiseControl將更新服務器上的工作拷貝中所有最近更改過的文件.

    關于這種方法, 過去有個問題 - Bob 會抱怨說: "這就像我釣住了一條10磅的魚, 但是線卻斷了. 我提交了我的修改, 然后看見一次構建被觸發了. 我等到構建結束. 我的更改信息出現在了更改信息列表中, 但是 QA 人員說我的修改根本就不在這次構建中! "

    這個問題通常發生在你check in的時候CruiseControl正在 bootstrapping 以獲取最新的版本. 由于最初的那段和不支持原子提交的版本控制系統一起工作的歷史, CruiseControl內部使用日期/時間來引用修改集. 在CruiseControl 2.7.1 中, 來自 ThoughtWorks Studios 的 CCE 團隊修正了這個問題. 他們在 Subversion modification set 中引入了一個 "useLocalRevision " 屬性:

    <bootstrappers>
      <svnbootstrapper localWorkingCopy="${working.dir}/${project.name}" useLocalRevision="true"/>
    </bootstrappers>

    一旦 bootstrapper 更新了CruiseControl服務器上的工作拷貝, 它就使工作拷貝的svn版本號對ModificationSet來說是可用的了. 當ModificationSet試圖計算出這次構建中哪些修改是新增的時候, 它就會限制它的查詢只查到工作拷貝的版本號. 這就使CruiseControl準確的報告修改. 它對于使用CruiseControl的大項目來說是一個巨大的進步. 這也將把你從與Bob的更多次談話中解救出來. <svn> 上的 "useLocalRevision" 另一個有用的副作用是svn的版本號能夠作為一個叫做"${svnrevision}"的屬性傳遞到構建中. 這就使稍后用正確的版本號給這次構建打標簽變得易如反掌.

    當我們涉及CruiseControl和Subversion(或者任何真正支持原子提交的版本控制系統)捆綁工作的時候: 永遠不要使用 QuietPeriod. QuietPeriod是在當你使用CVS或者其它不支持原子操作的版本控制系統的時候, 用來避免CruiseControl過早構建的. 它只會拖慢你的構建.

    有更多的 bootstrapper 可用來做一些有意思或有用的事: CruiseControl支持很多版本控制系統. 它們中的大多數都帶有一個可選的 bootstrapper. Bob和我前面已經描述了版本控制系統的bootstrapper的用處, 下面簡單的說一下剩余的幾個:

    • AntBootStrapper 會在構建開始之前執行一個Apache Ant腳本文件. 大部分情況下你用不到這個, 但是我曾經見過用它來獲取依賴項, 如果依賴項有變化的話就會觸發一次構建

    • ExecBootStrapper 會執行任何你告訴他的腳本或命令

    • LockFileBootStrapper 比較有意思. 繼續往下讀

    你有很多項目運行在同一個CruiseControl服務器上? 很好. 你配置了兩個或更多的構建線程? 你有兩個或多個項目同時構建? 太好了. 多個, 并發的項目是CruiseControl從2004年夏天開始支持的特性. 什么? 其中的兩個項目有時會競爭相同的資源? 噢, 這不好. 尤其煩人如果它只是一天或一段時間只發生一次. 你可以這樣做:

    <cruisecontrol>
      <system>
        <configuration>
          <threads count="2" />
        </configuration>
      </system>

      <project name="test-1" >
        <listeners>
          <lockfilelistener lockFile="/tmp/lock" projectName="${project.name}"/>
        </listeners>
        <bootstrappers>
          <lockfilebootstrapper lockFile="/tmp/lock" projectName="${project.name}" />
        </bootstrappers>
        <schedule interval="30">
          <exec command="/bin/true" />
        </schedule>
      </project>

      <project name="test-2" >
        <listeners>
          <lockfilelistener lockFile="/tmp/lock" projectName="${project.name}"/>
        </listeners>
        <bootstrappers>
          <lockfilebootstrapper lockFile="/tmp/lock" projectName="${project.name}" />
        </bootstrappers>
        <schedule interval="30">
          <exec command="/bin/true" />
        </schedule>
      </project>

    </cruisecontrol>

    lockfilebootstrapper 會在構建開始之前運行, 就像bootstrapper應該做的那樣. 它將在 "lockfile" 屬性指定的文件中查找項目的名稱. 如果 "lockfile" 指定的文件存在, 并且里面的項目名稱和在配置中設置的期待不匹配的話, 它將取消整個構建企圖. 這樣的話, 一個項目就可以警告其它項目說我正在構建, 而你永遠也不會看到兩個不能坐在一起的項目在同時構建. 然而你其它的那些不與第一個項目共享相同外部依賴的項目則可以同時運行. lockfilelistener 會在構建之后清除任何舊的 "lockfile", 這樣的話你就不會永久性的阻止某些構建的運行.

    "等等", Bob說, "我剛剛不得不花了10分鐘來等待FooLib項目得到構建! 這怎么辦?" "Bob," 你并非不近人情的說: "你知道我們只有一臺集成測試服務器. 現在它用來運行CruiseControl. 下次你和CTO一起釣魚的時候, 你可以告訴他項目的延遲, 再問問他我們能否花點明年的預算再購買一臺測試服務器. "

    ©Julian Simpson 2008. All rights reserved.

    在 bootstrapper 概念之前, CruiseControl只是檢查源代碼是否有修改, 不會更新源代碼工作拷貝, 通常都是用戶的構建腳本來負責更新源代碼. 而 bootstrapper 最開始的設計意圖就是作者在文中提到的那樣, 只是用來更新構建腳本, 再由構建腳本負責更新源代碼. 這在一些 bootstrapper 文檔中可略見端倪. 只是人們馬上就發現 boostrapper 可以用來更新所有源文件, 進而可以用來在構建之前做任何事情.

    其實 bootstrapper 和 publisher 是一對兄弟, 分別用來在構建前后插入用戶定義的操作, 就像 AOP 里的 before/after 一樣.

    See also:

    1. <<CruiseControl 的 108 種調度模式>>

    2. <<CruiseControl Enterprise 最佳實踐 (1) : Publish with a Publisher>>

    3. <<CruiseControl Enterprise 最佳實踐 (2) : Keep your dependencies to yourself>>

    4. <<CruiseControl Enterprise 最佳實踐 (3) : Configuring CruiseControl the CruiseControl way>>

     

    hi Julian, have a good desk !


    評論

    # re: CruiseControl Enterprise 最佳實踐 (4) : Bootstrap with a Bootstrapper  回復  更多評論   

    2008-02-17 16:43 by 我啦
    這樣的啊..

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲精品高清视频| 亚洲成AV人片在| 亚洲首页国产精品丝袜| 日韩在线播放全免费| 亚洲激情在线视频| 无码av免费一区二区三区试看| 精品久久久久久亚洲| 香蕉免费看一区二区三区| 久久精品国产亚洲AV不卡| 九九久久精品国产免费看小说| 国产亚洲?V无码?V男人的天堂 | 久久精品国产亚洲av瑜伽| 午夜免费不卡毛片完整版| 亚洲精华液一二三产区| 国产精品久免费的黄网站| 免费一级毛片在线播放视频免费观看永久| 免费一级肉体全黄毛片| 精品乱子伦一区二区三区高清免费播放| 国产成人综合亚洲亚洲国产第一页 | 成年女人男人免费视频播放 | 国产在线国偷精品产拍免费| 亚洲中文字幕无码av| 免费人成在线观看网站视频| 一级毛片完整版免费播放一区| 国产亚洲综合成人91精品| 曰批视频免费30分钟成人| 国产精品亚洲lv粉色| 亚洲一区二区三区无码中文字幕| 久久免费视频99| 亚洲一本到无码av中文字幕| 亚洲第一黄片大全| 国产无遮挡裸体免费视频在线观看 | 亚洲一日韩欧美中文字幕在线| 免费看国产一级特黄aa大片| 毛片基地看看成人免费| 亚洲综合男人的天堂色婷婷| 全免费a级毛片免费看不卡| A级毛片成人网站免费看| 亚洲人成网站色在线观看| 久久久青草青青国产亚洲免观| 1000部禁片黄的免费看|