web-dev-qa-db-ja.com

Jenkinsマルチブランチパイプラインで特定のパラメーターを使用してジョブをスケジュールする方法

Jenkinsには2つのFreeStyleプロジェクトがありました。

1つはビルド(日次ビルド+手動ビルド)を生成し、もう1つはテストを実行します。

私たちはジェンキンスのマルチブランチパイプラインに移行しているので、リポジトリごとに1つのプロジェクトがあり、異なる動作をさせるにはオプションを使用する必要があることを理解しています。

テストを実行するかどうか、セットアップを構築するかどうかを示すために、パラメーターを作成できます。その部分は問題ありません。

私の問題は、デフォルトでテストが実行されないことを必要とすることです(テストの生成には時間がかかるため、開発者が誤って[テストの実行]オプションをオンにしておくことはできません。

そして、私が毎日のビルドを夜に実行するときに、このオプションがチェックされている必要があります。

だから2つの質問:

  1. スケジュール方法は?
  2. このスケジュールに使用されるパラメーター値を提供する方法は?
11
J4N

別のマルチブランチジョブを作成して、スケジュールに従って実行し、必要なすべてのパラメーターをオーバーライドしてメインジョブをトリガーできます。こんな感じになります

pipeline {
    agent any
    triggers {
        pollSCM('0 0 * * *')
    }
    stages {
        stage('Triggering the main job') {
            steps {
                build job: "main/${BRANCH_NAME.replace('/', '%2F')}", 
                      parameters: [string(name: 'RUN_TESTS', value: 'true')]
            }
        }
    }
}

このファイルをメインのJenkinsfileとともにリポジトリに配置し、このファイルを使用するように別のマルチブランチパイプラインジョブを構成する必要があります。

5

これを同じ仕事に保つには、少しグルーヴィーなコーディングが必要になります。 MultiBranchパイプラインを使用しているため、これはすべてJenkinsfileに存在できます

まず、Vitaliiが言及するようにcronを設定します。これにより、スケジュールどおりにジョブが開始されます。

properties([
    pipelineTriggers([cron('0 0 * * *')])
])

次に、このジョブがスケジュールによってトリガーされたときに、実行に使用するパラメーターを調整します。そのため、最初にビルドの原因を確認する必要があります。これには、おそらくセキュリティスクリプトの承認が必要です。

List causes = currentBuild.rawBuild.getCauses().collect { it.getClass().getCanonicalName().tokenize('.').last() }

これに'TimerTriggerCause'が含まれている場合は、パラメーターを更新します。

if (causes.contains('TimerTriggerCause') { 
    setBooleanParam("EXECUTE_TESTS", true)
}

このために共有ライブラリに関数を記述しました。必要に応じて、同じJenkinsfileに関数を配置できます(パイプラインロジックの外側の下部)。

/**
 * Change boolean param value during build
 *
 * @param paramName new or existing param name
 * @param paramValue param value
 * @return nothing
 */
Void setBooleanParam(String paramName, Boolean paramValue) {
    List<ParameterValue> newParams = new ArrayList<>();
    newParams.add(new BooleanParameterValue(paramName, paramValue))
    try {
        $build().addOrReplaceAction($build().getAction(ParametersAction.class).createUpdated(newParams))
    } catch (err) {
        $build().addOrReplaceAction(new ParametersAction(newParams))
    }
}

そして、ジョブを通常どおり続行します。 params.EXECUTE_TESTSを評価すると、これは(デフォルトのfalseではなく)trueになります。

注:値のモデルをインポートする必要がある場合があります

import hudson.model.BooleanParameterValue

それをすべてまとめると(全体像のためにビットをすばやくまとめました)、jenkinsfileはこのようなものになります

#!groovy
import hudson.model.BooleanParameterValue


List paramsList = [
    choice(name: 'ACCOUNT_NAME', choices: ['account1', 'account2'].join('\n'), description: 'A choice param'),
    string(name: 'PARAM', defaultValue: 'something', description: 'A string param'),
    booleanParam(defaultValue: false, name: 'EXECUTE_TESTS', description: 'Checkbox'),
]

properties([
    buildDiscarder(logRotator(numToKeepStr: '20')),
    pipelineTriggers([cron('0 18 * * *')]), // 4am AEST/5am AEDT
    disableConcurrentBuilds(),
    parameters(paramList)
])


ansiColor {
    timestamps {
        node {
            try {
                causes = currentBuild.rawBuild.getCauses().collect { it.getClass().getCanonicalName().tokenize('.').last() }
                if (causes.contains('TimerTriggerCause') { 
                    setBooleanParam("EXECUTE_TESTS", true)
                }
                stage('Do the thing') {
                    // Normal do the things like build
                }
                stage('Execute tests if selected') {
                    if (params.EXECUTE_TESTS == true) {
                        // execute tests
                    } else {
                        echo('Tests not executed (Option was not selected/False)')
                    }
                }
            } catch (err) {
                throw err
            } finally {
                deleteDir()
            }
        }
    }
}

/**
 * Change boolean param value during build
 *
 * @param paramName new or existing param name
 * @param paramValue param value
 * @return nothing
 */
Void setBooleanParam(String paramName, Boolean paramValue) {
    List<ParameterValue> newParams = new ArrayList<>();
    newParams.add(new BooleanParameterValue(paramName, paramValue))
    try {
        $build().addOrReplaceAction($build().getAction(ParametersAction.class).createUpdated(newParams))
    } catch (err) {
        $build().addOrReplaceAction(new ParametersAction(newParams))
    }
}
4
metalisticpain

より簡単なアプローチを提案させてください。これは宣言型パイプライン用です。

テスト(アプリケーションコードと共にファーストクラスコードとして扱われる)とアプリケーションソースコードを同じリポジトリに保存することをお勧めします。

JenkinsがSCMからチェックアウトするときに、それらを1つのリポジトリにまとめると、テストスイートに合格したときにタグ(ラベル)を適用できます。ラベルはあなたの親友であり、可能な場合は常に成功時に適用する必要があります。執筆時点では、残念ながらマルチSCMチェックアウトはラベルの適用をサポートしていないようです。

私は現在5人の開発者チームを抱えており、現在マルチブランチパイプラインを使用して、生成するすべての機能ブランチを処理しています。また、「マスター」および「統合」ブランチもあります。マスターはクリーンリリース用です。統合は私の主要なブランチです。

宣言型パイプラインでのスケジューリングは、次のように簡単です。

triggers { 
    cron('0 22 * * *') 
}

pollSCMは、より複雑なcrontabの場合ほど信頼性が高いようには見えません。

宣言型パイプラインに条件を導入することを検討したい1つの方法は、branchnameを使用することです。

success {
    script {
        if( "${env.BRANCH_NAME}" == "integration" ) {
           //Create Package
           //Upload to Artifactory
           //Apply tag to Git
        }
    }
}

上記の例の機能ブランチは、単体テストを実行し、開発者にフィードバックを提供するだけです。さらに成功すると、統合ブランチのみがアーティファクトを生成し(後のテストフェーズ用)、リポジトリにタグを付けます。

ブランチに基づいて分岐動作を望まない場合は、Jenkinsで2つの異なるジョブ(パイプライン)を定義することをお勧めします。テストの実行。

これは私が単体テストとシステムテストで行うことです。

ユニットテストジョブは、Enterprise GitHubリポジトリ内のすべてのブランチに対して実行されるマルチブランチパイプラインです。 Integrationブランチのみがアーティファクトとタグ付けを作成し、変更を毎分ポーリングします。単体テストの実行には10分かかります。

システムテストジョブは単純なパイプラインであり、毎晩実行するようにスケジュールされており、実行には1時間程度かかります。

0
Andrew Gray

これはマルチブランチパイプラインにうまくマッピングできません。ブランチに依存するステージは確認しましたが、パラメーターに依存するステージは確認していません。ステージビューも毎日壊れます。

私がお勧めするのは、2つの個別のJenkinsfileを作成することです。たとえば、1つはJenkinsfileと呼ばれ、もう1つはJenkinsnightlyfileと呼ばれます。次に、同じリポジトリで異なるjenkinsfile名を使用するだけで、2つのマルチブランチパイプラインプロジェクトを作成できます。

通常のステージを最初のステージに入れ、すべてのテストを他のテストに入れます(わかりやすくするために、ここで作業を複数のステージに分割することもできます)。他の1つがjenkins-pipelineのような適切なトリガーを使用するようにしてください。

properties([
    pipelineTriggers([cron('0 0 * * *')])
])

または宣言型パイプラインの場合:

triggers { 
    cron('0 0 * * *') 
}
0
hakamairi