2017-04-12 15 views
3

私たちのクロスプラットフォームプロジェクトでは、Jenkinsをさまざまなプラットフォームで実行する必要があり、適切なテストとパッケージングが各プラットフォームで実行される必要があります。私はparallelnodeを組み合わせることができましたが、これはただ一つのstageでしか得られませんでした(下記参照)複数のステージをノード上で並列実行で作成する

私は複数の段階に分割することができます。私が作成したいのステージは、次のとおりです。

  • ビルド:/アーティファクト
  • UnitTestをワットライブラリ/プロジェクトをビルド:ビルドして実行ユニットが
  • でTestAppをテスト:/アーティファクト
  • ワットテストアプリケーションをビルドして実行します入力ステージ:アップロードしますか?
  • アップロード:
  • node使用方法に一貫性を維持する必要があります(stashを使用して)ステージ間のオブジェクトの

    1. コピーバンチ:外部サーバへアップロードアーティファクトは

は、私は次のことをやっているだろう。 (ノードlabelで生成されたオブジェクトは、適切なノードlabelに応じて停止する必要があります)。私は各ノードのための各隠しに一意にラベルを付ける必要があります。

これははるかに非効率的ではありませんか?私は人工的に多くのデータをコピーして、ステージを作成できるようにしています。

def checkoutAndBuild(Map args) { 
    node("${args.nodeName}") { 

     checkout([$class: 'GitSCM', 
        branches: scm.branches, 
        doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations, 
        extensions: scm.extensions + 
           [[$class: 'SubmoduleOption', 
            disableSubmodules: false, 
            parentCredentials: false, 
            recursiveSubmodules: true, 
            reference: '', 
            trackingSubmodules: false]] + 
           [[$class: 'CleanCheckout']], 
        userRemoteConfigs: scm.userRemoteConfigs 
       ]) 

     step([$class: 'CopyArtifact', 
      filter: "AppCommon/*/**, cmake/**/*, core/**/*, thirdparty/prebuilt/${args.prebuiltDir}/**/*, tools/**/*", 
      fingerprintArtifacts: true, 
      projectName: "${args.engineDependency_Job}", 
      selector: [$class: 'SpecificBuildSelector', buildNumber: "${args.engineDependency_BuildNo}"], 
      target: 'engine']) 

     dir("build/${args.buildDir}") { 
      echo 'Building..' 
      if (isUnix()) { 
       sh './build.sh Release' 
      } else { 
       bat 'build.bat Release' 
      } 
     } 

     def extras = args.additionalArtifacts ? ", ${args.additionalArtifacts}" : "" 
     archiveArtifacts artifacts: "dist/**/*${extras}", fingerprint: true 

     dir("test/build") { 
      echo 'Building test App' 
      sh "./full.sh ${args.buildDir} Release" 
     } 
    } 
} 

pipeline { 
    agent none 

    stages { 
     stage('Info') { 
      agent any 
      steps { 
       echo "Running ${env.JOB_NAME}/${env.BUILD_ID} on ${env.JENKINS_URL}" 
      } 
     } 

     stage('Build') { 
      steps { 
       parallel (
        ios: { 
         checkoutAndBuild nodeName: 'iOS', prebuiltDir: 'ios', buildDir: 'ios', engineDependency_Job: 'engine_iOS_Release', engineDependency_BuildNo: String.valueOf(engineBuild.ios) 
        }, 
        tvos: { 
         checkoutAndBuild nodeName: 'tvOS', prebuiltDir: 'tvos', buildDir: 'tvos', engineDependency_Job: 'engine_tvOS_Release', engineDependency_BuildNo: String.valueOf(engineBuild.tvos) 
        }, 
        android: { 
         checkoutAndBuild nodeName: 'Android', prebuiltDir: 'android', buildDir: 'AndroidNative', engineDependency_Job: 'engine_Android_Release', engineDependency_BuildNo: String.valueOf(engineBuild.android), additionalArtifacts: 'src/java/*' 
        }) 
      } 
     } 
     stage('Test Build') { 
      steps { 
       echo 'Testing...' 
      } 
     } 

     stage('Deploy') { 
      steps { 
       echo 'Deploying...' 
      } 
     } 

    } 

    post { 
     success { 
      slackSend channel: '#builds', 
         color: 'good', 
         message: "${currentBuild.fullDisplayName} succeeded. (<${env.BUILD_URL}|Open>)" 

     } 
     failure { 
      slackSend channel: '#builds', 
         color: 'danger', 
         message: "${currentBuild.fullDisplayName} failed. (<${env.BUILD_URL}|Open>)" 
     } 
    } 
} 

答えて

4

あなたのケースでは、宣言的パイプライン構文はあまり柔軟ではありません。 ステージ間にオブジェクトを配置することは非常に重くなり、最速のビルドターゲットが各ステージの前に遅いターゲットを待っている同期ステージにつながります。

ステージを同期させる必要がない場合は、すべてのビルドターゲットのすべてのステージが含まれる1つの大きなメソッドを作成することをお勧めします。 ステージを区別するために、ノード名の各ステージラベルにを追加することができます。

def checkoutBuildTestDeploy(Map args) { 
    node("${args.nodeName}") { 

     stage("Build ${args.nodeName}") { 
      checkout([$class: 'GitSCM', ... ]) 
      // And other build steps ... 
     } 
     stage("Unit test ${args.nodeName}") { 
      // Unit test steps 
     } 
     stage("Test app ${args.nodeName}") { 
      // Test steps 
     } 
     stage("Deploy ${args.nodeName}") { 
      // Input answer and upload 
     } 
    } 
} 

pipeline { 
    agent none 
    stages { 
     stage('Info') { 
      agent any 
      steps { 
       echo "Running ${env.JOB_NAME}/${env.BUILD_ID} on ${env.JENKINS_URL}" 
      } 
     } 

     stage('Run builds parallel') { 
      steps { 
       parallel (
        ios: { 
         checkoutBuildTestDeploy nodeName: 'iOS', prebuiltDir: 'ios', buildDir: 'ios', engineDependency_Job: 'engine_iOS_Release', engineDependency_BuildNo: String.valueOf(engineBuild.ios) 
        }, 
        tvos: { 
         checkoutBuildTestDeploy nodeName: 'tvOS', prebuiltDir: 'tvos', buildDir: 'tvos', engineDependency_Job: 'engine_tvOS_Release', engineDependency_BuildNo: String.valueOf(engineBuild.tvos) 
        }, 
        android: { 
         checkoutBuildTestDeploy nodeName: 'Android', prebuiltDir: 'android', buildDir: 'AndroidNative', engineDependency_Job: 'engine_Android_Release', engineDependency_BuildNo: String.valueOf(engineBuild.android), additionalArtifacts: 'src/java/*' 
        }) 
      } 
     } 
    } 
    post { 
     success { 
      slackSend channel: '#builds', 
         color: 'good', 
         message: "${currentBuild.fullDisplayName} succeeded. (<${env.BUILD_URL}|Open>)" 

     } 
     failure { 
      slackSend channel: '#builds', 
         color: 'danger', 
         message: "${currentBuild.fullDisplayName} failed. (<${env.BUILD_URL}|Open>)" 
     } 
    } 
} 
関連する問題