mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-04 04:35:43 -04:00
build: use git commit count for versionCode (#3233)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@@ -45,13 +45,21 @@ jobs:
|
||||
id: get_version_name
|
||||
run: echo "APP_VERSION_NAME=$(echo ${GITHUB_REF_NAME#v} | sed 's/-.*//')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Calculate Version Code from Epoch
|
||||
- name: Extract VERSION_CODE_OFFSET from config.properties
|
||||
id: get_version_code_offset
|
||||
run: |
|
||||
OFFSET=$(grep '^VERSION_CODE_OFFSET=' config.properties | cut -d'=' -f2)
|
||||
echo "VERSION_CODE_OFFSET=$OFFSET" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Calculate Version Code from Git Commit Count
|
||||
id: calculate_version_code
|
||||
# We use epoch minutes to ensure a unique, always-incrementing version code.
|
||||
# This is compatible with our release strategy of tagging the same commit for different
|
||||
# channels (internal, closed, open, prod), as each build needs a unique code.
|
||||
# This will overflow Integer.MAX_VALUE in the year 6052, hopefully we'll have moved on by then.
|
||||
run: echo "versionCode=$(( $(date +%s) / 60 ))" >> $GITHUB_OUTPUT
|
||||
run: |
|
||||
COMMIT_COUNT=$(git rev-list --count HEAD)
|
||||
OFFSET=${{ steps.get_version_code_offset.outputs.VERSION_CODE_OFFSET }}
|
||||
VERSION_CODE=$((COMMIT_COUNT + OFFSET))
|
||||
echo "versionCode=$VERSION_CODE" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
# This matches the reproducible versionCode strategy: versionCode = git commit count + offset
|
||||
|
||||
release-google:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import com.geeksville.mesh.buildlogic.Configs
|
||||
import com.geeksville.mesh.buildlogic.GitVersionValueSource
|
||||
import java.io.FileInputStream
|
||||
import java.util.Properties
|
||||
@@ -44,10 +43,16 @@ if (keystorePropertiesFile.exists()) {
|
||||
FileInputStream(keystorePropertiesFile).use { keystoreProperties.load(it) }
|
||||
}
|
||||
|
||||
val configPropertiesFile = rootProject.file("config.properties")
|
||||
val configProperties = Properties()
|
||||
|
||||
if (configPropertiesFile.exists()) {
|
||||
FileInputStream(configPropertiesFile).use { configProperties.load(it) }
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.geeksville.mesh"
|
||||
// Assuming Configs object is available (e.g., from buildSrc)
|
||||
compileSdk = Configs.COMPILE_SDK
|
||||
namespace = configProperties.getProperty("APPLICATION_ID")
|
||||
compileSdk = configProperties.getProperty("COMPILE_SDK").toInt()
|
||||
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
@@ -58,25 +63,26 @@ android {
|
||||
}
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId = Configs.APPLICATION_ID
|
||||
minSdk = Configs.MIN_SDK
|
||||
targetSdk = Configs.TARGET_SDK
|
||||
applicationId = configProperties.getProperty("APPLICATION_ID")
|
||||
minSdk = configProperties.getProperty("MIN_SDK").toInt()
|
||||
targetSdk = configProperties.getProperty("TARGET_SDK").toInt()
|
||||
|
||||
// Prioritize injected props, then ENV, then fallback to git commit count
|
||||
val vcOffset = configProperties.getProperty("VERSION_CODE_OFFSET")?.toInt() ?: 0
|
||||
println("Version code offset: $vcOffset")
|
||||
versionCode =
|
||||
(
|
||||
project.findProperty("android.injected.version.code")?.toString()?.toInt()
|
||||
?: System.getenv("VERSION_CODE")?.toInt()
|
||||
?: gitVersionProvider.get().toInt() // Restored GitVersionValueSource fallback
|
||||
?: (gitVersionProvider.get().toInt() + vcOffset)
|
||||
)
|
||||
versionName =
|
||||
(
|
||||
project.findProperty("android.injected.version.name")?.toString()
|
||||
?: System.getenv("VERSION_NAME")
|
||||
?: Configs.VERSION_NAME_BASE // Restored Configs.VERSION_NAME_BASE fallback
|
||||
?: configProperties.getProperty("VERSION_NAME_BASE")
|
||||
)
|
||||
buildConfigField("String", "MIN_FW_VERSION", "\"${Configs.MIN_FW_VERSION}\"") // Used Configs
|
||||
buildConfigField("String", "ABS_MIN_FW_VERSION", "\"${Configs.ABS_MIN_FW_VERSION}\"") // Used Configs
|
||||
buildConfigField("String", "MIN_FW_VERSION", "\"${configProperties.getProperty("MIN_FW_VERSION")}\"")
|
||||
buildConfigField("String", "ABS_MIN_FW_VERSION", "\"${configProperties.getProperty("ABS_MIN_FW_VERSION")}\"")
|
||||
// We have to list all translated languages here,
|
||||
// because some of our libs have bogus languages that google play
|
||||
// doesn't like and we need to strip them (gr)
|
||||
@@ -152,12 +158,6 @@ secrets {
|
||||
propertiesFileName = "secrets.properties"
|
||||
}
|
||||
|
||||
datadog {
|
||||
// if (!gradle.startParameter.taskNames.any { it.contains("fdroid", ignoreCase = true) }) {
|
||||
// composeInstrumentation = InstrumentationMode.AUTO
|
||||
// }
|
||||
}
|
||||
|
||||
// workaround for https://github.com/google/ksp/issues/1590
|
||||
androidComponents {
|
||||
onVariants(selector().withBuildType("release")) { variant ->
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package com.geeksville.mesh.buildlogic
|
||||
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
object Configs {
|
||||
const val APPLICATION_ID = "com.geeksville.mesh"
|
||||
const val MIN_SDK = 26
|
||||
const val TARGET_SDK = 36
|
||||
const val COMPILE_SDK = 36
|
||||
|
||||
|
||||
/**
|
||||
* This version string serves as a fallback for local development environments
|
||||
* where the version cannot be automatically determined from Git tags (e.g., a fresh clone
|
||||
* without fetching tags, or if Git is not accessible).
|
||||
*
|
||||
* On CI servers, the version is dynamically generated based on the current Git tag.
|
||||
*
|
||||
* Before creating a new release, this value should be updated manually
|
||||
* to reflect the version number of the Git tag that will be created for that release.
|
||||
* @see [RELEASE_PROCESS.md]
|
||||
*/
|
||||
const val VERSION_NAME_BASE = "2.7.1"
|
||||
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
|
||||
}
|
||||
@@ -53,8 +53,7 @@ abstract class GitVersionValueSource : ValueSource<String, GitVersionValueSource
|
||||
}
|
||||
output.toString().trim()
|
||||
} catch (e: Exception) {
|
||||
// Fallback to timestamp if git command fails (e.g., in a shallow clone)
|
||||
(System.currentTimeMillis() / 1000).toString()
|
||||
throw RuntimeException("Failed to determine git commit count for versionCode. Ensure you have a full git history (not a shallow clone) and .git is present.\nOriginal error: ${e.message}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
config.properties
Normal file
34
config.properties
Normal file
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
# Offset for reproducible versionCode calculation (see RELEASE_PROCESS.md)
|
||||
VERSION_CODE_OFFSET=29314197
|
||||
|
||||
# Application and SDK versions
|
||||
APPLICATION_ID=com.geeksville.mesh
|
||||
MIN_SDK=26
|
||||
TARGET_SDK=36
|
||||
COMPILE_SDK=36
|
||||
|
||||
# Base version name for local development and fallback
|
||||
# On CI, this is overridden by the Git tag
|
||||
# Before a release, update this to the new Git tag version
|
||||
VERSION_NAME_BASE=2.7.1
|
||||
|
||||
# Minimum firmware versions supported by this app
|
||||
MIN_FW_VERSION=2.5.14
|
||||
ABS_MIN_FW_VERSION=2.3.15
|
||||
Reference in New Issue
Block a user