[英]React Native - Automatic version name from package.json to android build manifest
Currently I have a react native app and the issue that I have is that is very time consuming to update the version on every build or commit.目前我有一个 react native 应用程序,我遇到的问题是在每次构建或提交时更新版本非常耗时。
Also, I have Sentry enabled so every time I build, some builds get the same version so some crashes are hard to determine where they came from.另外,我启用了 Sentry,所以每次我构建时,有些构建得到相同的版本,所以有些崩溃很难确定它们来自哪里。
Lastly, updating the version manually is error prone.最后,手动更新版本容易出错。
How can I setup my builds to generate an automatic version every time I build and forget about all of this manual task?我如何设置我的构建以在每次构建并忘记所有这些手动任务时生成自动版本?
While the currently accepted answer will work, there is a much simpler, and therefore more reliable way to do it.虽然目前接受的答案可行,但有一种更简单、因此更可靠的方法来做到这一点。 You can actually read the value set in package.json
right from build.gradle
.您实际上可以直接从build.gradle
读取package.json
设置的值。
Modify your android/app/build.gradle
:修改你的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()
}
}
This way you won't need a pre-build script or anything, it will just work.这样你就不需要预构建脚本或任何东西,它就可以工作。
Since I was working with this for several days, I decided to share with everyone how I did it, because it could help others.由于我为此工作了几天,所以我决定与大家分享我是如何做到的,因为它可以帮助其他人。
Tools used:使用的工具:
The app gradle only needs one line added at the end of it.应用程序 gradle 只需要在它的末尾添加一行。 In my case I have the Google Play Services gradle and I added it after that.就我而言,我有 Google Play Services gradle,然后我添加了它。
apply from: 'version.gradle'
This file should be in the same folder as your app gradle and this is the content:此文件应与您的应用程序 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
}
Now, let's review what the script is actually doing:现在,让我们回顾一下脚本实际在做什么:
This is the script that gets run first.这是首先运行的脚本。 Let's review what is doing:让我们回顾一下正在做什么:
$semver=(gitversion /showvariable Semver);
Set-Content -path props.properties -value semver=$semver;
npm version --no-git-tag-version --allow-same-version $semver
And that is it.就是这样。 Now every time you make a build, the version should be generated automatically, your package.json updated and your build should have that specific version name.现在每次进行构建时,都应该自动生成版本,更新 package.json 并且构建应该具有特定的版本名称。
Since I am using App Center to make the builds, I will tell you how you can use this in a Build machine.由于我使用App Center进行构建,因此我将告诉您如何在构建机器中使用它。 You only need to use a custom script.您只需要使用自定义脚本。
#!/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
This is needed because GitVersion is not currently a part of the build machines.这是必需的,因为 GitVersion 当前不是构建机器的一部分。 Also, you need to ignore the mono dependency when installing, otherwise you get an error when brew tries to link the files.此外,安装时需要忽略单声道依赖项,否则在 brew 尝试链接文件时会出现错误。
The @MacRusher version was fine for me. @MacRusher 版本对我来说很好。 Just for further readers, I had to add .toInteger() to make it work.只是为了进一步的读者,我不得不添加 .toInteger() 以使其工作。 Since I'm using yarn version --patch to automatically upgrade the version in package.json I also had to take only the two first characters.由于我使用 yarn version --patch 自动升级 package.json 中的版本,因此我也只需要取前两个字符。
Here is the new version:这是新版本:
// 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.