JFrog CLIでフィーチャーブランチを用いたリポジトリ管理を自動化する

Feature Branch Repository Management

 

フィーチャーブランチ・ワークフローは特定の機能に対して行った作業を専用のブランチに分離するために使用されます。これにより、完成前のすべての開発をチームの共通コードベースとは別のところで管理することが出来ます。基本的にはマージの準備が整うまでマスターをリスクに晒さず安全に保てます。

Feature Branch Workflows

チャレンジ

開発者はコードそのものと並行して、フィーチャーブランチから生成したアーティファクトや依存関係を管理しなくてはなりません。しかし、実際に新しいフィーチャーブランチを作成するたび、手動でリポジトリを作成する必要があるのでしょうか?どのようにすれば、より簡単な方法で管理し、作成と削除の全プロセスを自動化出来るでしょうか?

このブログ記事では、フィーチャーブランチ・ワークフローにJFrog Artifactoryの専用アーティファクトリポジトリとJFrog CLIを使用して、すべてを簡単に自動化する方法を見ていきます。

JFrog CLIはコンパクトでスマートなクライアントで、JFrog製品へのアクセスを自動化するシンプルなインターフェイスを提供しています。自動化スクリプトを簡素化して、メンテナンスを容易にします。ここでは具体的な方法として、JFrog CLIを使用したArtifactoryリポジトリ自動化の管理について見ていきましょう。

注:REST APIArtifactoryユーザープラグインを使用して実現することも出来ます。

解決策

JFrog CLIはArtifactoryリポジトリを管理するためのコマンド一式を提供します。例えばリポジトリの作成、更新、削除などです。

次の例ではCIプロセスの一環として、GitHub Actionsを使って3つのArtifactoryリポジトリ(ローカル、リモート、バーチャル)を作成しています。これは JFrog Pipelines、Jenkins、BitBucket などのオーケストレーションツールを使って行うことも可能です。

ArtifactoryとGitHub Actionsのインテグレーションについてより詳しく見る >

この例では、マスター以外へのプルリクエストに対しトリガーされるCIプロセスを作成します。これにはソフトウェアをビルドしてArtifactoryにデプロイする前に、Artifactoryリポジトリを自動的に作成するための追加ステップが含まれます。

Feature Branch Example

CIプロセスは「Build & Deploy (ビルドとデプロイ)」より前に次の2つのステップを実行するように構成されています。

  1. Feature Branch Repository Creation」フィーチャーブランチ用に新しいArtifactoryリポジトリを作成します。
  2. Feature Branch Repository Update」Artifactoryリポジトリが既に作成されている場合、「Feature Branch Repository Creation」ステップは失敗し、このステップでは既存のリポジトリを指定するように更新します。

注: リポジトリの命名規則は重要です。後に削除の仕組みで使われます。

Feature Branch Create and Update

コードの概要

何らかのブランチ = X,

  1. If X = ‘master’, 何もしない
  2. If X != ‘master’, 3つのリポジトリを作成する (存在しない場合)
    • ローカルリポジトリ ‘auto-cli-local-X’:生成されたアーティファクトを保存する
    • リモートリポジトリ ’auto-cli-jcenter-X’https://jcenter.bintray.comを指定する
    • バーチャルリポジトリ ‘auto-cli-virtual-X’’auto-cli-local-X’‘auto-cli-jcenter-X’ を指定する。CIサーバーはこのリポジトリのURLを用いる。
  3. サードパーティーの依存関係を取得し生成されたフィーチャーブランチのアーティファクトをプッシュするため、ビルドが現在用いているリポジトリ ’auto-cli-virtual-X’ を更新する

コードサンプル


    - if: always()   
      name: Feature Branch Repository Update
      env:
        SERVER_ID: tal-eplus-saas
      run: |
        echo "::set-env name=repository::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
        jfrog rt mvnc --server-id-resolve=$SERVER_ID --server-id-deploy=$SERVER_ID --repo-resolve-releases=auto-cli-virtual-$repository --repo-resolve-snapshots=auto-cli-virtual-$repository --repo-deploy-releases=auto-cli-virtual-$repository --repo-deploy-snapshots=auto-cli-virtual-$repository
     
    - if: always()
      name: Build & Deploy
      run: jfrog rt mvn clean install -f maths/pom.xml

メリット


フィーチャーブランチ専用のArtifactoryリポジトリを使うメリットは次のとおりです。

  • 開発用ブランチで使用しているバイナリ(アーティファクトとサードパーティーの依存関係)の分離を明確にします
  • 専用の分離されたフィーチャーブランチのリポジトリを使用して、「外部からのノイズ」なしにアプリケーションをデプロイします
  • フィーチャーごとの簡単な「クリーンアップ」が実現されます。フィーチャーの開発が完了しブランチがmasterにマージされると、開発に使用された無関係な依存関係やフィーチャーブランチのリポジトリにデプロイされた異なるバージョンの依存関係はすべて削除され、一箇所で簡単に追跡することが出来ます。
  • セキュリティスキャンをします。専用のリポジトリやビルドに対してJFrog Xray Watchesを使うことで実現できます。

クリーンアップ

多くの機能を開発してもこのソリューションのスケーラビリティを保ち続けるためには、使用されなくなった古いリポジトリを削除するクリーンアップ・メカニズムを定義する必要があります。
次に扱う、今回の例の最後のステップでは“NUMBER_OF_DAYS_TO_KEEP”パラメーターを使って古いリポジトリを削除します。これは3つのリポジトリタイプ(ローカル、リモート、バーチャル)と空のリポジトリをすべて削除します。例えば“NUMBER_OF_DAYS_TO_KEEP = 90”と設定すると、90日前に作成されたすべてのリポジトリが削除されます。
Artifactory REST APIおよびJFrog CLIの次の機能を使用します。

  • ‘auto-cli-local’ プレフィックスを持つ全てのリポジトリを取得する:GET /api/repositories
  • リポジトリ内で最後に変更されたファイルを見つけるため、jfrog rt searchを用いて検索する

jfrog rt rdelでリポジトリを削除します。

コードサンプル


    - if: always()
      name: Feature Branch Repository Deletion
      env:
        NUMBER_OF_DAYS_TO_KEEP: 90
      run: |
        # Extract all the LOCAL repositories created automatically by the CI process
        jfrog rt curl -XGET /api/repositories | jq '[.[] | .key | select(test("auto-cli-local"))]' > deletion/auto_created_repositories.json && cat deletion/auto_created_repositories.json

        # Calculate for which month are we going back to verify who should be deleted
        jq -n 'now - 3600 * 24 * '$NUMBER_OF_DAYS_TO_KEEP' | gmtime | todate' > deletion/months_indicator && cat deletion/months_indicator

        # Iterate over all the repositories, delete those by the latest file that was modified
        jq -c '.[]' deletion/auto_created_repositories.json | while read i; do
          echo Iterating repository = $i
          sh -c "jfrog rt s --spec deletion/repositories-spec.json --spec-vars='key1="$i"' > deletion/search_results && cat deletion/search_results"
          
          # If the repository is empty / latest modified file is older > NUMBER_OF_DAYS_TO_KEEP days => DELETE the repository
          if [[ $(cat deletion/search_results) == "[]" ]]; then
             echo "Deleting repository: $i, repository is empty"
             sh -c "jfrog rt rdel $i --quiet && jfrog rt rdel ${i//local/virtual} --quiet && jfrog rt rdel ${i//local/jcenter} --quiet"
          elif [[ $(cat deletion/search_results | jq --arg month_indicator $(cat deletion/months_indicator) '.[] | .modified | . <= $month_indicator') = "true" ]]; then             
             echo "Deleting repository: $i, too old to keep in Artifactory"
             sh -c "jfrog rt rdel $i --quiet && jfrog rt rdel ${i//local/virtual} --quiet && jfrog rt rdel ${i//local/jcenter} --quiet"
          else
             echo "Skipping Repository deletion - repository is still relevant"
          fi
        done

以上でGitHub Actionsのパイプラインが完了です。

Complete GitHub Actions pipeline

このパイプラインのコード全体はこちらで参照できます。

https://github.com/jfrog/project-examples/tree/master/github-action-examples/repo-management-github-actions-example