管理者設定 - 継続的インテグレーション

[管理] メニューの [プラットフォーム] セクションにある [継続的インテグレーション] ページでは、Looker の [継続的インテグレーション(CI)] 機能の設定を構成できます。LookML プロジェクトの品質と信頼性を確保するには、Looker(Google Cloud コア)の CI 設定を構成します。CI を使用すると、クエリエラーを防ぎ、本番環境に影響する前に SQL、データテスト、コンテンツ、LookML の問題を特定できます。また、LookML リポジトリに pull リクエストが送信されたときに CI バリデータが自動的に実行されるように構成して、開発ワークフローを効率化することもできます。

継続的インテグレーションのコンプライアンス機能

Looker CI は、FedRAMP High、FedRAMP Moderate、DoD Impact Level 5(IL5)の承認境界に含まれていません

Looker インスタンスで Looker CI 設定を有効にする前に、承認機関に相談して、Looker CI のコンプライアンス オファリングが組織固有のセキュリティ要件と規制要件を満たしているかどうかを確認してください。

Looker(Google Cloud コア)インスタンスの場合、利用可能になった Assured Workloads コントロール パッケージごとに、そのパッケージの変更要件とプロセスが満たされると、Looker CI 機能がデフォルトのオファリングとして追加されます。

継続的インテグレーションを有効にする

Looker の 継続的インテグレーション(CI) 機能を使用すると、LookML プロジェクトでテストを実行して、より信頼性が高く、効率的で、使いやすいデータ エクスペリエンスを提供できます。CI バリデータを使用すると、本番環境に影響する前に SQL、データテスト、コンテンツ、LookML の問題を特定して、LookML を検証し、ユーザーのクエリエラーを防ぐことができます。また、スケジュールに基づいて、または LookML リポジトリにpull リクエストが送信されたときに、CI バリデータが自動的に実行されるように構成することもできます。

Looker 管理者は、[継続的インテグレーションを有効にする] 切り替えを使用して、インスタンスで CI を有効にできます。

Looker CI ユーザー

インスタンスで継続的インテグレーションを有効にすると、Looker は [Looker CI ユーザー] ユーザー グループ[Looker CI ユーザー] ロールを持つ 10 人の Looker CI ユーザーを自動的に作成します。Looker 管理者は、[サービス アカウント] タブの [ユーザー] 管理ページから Looker CI ユーザーを表示できます。

インスタンスでアクセス権を使用して Explore へのアクセスを制御する場合は、Looker CI ユーザーをこれらのアクセス権に含める必要があります。CI ユーザーを含めるには、管理設定 - ユーザー属性のドキュメント ページの説明に沿って、関連するユーザー属性値を [Looker CI ユーザー] グループに割り当てます。

統合

継続的インテグレーションを使用すると、リモート Git リポジトリで pull リクエストまたは commit が発生したときに、CI スイートを自動的に実行できます。継続的インテグレーションは、次の Git プロバイダと統合するように構成できます。

  • GitHub(Looker CI GitHub アプリを使用)
  • GitLab(Looker API と GitLab CI を使用)
  • Bitbucket(Looker API と Bitbucket Pipelines を使用)
  • GitHub Actions(Looker API と GitHub Actions を使用)

GitHub

クラウドベースの GitHub リポジトリを LookML プロジェクトのリモート リポジトリとして使用している場合は、LookML デベロッパーが LookML リポジトリに pull リクエストを送信したときに CI スイートが自動的に実行されるように継続的インテグレーションを構成できます

リポジトリで CI スイートを自動的に実行するには、継続的インテグレーションに次の権限が必要です。

  • リポジトリのメタデータと pull リクエストに対する読み取りアクセス権
  • リポジトリの commit ステータス、リポジトリ フック、ワークフローに対する読み取り / 書き込みアクセス権

これらの権限は、Looker IDE で LookML プロジェクトの Git 接続を設定しても設定されません。CI 実行に pull リクエスト トリガーを使用する場合は、LookML プロジェクトを Git 接続で設定する必要があります(Git 接続の設定とテストのページを参照)。また、CI GitHub アプリの構成セクションの説明に沿って、CI GitHub アプリを構成する必要があります。

GitHub テーブル

[継続的インテグレーション] 管理ページの [GitHub] テーブルには、Looker インスタンスの LookML プロジェクト用に構成された GitHub リポジトリが一覧表示されます。これらの GitHub リポジトリは、Git 接続の設定とテストのドキュメント ページの説明に沿って、LookML デベロッパーによって構成されています。

リストされている GitHub リポジトリごとに、リポジトリが CI GitHub アプリで構成されているかどうかがテーブルに表示されます。

CI GitHub アプリの構成

リポジトリに CI GitHub アプリケーションを付与する手順は次のとおりです。

  1. Looker の [継続的インテグレーション] 管理ページで、[GitHub アプリを設定] ボタンをクリックします。 GitHub アプリのウェブページがブラウザ ウィンドウで開きます。
  2. LookML が保存されている GitHub アカウントを選択します。
  3. [リポジトリへのアクセス] セクションで、[すべてのリポジトリ] を選択して、リソース所有者が所有するすべての Git リポジトリに対して CI 統合を許可します。または、[選択したリポジトリのみ] を選択して、継続的インテグレーションで使用するリポジトリを選択します。
  4. [保存] をクリックします。

Looker CI GitHub アプリケーションがリポジトリに正常に付与されると、Looker の [Continuous Integration] 管理ページの [GitHub] テーブルに、リポジトリの [Installed] が表示されます。

GitLab

Looker API と公式の Looker Python SDK(looker-sdk)を使用して、GitLab CI から Looker の継続的インテグレーションの実行をトリガーできます。

GitLab CI パイプラインから Looker CI の実行をトリガーする手順は次のとおりです。

  1. GitLab で CI/CD 変数を構成します
  2. GitLab CI 用の Python スクリプトを作成します
  3. GitLab CI ワークフローを構成します

GitLab で CI/CD 変数を構成する

GitLab プロジェクトで、[設定] > [CI/CD] > [変数] に移動し、次の CI/CD 変数を作成します。機密値を保護するため、各変数を [マスク済み] に設定します。

  • LOOKERSDK_BASE_URL: Looker インスタンスの API URL(例: https://example.cloud.looker.com
  • LOOKERSDK_CLIENT_ID: Looker の [**ユーザー**] 管理ページで生成された API3 クライアント ID
  • LOOKERSDK_CLIENT_SECRET: Looker の [**ユーザー**] 管理ページで生成された対応する API3 クライアント シークレット

GitLab CI 用の Python スクリプトを作成する

リポジトリに run_looker_ci.py という名前の Python スクリプトを作成します。このスクリプトは Looker SDK を使用して CI の実行をトリガーし、実行が完了するまでポーリングを行います。

import os
import sys
import time
import looker_sdk
from looker_sdk import models as mdls

# Retrieve required settings from environment variables
project_id = os.getenv("LOOKER_PROJECT_ID")
suite_id = os.getenv("LOOKER_SUITE_ID")

# GitLab CI specific environment variables
branch = os.getenv("CI_COMMIT_REF_NAME")
commit = os.getenv("CI_COMMIT_SHA")

if not all([project_id, suite_id, branch, commit]):
    print("Error: Missing required environment variables (LOOKER_PROJECT_ID, LOOKER_SUITE_ID, or GitLab vars).")
    sys.exit(1)

# Initialize the Looker SDK.
# The SDK automatically picks up LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
print("Initializing Looker SDK...")
try:
    sdk = looker_sdk.init40()
except Exception as e:
    print(f"Failed to initialize Looker SDK: {e}")
    sys.exit(1)

# Configure the request body
print(f"Starting Looker CI run for project '{project_id}', suite '{suite_id}'...")
print(f"Branch: {branch} | Commit: {commit}")

request_body = mdls.CreateContinuousIntegrationRunRequest(
    suite_id=suite_id,
    branch=branch,
    commit=commit
)

# Trigger the CI run
try:
    run = sdk.create_continuous_integration_run(
        project_id=project_id,
        body=request_body
    )
    run_id = getattr(run, "run_id", getattr(run, "id", None))
    print(f"Looker CI run created successfully. Run ID: {run_id}")
except looker_sdk.error.SDKError as e:
    print(f"Failed to create Looker CI run: {e}")
    sys.exit(1)

# Poll for completion
run_status = run.status
terminal_statuses = ["cancelled", "error", "passed", "failed"]

while run_status not in terminal_statuses:
    print(f"Run {run_id} status is '{run_status}'. Waiting 15 seconds...")
    time.sleep(15)
    
    try:
        run = sdk.get_continuous_integration_run(
            project_id=project_id,
            run_id=run_id
        )
        run_status = run.status
    except looker_sdk.error.SDKError as e:
        print(f"Error while polling Looker CI run status: {e}")
        sys.exit(1)

print(f"Final Looker CI run status: {run_status}")

if run_status != "passed":
    print("Looker CI run did not pass. Failing the GitLab CI job.")
    sys.exit(1)

print("Looker CI run passed successfully!")

GitLab CI ワークフローを構成する

リポジトリのルート ディレクトリで、.gitlab-ci.yml パイプライン構成ファイルを作成または更新して、looker-sdk をインストールし、run_looker_ci.py を実行します。

stages:
  - test

looker-ci:
  stage: test
  image: python:3.10
  variables:
    LOOKER_PROJECT_ID: "LOOKER_PROJECT_ID"
    LOOKER_SUITE_ID: "LOOKER_SUITE_ID"
  script:
    - pip install looker-sdk
    - python run_looker_ci.py
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

次のように置き換えます。

  • LOOKER_PROJECT_ID: テストする Looker プロジェクトの ID
  • LOOKER_SUITE_ID: 実行する CI スイートの ID

Bitbucket

Looker API と公式の Looker Python SDK(looker-sdk)を使用して、Bitbucket Pipelines から Looker の継続的インテグレーションの実行をトリガーできます。

Bitbucket Pipelines から Looker CI の実行をトリガーする手順は次のとおりです。

  1. Bitbucket でリポジトリ変数を構成します
  2. Bitbucket Pipelines 用の Python スクリプトを作成します
  3. Bitbucket Pipelines ワークフローを構成します

Bitbucket でリポジトリ変数を構成する

Bitbucket リポジトリで、[リポジトリの設定] > [リポジトリ変数] に移動し、次のリポジトリ変数を作成します。機密値を保護するため、各変数を [保護済み] に設定します。

  • LOOKERSDK_BASE_URL: Looker インスタンスの API URL(例: https://example.cloud.looker.com
  • LOOKERSDK_CLIENT_ID: Looker の [**ユーザー**] 管理ページで生成された API3 クライアント ID
  • LOOKERSDK_CLIENT_SECRET: Looker の [Users] 管理ページで生成された対応する API3 クライアント シークレット

Bitbucket Pipelines 用の Python スクリプトを作成する

リポジトリに run_looker_ci.py という名前の Python スクリプトを作成します。このスクリプトは Looker SDK を使用して CI の実行をトリガーし、実行が完了するまでポーリングを行います。

import os
import sys
import time
import looker_sdk
from looker_sdk import models as mdls

# Retrieve required settings from environment variables
project_id = os.getenv("LOOKER_PROJECT_ID")
suite_id = os.getenv("LOOKER_SUITE_ID")

# Bitbucket Pipelines specific environment variables
branch = os.getenv("BITBUCKET_BRANCH")
commit = os.getenv("BITBUCKET_COMMIT")

if not all([project_id, suite_id, branch, commit]):
    print("Error: Missing required environment variables (LOOKER_PROJECT_ID, LOOKER_SUITE_ID, or Bitbucket vars).")
    sys.exit(1)

# Initialize the Looker SDK.
# The SDK automatically picks up LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
print("Initializing Looker SDK...")
try:
    sdk = looker_sdk.init40()
except Exception as e:
    print(f"Failed to initialize Looker SDK: {e}")
    sys.exit(1)

# Configure the request body
print(f"Starting Looker CI run for project '{project_id}', suite '{suite_id}'...")
print(f"Branch: {branch} | Commit: {commit}")

request_body = mdls.CreateContinuousIntegrationRunRequest(
    suite_id=suite_id,
    branch=branch,
    commit=commit
)

# Trigger the CI run
try:
    run = sdk.create_continuous_integration_run(
        project_id=project_id,
        body=request_body
    )
    run_id = getattr(run, "run_id", getattr(run, "id", None))
    print(f"Looker CI run created successfully. Run ID: {run_id}")
except looker_sdk.error.SDKError as e:
    print(f"Failed to create Looker CI run: {e}")
    sys.exit(1)

# Poll for completion
run_status = run.status
terminal_statuses = ["cancelled", "error", "passed", "failed"]

while run_status not in terminal_statuses:
    print(f"Run {run_id} status is '{run_status}'. Waiting 15 seconds...")
    time.sleep(15)
    
    try:
        run = sdk.get_continuous_integration_run(
            project_id=project_id,
            run_id=run_id
        )
        run_status = run.status
    except looker_sdk.error.SDKError as e:
        print(f"Error while polling Looker CI run status: {e}")
        sys.exit(1)

print(f"Final Looker CI run status: {run_status}")

if run_status != "passed":
    print("Looker CI run did not pass. Failing the Bitbucket Pipeline.")
    sys.exit(1)

print("Looker CI run passed successfully!")

Bitbucket Pipelines ワークフローを構成する

リポジトリのルート ディレクトリで、bitbucket-pipelines.yml ファイルを作成または更新して、looker-sdk をインストールし、run_looker_ci.py を実行します。

image: python:3.10

pipelines:
  pull-requests:
    '**':
      - step:
          name: Looker CI
          script:
            - export LOOKER_PROJECT_ID="LOOKER_PROJECT_ID"
            - export LOOKER_SUITE_ID="LOOKER_SUITE_ID"
            - pip install looker-sdk
            - python run_looker_ci.py

次のように置き換えます。

  • LOOKER_PROJECT_ID: テストする Looker プロジェクトの ID
  • LOOKER_SUITE_ID: 実行する CI スイートの ID

GitHub Actions

Looker API と公式の Looker Python SDK(looker-sdk)を使用して、GitHub Actions から Looker の継続的インテグレーションの実行をトリガーできます。

GitHub Actions ワークフローから Looker CI の実行をトリガーする手順は次のとおりです。

  1. GitHub でリポジトリ シークレットを構成します
  2. GitHub Actions 用の Python スクリプトを作成します
  3. GitHub Actions ワークフローを構成します

GitHub でリポジトリ シークレットを構成する

GitHub リポジトリで、[設定] > [シークレットと変数] > [アクション] に移動し、次のリポジトリ シークレットを作成します。

  • LOOKERSDK_BASE_URL: Looker インスタンスの API URL(例: https://example.cloud.looker.com
  • LOOKERSDK_CLIENT_ID: Looker の [**ユーザー**] 管理ページで生成された API3 クライアント ID
  • LOOKERSDK_CLIENT_SECRET: Looker の [Users] 管理ページで生成された対応する API3 クライアント シークレット

GitHub Actions 用の Python スクリプトを作成する

リポジトリに run_looker_ci.py という名前の Python スクリプトを作成します。このスクリプトは Looker SDK を使用して CI の実行をトリガーし、実行が完了するまでポーリングを行います。

import os
import sys
import time
import looker_sdk
from looker_sdk import models as mdls

# Retrieve required settings from environment variables
project_id = os.getenv("LOOKER_PROJECT_ID")
suite_id = os.getenv("LOOKER_SUITE_ID")

# GitHub Actions specific environment variables
# GITHUB_HEAD_REF is the branch name for PRs. 
# GITHUB_REF_NAME can be used as a fallback for non-PR events.
branch = os.getenv("GITHUB_HEAD_REF") or os.getenv("GITHUB_REF_NAME")
# GITHUB_PR_SHA is the head commit SHA for PRs.
# GITHUB_SHA can be used as a fallback for non-PR events.
commit = os.getenv("GITHUB_PR_SHA") or os.getenv("GITHUB_SHA")

if not all([project_id, suite_id, branch, commit]):
    print("Error: Missing required environment variables (LOOKER_PROJECT_ID, LOOKER_SUITE_ID, or GitHub vars).")
    sys.exit(1)

# Initialize the Looker SDK.
# The SDK automatically picks up LOOKERSDK_BASE_URL, LOOKERSDK_CLIENT_ID, and LOOKERSDK_CLIENT_SECRET.
print("Initializing Looker SDK...")
try:
    sdk = looker_sdk.init40()
except Exception as e:
    print(f"Failed to initialize Looker SDK: {e}")
    sys.exit(1)

# Configure the request body
print(f"Starting Looker CI run for project '{project_id}', suite '{suite_id}'...")
print(f"Branch: {branch} | Commit: {commit}")

request_body = mdls.CreateContinuousIntegrationRunRequest(
    suite_id=suite_id,
    branch=branch,
    commit=commit
)

# Trigger the CI run
try:
    run = sdk.create_continuous_integration_run(
        project_id=project_id,
        body=request_body
    )
    run_id = getattr(run, "run_id", getattr(run, "id", None))
    print(f"Looker CI run created successfully. Run ID: {run_id}")
except looker_sdk.error.SDKError as e:
    print(f"Failed to create Looker CI run: {e}")
    sys.exit(1)

# Poll for completion
run_status = run.status
terminal_statuses = ["cancelled", "error", "passed", "failed"]

while run_status not in terminal_statuses:
    print(f"Run {run_id} status is '{run_status}'. Waiting 15 seconds...")
    time.sleep(15)
    
    try:
        run = sdk.get_continuous_integration_run(
            project_id=project_id,
            run_id=run_id
        )
        run_status = run.status
    except looker_sdk.error.SDKError as e:
        print(f"Error while polling Looker CI run status: {e}")
        sys.exit(1)

print(f"Final Looker CI run status: {run_status}")

if run_status != "passed":
    print("Looker CI run did not pass. Failing the GitHub Action.")
    sys.exit(1)

print("Looker CI run passed successfully!")

GitHub Actions ワークフローを構成する

リポジトリに、次の構成でワークフロー ファイルを .github/workflows/looker-ci.yml に作成します。

name: Looker CI
on:
  pull_request:
    branches:
      - main

jobs:
  run-looker-ci:
    runs-on: ubuntu-latest


    env:
      # Automatically picked up by the Looker SDK
      LOOKERSDK_BASE_URL: ${{ secrets.LOOKERSDK_BASE_URL }}
      LOOKERSDK_CLIENT_ID: ${{ secrets.LOOKERSDK_CLIENT_ID }}
      LOOKERSDK_CLIENT_SECRET: ${{ secrets.LOOKERSDK_CLIENT_SECRET }}


      # Passed directly to the script
      LOOKER_PROJECT_ID: "LOOKER_PROJECT_ID"
      LOOKER_SUITE_ID: "LOOKER_SUITE_ID"
      GITHUB_PR_SHA: ${{ github.event.pull_request.head.sha }}

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'

      - name: Install Dependencies
        run: |
          python -m pip install --upgrade pip
          pip install looker-sdk

      - name: Run Looker CI
        run: python run_looker_ci.py

次のように置き換えます。

  • LOOKER_PROJECT_ID: テストする Looker プロジェクトの ID
  • LOOKER_SUITE_ID: 実行する CI スイートの ID

dbt Cloud の構成

dbt Cloud を使用している場合は、継続的インテグレーションを構成して、dbt Cloud CI ジョブが完了したときに CI スイートを 自動的に実行できます。CI スイートを実行すると、dbt モデルの変更によって LookML プロジェクトが破損しないようにできます。

dbt Cloud インテグレーションを構成するには、[dbt Cloud の構成] セクションで次の手順を行います。

  1. [dbt Cloud ホスト URL] フィールドに、dbt Cloud アカウントの URL を入力します。
  2. [dbt Cloud API Key] フィールドに、dbt Cloud サービス アカウント トークン を入力します。
  3. [Test Connection] をクリックします。Looker は、dbt Cloud アカウントに接続できることを確認し、[dbt Cloud アカウント ID] を取得します。
  4. [保存] をクリックします。

ユーザー属性

検証の実行中に継続的インテグレーションでオーバーライドできるユーザー属性を構成できます。ユーザー属性は、dbt Cloud インテグレーションと組み合わせて使用され、dbt Cloud CI ジョブで作成された一時スキーマを Looker に指定します。

CI のユーザー属性のデフォルトを構成するには、[ユーザー属性] セクションで次の手順を行います。

  1. [ユーザー属性] フィールドで、プルダウン リストからユーザー属性を選択します。ユーザー属性が選択されていない場合、Looker は CI 実行の データベース接続[Primary Dataset] フィールドで定義されているユーザー属性を使用します。
  2. [CI 実行の値] フィールドに、CI 実行でこのユーザー属性に使用する値を入力します。
  3. [保存] をクリックします。

複数のユーザー属性と値のペアを追加できます。[ユーザー属性] セクションで構成された各ユーザー属性は、[CI スイート構成]でオーバーライドとして選択できます。

ユーザー属性と値のペアを削除するには、[削除] をクリックします。