繁体   English   中英

React Native - 从 package.json 到 android 构建清单的自动版本名称

[英]React Native - Automatic version name from package.json to android build manifest

目前我有一个 react native 应用程序,我遇到的问题是在每次构建或提交时更新版本非常耗时。

另外,我启用了 Sentry,所以每次我构建时,有些构建得到相同的版本,所以有些崩溃很难确定它们来自哪里。

最后,手动更新版本容易出错。

我如何设置我的构建以在每次构建并忘记所有这些手动任务时生成自动版本?

虽然目前接受的答案可行,但有一种更简单、因此更可靠的方法来做到这一点。 您实际上可以直接从build.gradle读取package.json设置的值。

修改你的android/app/build.gradle

// On top of your file import a JSON parser
import groovy.json.JsonSlurper

// Create an easy to use function
def getVersionFromNpm() {
    //  Read and parse package.json file from project root
    def inputFile = new File("$rootDir/../package.json")
    def packageJson = new JsonSlurper().parseText(inputFile.text)

    // Return the version, you can get any value this way
    return packageJson["version"]
}

android {
    defaultConfig {
        applicationId "your.app.id"
        versionName getVersionFromNpm()
    }
}

这样你就不需要预构建脚本或任何东西,它就可以工作。

由于我为此工作了几天,所以我决定与大家分享我是如何做到的,因为它可以帮助其他人。

使用的工具:

  1. GitVersion :我们将使用 GitVersion 根据当前分支、标签、提交等许多因素自动生成语义版本。该工具做得非常好,您可以忘记命名版本。 当然,如果您将标签设置为提交,它将使用该标签作为名称。
  2. PowerShell :这个由 Microsoft 构建的命令行操作系统能够在 Mac、Linux 或 Windows 上运行,我选择它是因为构建可以与操作系统版本无关。 例如我在 Windows 上开发,但构建机器有 MacOS。

编辑 App build.gradle

应用程序 gradle 只需要在它的末尾添加一行。 就我而言,我有 Google Play Services gradle,然后我添加了它。

apply from: 'version.gradle'

版本.gradle

此文件应与您的应用程序 gradle 位于同一文件夹中,这是内容:

task updatePackage(type: Exec, description: 'Updating package.json') {
    commandLine 'powershell', ' -command ' , '$semver=(gitversion /showvariable Semver); Set-Content -path version.properties -value semver=$semver; npm version --no-git-tag-version --allow-same-version $semver'  
}
preBuild.dependsOn updatePackage

task setVariantVersion {

    doLast {

        if (plugins.hasPlugin('android') || plugins.hasPlugin('android-library')) {

            def autoIncrementVariant = { variant ->
                variant.mergedFlavor.versionName = calculateVersionName()
            }

            if (plugins.hasPlugin('android')){
                //Fails without putting android. first
                android.applicationVariants.all { variant -> autoIncrementVariant(variant) }
            }

            if (plugins.hasPlugin('android-library')) {
                //Probably needs android-library before libraryVariants. Needs testing
                libraryVariants.all { variant -> autoIncrementVariant(variant) }
            }
        }

    }

}
preBuild.dependsOn setVariantVersion
setVariantVersion.mustRunAfter updatePackage

ext {
    versionFile = new File('version.properties')
    calculateVersionName = {
        def version = readVersion()
        def semver = "Unknown"
        if (version != null){
            semver = version.getProperty('semver')
        }
        return semver
    }
}

Properties readVersion() {
    //It gets called once for every variant but all get the same version
    def version = new Properties()
    try {
        file(versionFile).withInputStream { version.load(it) }
    } catch (Exception error) {
        version = null
    } 
    return version
}

现在,让我们回顾一下脚本实际在做什么:

  1. updatePackage:此任务在构建的最开始运行(实际上是在 preBuild 之前),它执行 gitversion 以获取当前版本,然后创建一个 version.properties 文件,稍后由 gradle 读取该文件以获取版本。
  2. setVariantVersion:在每个变体上调用 afterEvaluate。 这意味着如果您有多个构建版本,如调试、发布、qa、暂存等,所有版本都将获得相同的版本。 对于我的用例,这很好,但您可能想要调整它。
  3. 任务顺序:困扰我的一件事是版本在生成文件之前正在运行。 这是通过使用 mustRunAfter 标记修复的。

PowerShell 脚本解释

这是首先运行的脚本。 让我们回顾一下正在做什么:

$semver=(gitversion /showvariable Semver);
Set-Content -path props.properties -value semver=$semver; 
npm version --no-git-tag-version --allow-same-version $semver
  1. 第 1 行:gitversion 有多种类型的版本。 如果你在没有任何参数的情况下运行它,你会得到一个包含许多变体的 json 文件。 在这里,我们说我们只想要 SemVer。 (另见 FullSemVer)
  2. 第 2 行:PowerShell 创建文件并将内容保存到其中的方法。 这也可以用 > 来完成,但我遇到了编码问题并且没有读取属性文件。
  3. 第 3 行:此行更新您的 package.json 版本。 默认情况下,它使用新版本保存对 git 的提交。 --no-git-tag-version 确保您不会覆盖它。

就是这样。 现在每次进行构建时,都应该自动生成版本,更新 package.json 并且构建应该具有特定的版本名称。

应用中心

由于我使用App Center进行构建,因此我将告诉您如何在构建机器中使用它。 您只需要使用自定义脚本。

app-center-pre-build.sh

#!/usr/bin/env sh
#Installing GitVersion
OS=$(uname -s)
if [[ $OS == *"W64"* ]]; then
    echo "Installing GitVersion with Choco"
    choco install GitVersion.Portable -y
else 
    echo "Installing GitVersion with Homebrew"
    brew install --ignore-dependencies gitversion
fi

这是必需的,因为 GitVersion 当前不是构建机器的一部分。 此外,安装时需要忽略单声道依赖项,否则在 brew 尝试链接文件时会出现错误。

@MacRusher 版本对我来说很好。 只是为了进一步的读者,我不得不添加 .toInteger() 以使其工作。 由于我使用 yarn version --patch 自动升级 package.json 中的版本,因此我也只需要取前两个字符。

这是新版本:

// On top of your file import a JSON parser
import groovy.json.JsonSlurper

def getVersionFromPackageJson() {
    //  Read and parse package.json file from project root
    def inputFile = new File("$rootDir/../package.json")
    def packageJson = new JsonSlurper().parseText(inputFile.text)

    // Return the version, you can get any value this way
    return packageJson["version"].substring(0,2).toInteger()
}

android {
    defaultConfig {
        applicationId "your.app.id"
        versionName getVersionFromPackageJson()
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM