Android gradle-releaseプラグインのカスタマイズされたバージョンを使用して、Mavenリリースプラグインをエミュレートしようとしています: https://github.com/townsfolk/gradle-release =
興味深いステップは次のとおりです。
ただし、生成されたAPKには常に以前のバージョンがあります(つまり、1.0.0ではなく1.0.0-SNAPSHOT)。
バージョン番号はgradle.propertiesに保存され、正しく更新されるため、変更を有効にするにはデータモデルのバージョンも更新する必要があると想定しています。
My Android plugin config:
defaultConfig {
versionCode versionCode as int // taken from gradle.properties
versionName versionName // taken from gradle.properties
minSdkVersion 10
targetSdkVersion 19
}
私が試したもの:
preBuild << {
Android.applicationVariants.each { variant ->
variant.versionName = versionName
}
}
ただし、バリアントにはversionNameがありません。
preBuild << {
Android.buildTypes.each { type ->
type.versionName = versionName
}
}
ただし、型にはversionNameがありません。
preBuild << {
Android.productFlavors.each { flavor ->
flavor.versionName = versionName
}
}
しかし、私のアプリにはフレーバーはありません(プレーンデバッグおよびリリースビルドタイプのみ)。
私の代替案は、bash/batスクリプトを記述して、Gradleを呼び出す前にバージョンをステップ実行することです。これは、ビルドのカスタマイズを改善するためにGroovyを使用する目的をほとんど無効にします。
実行段階でAndroid Gradleプラグインでバージョンを動的に更新するにはどうすればよいですか?
それがbuildTypes
の目的です。あなたが説明しているのは、release
ビルド、IMOです。
次に例を示します。assembleDebug
を実行すると、スナップショットビルドが提供され、assembleRelease
を実行すると、サフィックスとインクリメントされたバージョン番号のないクリーンビルドが提供されます。次のデバッグビルドでも、インクリメントされた数値が使用されます。
以下は、ファイルがフォルダーに作成された場合の完全に機能するビルドです。フレーバーでも動作するはずですが、それは単なる副産物です:)。 Gradle 2.2.1、Androidプラグイン1.1.3
apply plugin: 'com.Android.application'
apply from: 'auto-version.gradle'
buildscript {
repositories { jcenter() }
dependencies { classpath 'com.Android.tools.build:gradle:1.1.3' }
}
Android {
buildToolsVersion = "21.1.2"
compileSdkVersion = "Android-21"
buildTypes {
debug {
versionNameSuffix "-SNAPSHOT"
}
}
}
println "config code: ${calculateVersionCode()}, name: ${calculateVersionName()}"
<manifest package="com.example" />
ext {
versionFile = new File(project.rootDir, 'version.properties')
calculateVersionName = {
def version = readVersion()
return "${version['major']}.${version['minor']}.${version['build']}"
}
calculateVersionCode = {
def version = readVersion()
def major = version['major'] as int // 1..∞
def minor = version['minor'] as int // 0..99
def build = version['build'] as int // 0..999
return (major * 100 + minor) * 1000 + build
}
}
Properties readVersion() {
def version = new Properties()
def stream
try {
stream = new FileInputStream(versionFile)
version.load(stream)
} catch (FileNotFoundException ignore) {
} finally {
if (stream != null) stream.close()
}
// safety defaults in case file is missing
if(!version['major']) version['major'] = "1"
if(!version['minor']) version['minor'] = "0"
if(!version['build']) version['build'] = "0"
return version
}
void incrementVersionNumber() {
def version = readVersion()
// careful with the types, culprits: "9"++ = ":", "9" + 1 = "91"
def build = version['build'] as int
build++
version['build'] = build.toString()
def stream = new FileOutputStream(versionFile)
try {
version.store(stream, null)
} finally {
stream.close()
}
}
task incrementVersion {
description "Increments build counter in ${versionFile}"
doFirst {
incrementVersionNumber()
}
}
if (plugins.hasPlugin('Android') || plugins.hasPlugin('Android-library')) {
Android {
defaultConfig {
versionName = calculateVersionName()
versionCode = calculateVersionCode()
}
afterEvaluate {
def autoIncrementVariant = { variant ->
if (variant.buildType.name == buildTypes.release.name) { // don't increment on debug builds
variant.preBuild.dependsOn incrementVersion
incrementVersion.doLast {
variant.mergedFlavor.versionName = calculateVersionName()
variant.mergedFlavor.versionCode = calculateVersionCode()
}
}
}
if (plugins.hasPlugin('Android')) {
applicationVariants.all { variant -> autoIncrementVariant(variant) }
}
if (plugins.hasPlugin('Android-library')) {
libraryVariants.all { variant -> autoIncrementVariant(variant) }
}
}
}
}
実行gradle assembleDebug
正常にビルドするには、gradle assembleRelease
をインクリメントしてビルドし、gradle incrementVersion
単にインクリメントします。 注:gradle assemble
assembleDebug
とassembleRelease
の順序が異なる結果をもたらすため。
build
ディレクトリに生成されたファイルをチェックして、値が自分の好みに合っているかどうかを確認します。
複数のバリアントがリリースビルドタイプに一致するため、複数のフレーバーが存在する可能性があります。その場合、バージョンが複数回インクリメントされます。元々の質問は、フレーバーがないことでした。バージョン番号をインクリメントするときにさらに制御したい場合は、afterEvaluate
ブロックを削除して、いつでもincrementVersion
タスクを呼び出します。
gradle incrementVersion assembleFreeRelease assemblePaidRelease
(上記の手動実行はテストされていないアイデアです。)
「コミットされていない変更を確認する」はこの回答ではカバーされていません。これは別のゲームです。 tasks.preBuild.doFirst { /*fail here if uncommited changes*/ }
私が正しく理解している場合。しかし、それはバージョン管理に大きく依存しています。詳細については別の質問をしてください!
コードリビジョンの現在のgitコミットカウントをバージョン名に追加する必要がありました。多くの状況で本当に便利です。私は以下の簡単なgradleファイルになりました
apply plugin: 'com.Android.application'
Android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
def gitCommitCount = "git rev-list HEAD --count".execute().text.trim()
defaultConfig {
applicationId "my.app.package.name"
minSdkVersion 16
targetSdkVersion 21
versionCode 6
versionName "0.8"
}
buildTypes {
debug {
versionNameSuffix ".${gitCommitCount}"
}
release {
versionNameSuffix ".${gitCommitCount}"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-Android-optimize.txt'), 'proguard-rules.pro'
}
}
}
GitCommitCountと同様に、独自の変数を生成してバージョン名をカスタマイズできます。私は端末コマンドを実行してその結果を変数に保存しているだけです。
これは、versionNameを完全に変更する方法に関する質問に直接対処するものではありませんが、buildTypesにサフィックスを追加するために使用するものです。
defaultConfig {
versionName "1.0"
}
buildTypes {
debug {
versionNameSuffix "-SNAPSHOT"
}
}
Javanator's answer を使用し、それを少し変更して、コミットカウントが名前の変更に役立つだけでなく、バージョンコードも一意のままになるようにしました。ここに私がやったことのサンプルがあります(たぶんいくつかのことを最適化できますが、それでも私のために仕事をします):
Android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
def gitCommitCount = "git rev-list HEAD --count".execute().text.trim().toBigInteger()
project.ext.set("versionCode", gitCommitCount)
project.ext.set("versionNameSuffix", "(${gitCommitCount})")
defaultConfig {
applicationId "my.app.package.name"
minSdkVersion 15
targetSdkVersion 25
versionCode project.versionCode
versionName "1.0"
versionNameSuffix project.versionNameSuffix
setProperty("archivesBaseName", "MyProject-$versionName")
....
}
signingConfigs {
config {
.........
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
packagingOptions {
.....
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(
output.outputFile.parent,
output.outputFile.name.replace(".apk", "-${variant.versionName}.apk"))
}
}
}
Edit:最後のビットも次のようになります
applicationVariants.all { variant ->
if (variant.name.contains('release')) {
variant.outputs.each { output ->
variant.outputs.all {
outputFileName = "MyProject-${variant.versionName}${variant.versionCode}.apk"
}
}
}
}
私は、リリースビルドと非リリースビルドのビルドロジックを別々にするという同様のニーズに直面していました。異なるバージョン管理とは別に、異なるリポジトリ、さらには異なるリポジトリのセットを使用する必要がありました。
使用可能なプラグインにはどれも必要な機能がすべて備わっていなかったため、コマンドライン引数という単純なアプローチに基づいて独自のソリューションを開発しました。
次のようなgradleビルドスクリプトを呼び出すときに、コマンドラインパラメーターを渡すことができます。
gradle build -PmyParameter = myValue
または私の場合
gradle build -PisRelease = true
Gradleはそれを解析し、プロジェクトオブジェクトのプロパティとして自動的に使用可能になります。次のように使用できます。
if (project.isRelease) {
// Here be the logic!
}
このロジックを別のプラグインに抽出し、さまざまなプロジェクトで正常に使用しています。
これはあなたの質問に直接答えるものではありませんが、問題と考えられる別の解決策について考えるための別の角度をお伝えしたいと思います。