Jenkins から Bitbucket Pipelines に移行する方法

Jenkins は、Bitbucket Cloud に接続できる多くの CI/CD ツールの 1 つです。ただし、すでに Bitbucket Cloud を使用してコードを管理している場合は、Jenkins から Bitbucket Pipelines に移行すると、Bitbucket Cloud の機能やインターフェイスと完全に統合された拡張性の高い CI/CD ツールが提供されるため、全体的なエクスペリエンスが向上します。

Bitbucket Pipelines に移行するメリットの詳細をご確認ください。

はじめる前に

Jenkins サーバーから Bitbucket Pipelines に移行するには、各 Jenkins パイプラインの構成ファイルを Bitbucket Pipelines が理解できる形式に変換する必要があります。

Jenkins の設定ファイルは Groovy 形式で書かれていますが、Bitbucket Pipelines は YAML を使用しています。フォーマットを変換する時間を節約するために、Groovy ベースの Jenkins 設定ファイルを Bitbucket Pipelines の YAML ファイルに変換する自動移行ツールを作成しました。

ツールを使い始める前に、次のことをよく理解しておくことが重要です。

準備ができたら、次の作業に進みます。

自動移行ツールの制限事項

自動移行ツールは宣言型の Jenkins パイプラインのみをサポートします。スクリプト型のパイプラインはサポートされていません。

当社の移行ツールは、変換プロセスの力強いスタートをサポートするだけであることを理解することが重要です。Jenkins サーバーはプラグインベースなので、Jenkins 設定ファイルが参照するすべてのプラグインを考慮することはできません。

私たちのツールは、代表的な CI/CD ワークフローで使用される最も一般的な Jenkins プラグインをサポートしています。このツールを使用してJenkins設定ファイルを変換すると、変換できなかったコマンドや手動での確認が必要なコマンドが、変換後のBitbucket Pipelines設定ファイルに明確に表示されます。

次に例を示します。

1 2 # The migration assistant couldn't convert the following plugin in your Jenkinsfile. They may require manual conversion. # Unhandled plugin (<plugin_name>) String Param: (<string_params>) params: (<keyword_params>)

ほとんどの場合、ツールが作成する Bitbucket Pipelines ファイルを手動で確認して更新するか、特定の Jenkins プラグインに対応するようにツール自体をカスタマイズして、この変換プロセスを自分で完了する必要があります。

自動移行ツールの使用方法

移行ツールは、自己完結型の Docker イメージおよびカスタマイズ可能なソース コードとして提供されます。

ほとんどのユーザーには、Docker イメージを使用してツールを実行することをお勧めします。このイメージは最小限のセットアップで済み、Jenkins 設定ファイルにある最も一般的なプラグイン ベースのコマンドを変換します。

移行ツールを拡張して追加のプラグイン コマンドを変換したい場合は、必要に応じてカスタマイズできるソース コードが提供されます。この方法では、起動して実行するのに多くの労力が必要ですが、ツールの機能を拡張して特定の Jenkins プラグインのニーズをカバーできます。

移行ツールの使用方法にかかわらず、移行ツールが作成する Bitbucket Pipelines ファイルを確認することが重要です。構文例を参考にして、手動で修正してください。

自動移行ツールでサポートされている Jenkins プラグイン

自動移行ツールでサポートされる Jenkins プラグインは継続的に更新されます。サポートされているプラグインの最新リストをご覧ください。

移行のベスト プラクティス

ミッション クリティカルなワークフローの場合は、Jenkins から Bitbucket Pipelines への移行を段階的に展開することをお勧めします。この戦略により、必要に応じて Jenkins を活用しながら、既存のリポジトリを Bitbucket Pipelines に段階的に移行できます。

まず、重要度の低いリポジトリまたはビルド プロセスの一部を Bitbucket Pipelines に移行します。これにより、作業を進めながら構成をテストし、改良することができます。

この移行期間中は、jenkins-job-trigger パイプを使用して Jenkins ジョブをトリガーするように Bitbucket Pipelines を設定できます。このハイブリッドなアプローチにより、チームは Bitbucket Pipelines に徐々に慣れることができます。

パイプと呼ばれる強力な CI/CD 統合を使用すると、CI/CD ワークフローを強化し、ボイラープレート コードを最小限に抑えることができることを忘れないでください。厳選された 100 以上のパイプのリストから選択するか、組織内で独自のカスタム ソリューションを作成して共有します。

Docker で事前に構築された自動移行ツールを使用する

ほとんどのユーザーは、シンプルで使いやすい Docker イメージを使うべきです。

前提条件

  • Docker: Docker がシステムにインストールされ、実行されていることを確認します。

ツールを実行する

  1. 次のようにヘルプ メッセージを印刷します。

    1 docker run -it --rm atlassian/bitbucket-pipelines-importer --help
  2. 次のように Docker コンテナを実行します。

    1 docker run -it -v ${PWD}:/files --rm atlassian/bitbucket-pipelines-importer migrate jenkins -i /files/Jenkinsfile -o files/bitbucket-pipelines.yml

Docker ボリューム マウントの仕組みに慣れていないユーザーのために説明すると、${PWD}:/files は基本的に、ホスト マシンの現在のディレクトリであるコロンの左側を、Docker コンテナ内の /files ディレクトリであるコロンの右側にマウントします。

これにより、Docker コンテナ内で CLI が現在のディレクトリに対してファイルを読み書きできるようになります。また、現在のディレクトリは /files ディレクトリにマウントされているため、ホスト マシンの現在のディレクトリに存在していても、コンテナ内の CLI がファイルを正しく読み取ることができるように、入出力ファイルの前に /files を付ける必要があります。

Jenkinsfile のサンプル

  • 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 pipeline { agent { docker { image 'alpine:3.20' } } stages { stage('Back-end') { agent { docker { image 'maven:3.9.9-eclipse-temurin-21-alpine' } } steps { sh 'mvn --version' } } stage('Front-end') { agent { docker { image 'node:20.18.0-alpine3.20' } } steps { sh 'node --version' } } } }
  1. 生成された YAML ファイルの出力ディレクトリを確認します。

Bitbucket Pipelines の YAML ファイル出力のサンプル

  • 1 2 3 4 5 6 7 8 9 10 11 12 13 image: alpine:3.20 pipelines: default: - step: name: Back-end image: maven:3.9.9-eclipse-temurin-21-alpine script: - sh -c 'mvn --version' - step: name: Front-end image: node:20.18.0-alpine3.20 script: - sh -c 'node --version'

ソース コードから自動移行ツールを構築する

ツールの拡張やカスタマイズを希望するユーザー向けです。

前提条件

  • Java Development Kit (JDK): バージョン 21 以上。

  • Apache Maven: バージョン 3.6.0 以上。

  • Docker: Docker イメージの使用を選択したユーザー向け。

Maven を使用する

  1. 次のようにリポジトリをクローンします。

    1 git clone https://bitbucket.org/bitbucketpipelines/bitbucket-pipelines-importer/src/main/
  2. 次のようにディレクトリ内に移動します。

    1 cd bitbucket-pipelines-importer
  3. 次のようにプロジェクトをビルドします。

    1 mvn package spring-boot:repackage
  4. ツールを実行する

    1 java -jar target/bitbucket-pipelines-importer-0.0.3.jar --help

Docker を使用する

  1. 次のように Docker イメージをビルドします。

    1 docker build -t bitbucket-pipelines-importer .
  2. 次のようにツールを実行します。

    1 docker run -it --rm bitbucket-pipelines-importer --help

入力と出力

  • 入力: 入力ファイルへのパスとして指定された Jenkins パイプラインの Groovy ファイル。

  • 出力: 出力ファイルへのパスとして指定された Bitbucket Pipelines の YAML ファイル。

自動移行ツールを拡張する

外部の開発者によるツールへの貢献、および追加の Jenkins プラグインのサポートは歓迎していますが、ほとんどの場合、ユーザーはソースコードを使用するときに移行ツールのリポジトリをフォークし、独自のユースケースをサポートするために個人的に変更を加えることが期待されます。

プラグイン アーキテクチャ

このツールのプラグイン可能なアーキテクチャにより、ユーザーは次のことが可能になります。

  • カスタム プラグイン翻訳ハンドラーを定義する: デフォルトの実装ではカバーされていないカスタム Jenkins プラグインのサポートを追加します。

  • 既存のプラグインを上書き: プラグインの既定の変換をカスタム実装に置き換えます。

カスタム プラグイン翻訳ハンドラーを定義する

  1. 新しいプラグイン ハンドラーの作成:

    ツールが提供する PluginMappingStrategy インターフェイスを実装します。

    1 2 3 4 5 6 public class CustomPluginHandler implements PluginMappingStrategy { @Override public PluginMappingResult map(MappingContext context, JenkinsStep jenkinsStep) { return ...; } }
  2. ハンドラーの登録:

    カスタム ハンドラーを Spring のコンテキストで、または Spring コンポーネントとして定義して登録し、サポートするコマンドを設定し、プラグインの優先度を設定します。

    1 2 3 4 @Component @Order(BeanPrecedence.DEFAULT_MID_IMPLEMENTATION) @SupportedCommands({"custom"}) public class CustomPluginHandler implements PluginMappingStrategy {

既存のプラグインをオーバーライドする

  1. カスタム実装の作成:

    上書きする既存のプラグインに新しいハンドラーを実装します。

  2. より高い優先度の割り当て:

    @Order アノテーションを使用して、ハンドラーの優先度を高くします。

    1 2 3 4 5 6 7 8 9 public interface BeanPrecedence { int CUSTOM_IMPLEMENTATION = 1; int DEFAULT_MID_IMPLEMENTATION = 10; int DEFAULT_LOW_FALLBACK = 100; } @Component @Order(BeanPrecedence.CUSTOM_IMPLEMENTATION) @SupportedCommands({"sh"}) public class CustomPluginHandler implements PluginMappingStrategy {

手動構成ファイル リビジョンの構文例

以下に、Jenkins から Bitbucket Pipelines への手動での移行に関する例と構文比較を示します。

Hello World ビルドの実行

Jenkins (groovy)

パイプライン (yaml)

1 2 3 4 5 6 7 8 9 10 pipeline { agent any stages { stage('Example') { steps { echo 'Hello World' } } } }
1 2 3 4 5 6 7 image: atlassian/default-image:4 pipelines: default: - step: name: Example script: - echo 'Hello World'

並列ジョブの実行

Jenkins (groovy)

パイプライン (yaml)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 pipeline { agent any stages { stage('Parallel Steps') { parallel { stage('Build and Test') { steps { echo "Your build and test goes here..." } } stage('Lint') { steps { echo "Your linting goes here..." } } stage('Security scan') { steps { echo "Your security scan goes here..." } } } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 image: atlassian/default-image:4 pipelines: default: - parallel: - step: name: 'Build and Test' script: - echo "Your build and test goes here..." - step: name: 'Lint' script: - echo "Your linting goes here..." - step: name: 'Security scan' script: - echo "Your security scan goes here..."

環境変数の参照

Jenkins から Bitbucket Pipelines に移行する場合は、Jenkins で使用されている既存の変数とシークレットを Bitbucket Pipelines に手動で提供する必要があることに注意してください。これが必要なのは、2 つのシステムでは環境変数の処理方法が異なり、これらの認証情報が自動的には転送されないためです。Bitbucket Pipelines で変数とシークレットを管理する方法の詳細については、「変数とシークレット | Bitbucket Cloud | アトラシアン サポート」を参照してください。

Jenkins (groovy)

パイプライン (yaml)

1 2 3 4 5 6 7 8 9 10 pipeline { agent any stages { stage('Example') { steps { echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}" } } } }
1 2 3 4 5 6 7 image: atlassian/default-image:4 pipelines: default: - step: name: Example script: - echo "Running $BITBUCKET_BUILD_NUMBER on $BITBUCKET_GIT_HTTP_ORIGIN"

資格情報の処理

次のパイプライン コードは、シークレット テキストの資格情報に環境変数を使用してパイプラインを作成する方法の例を示しています。

Jenkins (groovy)

パイプライン (yaml)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 pipeline { agent any environment { AWS_ACCESS_KEY_ID = credentials('jenkins-aws-secret-key-id') AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key') } stages { stage('Example stage 1') { steps { // logic required credentials } } } }
1 2 3 4 5 6 7 8 9 10 image: atlassian/default-image:4 pipelines: default: - step: name: Example script: - pipe: atlassian/bitbucket-upload-file:0.7.1 variables: BITBUCKET_ACCESS_TOKEN: $BITBUCKET_ACCESS_TOKEN FILENAME: 'package.json'

タイムアウトを長くする

Jenkins (groovy)

パイプライン (yaml)

1 2 3 4 5 6 7 8 9 10 11 12 13 pipeline { agent any stages { stage('Example') { options { timeout(time: 1, unit: 'HOURS') } steps { echo 'Hello World' } } } }
1 2 3 4 5 6 7 8 image: atlassian/default-image:4 pipelines: default: - step: name: Example script: - echo 'Hello World' max-time: 60 # Timeout in minutes

cron 式

Jenkins (groovy)

Pipelines

1 2 3 4 5 6 7 8 9 10 11 12 13 pipeline { agent any triggers { cron('H 0 * * *') // This cron expression triggers the pipeline once every day at midnight } stages { stage('Example') { steps { echo 'Hello World' } } } }

Bitbucket Pipelines のスケジュールされたビルドは、ユーザー インターフェイスで構成されます。ビルド スケジュールを簡単に設定および管理し、ビルドの頻度とタイミングを指定できます。

ビルド、テスト、デプロイ

Jenkins (groovy)

パイプライン (yaml)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 pipeline { agent any tools {nodejs "nodejs"} environment { HEROKU_API_KEY = credentials('jenkins-heroku-api-key') HEROKU_APP_NAME = credentials('jenkins-heroku-app-name') } stages { stage('Build') { steps { sh 'npm install' sh 'npm run build' sh 'zip -r build.zip build/ } } stage('Test') { steps { sh 'npm test' } } stage('Deploy to Heroku') { steps { script { def deploymentUrl = "https://api.heroku.com/sources" def response = sh(script: """ curl -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/vnd.heroku+json; version=3" \ -H "Authorization: Bearer ${HEROKU_API_KEY}" \ "${deploymentUrl}" """, returnStdout: true).trim() def jsonSlurper = new groovy.json.JsonSlurper() def parsedResponse = jsonSlurper.parseText(response) def putUrl = parsedResponse.source_blob.put_url def getUrl = parsedResponse.source_blob.get_url sh """ curl "${putUrl}" \ -X PUT \ -H "Content-Type:" \ --data-binary @build.zip """ sh """ curl -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/vnd.heroku+json; version=3" \ -H "Authorization: Bearer ${HEROKU_API_KEY}" \ -d '{"source_blob":{"url":"${getUrl}","version":"${BUILD_NUMBER}"}}' \ "https://api.heroku.com/apps/${HEROKU_APP_NAME}/builds" """ } } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 image: atlassian/default-image:4 pipelines: default: - step: name: Build script: - npm install - npm run build - zip -r build.zip build/ artifacts: - build.zip - step: name: Test caches: - node script: - npm install - npm test - step: name: Deploy to Heroku services: - docker script: - pipe: atlassian/heroku-deploy:2.4.0 variables: HEROKU_API_KEY: $HEROKU_API_KEY HEROKU_APP_NAME: $HEROKU_APP_NAME ZIP_FILE: 'build.zip' WAIT: 'true'

 

さらにヘルプが必要ですか?

アトラシアン コミュニティをご利用ください。