Pytanie Jak automatycznie podkręcić kod wersji w systemie Android Gradle


Eksperymentuję z nowym systemem kompilacji systemu Android opartym na programie Gradle i myślę, jaki jest najlepszy sposób na automatyczne zwiększenie kodu wersji. Myślę o dwóch opcjach

  1. utwórz plik versionCode, odczytaj z niego numer, zwiększ go i zapisz go z powrotem do pliku
  2. przeanalizuj AndroidManifest.xml, odczytaj z niego kod wersji, zwiększ go i zapisz w AndroidManifest.xml

Czy istnieje jakieś bardziej proste lub odpowiednie rozwiązanie?

Czy ktoś użył jednej z opcji mentiod i mógł mi ją udostępnić?


76
2017-07-03 12:52


pochodzenie


Czytanie z version.properties plik stackoverflow.com/a/21405744 - Dori


Odpowiedzi:


Zdecydowałem się na drugą opcję - do parsowania AndroidManifest.xml. Oto działający fragment.

task('increaseVersionCode') << {
    def manifestFile = file("AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig') {
        task.dependsOn 'increaseVersionCode'
    }
}

versionCode w tym przypadku jest wydany dla wersji release. Aby go zwiększyć do kompilacji debugowania, zmień równanie task.name w task.whenTaskAdded oddzwonić.


56
2017-07-08 11:12



jedno pytanie, jak zintegrować te kody z systemem budowy Cradle? - Jacky
Również nieco czystsza odpowiedź nie modyfikuje XML w miejscu, ale zachowuje numer wersji w pliku rekwizytów: stackoverflow.com/questions/21405457/... - Paul Cantrell
Po prostu zmień plik ("AndroidManifest.xml") do pliku ("src / main / AndroidManifest.xml"), jeśli korzystasz z nowej struktury projektu. - Elhanan Mishraky
Co się stanie, jeśli nie ustawię wersjiCode w moim AndroidManifest.xml? - Igor Ganapolsky
@Jacky Jeśli nadal nie masz obejścia, zobacz moją odpowiedź: stackoverflow.com/a/39619297/1150251 - iStar


Używam tego kodu do aktualizacji zarówno wersjiCode i wersjiName, przy użyciu schematu "major.minor.patch.build".

import java.util.regex.Pattern

task('increaseVersionCode') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

task('incrementVersionName') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
    def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'increaseVersionCode'
        task.dependsOn 'incrementVersionName'
    }
}

39
2018-02-22 07:35



+1 za ilość kontroli, jaką otrzymujesz - TheIcemanCometh
Zapomnieliście zaimportować wzorzec u góry: import java.util.regex.Pattern - Mic92
Naprawiono to, dzięki! - Andres
Wiem, że ten jest trochę stary, ale hej to nie boli zapytać, ale próbowałem używać powyższego fragmentu, otrzymuję ten błąd Error:(48) Execution failed for task ':app:incrementVersionName'. > No match found jakieś pomysły? - acrichm
@acrichm: upewnij się, że ustawiłeś android:versionName="0.0.0.1" w manifeście nie będzie oczekiwana liczba meczów - Jay


nie wydaje się to być dokładną konfiguracją, której używasz, ale w moim przypadku kompilacje są uruchamiane przez Jnkinsa i chciałem użyć jego wartości $ BUILD_NUMBER jako kodu wersji aplikacji. Poniższe zrobili dla mnie lewę.

defaultConfig {
    ...
    versionCode System.getenv("BUILD_NUMBER") as Integer ?: 9999
    ...
}

36
2018-04-16 17:46



Co to jest System.genenv? - Igor Ganapolsky
To bardzo mi pomogło, gdy używam Jenkinsa. Możesz tego użyć ta wtyczka utworzyć zmienną środowiskową z numerem kompilacji i odczytać ją System.getenv() w gradle. - Lamorak


Używam znacznika czasu dla kodu wersji:

def date = new Date()
def formattedDate = date.format('yyMMddHHmm')
def code = formattedDate.toInteger()

defaultConfig {
    minSdkVersion 10
    targetSdkVersion 21
    versionCode code
}

13
2018-02-23 07:26



to jest proste i genialne. kciuki w górę - Євген Гарастович


Jeśli przechowujesz kod wersji w pliku build.gradle, użyj następnego fragmentu kodu:

import java.util.regex.Pattern    
task('increaseVersionCode') << {
    def buildFile = file("build.gradle")
    def pattern = Pattern.compile("versionCode\\s+(\\d+)")
    def manifestText = buildFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode " + ++versionCode)
    buildFile.write(manifestContent)
}

6
2018-03-25 13:17



Ten wzorzec nie pasuje do versionCode. - lagos
Czy możesz opublikować swój build.gradle? - Elhanan Mishraky
Mój build.gradle jest normalnym plikiem kompilacji. Wygląda linia kodu wersji versionCode 18 . Nawet jeśli uruchomiłem twoje wyrażenie regularne na testerze ("versionCode \d+") nie pasuje. - lagos
Błąd polegał na tym, że jeszcze jeden biały spacja. Android Studio używa dwóch białych znaków versionCode oraz cyfrę, ponieważ będzie ona wyrównana wraz z tekstem w versionName. - lagos
Teraz powinno działać, przepraszam za to. - Elhanan Mishraky


Aby uwzględnić zarówno smaki produktu, jak i typy kompilacji, i użyć logiki @ sealskej do analizy pliku manifestu:

android.applicationVariants.all { variant ->
    /* Generate task to increment version code for release */
    if (variant.name.contains("Release")) {
        def incrementVersionCodeTaskName = "increment${variant.name}VersionCode"
        task(incrementVersionCodeTaskName) << {
            if (android.defaultConfig.versionCode == -1) {
                def manifestFile = file(android.sourceSets.main.manifest.srcFile)
                def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
                def manifestText = manifestFile.getText()
                def matcher = pattern.matcher(manifestText)
                matcher.find()
                def versionCode = Integer.parseInt(matcher.group(1))
                android.defaultConfig.versionCode = versionCode + 1
                def manifestContent = matcher.replaceAll("versionCode=\"" + android.defaultConfig.versionCode + "\"")
                manifestFile.write(manifestContent)
            }
        }
        def hookTask = variant.generateBuildConfig
        hookTask.dependsOn(incrementVersionCodeTaskName)
    }
}

4
2017-10-03 23:42



Gdzie musimy to napisać ... Mam na myśli, w której klasie / pliku ten kod musi zostać dodany - ChArAnJiT
jest to część build.gradle, ponieważ jest to część procesu kompilacji - Max Ch


Gradle Advanced Build Version to wtyczka do Androida, która sprawia, że ​​generowanie versionCode i wersjaName automatycznie. istnieje wiele dostosowań. tutaj możesz znaleźć więcej informacji na ten temat https://github.com/moallemi/gradle-advanced-build-version


4
2018-01-12 05:24



Uwaga: to nie obsługuje automatycznego zwiększania nazwy wersji - hooby3dfx


Zwiększ zadanie kodu wersji (Integer):

Działa to poprzez inkrementowanie kodu wersji o 1, na przykład:

  android:versionCode="1"
1 + 1 = 2
import java.util.regex.Pattern

task incrementVersionCode << {
    def manifestFile = file('AndroidManifest.xml')
    def matcher = Pattern.compile('versionCode=\"(\\d+)\"')
    .matcher(manifestFile.getText())
    matcher.find()
    def manifestContent = matcher.replaceAll('versionCode=\"' +
        ++Integer.parseInt(matcher.group(1)) + '\"')
    manifestFile.write(manifestContent)
}

Inkrement VersionName Zadanie (String):

Ostrzeżenie: musi zawierać 1 okres dla Regex

Działa to poprzez inkrementowanie nazwy wersji o 0.01, na przykład: Możesz łatwo modyfikować i zmieniać swój przyrost lub dodawać kolejne cyfry.

android:versionName="1.0"
1.00 + 0.01 -> 1.01
1.01 + 0.01 -> 1.02
1.10 + 0.01 -> 1.11
1.99 + 0.01 -> 2.0
1.90 + 0.01 -> 1.91
import java.util.regex.Pattern

task incrementVersionName << {
    def manifestFile = file('AndroidManifest.xml')
    def matcher = Pattern.compile('versionName=\"(\\d+)\\.(\\d+)\"')
    .matcher(manifestFile.getText())
    matcher.find()
    def versionName = String.format("%.2f", Integer
        .parseInt(matcher.group(1)) + Double.parseDouble("." + matcher
            .group(2)) + 0.01)
    def manifestContent = matcher.replaceAll('versionName=\"' +
        versionName + '\"')
    manifestFile.write(manifestContent)
}

Przed:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exmaple.test"
    android:installLocation="auto"
    android:versionCode="1"
    android:versionName="1.0" >

Po:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exmaple.test"
    android:installLocation="auto"
    android:versionCode="2"
    android:versionName="1.01" >

3
2017-09-29 02:38





Aby dodać do postu @ sealskej, w ten sposób możesz zaktualizować zarówno kod wersji, jak i wersję (tutaj zakładam, że twoja wersja główna i dodatkowa to 0):

task('increaseVersion') << {
    def manifestFile = file("AndroidManifest.xml")
    def patternVersionCode = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionCode = patternVersionCode.matcher(manifestText)
    matcherVersionCode.find()
    def versionCode = Integer.parseInt(matcherVersionCode.group(1))
    def manifestContent = matcherVersionCode.replaceAll("versionCode=\"" + ++versionCode + "\"")

    manifestFile.write(manifestContent)

    def patternVersionNumber = Pattern.compile("versionName=\"0.0.(\\d+)\"")
    manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def versionNumber = Integer.parseInt(matcherVersionNumber.group(1))
    manifestContent = matcherVersionNumber.replaceAll("versionName=\"0.0." + ++versionNumber + "\"")
    manifestFile.write(manifestContent)
}

2
2017-07-13 05:50