Android
Android アプリケーションの一般的な公開サイクルには、次の主な手順が含まれます。
アプリケーションを構築します。
アプリケーションに署名します。
アプリケーションを Google Play Console にアップロードします。
Space Automation を使用してこれらの手順を自動化するには、いくつかの方法があります。
Google Play 開発者 API を使用します。
Android の構築および公開ワークフローを初めて使用する場合は、次の Android パブリッシングの基本トピックから始めることをお勧めします。Android プロジェクトでのテストの自動化に興味がある場合は、「Android プロジェクトでテストを実行する」を参照してください。
Android パブリッシングの基本
このトピックの内容は、開発者 .android.com/ からの情報に基づいています。このトピックの公開日以降、特定の情報が変更されている可能性があることに注意してください。実際の情報については、Google の公式ドキュメントを参照してください。
ビルドシステム
通常、Android アプリケーションは Gradle ビルドツールを使用して構築されます。Kotlin および Gradle を使用した Java アプリケーションを構築するためのすべての推奨事項は、Android アプリケーションにも適用できます。基本的に、アプリを構築するために必要なのは、./gradlew build
を実行することだけです。
ビルドアーティファクト形式
次のいずれかの形式でアーティファクトを生成するように Android ビルドを構成できます。
Android アプリケーションパッケージ (APK) – アプリのバイナリ、スクリーンショット、その他のリソースを含むアーカイブ。アプリケーション開発者の身元を確認するには、APK ファイルを秘密鍵でデジタル署名する必要があります。その後、APK を Google Play にアップロードするか、個別に配布することができます。複数のデバイスをより適切にサポートするには、各デバイスに最適化された APK をいくつか作成する必要があります。または、単一の「最適化されていない」APK を作成することもできます。
Android アプリバンドル (AAB) – アプリのバイナリやその他のリソースを含み、APK の生成を Google Play に委ねる公開形式。長所: Google Play 自体がデバイス構成ごとに多数の APK を作成します。APK と同様に、バンドルも Google Play にアップロードする前に署名する必要があります。
署名の基本
アプリに署名するには 2 つの方法があります。
プライベートアプリ署名キー – (APK のみに適用) プライベートアプリシグネチャーキーを使用して APK に直接署名します。署名キーは、アプリの存続期間中は決して変更されません。キーを使用して APK に署名するには、Android Studio、Gradle タスク、またはコマンドラインツールを使用します。キーを紛失すると、アプリを更新できなくなります。
Play アプリの署名 – (APK と AAB に適用可能、推奨) このフローでは、アップロードキーとプライベートアプリ署名キーの 2 つのキーを使用します。アップロードキーを自分側に保存し、アップロードする前にそれを使用して AAB または APK に署名します。アプリ署名キーは Google によって保存されます。ダウンロードすることはできません。Google はこのキーを使用して APK (アップロードされたもの、または AAB から構築されたもの) に署名します。主な利点は、アップロードキーを紛失したり侵害された場合に、新しいキーを発行できることです。詳細
Gradle および Gradle Play Publisher を使用してアプリを構築して公開する
前提条件
対象イメージ
|
Android アプリケーションは Gradle ビルドツールを使用します。Android プロジェクトのデフォルトの Gradle 構成では、アプリの APK または AAB の生成と署名を自動化できます。できないことは、アプリのアップロードや宣伝などのリリース活動を自動化することです。このセクションでは、Gradle Play パブリッシャー(英語)プラグインを使用してこの課題を解決する方法を説明します。これは、Google Play Developer API を使用してすべてのリリースアクティビティを実行できる非公式 Gradle プラグインです。
Gradle Play パブリッシャーのドキュメント(英語)の説明に従って、Google Cloud Platform サービスアカウントを作成します。プラグインはこのアカウントを使用して、Google Play Console でリリースアクティビティを実行します。
サービスアカウントを作成するときに、アカウントの秘密キーを
.json
ファイルで取得します。ファイルをコンピューターに保存します。次の手順で必要になります。アプリに対する十分な権限をアカウントに提供していることを確認してください: テストトラックのリリースを管理する権限が必要です。
。この例では、アプリを内部テストトラックに公開するため、アカウントにはアプリケーションに署名するためのアップロードキーを生成します (この例では、Play アプリの署名を使用します)。すでにキーを持っている場合は、この手順をスキップしてください。キーを生成するには、以下を使用できます。
Android Studio. 詳細
keytool
コマンドラインツール。例:keytool -genkey -v -keystore uploadkey.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
キーを作成するときは、次の情報を指定する必要があります (次の手順で必要になります)。
キーストアファイル名: キーを保存する
.jks
ファイル。キーストアのパスワード:
.jks
キーストレージのパスワード。キーのエイリアス: 秘密キーの名前。
キーのパスワード: 秘密キーのパスワード。
セキュリティ上の理由から、アプリのシークレット署名キーデータと Google サービスアカウントキーはシークレットとパラメーターストレージに保存されます。
すべての機密データをシークレットおよびパラメーターとして保存します。
まず、バイナリ
.jks
キーストアファイルを 16 進形式に変換しましょう。こうすることで、シークレットとして保存することができます。ビルド中に、オートメーションスクリプトは 16 進シークレットをバイナリ.jks
ファイルに変換します。キーストアファイルを変換するには、xxd
ツール (xxd
パッケージの一部) を使用できます。xxd -plain upload_key.jks > upload_key.hexxxd
ツールがない場合は、最初にsudo apt get install xxd
を実行します。Space で、必要なプロジェクトを開きます。
設定 | シークレットとパラメーターを開き、新しいシークレットを作成します。
upload_key.hex
ファイルを開き、その内容をコピーし、シークレット値として貼り付けます。同様に、Google サービスアカウントキーを変換し、そのシークレットを作成します。
xxd -plain google_sa_key.json > google_sa_key.hex実際には、
.json
は単なるプレーンテキストであるため、16 進数に変換する必要はありません。ただし、コピー & ペーストのエンコーディングの課題を回避するには、16 進数として保存し、ビルド中にプレーンテキストに変換し直すことをお勧めします。キーストアのパスワードとキーのパスワードのシークレットを作成します。
キーエイリアスのパラメーターを作成します (安全なストレージは必要ありません)。
その結果、プロジェクトのシークレットとパラメーターには 4 つのシークレットと 1 つのパラメーターが存在します。
プロジェクトレベルの
build.gradle
ファイルで、アプリケーション署名を構成します。セキュリティ上の理由から、環境変数を使用してシークレットとパラメーターストレージに保存されている主要データにアクセスします。例:... // Key store file name // The Automation script will create the key store file in the root directory, // but this build.gradle is located one level down - on the project level. def appKeyStoreFile = "../upload_key.jks" // Key store password, key alias and password created on the prev steps. // Env vars will be assigned by the Automation script. def appKeyStorePassword = System.env.KEY_STORE_PASSWORD def appKeyAlias = System.env.KEY_ALIAS def appKeyPassword = System.env.KEY_PASSWORD android { ... signingConfigs { release { storeFile file(appKeyStoreFile) storePassword appKeyStorePassword keyAlias appKeyAlias keyPassword appKeyPassword } } buildTypes { release { signingConfig signingConfigs.release ... } } }プロジェクトレベルの
build.gradle
ファイルで、Gradle Play Publisher プラグインを構成します。セキュリティ上の理由から、サービスアカウントキーをシークレットとパラメーターストレージに保存し、自動化スクリプトを使用して作成します。プラグインの設定方法の詳細については、プラグインのドキュメント(英語)を参照してください。import com.github.triplet.gradle.androidpublisher.ReleaseStatus plugins { id 'com.android.application' id 'com.github.triplet.play' version '3.3.0' } // Service account key file you created on step 1 // The Automation script will create the key store file in the root directory, // but this build.gradle is located one level down - on the project level. def googleServiceAccountKeyFile = "../google_sa_key.json" ... android {...} play { // We will publish the app to the internal testing track track.set("internal") serviceAccountCredentials.set(file(googleServiceAccountKeyFile)) // Our app is not yet publicly available, // we will publish it in the draft state. releaseStatus.set(ReleaseStatus.DRAFT) } ...ビルド実行番号に応じてアプリのバージョンを自動的に変更する場合は、プロジェクトレベルの
build.gradle
のversionCode
パラメーターとversionName
パラメーターを変更します。例:versionCode
をビルド番号と等しく、versionName
を1.0.$build_number
にしたい場合:def appVersionCode = Integer.valueOf(System.env.JB_SPACE_EXECUTION_NUMBER ?: 0) def appVersionName = "1.0.${System.env.JB_SPACE_EXECUTION_NUMBER}" ... android { ... defaultConfig { ... versionCode appVersionCode versionName appVersionName } } ...結果のプロジェクト
build.gradle
は次のようになります。import com.github.triplet.gradle.androidpublisher.ReleaseStatus plugins { id 'com.android.application' id 'com.github.triplet.play' version '3.3.0' } def appVersionCode = Integer.valueOf(System.env.JB_SPACE_EXECUTION_NUMBER ?: 0) def appVersionName = "1.1.${System.env.JB_SPACE_EXECUTION_NUMBER}" def appKeyStoreFile = "../upload_key.jks" def appKeyStorePassword = System.env.KEY_STORE_PASSWORD def appKeyAlias = System.env.KEY_ALIAS def appKeyPassword = System.env.KEY_PASSWORD def googleServiceAccountKeyFile = "../google_sa_key.json" apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { compileSdkVersion 30 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.first.simpleandroidapp" minSdkVersion 28 targetSdkVersion 30 versionCode appVersionCode versionName appVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } signingConfigs { release { storeFile file(appKeyStoreFile) storePassword appKeyStorePassword keyAlias appKeyAlias keyPassword appKeyPassword // Optional, specify signing versions used v1SigningEnabled true v2SigningEnabled true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { viewBinding true } } play { track.set("internal") serviceAccountCredentials.set(file(googleServiceAccountKeyFile)) releaseStatus.set(ReleaseStatus.DRAFT) } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.4' implementation 'androidx.navigation:navigation-ui-ktx:2.3.4' testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }プロジェクトルートで、
.space.kts
自動化スクリプトを作成します。job("Build and publish bundle to internal track") { // disable gitPush job trigger startOn { gitPush { enabled = false } } container("Build and publish", "mycompany.registry.jetbrains.space/p/projectkey/mydocker/automation-android:1.0.5") { env["GOOGLE_SA_KEY"] = Secrets("google_sa_key") env["KEY_STORE"] = Secrets("key_store") env["KEY_STORE_PASSWORD"] = Secrets("key_store_password") env["KEY_PASSWORD"] = Secrets("key_password") env["KEY_ALIAS"] = Params("key_alias") shellScript { content = """ echo Get private signing key... echo ${'$'}KEY_STORE > upload_key.hex xxd -plain -revert upload_key.hex upload_key.jks echo Get Google service account key... echo ${'$'}GOOGLE_SA_KEY > google_sa_key.hex xxd -plain -revert google_sa_key.hex google_sa_key.json echo Build and publish AAB... ./gradlew publishBundle """ } } }注:
次の要件を満たすカスタム Docker イメージを使用します。
この例では、AAB を構築して公開します。代わりに APK をビルドして公開したい場合は、行
./gradlew publishBundle
を./gradlew publishApk
に変更します。
ジョブを実行します。ジョブが正常に完了したら、Google Play Console を確認します。アップロードされたアプリケーションのドラフトが含まれている必要があります。
必要に応じて、アプリのメタデータ (スクリーンショット、説明など) のアップロード、アプリアーティファクトのプロモーション、製品フレーバーの操作など、他のすべてのリリースタスクを自動化するように Gradle Play Publisher を構成できます。詳細については、Gradle Play パブリッシャーのドキュメント(英語)を参照してください。
fastlane を使用してアプリをビルドして公開する
前提条件
対象イメージ
|
Android アプリケーションは Gradle ビルドツールを使用します。Android プロジェクトのデフォルトの Gradle 構成では、アプリの APK または AAB の生成と署名を自動化できます。できないことは、アプリのアップロードや宣伝などのリリース活動を自動化することです。このセクションでは、fastlane(英語) プラットフォームを利用してこの課題を解決する方法を説明します。fastlane ツールを使用すると、デプロイを自動化し、iOS および Android アプリケーションのルーチンをリリースできます。このツールは、通常、プロジェクトソースとともに VCS に保存される Fastfile
ファイルで構成されます。
fastlane のドキュメント(英語)の説明に従って、Google Cloud Platform サービスアカウントを作成します。このツールは、このアカウントを使用して、Google Play Console でリリースアクティビティを実行します。
サービスアカウントを作成するときに、アカウントの秘密キーを
.json
ファイルで取得します。ファイルをコンピューターに保存します。次の手順で必要になります。アプリに対する十分な権限をアカウントに提供していることを確認してください: テストトラックのリリースを管理する権限が必要です。
。この例では、アプリを内部テストトラックに公開するため、アカウントにはアプリケーションに署名するためのアップロードキーを生成します (この例では、Play アプリの署名を使用します)。すでにキーを持っている場合は、この手順をスキップしてください。キーを生成するには、以下を使用できます。
Android Studio. 詳細
keytool
コマンドラインツール。例:keytool -genkey -v -keystore uploadkey.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
キーを作成するときは、次の情報を指定する必要があります (次の手順で必要になります)。
キーストアファイル名: キーを保存する
.jks
ファイル。キーストアのパスワード:
.jks
キーストレージのパスワード。キーのエイリアス: 秘密キーの名前。
キーのパスワード: 秘密キーのパスワード。
セキュリティ上の理由から、アプリのシークレット署名キーデータと Google サービスアカウントキーはシークレットとパラメーターストレージに保存されます。
すべての機密データをシークレットおよびパラメーターとして保存します。
まず、バイナリ
.jks
キーストアファイルを 16 進形式に変換しましょう。こうすることで、シークレットとして保存することができます。ビルド中に、オートメーションスクリプトは 16 進シークレットをバイナリ.jks
ファイルに変換します。キーストアファイルを変換するには、xxd
ツール (xxd
パッケージの一部) を使用できます。xxd -plain upload_key.jks > upload_key.hexxxd
ツールがない場合は、最初にsudo apt get install xxd
を実行します。Space で、必要なプロジェクトを開きます。
設定 | シークレットとパラメーターを開き、新しいシークレットを作成します。
upload_key.hex
ファイルを開き、その内容をコピーし、シークレット値として貼り付けます。同様に、Google サービスアカウントキーを変換し、そのシークレットを作成します。
xxd -plain google_sa_key.json > google_sa_key.hex実際には、
.json
は単なるプレーンテキストであるため、16 進数に変換する必要はありません。ただし、コピー & ペーストのエンコーディングの課題を回避するには、16 進数として保存し、ビルド中にプレーンテキストに変換し直すことをお勧めします。キーストアのパスワードとキーのパスワードのシークレットを作成します。
キーエイリアスのパラメーターを作成します (安全なストレージは必要ありません)。
その結果、プロジェクトのシークレットとパラメーターには 4 つのシークレットと 1 つのパラメーターが存在します。
プロジェクトレベルの
build.gradle
ファイルで、アプリケーション署名を構成します。セキュリティ上の理由から、環境変数を使用してシークレットとパラメーターストレージに保存されている主要データにアクセスします。例:... // Key store file name // The Automation script will create the key store file in the root directory, // but this build.gradle is located one level down - on the project level. def appKeyStoreFile = "../upload_key.jks" // Key store password, key alias and password created on the prev steps. // Env vars will be assigned by the Automation script. def appKeyStorePassword = System.env.KEY_STORE_PASSWORD def appKeyAlias = System.env.KEY_ALIAS def appKeyPassword = System.env.KEY_PASSWORD android { ... signingConfigs { release { storeFile file(appKeyStoreFile) storePassword appKeyStorePassword keyAlias appKeyAlias keyPassword appKeyPassword } } buildTypes { release { signingConfig signingConfigs.release ... } } }ビルド実行番号に応じてアプリのバージョンを自動的に変更する場合は、プロジェクトレベルの
build.gradle
のversionCode
パラメーターとversionName
パラメーターを変更します。例:versionCode
をビルド番号と等しく、versionName
を1.0.$build_number
にしたい場合:def appVersionCode = Integer.valueOf(System.env.JB_SPACE_EXECUTION_NUMBER ?: 0) def appVersionName = "1.0.${System.env.JB_SPACE_EXECUTION_NUMBER}" ... android { ... defaultConfig { ... versionCode appVersionCode versionName appVersionName } } ...結果のプロジェクト
build.gradle
は次のようになります。plugins { id 'com.android.application' } def appVersionCode = Integer.valueOf(System.env.JB_SPACE_EXECUTION_NUMBER ?: 0) def appVersionName = "1.1.${System.env.JB_SPACE_EXECUTION_NUMBER}" def appKeyStoreFile = "../upload_key.jks" def appKeyStorePassword = System.env.KEY_STORE_PASSWORD def appKeyAlias = System.env.KEY_ALIAS def appKeyPassword = System.env.KEY_PASSWORD apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android { compileSdkVersion 30 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.first.simpleandroidapp" minSdkVersion 28 targetSdkVersion 30 versionCode appVersionCode versionName appVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } signingConfigs { release { storeFile file(appKeyStoreFile) storePassword appKeyStorePassword keyAlias appKeyAlias keyPassword appKeyPassword // Optional, specify signing versions used v1SigningEnabled true v2SigningEnabled true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { viewBinding true } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.4' implementation 'androidx.navigation:navigation-ui-ktx:2.3.4' testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }ファストレーンを構成します。fastlane/Fastfile で、新しいレーンを追加します。
desc "Upload app draft to internal testing track" lane :deploy_draft_to_internal do gradle( task: 'bundle', build_type: 'Release' ) upload_to_play_store( track: 'internal', release_status: 'draft' ) endこのレーンは、まずアプリケーション AAB を構築し、それを内部テストトラックにアップロードします。
fastlane/Appfile ファイルで、Google Play サービスアカウントキーへのパス (プロジェクトルートからの相対パス) を指定します。ビルド中に、プロジェクトシークレットからキーを取得し、それをルートディレクトリに置きます。ここでは任意の名前を指定できます。例:
Appfile
は次のようになります。json_key_file("google_sa_key.json") package_name("com.first.simpleandroidapp")プロジェクトルートで、
.space.kts
自動化スクリプトを作成します。job("Build and publish bundle to internal track") { // disable gitPush job trigger startOn { gitPush { enabled = false } } container("Build and publish", "mycompany.registry.jetbrains.space/p/projectkey/mydocker/automation-android-fastlane:1.0.5") { env["GOOGLE_SA_KEY"] = Secrets("google_sa_key") env["KEY_STORE"] = Secrets("key_store") env["KEY_STORE_PASSWORD"] = Secrets("key_store_password") env["KEY_PASSWORD"] = Secrets("key_password") env["KEY_ALIAS"] = Params("key_alias") shellScript { content = """ echo Get private signing key... echo ${'$'}KEY_STORE > upload_key.hex xxd -plain -revert upload_key.hex upload_key.jks echo Get Google service account key... echo ${'$'}GOOGLE_SA_KEY > google_sa_key.hex xxd -plain -revert google_sa_key.hex google_sa_key.json echo Build and publish AAB... fastlane android deploy_draft_to_internal """ } } }注:
次の要件を満たすカスタム Docker イメージを使用します。
サービスアカウントキーをルートディレクトリの
google_sa_key.json
ファイル ( fastlane/Appfile で指定したのと同じファイル) に復元します。
ジョブを実行します。ジョブが正常に完了したら、Google Play Console を確認します。アップロードされたアプリケーションのドラフトが含まれている必要があります。
必要に応じて、アプリのメタデータ (スクリーンショット、説明など) のアップロード、アプリアーティファクトのプロモーション、製品フレーバーの操作など、他のすべてのリリースタスクを自動化するように fastlane を構成できます。詳細については、fastlane のドキュメント(英語)を参照してください。
Android プロジェクトでテストを実行する
Android プロジェクトは、次の 2 種類のテストをサポートします。
ローカルユニットテスト
これらは「通常の」単体テストです。これらのテストは通常、Android アプリケーションをビルド / 公開するときに実行されます。例:
./gradlew test
を使用してローカル単体テストを実行できます。計測されたテスト
これらのテストは、実際の Android デバイス上またはエミュレータ内で実行されます。インストルメント化されたテストの実行を自動化するには、Google が提供するクラウドベースのサービスである Firebase Test Lab を使用できます。Firebase Test Lab は、オートメーションスクリプトで使用できる
gcloud
コマンドラインツールを完全にサポートしています。詳細 (英語)
関連ページ:
![](https://resources.jetbrains.com/help/img/space/secretsMavenRepo.png)
Java および Kotlin 用の Gradle
前提条件 Java または Kotlin で書かれたプロジェクトがあります。プロジェクトでは Gradle を使用します。Gradle ラッパーはプロジェクトのルートディレクトリに存在します。アーティファクトを Space パッケージに公開する場合は、プロジェクトに Maven リポジトリがあることを確認してください。対象イメージ JRE/JDK バージョン 11 以降を含むイメージ。例:amazoncorretto イメージ。通常、プロジェクトを構築してテストを実行するために必要なのは、プロジェクト...
![](https://pleiades.io/icons/jetbrains_logo.png)
パラメーターとシークレット
パラメーターは、ユーザーによって定義されるか、Automation によって提供される名前と値のペアです。パラメーターの主な目的は、さまざまなデータをジョブに渡すことです。例: これは、Docker イメージ名、URL、コマンドライン引数などです。あるいは、アクセストークンやパスワードである場合もあります。このような機密パラメーターはシークレットと呼ばれます。ジョブでパラメーターを使用する:ジョブのパラメーターを取得するには、その名前を二重波括弧: 内の文字列で指定します。これは、、を除く、DS...