Refactor: Improve GitHub release workflow and build configuration (#2251)

pull/2252/head
James Rich 2025-06-25 23:16:55 +00:00 zatwierdzone przez GitHub
rodzic d507161bde
commit 496de47766
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
8 zmienionych plików z 284 dodań i 112 usunięć

Wyświetl plik

@ -2,108 +2,253 @@ name: Make Release
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
branch:
description: 'Branch to build from'
required: true
default: 'main' # Or your most common release branch
type: string
create_github_release:
description: 'Create a GitHub Release (and upload assets)'
required: true
default: true
type: boolean
permissions: write-all permissions: write-all # Needed for creating releases and uploading assets
jobs: jobs:
# Job to prepare common environment variables like version
prepare-release-info:
runs-on: ubuntu-latest
outputs:
versionCode: ${{ steps.get_version.outputs.versionCode }}
versionName: ${{ steps.get_version.outputs.versionName }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
submodules: 'recursive'
release-build: - name: Get `versionCode` & `versionName`
id: get_version
run: |
echo "versionCode=$(grep -oP 'VERSION_CODE = \K\d+' ./buildSrc/src/main/kotlin/Configs.kt)" >> $GITHUB_OUTPUT
echo "versionName=$(grep -oP 'VERSION_NAME = \"\K[^\"]+' ./buildSrc/src/main/kotlin/Configs.kt)" >> $GITHUB_OUTPUT
# Job for F-Droid build
build-fdroid:
needs: prepare-release-info # Depends on version info
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.repository == 'meshtastic/Meshtastic-Android' if: github.repository == 'meshtastic/Meshtastic-Android'
outputs:
apk_path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
apk_name: fdroidRelease-${{ needs.prepare-release-info.outputs.versionName }}.apk
steps: steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
submodules: 'recursive'
- name: Checkout code - name: Cache Gradle packages
uses: actions/checkout@v4 uses: actions/cache@v4
with: with:
submodules: 'recursive' path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Get `versionCode` & `versionName` - name: Validate Gradle wrapper
run: | uses: gradle/actions/wrapper-validation@v4
echo "versionCode=$(grep -oP 'VERSION_CODE = \K\d+' ./buildSrc/src/main/kotlin/Configs.kt)" >> $GITHUB_ENV
echo "versionName=$(grep -oP 'VERSION_NAME = \"\K[^\"]+' ./buildSrc/src/main/kotlin/Configs.kt)" >> $GITHUB_ENV
- name: Validate Gradle wrapper - name: Load secrets (only keystore for F-Droid)
uses: gradle/actions/wrapper-validation@v4 run: |
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
env:
KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }}
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
- name: Load secrets - name: Set up JDK 21
run: | uses: actions/setup-java@v4
rm ./app/google-services.json with:
echo $GSERVICES > ./app/google-services.json java-version: '21'
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME distribution: 'jetbrains'
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
echo -e "versionCode=$versionCode\nversionName=$versionName" > ./version_info.txt - name: Build F-Droid release
env: run: ./gradlew assembleFdroidRelease
- name: Upload F-Droid APK artifact (for release job)
uses: actions/upload-artifact@v4
with:
name: fdroid-apk
path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
retention-days: 1 # Keep for a short period as it will be uploaded to release
# Job for Play Store build
build-google:
needs: prepare-release-info # Depends on version info
runs-on: ubuntu-latest
if: github.repository == 'meshtastic/Meshtastic-Android'
outputs:
aab_path: app/build/outputs/bundle/googleRelease/app-google-release.aab
aab_name: googleRelease-${{ needs.prepare-release-info.outputs.versionName }}.aab
apk_path: app/build/outputs/apk/google/release/app-google-release.apk
apk_name: googleRelease-${{ needs.prepare-release-info.outputs.versionName }}.apk
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
submodules: 'recursive'
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v4
- name: Load secrets
run: |
rm -f ./app/google-services.json # Ensure clean state
echo $GSERVICES > ./app/google-services.json
echo $KEYSTORE | base64 -di > ./app/$KEYSTORE_FILENAME
echo "$KEYSTORE_PROPERTIES" > ./keystore.properties
env:
GSERVICES: ${{ secrets.GSERVICES }} GSERVICES: ${{ secrets.GSERVICES }}
KEYSTORE: ${{ secrets.KEYSTORE }} KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }} KEYSTORE_FILENAME: ${{ secrets.KEYSTORE_FILENAME }}
KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }} KEYSTORE_PROPERTIES: ${{ secrets.KEYSTORE_PROPERTIES }}
- name: Set up JDK 17 - name: Set up JDK 24
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
java-version: '21' java-version: '24'
distribution: 'jetbrains' distribution: 'jetbrains'
# Note: we don't use caches on release builds because we don't want to accidentally not have a virgin build machine
- name: Build F-Droid release - name: Build Play Store release
run: ./gradlew assembleFdroidRelease run: ./gradlew bundleGoogleRelease assembleGoogleRelease
- name: Enable Crashlytics - name: Upload Play Store AAB artifact (for release job)
run: sed -i 's/USE_CRASHLYTICS = false/USE_CRASHLYTICS = true/g' ./buildSrc/src/main/kotlin/Configs.kt uses: actions/upload-artifact@v4
with:
name: google-aab
path: app/build/outputs/bundle/googleRelease/app-google-release.aab
retention-days: 1
- name: Build Play Store release - name: Upload Play Store APK artifact (for release job)
run: ./gradlew bundleGoogleRelease assembleGoogleRelease uses: actions/upload-artifact@v4
with:
name: google-apk
path: app/build/outputs/apk/google/release/app-google-release.apk
retention-days: 1
- name: Create GitHub release # Job to create GitHub release and upload assets (runs after builds if enabled)
uses: actions/create-release@v1 create-github-release:
id: create_release needs: [ prepare-release-info, build-fdroid, build-google ]
with: runs-on: ubuntu-latest
draft: true # Only run this job if the input create_github_release is true
prerelease: true if: github.repository == 'meshtastic/Meshtastic-Android' && github.event.inputs.create_github_release == 'true'
release_name: Meshtastic Android ${{ env.versionName }} alpha steps:
tag_name: ${{ env.versionName }} # We need version info again for release name and tag
body: | # Alternatively, we could pass it as an artifact, but this is simpler for just two values
Autogenerated by github action, developer should edit as required before publishing... - name: Checkout code (for version_info.txt and version retrieval)
env: uses: actions/checkout@v4
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with:
ref: ${{ github.event.inputs.branch }} # Checkout the specified branch
- name: Add F-Droid APK to release - name: Get `versionCode` & `versionName` (again for this job's env)
uses: actions/upload-release-asset@v1 id: get_version # Unique ID within this job
env: run: |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} echo "versionCode=$(grep -oP 'VERSION_CODE = \K\d+' ./buildSrc/src/main/kotlin/Configs.kt)" >> $GITHUB_ENV
with: echo "versionName=$(grep -oP 'VERSION_NAME = \"\K[^\"]+' ./buildSrc/src/main/kotlin/Configs.kt)" >> $GITHUB_ENV
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: app/build/outputs/apk/fdroid/release/app-fdroid-release.apk
asset_name: fdroidRelease-${{ env.versionName }}.apk
asset_content_type: application/zip
- name: Add Play Store AAB to release - name: Create version_info.txt
uses: actions/upload-release-asset@v1 run: |
env: echo -e "versionCode=${{ env.versionCode }}\nversionName=${{ env.versionName }}" > ./version_info.txt
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: app/build/outputs/bundle/googleRelease/app-google-release.aab
asset_name: googleRelease-${{ env.versionName }}.aab
asset_content_type: application/zip
- name: Add Play Store APK to release - name: Download F-Droid APK
uses: actions/upload-release-asset@v1 uses: actions/download-artifact@v4
env: with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} name: fdroid-apk
with: path: ./fdroid-apk-download # Download to a specific folder
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: app/build/outputs/apk/google/release/app-google-release.apk
asset_name: googleRelease-${{ env.versionName }}.apk
asset_content_type: application/zip
# https://github.com/f-droid/fdroiddata/blob/main/metadata/com.geeksville.mesh.yml#L34 - name: Download Google AAB
- name: Add `version_info.txt` to release uses: actions/download-artifact@v4
uses: actions/upload-release-asset@v1 with:
env: name: google-aab
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} path: ./google-aab-download
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} - name: Download Google APK
asset_path: version_info.txt uses: actions/download-artifact@v4
asset_name: version_info.txt with:
asset_content_type: text/plain name: google-apk
path: ./google-apk-download
- name: Create GitHub release
uses: actions/create-release@v1
id: create_release_step
with:
draft: true
prerelease: true
release_name: Meshtastic Android ${{ env.versionName }} alpha (Branch ${{ github.event.inputs.branch }})
tag_name: ${{ env.versionName }} # Consider making tag unique if version can be same across branches, e.g., ${{ env.versionName }}-${{ github.event.inputs.branch }}
target_commitish: ${{ github.event.inputs.branch }}
body: |
Release built from branch: `${{ github.event.inputs.branch }}`
Version: ${{ env.versionName }} (Code: ${{ env.versionCode }})
Autogenerated by GitHub Action. Please review and edit before publishing.
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Add F-Droid APK to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release_step.outputs.upload_url }}
asset_path: ./fdroid-apk-download/app-fdroid-release.apk # Path from download
asset_name: fdroidRelease-${{ env.versionName }}.apk
asset_content_type: application/vnd.android.package-archive
- name: Add Play Store AAB to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release_step.outputs.upload_url }}
asset_path: ./google-aab-download/app-google-release.aab # Path from download
asset_name: googleRelease-${{ env.versionName }}.aab
asset_content_type: application/octet-stream # More generic for AAB
- name: Add Play Store APK to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release_step.outputs.upload_url }}
asset_path: ./google-apk-download/app-google-release.apk # Path from download
asset_name: googleRelease-${{ env.versionName }}.apk
asset_content_type: application/vnd.android.package-archive
- name: Add version_info.txt to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release_step.outputs.upload_url }}
asset_path: ./version_info.txt
asset_name: version_info.txt
asset_content_type: text/plain

Wyświetl plik

@ -72,11 +72,9 @@ android {
} }
create("google") { create("google") {
dimension = "default" dimension = "default"
if (Configs.USE_CRASHLYTICS) { // Enable Firebase Crashlytics for Google Play builds
// Enable Firebase Crashlytics for Google Play builds apply(plugin = libs.plugins.google.services.get().pluginId)
apply(plugin = libs.plugins.google.services.get().pluginId) apply(plugin = libs.plugins.firebase.crashlytics.get().pluginId)
apply(plugin = libs.plugins.firebase.crashlytics.get().pluginId)
}
} }
} }
buildTypes { buildTypes {
@ -126,7 +124,7 @@ android {
aidl = true aidl = true
buildConfig = true buildConfig = true
} }
// Configure the build-logic plugins to target JDK 17 // Configure the build-logic plugins to target JDK 21
// This matches the JDK used to build the project, and is not related to what is running on device. // This matches the JDK used to build the project, and is not related to what is running on device.
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_21 sourceCompatibility = JavaVersion.VERSION_21
@ -144,7 +142,9 @@ android {
kotlin { kotlin {
compilerOptions { compilerOptions {
jvmTarget = JvmTarget.JVM_21 // match Java 21 jvmToolchain {
JvmTarget.JVM_21
}
freeCompilerArgs.addAll( freeCompilerArgs.addAll(
"-opt-in=kotlin.RequiresOptIn", "-opt-in=kotlin.RequiresOptIn",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",

Wyświetl plik

@ -85,6 +85,7 @@ interface PacketDao {
@Upsert @Upsert
suspend fun insert(packet: Packet) suspend fun insert(packet: Packet)
@Transaction
@Query( @Query(
""" """
SELECT * FROM packet SELECT * FROM packet
@ -93,7 +94,6 @@ interface PacketDao {
ORDER BY received_time DESC ORDER BY received_time DESC
""" """
) )
@Transaction
fun getMessagesFrom(contact: String): Flow<List<PacketEntity>> fun getMessagesFrom(contact: String): Flow<List<PacketEntity>>
@Query( @Query(
@ -164,6 +164,7 @@ interface PacketDao {
) )
suspend fun getDataPackets(): List<DataPacket> suspend fun getDataPackets(): List<DataPacket>
@Transaction
@Query( @Query(
""" """
SELECT * FROM packet SELECT * FROM packet
@ -174,6 +175,7 @@ interface PacketDao {
) )
suspend fun getPacketById(requestId: Int): Packet? suspend fun getPacketById(requestId: Int): Packet?
@Transaction
@Query("SELECT * FROM packet WHERE packet_id = :packetId LIMIT 1") @Query("SELECT * FROM packet WHERE packet_id = :packetId LIMIT 1")
suspend fun getPacketByPacketId(packetId: Int): PacketEntity? suspend fun getPacketByPacketId(packetId: Int): PacketEntity?

Wyświetl plik

@ -24,17 +24,8 @@ buildscript {
classpath(libs.agp) classpath(libs.agp)
classpath(libs.kotlin.gradle.plugin) classpath(libs.kotlin.gradle.plugin)
classpath(libs.kotlin.serialization) classpath(libs.kotlin.serialization)
classpath(libs.google.services)
// Google Play Services and Firebase Crashlytics classpath(libs.firebase.crashlytics.gradle)
// If you want to use Firebase Crashlytics,
// set Configs.USE_CRASHLYTICS to true in:
// buildSrc/src/main/kotlin/Configs.kt
// Disabled by default for fdroid builds
if (Configs.USE_CRASHLYTICS) {
classpath(libs.google.services)
classpath(libs.firebase.crashlytics.gradle)
}
classpath(libs.protobuf.gradle.plugin) classpath(libs.protobuf.gradle.plugin)
classpath(libs.hilt.android.gradle.plugin) classpath(libs.hilt.android.gradle.plugin)
} }

Wyświetl plik

@ -22,7 +22,6 @@ object Configs {
const val COMPILE_SDK = 36 const val COMPILE_SDK = 36
const val VERSION_CODE = 30625 // format is Mmmss (where M is 1+the numeric major number) const val VERSION_CODE = 30625 // format is Mmmss (where M is 1+the numeric major number)
const val VERSION_NAME = "2.6.25" const val VERSION_NAME = "2.6.25"
const val USE_CRASHLYTICS = false // Set to true if you want to use Firebase Crashlytics
const val MIN_FW_VERSION = "2.5.14" // Minimum device firmware version supported by this app const val MIN_FW_VERSION = "2.5.14" // Minimum device firmware version supported by this app
const val ABS_MIN_FW_VERSION = "2.3.15" // Minimum device firmware version supported by this app const val ABS_MIN_FW_VERSION = "2.3.15" // Minimum device firmware version supported by this app
} }

Wyświetl plik

@ -1,3 +1,20 @@
#
# Copyright (c) 2025 Meshtastic LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Project-wide Gradle settings. # Project-wide Gradle settings.
# IDE (e.g. Android Studio) users: # IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override* # Gradle settings configured through the IDE *will override*
@ -13,10 +30,9 @@ org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true org.gradle.parallel=true
# Not encouraged by Gradle and can produce weird results. Wait for isolated projects instead. org.gradle.configureondemand=true
org.gradle.configureondemand=false
# Enable caching between builds. # Enable caching between builds.
org.gradle.caching=true org.gradle.caching=true
@ -29,6 +45,8 @@ org.gradle.configuration-cache=true
# https://developer.android.com/topic/libraries/support-library/androidx-rn # https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=false
# Kotlin code style for this project: "official" or "obsolete": # Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official kotlin.code.style=official

Wyświetl plik

@ -17,6 +17,23 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/* /*
* Copyright (c) 2025 Meshtastic LLC * Copyright (c) 2025 Meshtastic LLC
* *
@ -68,8 +85,8 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_11 sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_21
} }
buildFeatures { buildFeatures {
aidl = true aidl = true
@ -78,7 +95,7 @@ android {
kotlin { kotlin {
compilerOptions { compilerOptions {
jvmTarget = JvmTarget.JVM_11 // match Java 11 jvmTarget = JvmTarget.JVM_21
} }
} }

Wyświetl plik

@ -30,15 +30,15 @@ android {
buildFeatures { buildFeatures {
buildConfig = true buildConfig = true
} }
compileSdk = 35 compileSdk = Configs.COMPILE_SDK
defaultConfig { defaultConfig {
minSdk = 21 minSdk = Configs.MIN_SDK_VERSION
} }
namespace = "com.geeksville.mesh.network" namespace = "com.geeksville.mesh.network"
compileOptions { compileOptions {
sourceCompatibility(JavaVersion.VERSION_17) sourceCompatibility(JavaVersion.VERSION_21)
targetCompatibility(JavaVersion.VERSION_17) targetCompatibility(JavaVersion.VERSION_21)
} }
flavorDimensions += "default" flavorDimensions += "default"
@ -54,7 +54,7 @@ android {
kotlin { kotlin {
compilerOptions { compilerOptions {
jvmTarget.set(JvmTarget.JVM_17) jvmTarget.set(JvmTarget.JVM_21)
} }
} }