JenkinsとJFrog Pipelines: CI/CDの連携によるソフトウェアのリリース

ソフトウェア開発者はリリースを継続して行うと同時に技術を先に進める必要があります。Jenkinsの継続的インテグレーション(CI)パイプラインをより新しい最適化されたシステムに移行することは、それほど難しいことではありません。また皆様の企業で現在の作業を完全に中断し、システムを丸ごと入れ替えるような余裕はないでしょう。

私たちはCI/CDソリューションであるJFrog Pipelinesを構築した時に、このことを深く理解していました。そのため、現在のJenkinsパイプラインとJFrog Pipelinesパイプラインを容易に接続できるようにしました。

多くの組織と同様に皆様も多くのJenkinsパイプラインを構築するために何百時間もの開発者の時間を費やしてきたかも知れません。これらのJenkinsパイプラインはCIの基本的な部分を継続して実行することができますが、JFrog Pipelinesの新しいワークフローに引き渡すことができます。

ここではJenkinsとJFrog Pipelinesの連携を可能にするための方法を見てみましょう。

 

Pipelinesとプラットフォームの違い

Pipelinesは「ワンストップDevOps」のためのソリューションを提供するJFrog DevOps PlatformのエンドツーエンドのCI/CDコンポーネントです。ArtifactoryをベースとしたJFrogプラットフォームはアーティファクトリポジトリバイナリの配布セキュリティスキャン、CI/CD自動化から組織のソフトウェアデリバリーを管理するために必要なすべてを提供します。

皆様のJenkinsパイプラインは、すでにGoDockerHelmなどのアーティファクトとビルドをArtifactoryリポジトリにプッシュしている可能性も十分にあるでしょう。これはArtifactoryのユニバーサルリポジトリ管理が、様々なDevOpsツールとの接続を可能にしているからです。そのおかげでArtifactoryはバイナリリポジトリ管理の業界標準として受け入れられるようになりました。

JFrog Pipelinesは、JFrog DevOps Platformのすべてのツールを統合する自動化ツールです。Jenkinsと同様に、コードからビルド、バイナリ、そして配布に至るまでの各段階でソフトウェアを移動させることができます。しかし、JFrog Platformの一部として、Artifactory、Xray、およびDistributionと自然に統合されており、統一したパーミッションモデルで管理することができ、きめ細かなアクセス制御が可能です。

Pipelinesはエンタープライズ規模で運用も可能であり、すべての管理者とチームに単一のプラットフォームを提供し、何百ものCI/CDパイプラインをサポートすることができます。

これらの理由から、CIをJenkinsからPipelinesに移行することをお勧めしますが、一度に移行するのは現実的ではないかもしれません。

JenkinsからPipelinesへ

この例では、Jenkinsがビルド、ユニットテストを実行し、ステージングDockerリポジトリにプッシュするGo RESTアプリケーションを構築しました。次に、JFrog PipelinesがDocker GoアプリケーションをステージングリポジトリからKubernetesクラスタにデプロイします。ここではGoogle Kubernetes Engine(GKE)を使用します。さらに、Dockerレジストリとして Artifactoryを使用します。これにより、同じビルドを別のリリースレジストリにプッシュすることなく、簡単にリリースへのプロモーションを行うことができます。

この例のコードリポジトリには、Go REST アプリケーション、Jenkins パイプライン Jenkinsfile、および JFrog Pipelines YAML ファイルが含まれています。ベストプラクティスでは、パイプラインのインフラストラクチャもこれらのファイルで定義されています。

Jenkins パイプライン

Jenkinsパイプラインは、アプリケーションの初期ビルドとテストを実行し、Dockerコンテナをビルド情報とともにリポジトリにプッシュします。

それでは、Jenkinsのパイプラインを見てみましょう。以下のJenkinsfileの重要なセクションは、Publish Build Infopostステージです。JenkinsがGoアプリケーションイメージをビルドしてテストした後、ビルド情報をArtifactoryに公開します。

stages {
 stage('Build') {
     steps {
         container('golang'){
             sh 'go build'
         }
     }
 }
 stage('Unit Tests') {
     steps {
         container('golang'){
             sh 'go test ./... -run Unit'
         }
     }
 }
 stage('Docker Build') {
   steps {
     container('docker'){
         sh "docker build -t partnership-public-images.jfrog.io/goci-example:latest ."
     }
   }
 }
 stage('Docker Push to Repo') {
   steps {
     container('docker'){
         script {
           docker.withRegistry( 'https://partnership-public-images.jfrog.io', 'gociexamplerepo' ) {
             sh "docker push partnership-public-images.jfrog.io/goci-example:latest"
           }
        }
     }
   }
 }
 stage('Publish Build Info') {
   environment {
     JFROG_CLI_OFFER_CONFIG = false
   }
   steps {
     container('jfrog-cli-go'){
         withCredentials([usernamePassword(credentialsId: 'gociexamplerepo', passwordVariable: 'APIKEY', usernameVariable: 'USER')]) {
             sh "jfrog rt bce $JOB_NAME $BUILD_NUMBER"
             sh "jfrog rt bag $JOB_NAME $BUILD_NUMBER"
             sh "jfrog rt bad $JOB_NAME $BUILD_NUMBER \"go.*\""
             sh "jfrog rt bp --build-url=https://jenkins.openshiftk8s.com/ --url=https://partnership.jfrog.io/artifactory --user=$USER --apikey=$APIKEY $JOB_NAME $BUILD_NUMBER"
         }
     }
   }
 }
}

 

次にpostステージでは、Pipelines REST APIのwebhookでビルド情報を送り、JFrog Pipelinesをトリガーします。次に、このWebhookがJFrog Pipelinesでどのように設定されているかについて説明します。

post {
   success {
     script {
        sh "curl -XPOST -H \"Authorization: Basic amVmabcdefM25rMW5z=\" \"https://partnership-pipelines-api.jfrog.io/v1/projectIntegrations/17/hook\" -d '{\"buildName\":\"$JOB_NAME\",\"buildNumber\":\"$BUILD_NUMBER\",\"buildInfoResourceName\":\"jenkinsBuildInfo\"}' -H \"Content-Type: application/json\""
     }
   }
}

JenkinsとJFrog Pipelinesを接続するには、まずPipelinesデプロイメントでJenkins インテグレーションを作成する必要があります(ここではjenkins_openshiftk8s_comと呼びます)。このUIは上記のcurl webhookコマンドを提供し、JenkinsパイプラインがJFrog Pipelinesをトリガーできるようにします。

JFrog Pipelines

JFrog Pipelinesは、Jenkinsパイプラインによってプッシュされたビルド情報を介してトリガーされ、残りのデプロイメントとステージングアクションを実行してリリースします。

JFrog Pipelinesは、パイプラインのステップをYAMLで定義します。このファイルの最初のセクションはリソースです。これらはパイプラインで使用されるデータのソースとデスティネーションです。この例では、GitHubリポジトリ、jenkins_openshiftk8s_com Jenkinsインテグレーションに接続されたBuildInfoリソース、リリースを促進するための最終的なBuildInfoリソースを定義しています。BuildInfoリソースはビルドのメタデータを保存するために使用します。

resources:
 - name: gociexampleGithubRepo
   type: GitRepo
   configuration:
     gitProvider: myGithub
     path: myaccount/goci-example
 - name: jenkinsBuildInfo
   type: BuildInfo
   configuration:
     sourceArtifactory: MyArtifactory
     buildName: goci-example/master
     buildNumber: 1
     externalCI: jenkins_openshiftk8s_com
 - name: releaseBuildInfo
   type: BuildInfo
   configuration:
     sourceArtifactory: MyArtifactory
     buildName: goci-example/master
     buildNumber: 1

 

最初のステップは、jenkinsBuildInfoを通してJenkinsのトリガーを受け取るBashステップです。

- name: start_from_jenkins
 type: Bash
 configuration:
   inputResources:
     - name: jenkinsBuildInfo
 execution:
   onExecute:
     - echo 'Jenkins job triggered Pipelines'

 

すべてがうまくいったら、Go RESTアプリケーションをステージング環境にデプロイします。ここではGKE クラスタを使用します。このクラスタは、gociexampleClusterCreds という名前のKubernetes インテグレーションを通して参照します。kubeconfigデータをIntegrationオブジェクトとして提供することで、任意のKubernetesクラスタと統合することができます。

HelmDeployステップを使用して、リポジトリのHelmChartディレクトリを使用してアプリケーションをデプロイします。

- name: deploy_staging
 type: HelmDeploy
 configuration:
   inputSteps:
     - name: start_from_jenkins
   inputResources:
     - name: gociexampleGithubRepo
       trigger: false
   integrations:
     - name: gociexampleClusterCreds
   releaseName: goci-example
   chartPath: chart/goci-example/

 

次に、Go RESTアプリケーションが利用可能になるのを待つBashステップがあります。

- name: wait_for_server
 type: Bash
 configuration:
   inputSteps:
     - name: deploy_staging
 execution:
   onExecute:
     - timeout 60 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://goci-example.35.238.177.209.xip.io)" != "200" ]]; do sleep 5; done' || true

 

Go REST アプリケーションがステージング環境で起動したら、ステージングテストを実行します。

- name: staging_test
 type: Bash
 configuration:
   inputSteps:
     - name: wait_for_server
   inputResources:
     - name: gociexampleGithubRepo
       trigger: false
   runtime:
     type: image
     image:
       auto:
         language: go
         versions:
           - "1.13"
   environmentVariables:
     STAGING_URL: "http://goci-example.35.238.177.209.xip.io"
 execution:
   onExecute:
     - cd ../dependencyState/resources/gociexampleGithubRepo
     - go mod download
     - go test ./test -run Staging

 

最後に、ステージングテストをパスした場合は、ビルドをリリースに向けてプロモーションします。

- name: promote_release
 type: PromoteBuild
 configuration:
   targetRepository: partnership-public-images.jfrog.io
   status: Released
   comment: Passed staging tests.
   inputResources:
     - name: jenkinsBuildInfo
   outputResources:
     - name: releaseBuildInfo

 

JFrog Pipelinesをさらに拡張して、エンドシステムやJFrog Edgeシステムにソフトウェアを公開するために、JFrog Distributionを使用して継続的デリバリー(CD)を実現することができます。ただし、これについては今後のブログ記事に譲ることにします。

DevOpsへの道を続ける

ご覧のように、JenkinsパイプラインをJFrog Pipelinesに接続するのは簡単なプロセスです。必要に応じて、JFrog PipelinesからJenkinsパイプラインをトリガーすることもできます。

ツールのパッチワークからソフトウェアデリバリーツールチェーンを開発するのは、時間がかかり、イライラすることがあります。JFrog Platformのような統一されたツールチェーンを使用することで、ツールではなくソフトウェアに集中することができます。しかし、既存のツールがある場合は、それらを簡単にJFrogプラットフォームに接続して、その機能を活用することができます。