たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 3920
どうもこんばんわ。
創作彼女の恋愛公式 攻略しました。
ゆめみちゃんが可愛かったです。アペンド配信まだですか!!!!
表情いっぱいあるのかわいい。
共通が長いのが好きな方はどうぞ、わたし的には個別長いほうが良いかな
(え?グランドエンディング?...アペンド配信に期待)
GitHub ActionsでAndroidのリリースAPKを作成したい!
releaseブランチへpushしたら勝手にAPK作ってくれるようにしたい!
このブログでも何回か登場してるやつ。
ビルド作業とかを自分のPCじゃなくてGitHubのマシンでやらせることができる。
しかもパブリックリポジトリなら無料!。
今回はこれを使ってそこそこ時間のかかるAPK作成をGitHub Actions(他の人のPC)にやらせます!
今回はkts
へ移行したbuild.gradle.kts
を利用します。
build.gradle
の場合はコピペで動かないと思います;;
build.gradle.kts
を編集してコマンドラインからAPKを作成して署名できるようにするGitHub Actions
を組む今回はrelease
ブランチを作成して、このブランチに対してpushがあった際に自動でAPKを作成するようにします。
APKを作成したい場合はこのブランチへmasterの中身をマージしてpushすれば良いわけなんですね。
(もし最初からあるmasterブランチをpushするたびにapkを作りたい場合はこれの作業はいらない)
appフォルダにあるbuild.gradle.kts
を開きます。
build.gradle
をお使いの方はすいませんわからないです(Kotlinしか分からんしKotlinも分からん)
そしてコピペしてください。
import java.util.*
android {
// 省略
// APK作成と署名の設定
signingConfigs {
// 環境変数から取りに行く
create("release_signing_config") {
// 存在しない場合はとりあえずスルーする
if (System.getenv("ENV_SIGN_KEYSTORE_BASE64") != null) {
// GitHubActionsの環境変数に入れておいた署名ファイルがBase64でエンコードされているので戻す
System.getenv("ENV_SIGN_KEYSTORE_BASE64").let { base64 ->
val decoder = Base64.getDecoder()
// ルートフォルダに作成する
File("keystore.jks").also { file ->
file.createNewFile()
file.writeBytes(decoder.decode(base64))
}
}
// どうやら appフォルダ の中を見に行ってるみたいなのでプロジェクトのルートフォルダを指定する
storeFile = File(rootProject.projectDir, "keystore.jks")
keyAlias = System.getenv("ENV_SIGN_KEY_ALIAS")
keyPassword = System.getenv("ENV_SIGN_KEY_PASSWORD")
storePassword = System.getenv("ENV_SIGN_STORE_PASSWORD")
}
}
}
buildTypes {
release {
// 署名の設定を適用する
signingConfig = signingConfigs.getByName("release_signing_config")
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
一番上のimport java.util.*
はBase64のデコードを行うために必要です。
署名に使うパスワードとかは環境変数から取得するようにしました。
build.gradle.kts
へ直接書くとパスワードが誰でも見れてしまうので大問題です。
じゃあどこにパスワードを保存しておくかという話ですが、GitHubのSecret機能にパスワードなんかの機密情報を登録しておきます。
そしてGitHub Actionsの環境変数をセットする際にSecretの値を使うことで、安全にパスワードを渡すことが出来ます。
でも署名ファイルをどうやって渡すのかというのが問題になります。パスワードは文字列でしたが今回はファイルです。
この問題を解決するのがBase64
です。これを利用することでファイルをよく分からん文字列に変換してくれます(その逆も可)。文字列になったらこっちのものです。
なのでSecretへ文字列になった署名ファイルを登録しておいて、
ビルド時に文字列から署名ファイルを作成することで安全に署名ファイルも管理できました。
他の例だと、Base64へのエンコード/デコードをコマンドラインにやらせてる例がありますが、なんかbuild.gradle.kts
の中でいい感じに変換できたのでこれで行きます。
Androidアプリの署名で使ってるkeystore.jks
みたいなファイルをBase64に変換します。
Windowsの標準機能でBase64に変換できるみたいなのでやってみましょう。
適当なフォルダでPowerShellとかを開いてコマンドを叩きます
certutil -encode {署名ファイルのパス} encode.txt
コマンドを叩くとencode.txt
が出来てると思うので開いて、
-----BEGIN CERTIFICATE-----
、-----END CERTIFICATE-----
を消して
改行も消します。
消せたらコピーします。
リポジトリの Secrets > Actions へ進みます。
そしてこの中に署名で使うパスワード等を保存していくわけですが、
さっきのbuild.gradle.kts
をパクった場合の名前と値の対応表です↓
名前変えた場合はそれぞれ変えて...
New repository secretから追加できます。
名前 | 入れる中身 |
---|---|
ENV_SIGN_KEYSTORE_BASE64 | Base64にした署名ファイル |
ENV_SIGN_KEY_ALIAS | Key alias |
ENV_SIGN_KEY_PASSWORD | Key password |
ENV_SIGN_STORE_PASSWORD | Key store password |
もしパクった場合はSecretはこうなります
GitHubのリポジトリにあるActions
から新しいワークフローを作成します。
テンプレ置いておくので皆さんは Simple workflow を選んでいいですよ。
そしてAPKを作成するワークフローはこちらです!!!
name: Generate Release APK
on:
# releaseブランチ更新時に起動する
push:
branches: [ release ]
# 手動実行ボタン
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
# releaseブランチをチェックアウト
- uses: actions/checkout@v2
with:
ref: 'release'
# JDK導入
- name: set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
cache: gradle
# 権限を与える
- name: Grant permission gradlew
run: chmod +x gradlew
# コマンドラインからAPKの作成。実行前に環境変数をGitHubActionsのSecretから取得
- name: Building APK
env:
ENV_SIGN_KEYSTORE_BASE64: ${{secrets.ENV_SIGN_KEYSTORE_BASE64}}
ENV_SIGN_KEY_ALIAS: ${{secrets.ENV_SIGN_KEY_ALIAS}}
ENV_SIGN_KEY_PASSWORD: ${{secrets.ENV_SIGN_KEY_PASSWORD}}
ENV_SIGN_STORE_PASSWORD: ${{secrets.ENV_SIGN_STORE_PASSWORD}}
run: ./gradlew assembleRelease
# アーティファクトとして保存
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: app-release.apk
path: app/build/outputs/apk/release/app-release.apk
もしブランチ名が違う場合は branches: [ release ]
と ref: 'release'
のrelease
の部分を各自書き換えてください。(master
とか?)
GitHubのSecretは勝手に環境変数にはならないので、env
で定義する必要があります。
出来たらコミット+プッシュしましょう。
(releaseブランチをGitHub Actionsのトリガーにしていた場合)
releaseブランチに切り替えて、pushしてみます。
これで動き始めるはず。Actionsタブへ移動します。
pushせずに動かすことが出来ます。ここをポチッと
APKもちゃんとアーティファクトの欄にありますね。
これで自分のPCへ負荷をかけずにAPKを作ることが出来ました。やったー
Windows以外は知りません
Android Studioのターミナルを開きます。
環境変数の設定をします。{}
の部分は各自違うと思うのでそれぞれ入れてください
set ENV_SIGN_KEYSTORE_BASE64 = {Base64にした署名ファイル}
set ENV_SIGN_KEY_ALIAS = {Key alias}
set ENV_SIGN_KEY_PASSWORD = {Key password}
set ENV_SIGN_STORE_PASSWORD = {Key store password}
確認のためにset
を叩くと環境変数一覧を見ることが出来ます
set
パスワードとかに間違いがなければ以下のコマンドを入力します
gradlew assembleRelease
終わると app/build/outputs/apk/release
の中にAPKが出来ていると思います。
最低限の build.gradle.kts 置いておきます。
// トップレベル (appフォルダじゃない) build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application").version("7.1.0").apply(false)
id("com.android.library").version("7.1.0").apply(false)
id("org.jetbrains.kotlin.android").version("1.6.10").apply(false)
}
tasks.register("clean") {
doFirst {
delete(rootProject.buildDir)
}
}
// appフォルダ内 build.gradle.kts
import java.util.*
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-kapt")
}
android {
compileSdk = 31
defaultConfig {
applicationId = "io.github.takusan23.chocodroid"
minSdk = 21
targetSdk = 31
versionCode = 1
versionName = "1.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
viewBinding = true
}
// APK作成と署名の設定
signingConfigs {
/**
* 予め GitHubActions の環境変数に入れておく
*
* ローカル環境で行う場合 (Windows cmd.exe)
*
* set ENV_SIGN_KEYSTORE_BASE64 = Base64エンコードした署名ファイル
* set ENV_SIGN_KEY_ALIAS = KeyAlias
* set ENV_SIGN_KEY_PASSWORD = KeyPassword
* set ENV_SIGN_STORE_PASSWORD = StorePassword
* */
create("release_signing_config") {
// 存在しない場合はとりあえずスルーする
if (System.getenv("ENV_SIGN_KEYSTORE_BASE64") != null) {
// GitHubActionsの環境変数に入れておいた署名ファイルがBase64でエンコードされているので戻す
System.getenv("ENV_SIGN_KEYSTORE_BASE64").let { base64 ->
val decoder = Base64.getDecoder()
// ルートフォルダに作成する
File("keystore.jks").also { file ->
file.createNewFile()
file.writeBytes(decoder.decode(base64))
}
}
// どうやら appフォルダ の中を見に行ってるみたいなのでプロジェクトのルートフォルダを指定する
storeFile = File(rootProject.projectDir, "keystore.jks")
keyAlias = System.getenv("ENV_SIGN_KEY_ALIAS")
keyPassword = System.getenv("ENV_SIGN_KEY_PASSWORD")
storePassword = System.getenv("ENV_SIGN_STORE_PASSWORD")
}
}
}
buildTypes {
release {
// 署名の設定を適用する
signingConfig = signingConfigs.getByName("release_signing_config")
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.appcompat:appcompat:1.4.0")
implementation("com.google.android.material:material:1.4.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
}