社内マシンでのAndroidビルドの廃止とリリースビルドの確認をスムーズにしました

アプリチームの松田です。
今回は自分が行ったアプリチームの最近の開発の改善について、共有しようと思います。

課題

アプリチームではリリースビルドやQA用のビルドで、以下の問題を抱えていました。

リリースビルドを行い、QA用にFirebase App Distributionに配信する為のMac Miniが社内に存在しているのです。これは、ずっと起動し続けている為、それが原因でビルドできなくなり、再起動が必要な時があります。
特にこのマシンでないといけない理由もなく、過去から引き続いて使用されていただけでした。アップデート等のコストもかかりますし、これをCIサービスに移すことにしました。

改善

これらの処理をGitHub Actionsに移すことにしました。手動での実行が楽なのが良い点です。
ボタンを押したら実行されるというのは workflow_dispatch を利用すればできます。 こちらを利用して、QA用リリースビルドを行えるようしました。Checkboxでのfeatureフラグの有効化機能もあります。

配信が終わると以下のような出力が行われます。
Firebase App Distributionのダウンロードリンクと、そのQRコードです。Jetpack Composeの導入に伴い、リリースビルドでの動作確認が以前より多くなった為、開発中にリリースビルドを行い、すぐにダウンロードして確認したいという需要がありました。そのため、QRコードを読み取るだけでアプリのインストールページに飛べるのは非常に楽です。

Firebase App Distributionへのリンクや、それを構成するIDはAPIを叩かないと取得できないようだったので、以下のAPIを叩いて取得しました。
https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.apps.releases/list

QAコード

QRコードについては、GitHubに画像をアップロードするAPIが無いため、文字列でQRコードを構成しました。

generate_qrcode.main.kts

#!/usr/bin/env kotlin
@file:DependsOn("com.google.zxing:core:3.5.0")

import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.MultiFormatWriter
import com.google.zxing.common.BitMatrix
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel

object QRCodeGenerator {
    fun generate(text: String): String {
        val hints: Map<EncodeHintType, Any> = mutableMapOf(
            EncodeHintType.MARGIN to 1,
            EncodeHintType.ERROR_CORRECTION to ErrorCorrectionLevel.L
        )

        val size = 0
        val matrix = MultiFormatWriter().encode(
            text,
            BarcodeFormat.QR_CODE, size, size, hints
        )

        return generateTwoYQRCode(matrix.toList())
    }

    private fun BitMatrix.toList(): List<List<Boolean>> {
        val matrix = this
        return (0 until matrix.height).map { y ->
            (0 until matrix.width).map { x ->
                matrix.get(x, y).not()
            }
        }
    }

    private fun generateTwoYQRCode(matrix: List<List<Boolean>>): String {
        val result = matrix.windowed(size = 2, step = 2, partialWindows = true).map { yList ->
            (yList[0].indices).map { xIndex ->
                val yTop = yList[0][xIndex]
                val yBottom = yList.getOrNull(1)?.get(xIndex) ?: false

                when {
                    yTop && yBottom -> {
                        "█"
                    }
                    yTop && !yBottom -> {
                        "▀"
                    }
                    !yTop && yBottom -> {
                        "▄"
                    }
                    else -> {
                        " "
                    }
                }
            }
        }

        return result.joinToString("\n") { row ->
            row.joinToString("")
        }
    }
}

println(QRCodeGenerator.generate(args[0]))

その他の改善

この workflow_dispatch を使用してバージョンをインクリメントして、リリースPRを作成する機能も作成しました。今まではバージョンをインクリメントするGradle Taskを実行した後、手動でPRを作成していたため、リリース作業が楽になりました。

おわりに

GitHub Actionsはコメントをトリガーにして実行やPRの作成等、GitHub上での業務改善にとても便利なので、今後も活用していこうと思っています。