Jenkins パイプラインアクション

  • リリースバージョン: Yokohama
  • 更新日 2025年01月30日
  • 所要時間:30分
  • Jenkinsパイプラインでこれらのアクションを使用して、DevOps コンフィグデータモデルを操作します。

    重要:
    Washington DC リリース以降、DevOps コンフィグ は将来の廃止に備えて準備されます。これは非表示になり、新しいインスタンスにはインストールされなくなりますが、引き続きサポートされます。詳細については、Now Support ナレッジベースの「Deprecation Process (廃止プロセス) [KB0867184]」の記事を参照してください。

    Jenkins スクリプト化されたパイプラインと宣言的なパイプラインがサポートされています。

    これらのアクションは、目標を達成するための特定のパイプライン定義を作成するために提供されています。これらのアクションを実行するコマンドを Jenkins ファイルに追加します。
    • snDevOpsConfig

      構成データをアップロード、検証、公開するための複合アクション。

    • snDevOpsConfigUpload

      エージェントジョブを介して構成データを DevOps コンフィグ にアップロードします。

    • snDevOpsConfigGetSnapshots

      特定の展開可能項目、または影響を受けるすべての展開可能項目のスナップショットを取得します。

    • snDevOpsConfigPublish

      指定されたアプリケーションと展開可能項目のスナップショットを公開します。

    • snDevOpsConfigExport

      特定のアプリケーションおよび展開可能項目のスナップショットをエクスポートします。

    • snDevOpsConfigRegisterPipeline

      変更セットやスナップショットをパイプライン実行に結び付けます。

    • snDevOpsConfigValidate

      組織のポリシーに対して構成データを検証します。

    • snDevOpsChange

      関連するスナップショットが添付された変更要求を作成します。

    snDevOpsConfig

    構成データの変更をワンステップでアップロード、検証、公開します。

    このアクションは、snDevOpsConfigUpload、snDevOpsConfigGetSnapshots、および snDevOpsConfigRegisterPipeline の各アクションを個別に実行するのではなく、各アクションを 1 つのアクションに結合します。

    入力変数
    構成ファイル データモデルのコンポーネントまたは展開可能パスにアップロードする構成データファイルを指定します。
    applicationName 構成データがアップロードされるアプリケーションを指定します。
    ターゲット 構成データがアップロードされるデータモデルターゲット ( コンポーネントコレクション展開可能項目など) を指定します。
    collectionName (オプション)アップロードするコレクションの名前 (ターゲットがコレクションの場合は必須)。
    deployableName (オプション)アップロード先の展開可能項目の名前 (ターゲットが展開可能な場合は必須)。
    namePath

    構成データがアップロードされるデータモデル内の名前パスを指定します。

    注:
    vars フォルダーにアップロードする場合、変数フォルダーパスを指定するには、名前パスを「vars/」で始める必要があります。
    dataFormat 構成ファイルのデータ形式 ( JSONYAMLXML など) を指定します。
    autoCommit アップロード後に構成データをコミットするかどうかを指定します (true/false)。デフォルトは true です。
    autoValidate コミット中に構成データを検証するかどうかを指定します (true/false)。デフォルトは true です。
    自動公開 検証後に構成データを公開するかどうかを指定します (true/false)。デフォルトは true です。
    changesetNumber

    (オプション)このアップロードアクティビティが関連付けられている (オープンな) 変更セットを指定します。指定しない場合、新しい変更セットが作成されます。

    注:
    複数のアップロードシナリオでのみ使用されます。
    マーク失敗 (オプション)検証の試行が失敗した場合 (バックエンドの問題が原因で) パイプラインを失敗させます。
    結果を表示 (オプション)検証結果を Jenkins ジョブコンソールログに表示します。
    continueWithLatest (オプション)スナップショットが生成されない場合 (true/false)、applicatioName-deployableName-changesetNumber の組み合わせに従って最新のスナップショットを返すかどうかを指定します。デフォルトは false です。
    出力
    • 成功した場合は、スナップショットまたはスナップショットのセット。
    • 失敗した場合は、API/バックエンドの失敗メッセージが表示されます。
    • 入力:
      
      snapshotObj = snDevOpsConfig(
           applicationName: "PaymentDemo",
           configFile: "config/application/Collection/Collection2/*.json",
           target: "collection",
           collectionName: "release-1.0",
           namePath: "settings/infrastructure/database",
           dataFormat: "json",
           autoCommit: 'true',
           autoValidate: 'true',
           autoPublish: 'true',
           continueWithLatest: 'true',
           markFailed: 'true',
           showResults: 'false'
      )
      
      echo"*************************\n ${snapshotObj}"
    • 出力 Jenkins snDevOpsConfig 応答 出力
    例 - コレクション
    注:
    コレクションにアップロードする場合は、 collectionName 引数が必要です。
    
    snDevOpsConfig(
         applicationName: 'PaymentDemo',
         target: 'collection',
         collectionName: 'release-1.0',
         namePath: 'web-api-v1.0',
         configFile: 'k8s/helm/*.yml',
         dataFormat: 'yaml',
         autoCommit: 'true',
         autoValidate: 'true',
         autoPublish: 'true'
    )
    例:展開可能
    注:
    展開可能項目にアップロードする場合は、 deployableName 引数が必要です。
    
    snDevOpsConfig(
         applicationName: 'PaymentDemo',
         target: 'deployable',
         deployableName: 'Production',
         namePath: 'web-api-v1.0',
         configFile: 'k8s/helm/*.yml',
         dataFormat: 'yaml',
         autoCommit: 'true',
         autoValidate: 'true',
         autoPublish: 'true'
    )
    1 回のコミットで複数のアップロード

    さまざまな場所から構成データをアップロードする場合、またはデータモデルへの単一のコミットとして追跡される複数のターゲット (1 つのコンポーネント、1 つの展開可能項目など) に一連のデータをアップロードする場合は、最初のアップロードセットで必要な回数 snDevOpsConfigUpload アクションを呼び出してから、最後のアップロードで snDevOpsConfig アクションを呼び出すことができます。

    次に例を示します。

    • 最初のアップロードでは、変数 ($changeset など) を作成し、ステップの戻り値をその変数に割り当てて、後続のアップロードで再利用できるようにします。

      1 - XML ファイルをコンポーネントにアップロード:
      
      $changeset = snDevOpsConfigUpload(
           applicationName: 'PaymentDemo',
           target: 'component',
           namePath: 'paymentService-v1.0',
           configFile: 'infra/v1/config.xml',
           dataFormat: 'xml',
           autoCommit: 'false',
           autoValidate: 'false',
           autoPublish: 'false'
      )
    • 後続のアップロード (および最終アップロード) では、変数を入力として使用します。

      2 - JSON ファイルを展開可能項目の vars フォルダーにアップロードします:
      
      snDevOpsConfig(
           applicationName: 'PaymentDemo',
           target: 'deployable',
           deployableName: 'Production',
           namePath: 'vars/dbSettings',
           configFile: 'infra/prod/dbConfig.json',
           dataFormat: 'json',
           changesetNumber: ”${changeset}”,
           autoCommit: 'false',
           autoValidate: 'false',
           autoPublish: 'false',
           continueWithLatest: 'true'
      )
    複数のデータフォーマットをアップロード
    さまざまなファイル形式で構成データをアップロードするには、次の仕様を使用して snDevOpsConfig アクションを呼び出します。
    • configFile 引数のパスでワイルドカードが使用されていることを確認してください。
    • dataFormat 引数を指定しないでください。

    次に例を示します。

    • これらの構成ファイルがあるとします。

      DevOps コンフィグ Jenkins アップロードファイル

    • これは、 snDevOpsConfig を使用して構成ファイルをアップロードする方法です。
      
      snDevOpsConfig(
           applicationName: 'PaymentDemo',
           target: 'component',
           namePath: 'paymentService-v1.0',
           configFile: 'infra/v1/*',
           autoCommit: 'true',
           autoValidate: 'true',
           autoPublish: 'true'
      )

    snDevOpsConfigUpload

    このアクションでは、アプリケーションデータモデル内の特定の場所に構成ファイルをアップロードします。

    これは、パイプラインの実行中にすべての構成ファイルをアプリケーションデータモデルにアップロードするために、反復的な性質で使用することを意図しています。

    楨:
    • アップロード先:
      • コンポーネント、コレクション、または展開可能項目。
      • コンポーネント、コレクション、または展開可能項目の変数 (vars) フォルダー。
    • 構成ファイル入力の正規表現パターン。
    • 同じパイプライン内で複数回呼び出される機能。
    入力変数
    構成ファイル データモデルのコンポーネントまたは展開可能パスにアップロードする構成データファイルを指定します。
    applicationName 構成データがアップロードされるアプリケーションを指定します。
    ターゲット 構成データがアップロードされるデータモデルターゲット ( コンポーネントコレクション展開可能項目など) を指定します。
    collectionName (オプション)アップロードするコレクションの名前 (ターゲットがコレクションの場合は必須)。
    deployableName アップロード先の展開可能項目の名前 (ターゲットが展開可能な場合は必須)。
    namePath

    構成データがアップロードされるデータモデル内の名前パスを指定します。

    注:
    vars フォルダーにアップロードする場合、変数フォルダーパスを指定するには、名前パスを「vars/」で始める必要があります。
    dataFormat 構成ファイルのデータ形式 ( JSONYAMLXML など) を指定します。
    変換パス (オプション)構成ファイルのディレクトリ構造を (ワークスペースに関して) 保持し、そのディレクトリをデータモデル内のパスに変換するかどうかを指定します。
    changesetNumber

    (オプション)このアップロードアクティビティが関連付けられている (オープンな) 変更セットを指定します。指定しない場合、新しい変更セットが作成されます。

    注:
    複数のアップロードシナリオでのみ使用されます。
    autoCommit アップロード後に構成データをコミットするかどうかを指定します (true/false)。デフォルトは false です。
    autoValidate コミット中に構成データを検証するかどうかを指定します (true/false)。デフォルトは false です。
    出力変数
    changesetNumber

    (オプション)このアップロードアクティビティが関連付けられている (オープンな) 変更セットを指定します。

    変更セット番号が指定されていない場合は、新しい変更セットが作成されます。

    • 入力:

      snDevOpsConfigUpload アクションの例を次に示します。説明のために、応答を変数 changeSetId に割り当てて、デバッグ シナリオのコンソール ログにエコーアウトできるようにします。

      
      changeSetId = snDevOpsConfigUpload(
           applicationName: "PaymentDemo",
           target: 'component',
           namePath: "web-api-v1.0",
           configFile: "k8s/helm/values.yml",
           dataFormat: "json",
           autoCommit: 'true',
           autoValidate: 'true'
      )
      
      echo "Changeset: $changeSetId created"
    • 出力:

      DevOps コンフィグ でデータモデルにアップロードされるデータに加えて、出力は次のようになります (Blue Ocean プラグインを使用してコンソール出力を可視化します)。

      DevOps コンフィグ構成のアップロード出力

    例 - 複数のアップロード (コンポーネント)
    アップロードアクションを複数回呼び出すと、アップロードを 1 つの変更セットの一部に保持しながら、さまざまな場所からさまざまなファイル形式で構成データをアップロードできます。
    • 最初のアップロードで、changesetNumber 出力変数が後続のアップロードで再利用できるように、アクションに名前を付けます。
      YAML ファイルのアップロード:
      
      $changeset = snDevOpsConfigUpload(
           applicationName: 'PaymentDemo',
           target: 'component',
           namePath: 'wep-api-v1.0',
           configFile: 'k8s/helm/values.yml',
           dataFormat: 'yaml',
           autoCommit: 'false',
           autoValidate: 'false'
      )
    • 後続のアップロードでは、最初のアップロードの changesetNumber 出力変数を入力変数として参照します。
      3 JSON ファイルのアップロード:
      
      snDevOpsConfigUpload(
           applicationName: 'PaymentDemo',
           target: 'component',
           namePath: 'wep-api-v1.0',
           configFile: 'infra/*.json',
           dataFormat: 'json',
           autoCommit: 'false',
           autoValidate: 'false',
           changesetNumber: ”${changeset}”
      )
    • 最後の呼び出しでは、最初のアップロードからの changesetNumber 出力変数を入力変数として参照することに加えて、autoCommit と autoValidate を true に設定します。
      INI ファイルのアップロード:
      
      snDevOpsConfigUpload(
           applicationName: 'PaymentDemo',
           target: 'component',
           namePath: 'wep-api-v1.0',
           configFile: 'featureToggles/set1.ini',
           dataFormat: 'ini',
           autoCommit: 'true',
           autoValidate: 'true',
           changesetNumber: ”${changeset}”
      )
    例 - 複数のアップロード (コレクションと変数)
    アップロードアクションを複数回呼び出すと、アップロードを 1 つの変更セットの一部に保持しながら、さまざまな場所からさまざまなファイル形式で構成データをアップロードできます。
    • 最初のアップロードでは、変数 ($changeset など) を作成し、ステップの戻り値をその変数に割り当てて、後続のアップロードで再利用できるようにします。
      XML ファイルのアップロード:
      
      $changeset = snDevOpsConfigUpload(
           applicationName: 'PaymentDemo',
           target: 'collection',
           collectionName: 'release-v1.0',
           namePath: 'v1-common-configs',
           configFile: 'infra/v1/config.xml',
           dataFormat: 'xml',
           autoCommit: 'false',
           autoValidate: 'false'
      )
    • 後続のアップロードでは、変数を入力として使用します。
      JSON ファイルのアップロード:
      
      snDevOpsConfigUpload(
           applicationName: 'PaymentDemo',
           target: 'deployable',
           deployableName: 'Production',
           namePath: 'vars/dbSettings',
           configFile: 'infra/prod/dbConfig.json',
           dataFormat: 'json',
           autoCommit: 'true',
           autoValidate: 'true',
           changesetNumber: ”${changeset}”
      )
    注:
    変数フォルダーにアップロードするには、uploadTarget を deployable に設定し、deployableName と changesetNumber に正しい値を設定する必要があります。

    snDevOpsConfigGetSnapshots

    このアクションは、さまざまなシナリオで使用することを目的としています。

    • 影響を受ける展開可能項目のすべてのスナップショットを取得します。

      構成ファイルがアプリケーションデータモデルにアップロードされると、アップロードの影響を受けると判断された展開可能項目のスナップショットが作成されます。CI フローに従って、前回の Upload コールで検証が有効になっていたと仮定して、次のステップではスナップショットのリストを反復処理し、すべてが検証に合格したことを確認します。

    • 特定のスナップショットを取得します。

      CD フローに従って、特定のスナップショットを取得して公開し、エクスポートしてダウンストリームで使用できます (たとえば、インフラストラクチャやアプリケーションをプロビジョニングする場合など)。

    • アップロードでスナップショットが生成されない場合に、アプリケーションの展開可能項目の最新のスナップショットを取得します。

      構成変更が行われていない場合、一連の構成データをアプリケーションに展開可能変更セットの組み合わせの環境に展開できます。

    • パイプライン実行でポリシー検証結果を表示します。

      Jenkins ビルドテスト結果ページで、スナップショットを取得するときに、ポリシー検証結果をテスト結果として表示します。例外への準拠を含めます。

    入力定義
    applicationName 構成データのアップロード元またはエクスポート元となるアプリケーションを指定します。
    deployableName (オプション)最新のスナップショットデータを取得するアプリケーションの展開可能項目を指定します。
    changesetNumber (オプション)ユーザーが関心を持っている構成変更セットの変更セット ID を指定します。
    isValidated (オプション)合格したスナップショットのみを返すか、例外 (true/false) を伴って渡されたスナップショットのみを返すかを指定します。デフォルトは true です。
    continueWithLatest (オプション)スナップショットが生成されない場合 (true/false)、applicatioName-deployableName-changesetNumber の組み合わせに従って最新のスナップショットを返すかどうかを指定します。デフォルトは false です。
    出力
    • 成功した場合は、スナップショットまたはスナップショットのセット。
    • 失敗した場合は、API/バックエンドの失敗メッセージが表示されます。
    • 特定のスナップショット (指定):
      
      $snapshots = snDevOpsConfigGetSnapshots(
           applicationName: 'PaymentDemo',
           deployableName: 'Production',
           changesetNumber: 'Chset-16',
           isValidated: 'true',
           continueWithLatest: 'true'
      )
    • 最新の検証済みスナップショット (アプリケーションと展開可能項目の組み合わせに関する最新のスナップショットを返します):
      
      $snapshots = snDevOpsConfigGetSnapshots(
           applicationName: 'PaymentDemo',
           deployableName: 'Production',
           isValidated: 'true'
      )
    • すべての変更セットスナップショット (アプリケーションと展開可能項目の組み合わせのすべてのスナップショットを返します):
      
      $snapshots = snDevOpsConfigGetSnapshots(
           applicationName: 'PaymentDemo',
           changesetNumber: 'Chset-16'
      )
    • パイプライン実行でポリシー検証結果を表示します。
      1. snDevOpsConfigGetSnapshots アクション中に生成されたスナップショット検証結果を含むファイルのパスに変数を割り当てます。
      2. JUnitアクションを呼び出して、スナップショットの検証結果をパイプライン実行テストセクションにロードします。
      
      stage('Validate') {
          steps {
      	script {
                 changeSetResults = snDevOpsConfigGetSnapshots( … )
                 if (!changeSetResults) {
                    echo "No snapshots were created"
                 } else {
      	       def changeSetResultsObject = readJSON text: changeSetResults
      
      	       changeSetResultsObject.each {
                        snapshotName = it.name
                        snapshotObject = it
      	       }
      	       // STEP 1
      		validationResultsPath = "${snapshotName}_${currentBuild.projectName}_${currentBuild.number}.xml"
      	    }
      	}
          }
      }
      
      post {
          always {
              // STEP 2
              junit testResults: "${validationResultsPath}", skipPublishingChecks: true
          }
      }
      

    snDevOpsConfigPublish

    このアクションは、指定されたアプリケーションと展開可能項目のスナップショットを公開します。ここから、エクスポートプロセスを通じてスナップショットを消費できます。

    入力定義
    applicationName 構成データの公開元のアプリケーションを指定します。
    deployableName 構成データの公開元のアプリケーションの展開可能項目を指定します。
    snapshotName 公開するスナップショットの名前を指定します。
    出力
    • 成功した場合は true。
    • それ以外の場合は false。
    
    snDevOpsConfigPublish(
         applicationName: 'PaymentDemo',
         deployableName: 'Production',
         snapshotName: 'Production-v23.dpl',
    )

    snDevOpsConfigExport

    このアクションでは、指定されたアプリケーションと展開可能項目のスナップショットをエクスポートします。

    ユーザーは、エクスポーター、関連するエクスポーター引数、エクスポート形式 (YAML、JSON など)、およびエクスポートされた構成データの出力場所を指定する必要があります。

    ここから、構成データをパイプラインのダウンストリームにある展開ツールまたはプロビジョニングツールの入力として直接使用できます。

    入力引数
    applicationName データのエクスポート元のアプリケーションを指定します。
    deployableName データのエクスポート元のアプリケーションの展開可能な構成を指定します。
    snapshotName

    (オプション)データのエクスポート元のスナップショットを指定します。

    スナップショットが指定されていない場合は、展開可能項目の最新のスナップショットが使用されます。

    exporterName スナップショットに適用するエクスポーター ( UniqueCDI など) を指定します。
    exporterArgs (オプション)エクスポーターとともに使用する引数を指定します。
    エクスポート形式 スナップショットデータをエクスポートする形式 ( INIYAMLPROPS など) を指定します。
    fileName

    データのエクスポート先のファイルを指定します (ワークスペースにあると想定)。

    ファイル名が指定されていない場合は、アプリケーション名と展開可能名 (およびファイル拡張子) の連結がデフォルトで使用されます。

    出力
    • 成功した場合は true。
    • それ以外の場合は false。
    
    snDevOpsConfigExport(
         applicationName: 'PaymentDemo',
         deployableName: 'Production',
         snapshotName: 'Production-v23.dpl',
         exporterFormat: 'yaml',
         exporterName: 'returnAllData-now',
         exporterArgs: '',
         fileName: 'exported_file-Production-20220302.yml'
    )

    snDevOpsConfigRegisterPipeline

    このアクションは、変更セットやスナップショットをパイプラインに関連付けて、パイプラインの実行中に追跡できるようにします。DevOps チェンジベロシティでは、これはパイプライン UI に表示されます。

    DevOps変更の促進機能の詳細については、DevOps変更プロセスの加速を参照してください。

    入力引数
    applicationName アプリケーションの名前を指定します。
    changesetNumber

    (オプション)パイプライン実行に関連付ける変更セットを指定します。

    注:
    changesetNumber または snapshotName のいずれかを指定します。両方を指定することはできません。
    snapshotName

    (オプション)パイプライン実行に関連付けるスナップショットの名前を指定します。

    注:
    changesetNumber または snapshotName のいずれかを指定します。両方を指定することはできません。
    出力
    • 成功した場合は true。
    • それ以外の場合は false。
    • 入力:

      snDevOpsConfigRegisterPipeline アクションの例を次に示します。説明のために、応答を変数 changeSetRegResult に割り当てて、デバッグ シナリオのコンソール ログにエコーアウトできるようにします。

      
      changeSetRegResult = snDevOpsConfigRegisterPipeline(
           applicationName: "PaymentDemo",
           changesetNumber: "Chset-122"
      )
      
      echo "Pipeline registration result: ${changeSetRegResult}"
    • 出力:

      DevOps コンフィグ でデータモデルにアップロードされるデータに加えて、出力は次のようになります (Blue Ocean プラグインを使用してコンソール出力を可視化します)。

      DevOps 構成の登録パイプライン出力

    snDevOpsConfigValidate

    組織のポリシーに対して構成データを検証します。

    入力引数
    applicationName 検証するアプリケーション。
    deployableName 検証するアプリケーションに展開可能。
    snapshotName (オプション)検証するスナップショットの名前。
    マーク失敗 (オプション)検証の試行が失敗した場合 (バックエンドの問題が原因で) パイプラインを失敗させます。
    結果を表示 (オプション)検証結果を Jenkins ジョブコンソールログに表示します。
    出力
    • 成功した場合、出力はありません。
    • 失敗した場合は、API/バックエンドの失敗メッセージが表示されます。
    • 特定のスナップショット (指定):
      
      snDevOpsConfigValidate(
           applicationName: 'PaymentDemo',
           deployableName: 'Production',
           snapshotName: 'Production-v23.dpl',
      )
    • 最新のスナップショット (アプリケーションと展開可能項目の組み合わせに関する最新のスナップショットを取得して検証):
      
      $changeset = snDevOpsConfigValidate(
           applicationName: 'PaymentDemo',
           deployableName: 'Production'
      )

    snDevOpsChange

    変更要求を作成し、参照用にスナップショットを添付します。

    DevOps変更の促進機能の詳細については、DevOps変更プロセスの加速を参照してください。

    入力引数
    applicationName アプリケーションの名前を指定します。
    snapshotName 変更要求に関連付けるスナップショットの名前を指定します。
    
    snDevOpsChange(
         applicationName: 'PaymentDemo',
         snapshotName: 'Production-v23.dpl'
    )

    Jenkins パイプラインの例

    
    pipeline {
        environment {
            buildArtifactsPath = "build_artifacts/${currentBuild.number}"
            validationResultsPath = ""
        }
    
        agent any
    
        stages {
            // Initialize pipeline
            stage('Initialize') {
                steps {
                    script {
                        // DevOps Config application related information
                        appName = 'PaymentDemo'
                        deployableName = 'Production'
                        componentName = "web-api-v1.0"
                        collectionName = "release-1.0"
                        // Configuration file information
                        exportFormat = 'yaml'
                        configFilePath = "k8s/helm/values.yml"
                        // Exporter related information
                        exporterName = 'returnAllData-nowPreview' 
                        exporterArgs = ''
                        // Jenkins variables declared to be used in pipeline
                        exportFileName = "${buildArtifactsPath}/export_file-${appName}-${deployableName}-${currentBuild.number}.${exportFormat}"
                        changeSetId = ""
                        snapshotName = ""
                        snapshotObject = ""
                        isSnapshotValidateionRequired = false
                        isSnapshotPublisingRequired = false
                    }
                }
            }
                
            // Validate configuration data changes
            stage('Validate') {
                parallel {
                    stage('Config') {
                        stages('Config Steps') {
                            // Upload configuration data to DevOps Config
                            stage('Upload, Validate, & Publish') {
                                steps {
                                    sh "echo uploading and auto-validating configuration file: ${configFilePath}"
                                    script {
                                        changeSetResults = snDevOpsConfig(
                                            applicationName: "${appName}",
                                            target: 'component',
                                            namePath: "${componentName}",
                                            configFile: "${configFilePath}",
                                            dataFormat: "${configFileFormat}",
                                            autoCommit: 'true',
                                            autoValidate: 'true',
                                            autoPublish: 'true',
                                            isValidated: 'true',
                                            continueWithLatest: 'true',
                                            markFailed: 'true'
                                        )
    
                                        echo "Snapshots generated, validated, and published: ${changeSetResults}"
    
                                        def changeSetResultsObject = readJSON text: changeSetResults
    
                                        changeSetResultsObject.each {
                                            snapshotName = it.name
                                            snapshotObject = it
                                        }
    
                                        validationResultsPath = "${snapshotName}_${currentBuild.projectName}_${currentBuild.number}*.xml"
                                    }
                                }
                            }
                            // Export published snapshot to be used by downstream deployment tools
                            stage('Export') {
                                steps {
                                    script {
                                        // create build artifacts dir to store export file
                                        sh "mkdir -p ${buildArtifactsPath}"
                                        
                                        exportResponse = snDevOpsConfigExport(
                                            applicationName: "${appName}",
                                            snapshotName: "${snapshotObject.name}",
                                            deployableName: "${deployableName}",
                                            exporterFormat: "${exportFormat}",
                                            fileName: "${exportFileName}",
                                            exporterName: "${exporterName}",
                                            exporterArgs: "${exporterArgs}"
                                        )
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            // Create change request and attach snapshot for reference
            stage('Change Management') {
                steps {
                    script {
                        // Trigger change request
                        snDevOpsChange(
                            applicationName: "${appName}",
                            snapshotName: "${snapshotName}"
                        )
                    }     
                }
            }
        }
        // NOTE: attach snapshot validation results to run (if the snapshot fails validation)
        post {
            always {
                // attach policy validation results
                junit testResults: "${validationResultsPath}", skipPublishingChecks: true
            }
        }
    }