【TECH BLOG】Rubyを用いてGoogle Sheetsからリリースノートを取得しGoogle Play Consoleに自動アップロードする取り組み
はじめに
こんにちは、ブランドソリューション開発本部 フロントエンド部 WEAR Androidブロックの武永です。普段はファッションコーディネートアプリWEARのAndroidアプリを開発しています。
リリースノートを手動で毎回入力するのが面倒
WEARは多言語対応をしています。Google Play Consoleへアップロード後、Google Sheetsからテキストを4言語分コピーしたのち、申請画面でテキストを貼り付ける作業が面倒でした。誤って違う言語のリリース文言を記述してしまうリスクもあったので、検討した結果リリースノートもアプリと同じタイミングでアップロードすることにしました。
導入方法
今回はGitHub ActionsでRubyをセットアップし、Rubyのファイルを実行してリリースノートのテキストを取得します。それをテキストファイルとしてダウンロードします。使用するライブラリは2つあります。
1つ目はGoogle Sheetsからテキストを取得するRubyライブラリの「google-drive-ruby」です。Google Sheetsを操作できるライブラリはいくつかあったのですが、スター数もそれなりにあり信頼できると思い選定しました。
2つ目はGoogle Play Consoleにアプリのパッケージをアップロードするライブラリの「gradle-play-publisher」です。非公式ではありますが、できることの柔軟さが魅力的で選定に至りました。それでは実際に見ていきましょう。
Rubyファイルのセットアップ
プロジェクト直下にGoogle Sheetsからテキストを取得する下記のGemfileとRubyファイルを追加します。
- Gemfile
source "https://rubygems.org"
gem 'google_drive'
- download_release_note_text.rb
require 'google_drive'
def fetch_google_sheets
service_acount_key_json = {
type: 'service_account',
project_id: ENV["SERVICE_ACCOUNT_PROJECT_ID"],
private_key_id: ENV["SERVICE_ACCOUNT_PRIVATE_KEY_ID"],
private_key: ENV["SERVICE_ACCOUNT_PRIVATE_KEY"].gsub(/\\n/, "\n"),
client_email: ENV["SERVICE_ACCOUNT_CLIENT_EMAIL"],
client_id: "CLIENT_ID",
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
token_uri: 'https://oauth2.googleapis.com/token',
auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
client_x509_cert_url: ENV["SERVICE_ACCOUNT_CLIENT_X509_CERT_URL"]
}.to_json
service_acount_key_io = StringIO.new(service_acount_key_json)
session = GoogleDrive::Session.from_service_account_key(service_acount_key_io)
spreadsheet = session.spreadsheet_by_key(ENV["GOOGLE_SPREAD_SHEET_ID"])
return spreadsheet
end
def save_metadata(spreadsheet)
branchName = ENV["GITHUB_BRANCH_NAME"].dup
versionName = branchName.delete("qa/")
LANGUAGES.each do |key, value|
row = spreadsheet.worksheet_by_title(key).rows.find { |row| row[0] == versionName }
path = "./app/src/main/play/release-notes/#{value}/default.txt"
File.open(path, mode = 'wb') do |f| f.write(row[RELEASE_NOTES_COLUMN]) end
end
end
LANGUAGES = {'ja'=>'ja-JP', 'zh-Hans'=>'zh-CN', 'zh-Hant'=>'zh-TW', 'en-US'=>'en-US'}
RELEASE_NOTES_COLUMN = 7
spreadsheet = fetch_google_sheets
save_metadata(spreadsheet)
Rubyファイル上でGoogle Sheetsを認証します。その後リリースノートファイル作成の関数を呼び出しテキストファイルとして保存しています。LANGUAGESのdictionary型はGoogle Play ConsoleにアップロードできるようにGoogle Sheetsのシート名を置き換えています。ちなみにサービスアカウントで .gsub(/\n/, "\n"), の処理を行なっている理由は、環境変数から改行コードを読み込んだ場合 \\n になるので置換しています。詳しい説明は後ほど行ないます。
次にGitHub Actions上で上記のRubyファイルを実行できるようにセットアップします。
- download_release_note.yml
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.2.0
with:
ref: ${{ github.head_ref }}
- uses: actions/setup-ruby@v1
with:
ruby-version: 3.1
- name: Prepare bundler
run: |
gem install bundler
bundle install --jobs 4 --retry 3
- name: Deploy Metadata
run: bundle exec ruby get_release_note_text.rb
env:
GITHUB_BRANCH_NAME: ${{ github.head_ref }}
GOOGLE_SPREAD_SHEET_ID: ${{ secrets.GOOGLE_SPREAD_SHEET_ID }}
SERVICE_ACCOUNT_PROJECT_ID: ${{ secrets.SERVICE_ACCOUNT_PROJECT_ID }}
SERVICE_ACCOUNT_PRIVATE_KEY_ID: ${{ secrets.SERVICE_ACCOUNT_PRIVATE_KEY_ID }}
SERVICE_ACCOUNT_PRIVATE_KEY: ${{ secrets.SERVICE_ACCOUNT_PRIVATE_KEY }}
SERVICE_ACCOUNT_CLIENT_EMAIL: ${{ secrets.SERVICE_ACCOUNT_CLIENT_EMAIL }}
SERVICE_ACCOUNT_CLIENT_ID: ${{ secrets.SERVICE_ACCOUNT_CLIENT_ID }}
SERVICE_ACCOUNT_CLIENT_X509_CERT_URL: ${{ secrets.SERVICE_ACCOUNT_CLIENT_X509_CERT_URL }}
- name: Commit and Push
run: |
git add ./app/src/main/play/*
git diff --name-only
set -x
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git add .
git commit --author=. -m 'add release note text'
git push
こちらはプルリクエストが作成されたタイミングで実行されるワークフローです。リリースノートを取得した後にその変更をコミットし、originにプッシュします。セキュアな情報が多いのでシークレットに変数を追加することを推奨します。
上記のプルリクエストがクローズされたらGoogle Play Consoleにパッケージをアップロードします。
- internal_test_deploy.yml
on:
pull_request:
branches:
- main
types: [closed]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: set up JDK 11
uses: actions/setup-java@v3
with:
distribution: "zulu"
java-version: 11
- name: Create Empty local.properties for ci
run: echo > local.properties
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Create Credential File
run: echo '${{secrets.SERVICE_ACCOUNT_JSON}}' > ./app/service_account.json
- name: Upload to Play Console
run: ./gradlew publishReleaseBundle
- app/build.gradle
//細かい導入方法は割愛しています
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
play {
serviceAccountCredentials.set(file('service_account.json'))
track.set("internal")
releaseStatus.set(ReleaseStatus.COMPLETED)
}
gradle-play-publisherはbuild.gradleに記述しアップロードをします。GitHub Actionsの実行ファイルはシンプルになります。internalは内部テスト配布です。内部テスト配布にしている理由は審査が入らないトラックなので即時にGoogle Play Consoleへ反映され確認がしやすいからです。alpha,betaは審査が入るので注意が必要です。
困ったこと
Google Sheetsでリリースノートのバージョン管理を行なっているのですが、そのバージョンとトリガーになるブランチ名を一致させないといけませんでした。そこでGitHub Actionsでブランチ名を取得できる変数を使う方法を採用しました。実際に見ていきましょう。
続きはこちら