先日開催されたYear End Looker Meetup 2020で登壇の機会をいただき、「ScalebaseにおけるLooker 組込みアナリティクスを活用した顧客向け分析サービスの展開」というタイトルでLTしてきました。 (Speakerdeck)
LT内では、GitHub Actionsを使ってLookMLの開発フローを一部自動化していることについて紹介しましたが、具体的なGitHub Actionsの記述については言及していませんでした。この記事では補足として、LookML開発フローに組み込んでいるGitHub Actionsのコードサンプルを紹介します。
リリースフロー自動化
Looker 7.20以前の構成(本番インスタンス・開発(ステージングインスタンス)を別リポジトリで管理している場合)
Looker7.20以降からは任意ブランチをLookerのデプロイ元(production)に指定できるようになりました。今後は、特別な事情がない限り、単一リポジトリで管理したほうが楽です。筆者は新しいデプロイ設定を試してはいませんが、7.20以後はこのようにできるであろうという設定を次の節に書いておきます。
7.20以前では、master以外のブランチをLookerインスタンスのデプロイ元設定にすることができませんでした。この制約だと、gitリポジトリのmasterブランチにマージしたタイミングで開発(ステージング)・本番インスタンス両方に同時にデプロイが走ってしまうことになります。本番インスタンスへの反映は、ステージングインスタンスへのデプロイ反映結果を見てから、ワンクッション置くほうが安全です。これを実現するために、本番・ステージング用に対応する2つのリポジトリを用意しています。2リポジトリ構成の場合、図のような開発フローを実現できます。2リポジトリ間の同期・リリース用Pull Requestの準備は、図中②・③の2つのGitHub Actionsで自動化できます。そのコードは次のような形になります。
on:
push:
branches:
- master
name:repoBのmasterブランチをrepoAのstagingブランチに同期
jobs:
PushStagingToProductionRepository:
#repoBでしかgithub actionsが発火しないようにフィルタ
if: ${{ github.repository == 'yourorg/repoB' }}
name: git push
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.1
with:
fetch-depth: 0
- run: |
#repoAに書き込むための設定
git remote set-url origin https://x-access-token:${GH_TOKEN_REPOA_PUSH}@github.com/${GITHUB_REPOSITORY}.git
git remote add prod https://x-access-token:${GH_TOKEN_REPOA_PUSH}@github.com/yourorg/repoA.git
env:
# repoAにpushするためのgithub tokenを発行してsecretに設定
GH_TOKEN_REPOA_PUSH: ${{ secrets.GH_TOKEN_REPOA_PUSH }}
- run: |
git fetch origin master
git checkout master
git pull --ff-only origin master
# 他のprivate repositoryにアクセスするための設定
git config --local --remove-section http."https://github.com/"
git config --global url."https://x-access-token:${GH_TOKEN_REPOA_PUSH}@github.com/".insteadOf "https://github.com/"
git fetch prod
git push -f prod master:staging
env:
GH_TOKEN_REPOA_PUSH: ${{ secrets.GH_TOKEN_REPOA_PUSH }}
on:
push:
branches:
- staging
name: 本番インスタンスリリース用PR作成
jobs:
PRReleaseProd:
#repoAでしかgithub actionsが発火しないようにフィルタ
if: ${{ github.repository == 'yourorg/repoA' }}
name: リリースPR作成
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.1
with:
fetch-depth: 0
- run: git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TZ: Asia/Tokyo
- run: |
CURRENT_REF=$(git rev-parse HEAD)
echo ::set-output name=pr_title::"[Production] LookML本番インスタンスへデプロイ $(date +%Y%m%d)"
id: vars
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TZ: Asia/Tokyo
- name: pull-request
uses: ainoya/pull-request@master
with:
source_branch: staging
destination_branch: master
pr_title: ${{ steps.vars.outputs.pr_title }}
pr_body: "このPRをマージすることでLookMLを本番インスタンスにデプロイします。"
github_token: ${{ secrets.GITHUB_TOKEN }}
Looker 7.20以降の構成
Looker 7.20以後は1リポジトリで前述のフローをよりシンプルに実現可能です。図中の②を実現するGitHub Actionsはx-motemen/git-pr-releaseを使って次のように実現できます。
on:
push:
branches:
- master
name: Create PR releasing Production
jobs:
PRReleaseProd:
name: Create PR releasing Production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.1
with:
fetch-depth: 0
- run: |
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
git fetch origin master
git fetch origin prod
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TZ: Asia/Tokyo
- run: |
cat << EOF > pr.template
[Production] Release <%= Time.now.strftime("%F %T") %>
<% pull_requests.each do |pr| -%>
<%= pr.to_checklist_item %>
<% end -%>
EOF
- name: git-pr-release-prod
uses: ainoya/git-pr-release-action@master
env:
GIT_PR_RELEASE_TEMPLATE: ./pr.template
GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_PR_RELEASE_BRANCH_STAGING: master
GIT_PR_RELEASE_BRANCH_PRODUCTION: prod
GIT_PR_RELEASE_LABELS: "Release/Production"
TZ: Asia/Tokyo
2020/12/08追記: ③でwebhook経由でデプロイをトリガさせる処理が不足していたので追記しています。ref
on:
push:
branches:
- prod
name: Looker APIを叩いてデプロイを起動する
jobs:
PRReleaseProd:
name: Create PR releasing Production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.1
with:
fetch-depth: 0
- run: |
# webhook経由でprodブランチからの
# 事前にAdvanced deploy modeをLookerの設定で有効にしておく
# https://docs.looker.com/data-modeling/getting-started/advanced-deploy-mode
curl -X POST -H "X-Looker-Deploy-Secret:${LOOKER_WEBHOOK_SECRET}"
https://yourinstance.looker.com/webhooks/projects/yourproject/deploy/prod
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LOOKER_WEBHOOK_SECRET: ${{ secrets.LOOKER_WEBHOOK_SECRET }}
git-pr-releaseを使えばmasterにマージされていたPull Requestを一覧化してチェックリスト化、PRの本文に簡単に書けるので、リリース時の動作確認チェックもしやすくなるかと思います。
Looker model/dashboard定義の自動生成
デプロイフローと同じ要領で、LookMLの定義を自動生成することも可能です。次のスクリプトは、上図のように、ベースとなるmodel定義から、各環境ごとのmodel定義を自動生成するために使用しているGitHub Actionsです。
# ベースのLookMLから各環境用の定義を自動生成する
on:
push:
branches:
- master
name: ベースのLookMLから各環境用の定義を自動生成する
jobs:
generateLookML:
name: git push
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.1.1
with:
fetch-depth: 0
- run: |
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
- run: |
git switch -c generate-lookml
git config --global user.email "github-actions@example.com"
git config --global user.name "github-actions"
make build # ベースの定義を生成するスクリプトを走らせる
git add generated # generatedディレクトリ配下に自動生成したものが配置されるとして、generatedディレクトリをgit add
git commit -am 'LookML定義自動生成'
git push -f origin generate-lookml # 生成結果をgit push
- name: pull-request
uses: ainoya/pull-request@master
with:
source_branch: generate-lookml
destination_branch: master
pr_title: LookML定義 自動生成
pr_body: "各環境用のLookML定義を生成しました"
github_token: ${{ secrets.GITHUB_TOKEN }}
まとめ
この記事では、GitHub Actionsを用いてLookMLの開発フローをちょっと自動化する方法について紹介しました。冒頭では最新バージョンのLookerでは不要なフローについてやや冗長に紹介してしまいましたが、どこかで特殊な構成を実現されようとしている方向けの参考になればと思い書いてしまいました。LookMLはgit管理可能であることを生かして、他のプログラミング言語の開発プロジェクトと同様にCI/CDを構築できます。今回紹介したもの以外にも、lintやtestなど、CIにあると便利なものがありそうなので、またの機会に紹介したいと思います。