2015-10-03 16 views
7

私は、継続的な統合環境でプロジェクトを構築するためのカスタムタスクを構築しようとしています。これは、コンパイル sbtでタスクをどのように構成しますか?

  • ビルドアプリケーションアーティファクト
  • をjshint
  • 実行
  • 実行NPMテスト
  • コンパイルテンプレートチャットルームへのメッセージを開始し

    1. 送信ビルドの線に沿ってステップのセットです
    2. デプロイメントサーバにアーティファクトをアップロード
    3. 実行テスト
    4. は、当社の展開サーバーへのテスト結果を送る
    5. 送信部屋10は任意のステップが失敗した場合に行われるべき、とのメッセージがどのステップ失敗に応じてカスタマイズする必要があるステップ

    注意をチャットする結果メッセージを構築し、例えばステップ5が失敗した場合、「コンパイルに失敗しました」と表示されます。ステップ8が失敗すると、実行されたテストの数と失敗した数が示されます。

    これはマルチプロジェクトビルドなので、テストを実行して結果を公開するときにすべてのテストを実行し、集計結果を公開する必要があります。

    さらに興味深いことに、npmテスト、jshint、およびアーティファクトは、webappサブプロジェクト(Javascriptが存在し、Webサーバーが存在する)で実際に意味をなさないだけです。

    私はインスピレーションのためにsbt-releaseを見てきましたが、私は1つのタスクによって生成された価値をどのように取って、次の1つでそれを使用するか、集計でタスクを実行し、 (Extractedの集計タスクを実行するメソッドがありますが、生成された値は与えられません)、サブプロジェクトでタスクを実行して生成値を取得する方法、およびエラー処理を行う方法

    これまでのところ、私が試した二つのアプローチ上記と

    npmTest.result.value match {                  
        case Inc(inc) =>                    
        println(inc)                     
        case Value(res) => Def.taskDyn {                
        (executeTests in Test).result.value match {             
         case Inc(inc) =>                   
         println(inc)                    
         case Value(res) =>                   
         println(res)                    
        }                       
        } 
    

    問題はexecuteTestsは常にnpmTestが失敗しても、実行されていることです。そしてprintlnのどれも実行されません。

    npmTest.result.                      
    flatMap {-                      
        case Inc(inc) =>                    
        task { println(inc) }                   
        case Value(res) =>-                    
        (executeTests in Test).result.                
         flatMap {                     
         case Inc(inc) =>                   
          task { println(inc) }                 
         case Value(res) =>                  
          task { println(res) }                 
         }                       
    }     
    

    (executeTasks in Test)...Initialize[Task[Unit]]値を生成し、Task[Unit]が必要とされているため、この1つはコンパイルされません。

    これをsbtで行う方法はありますか?

  • +0

    ちょっと考えてみましょう。シェルスクリプトを書くだけでいいかもしれません。これがすべてsbtの枠組みで起こるための厳密な必要性はありますか? –

    +0

    書かれているように、質問は非常に広いです。マニュアルを読んだり、何か具体的なことにこだわらなければ、ここで1つ以上の質問を開き、コードを表示する以外の方法を知ることは難しいです。 –

    +0

    現在、ハッキングされたシェルスクリプトを使用しています。その問題は、興味深い情報、例えばコンパイルが失敗したということですか?いくつのテストが実行/失敗したか?それほど簡単には入手できません。私が今までしようとしたことは、 'sendBuildStart.flatMap(コンパイル時にコンパイルする).result.flatMap {case Inc(inc)=> sendCompileFailure(inc); case Value(_)=>テストでテスト).result.flatMap {case Inc(inc)=> sendTestFailed(inc);大文字小文字の値(_)=> .... '残念ながら何も実行されていないようです。 – purefn

    答えて

    4

    良い古いflatMapmapを使用してタスクを構成できるソリューションが見つかりました。

    sealed abstract class Step[A] { 
        def run: Def.Initialize[Task[Result[A]]] 
        def map[B](f: A => B): Step[B] 
        def flatMap[B](f: A => Step[B]): Step[B] 
    } 
    
    object Step { 
        val thisProjectRef = settingKey(Keys.thisProjectRef) 
        val clean = taskKey(Keys.clean) 
        val compile = taskKey(Keys.compile.in(Compile)) 
        val assembly = taskKey(sbtassembly.AssemblyPlugin.autoImport.assembly) 
    
        private[this] def apply[A](task: Def.Initialize[Task[Result[A]]]): Step[A] = 
        new Step[A] { 
         val run = task 
    
         def map[B](f: A => B): Step[B] = 
         apply[B](Def.taskDyn { 
          run.value match { 
          case Inc(inc) => Def.task(Inc(inc): Result[B]) 
          case Value(a) => Def.task(Value(f(a))) 
          } 
         }) 
    
         def flatMap[B](f: A => Step[B]): Step[B] = 
         apply[B](Def.taskDyn { 
          run.value match { 
          case Inc(inc) => Def.task(Inc(inc): Result[B]) 
          case Value(a) => Def.task(f(a).run.value) 
          } 
         }) 
        } 
    
        def task[A](t: Def.Initialize[Task[A]]): Step[A] = 
        apply(t.result) 
    
        def taskKey[A](t: TaskKey[A]): Step[A] = 
        apply(Def.task(t.result.value)) 
    
        def settingKey[A](s: SettingKey[A]): Step[A] = 
        apply(Def.task(s.value).result) 
    } 
    

    次に、あなたは

    rainicornPublish <<= { 
         val result = 
         for { 
          ass <- Step.assembly 
          juri <- uploadAssemblyTask(ass) 
          to <- runAllTests 
          _ <- finish(ass, juri, to) 
         } yield (ass, to) 
    
         Def.task(result.run.value match { 
         case Inc(inc) => throw new RainicornException(None) 
         case Value(v) => v 
         }) 
        } 
    

    として、あなたのタスクを定義することができ、各タスクは、あなたが期待するのと同じように、順番に発生します。

    +0

    コマンドとして実行し、Project.ru nすべての方法でダウンします。 – pfn

    +0

    @pfnそれは私が取り上げるアプローチです。私は私の答えを更新します。 – purefn

    関連する問題