解決AppCenter建置React Native APP的問題

因為AppCenter提供CodePush功能,可以直接發布React-Native的js部分程式,讓上架後維護簡單的UI或資料調整便很容易,而且使用起來簡單沒有負擔,所以就決定在我目前的RN項目中套用。

另外,AppCenter提供直接連結到github public/private repo進行自動建置動作的功能,為了完成用RN的DevOps學習計畫,便著手使用AppCenter的Build功能。

AppCenter連結Github本身沒甚麼難度,按幾個確認按鈕就結束了,但是build app總是不會成功。

從AppCenter提供的LOG會得到錯誤訊息區段如下

==============================================================================
Task : Publish build artifacts
Description : Publish build artifacts to Azure Pipelines or a Windows file share
Version : 1.158.3
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/publish-build-artifacts
==============================================================================
##[error]Publishing build artifacts failed with an error: Not found PathtoPublish: /Users/runner/work/1/a/build
##[section]Finishing: Publish build

遭遇這個問題起初我以為是APK輸出路徑問題,但是實際上這路徑是前面的script所給的,所以根本問題不是發生在這個區段,而是下面這段,它找不到APK檔案

BUILD SUCCESSFUL in 2m 3s
188 actionable tasks: 179 executed, 9 up-to-date
##[section]Finishing: Gradle Task
##[section]Starting: Android Postprocess
==============================================================================
Task : Shell script
Description : Run a shell script using Bash
Version : 2.165.2
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/shell-script
==============================================================================
[command]/bin/bash /Users/runner/runners/2.179.0/scripts/android-postprocess.sh /Users/runner/work/1/s/android/app/build/outputs/apk
Removing all ABI or density dependent APKs…
Found 0 APK file(s)
Found 0 unaligned APK file(s)
~/work/1/s/android/app/build/outputs ~/runners/2.179.0/scripts

該script會去找android/app/build/outputs/apk這個目錄下的APK檔案但是沒找著。


那解決這個Build問題的解法是?

你在AppCenter上不能對每個CPU Architecture產出各自APK檔的設定, 解法來源,它會導致後續的script找不到APK檔案。

首先,我在AppCenter上加了一個Environment variable的鍵名為BUILD_IN_APPCENTER, 其值為1。

接著在RN的gradle(android\app\build.gradle)裡讀取該Environment variable來改變RN專案的設定

def isAppCenterBuild = System.getenv("BUILD_IN_APPCENTER") ? true : false
def enableSeparateBuildPerCPUArchitecture = !isAppCenterBuild


解決這個問題時做的其他嘗試

在解決這個問題的時候我有嘗試下面這些方案,順便記錄一下

1. 讓gradle產出的APK檔案到上一層

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
....
            output.outputFileName = "../" + output.outputFileName

這個方案在本機可以成功,但是AppCenter上就會被擋,錯誤訊息:

java.io.IOException: Failed to create '/Users/runner/work/1/s/android/app/build/outputs/apk/release/../app-release.apk'

2. 改變gradle outputFile檔案路徑

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
....
            output.outputFile = new File(orignalFile.parent, output.outputFileName)

這個方法我們會得到錯誤訊息: 

ERROR: groovy.lang.GroovyRuntimeException: Cannot set the value of read-only property 'outputFile' for ...

在新版的gradle中output.outputFile是唯讀的property,所以當你改變outputFileName時它會自動改變

3. 讓產出的APK檔案到專案根目錄下的build資料夾

    applicationVariants.all { variant -> ...
        variant.packageApplicationProvider.get().outputDirectory = new File(outputDirectory.parent)         variant.outputs.each { output -> ...

這個方法失敗,因為它的路徑並不是我要的

我要${git-root}/build

但是上面這段gradle是產出到${git-root}/android/build

3. 改變APP檔案名稱

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
....
            def appName = variant.applicationId
            def date = new Date()
            def formattedDate = date.format('yyyyMMdd')
            def fullVersion = "${variant.versionName}.${variant.versionCode}"
            def buildType = isAppCenterBuild ? "${variant.name}-universal" : "${variant.name}-${abi}"
            output.outputFileName = "${appName}-${formattedDate}_${fullVersion}-${buildType}.apk"
            println "final.outputFile:${output.outputFile}"

雖然我改變了檔案名稱,但是因為錯誤訊息沒有提示用哪個檔名,所以最後作罷。


留言