Jenkins Pipelineに制御を戻す

Jenkins Pipeline Pluginは、ソフトウェアの継続的配信(Continuous Delivery)を手配するのに非常に便利なものです。 プラグインを使用すると、 ステージでソフトウェア配信をエンドユーザーに分割し、それぞれを制御(ノード、処理内容、実行方法)し、最終的に配信プロセスを視覚化できます。 Blueoceanプラグインと合わせて、すべてが非常に美味しそうです。 実際には、Jenkinsに加えて、このプロセス( ワークフロー )に参加する他のシステムが存在することが判明する場合があります。問題は、既存のソリューションと統合する方法です。 ここでの例はJiraで 、ここでは特定の問題がテスターに​​降りかかり、インターフェイスを呼び出します(まあ、または他の有用な作業を行います)。







それでは、実装オプションは何ですか?







明らかに、少なくとも2つあります。









最初のオプションは、少なくとも何かをチェックするサイクルを書く必要があるという点で、少なくとも不便です。一定の時間後にそれを中断することを忘れないでください。そして、一般的に、ポーリングは私にとっては最もクールな方法ではありません。 したがって、すぐにWebフックに注目します。







ドキュメントを完成させた後、Webフックという名前の機能は見つかりませんでした。実際、これはあまりよくありません。なぜなら、ターゲットソリューションよりも一種の回避策があるからです。







球形真空の球形馬の非常に単純な構成で実験を行います(文字列の例から例を取り上げます)。







node { stage 'Stage 1' echo 'Hello World 1' stage 'Stage 2' echo 'Hello World 2' stage 'Stage 3' build job: 'hello-task', parameters: [[$class: 'StringParameterValue', name: 'CoolParam', value: 'hello']] }
      
      





アクションのシーケンスのステップを説明するために、プラグインはgroovy-dslを使用します。 上記の例では、すべてが1つのノードで実行されます(さらに、これはマスターなので、これを行わないでください;))。 ご覧のとおり、実行には3つの段階があり、そのうち2つは単にコンソールにHello World



を書き込むだけです(驚くべきことです)。







このタスクを実行すると、ログに同様のものが表示されます。







 Started by user admin [Pipeline] node Running on master in /var/jenkins_home/jobs/pipeline-test/workspace [Pipeline] { [Pipeline] stage (Stage 1) Entering stage Stage 1 Proceeding [Pipeline] echo Hello World 1 [Pipeline] stage (Stage 2) Entering stage Stage 2 Proceeding [Pipeline] echo Hello World 2 [Pipeline] stage (Stage 3) Entering stage Stage 3 Proceeding [Pipeline] build (Building hello-task) Scheduling project: hello-task Starting building: hello-task #2 [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS
      
      





さて、スクリプトからのコマンドと、個別に定義した子タスクの両方を実行しました。







ここで、第1段階と第2段階の間に、作業を続行するために外部システムからの承認が必要になると想像してください。 それを実装するために、 入力構造を介したユーザー入力を待機するメカニズムを使用します。 最も単純な形式では、次のようになります。







 input 'Ready to go?'
      
      





再度ジョブを実行すると、インターフェイスで確認アクションを実行する必要があることがわかります。

alt







しかし、マウスをクリックするのが好きな人にとってはインターフェースはクールですが、それでも私たちの問題を解決することはできませんので、 APIを吸ってみましょう。 そして、ここでは、ドキュメントは大丈夫ではありません。 何をどのように呼び出すかを理解するには、 チャットルームで知っている人にアドバイスを求め、 コードを調べる必要があります







この例にはパラメーターがないため、 proceedEmpty



メソッドを使用してアクションを確認できます。 これを行うには、urlのPOSTリクエストをスローする必要があります。







 JENKINS_ROOT_URL/job/JOB_NAME/BUILD_NUMBER/input/INPUT_ID/proceedEmpty?token=YOUR_TOKEN
      
      





ここでの主な難しさは、 INPUT_ID



取得することです。APIで取得できなかったためです。ページを解析するか、フォーム送信トラフィックを表示するだけで、それが何であるかを理解できます。 良いニュースは、 INPUT_ID



常に一定であることです。 悪い-デフォルトでは、ランダムに生成され、文字列です。 歩くたびに認識することは最も楽しいアクティビティではないため、 id



プロパティを使用してこのIDを手動で設定する必要があります。







 input message: 'Ready to go?', id: 'go'
      
      





ここでは、実際のIDは常に大文字で始まることに注意する価値があります。 その結果、私の場合、リクエストは次のようになりました。







 http://localhost:8080/job/pipeline-test/16/input/Go/proceedEmpty?token=f7614a8510b59569347714f53ab1e764
      
      





入力メカニズムのもう1つの利点は、追加のパラメーターを設定できることです。このパラメーターを使用できます。







 def testPassParamInput = input( id: 'testPassParam', message: 'Pass param?', parameters: [ [$class: 'StringParameterDefinition', defaultValue: 'hello', description: 'Test parameter', name: 'testParam'] ])
      
      





これを行うには、子ジョブに渡すパラメーター(この場合はtestParam



を定義できます。 したがって、子ジョブの呼び出しを書き換えて、このパラメーターを受け入れるようにすることができます。







 build job: 'hello-task', parameters: [[$class: 'StringParameterValue', name: 'CoolParam', value: testPassParamInput]]
      
      





オブジェクト全体がvalueに渡されることに注意してください。 複数のパラメーターがある場合は、どのパラメーターを取るかを明示的に示す必要があります。







 testPassParamInput['testParam']
      
      





インターフェイスには、次のようなものがあります。







alt







しかし、 GUIは私たちにとってほとんど関心なく、 APIをさらに研究します 。 通常のHTTP経由でパラメーターを転送するには、別の方法を使用する必要がありproceed









 JENKINS_ROOT_URL/job/JOB_NAME/BUILD_NUMBER/input/INPUT_ID/proceed?token=YOUR_TOKEN
      
      





この場合、パラメーターとその値を使用してフォームを転送する必要があります。 これを行うには、まず、正しいJSONを生成します







 { "parameter" : [ { "name" : "testParam", "value" : "new cool value" } ] }
      
      





ここで、nameはパラメーターの名前、 value



それぞれ値です。







今、それを正しく伝える方法の問題が生じ、ここで未経験者に問題が生じ始めます。 JenkinsはJSONPを実装しているため、このコンテンツをリクエスト本文で直接送信することはできません。 代わりに、フォームにラップしてjson



フィールドに詰め込む必要があります。 Postmanでこれを行うと、最終的なクエリは次のようになります。







 ----WebKitFormBoundaryE19zNvXGzXaLvS5C Content-Disposition: form-data; name="json" { "parameter": [ { "name" : "testParam", "value" : "new cool value" } ] } ----WebKitFormBoundaryE19zNvXGzXaLvS5C
      
      





あまりきれいではありませんが、動作します。 これで、ログで実際にユーザー(この場合は管理者)によってアクションが確認されたことを確認できます。







 Hello World 2 [Pipeline] input Ready to go? Proceed or Abort Approved by admin [Pipeline] input Input requested Approved by admin [Pipeline] stage (Stage 3) Entering stage Stage 3 Proceeding [Pipeline] build (Building hello-task) Scheduling project: hello-task Starting building: hello-task #11
      
      





外部システムが良い結果をもたらさない場合、 abort



メソッドをプルする必要があります。







 JENKINS_ROOT_URL/job/JOB_NAME/BUILD_NUMBER/input/INPUT_ID/abort?token=YOUR_TOKEN
      
      





データは送信されません。 このリクエストを実行した後のログでは、ユーザーによって実行が実際に拒否されたことがわかります。







 Rejected by admin Finished: ABORTED
      
      





そして最後に。 これらすべてのリクエストには基本的な承認、トークン、 クラムが必要であることを忘れないでください。 後者は、 JENKINS_ROOT_URL/crumbIssuer/api/json



で入手できます。







 { "_class":"hudson.security.csrf.DefaultCrumbIssuer", "crumb":"f4c1a2dc6a67c70e66c35c807e542f4e", "crumbRequestField":"Jenkins-Crumb" }
      
      





その後、新しいJenkins-Crumb



ヘッダーとその値をcrumb



フィールドからhttpリクエストのヘッダーに挿入します。







まとめ



現在の形式では、 Pipeline Pluginは外部システムから制御アクションを埋め込む機能を提供し、複雑で一時的な実装プロセスでソフトウェア配信を自動化する多くの機会を開きます。 同時に、これらのアクションのためのより明確で美しいAPIが必要です。








All Articles