更新 React Native App 版本号

编辑于2019年10月11日
原文:Versioning React Native apps
地址:https://medium.com/@andr3wjack/versioning-react-native-apps-407469707661

React Naitve 整合了 JavaScript、Android 和 iOS。随之而来的是三种不同的构建工具:npm、Xcode 和 Gradle。当我们要发布 App 并增加版本号是会发生什么?我们必须要更新 package.json、build.gradle 和 info.plist。

通过一条命令更新版本号?

如果我们可以做到只运行下面的命令就能实现那就最好了:

npm version [major|minor|patch]

尝试一下

作为一名Android开发人员,我知道Gradle可以做很多事情,所以我从 Android 开始。

build.gradle 文件中,我需要读取 package.json 文件,这在 Gradle 中非常容易做到。

import groovy.json.JsonSlurper
def getNpmVersion() {
    def inputFile = new File("../package.json")
    def packageJson = new JsonSlurper().parseText(inputFile.text)
    return packageJson["version"]
}

然后我可以将它拆分为单独的字符串,以便在构建脚本中使用它。

def (major, minor, patch) = getNpmVersion().tokenize('.')

如何使用 package.json 版本计算 versioncode 和 versionname 取决于您自己。您可以在 github 上看到一个完整的例子。

android/build.gradle

def getNpmVersionArray() { // major [0], minor [1], patch [2]
    def (major, minor, patch) = getNpmVersion().tokenize('.')
    return [Integer.parseInt(major), Integer.parseInt(minor), Integer.parseInt(patch)] as int[]
}
subprojects {
    ext {
        def npmVersion = getNpmVersionArray()
        versionMajor = npmVersion[0]
        versionMinor = npmVersion[1]
        versionPatch = npmVersion[2]
    }
}

android/app/build.gradle

android {
    ...

    defaultConfig {
        ...
        versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch
        versionName "${versionMajor}.${versionMinor}.${versionPatch}"
    }
}

iOS

Xcode 没有 Gradle 这种方便的功能,所以我打算使用 bash。

#!/usr/bin/env bash -e

PROJECT_DIR="ios/ReactNativeApp"
INFOPLIST_FILE="Info.plist"
INFOPLIST_DIR="${PROJECT_DIR}/${INFOPLIST_FILE}"

PACKAGE_VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]')

BUILD_NUMBER=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_DIR}")
BUILD_NUMBER=$(($BUILD_NUMBER + 1))


# Update plist with new values
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${PACKAGE_VERSION#*v}" "${INFOPLIST_DIR}"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUMBER" "${INFOPLIST_DIR}"

该脚本读取 package.json 中的版本信息,增加版本号,然后通过 PlistBuddy 更新 info.plist

整合到一起

默认情况下,npm version会更新版本号,如果是在 git 仓库中,会创建一个新版本 commit 并打上标签。同时,npm version 提供了三个挂载点,用于执行用户自定义的操作:perversion、version 和 postversion。

要在增加版本时执行version-ios.sh脚本,可以添加以下内容:

{
    "scripts": {
    "version": "./version-ios.sh"
}

成功

有了它,我们现在就可以增加版本,而无需再进行三次更新,只用执行 npm version [major|minor|patch]

使用 npm version 的钩子,我们可以做更多的事情!我们可以更新CHANGELOG.md,创建发布分支,然后将分支和标签推送到远程。

源码:https://github.com/AndrewJack/versioning-react-native-app