1. 程式人生 > 其它 >Electron應用上架Mac App Store配置說明

Electron應用上架Mac App Store配置說明

由於業務需要Electron應用需要打包上架到Mac App Store,特做以下記錄說明

1、下載所需證書檔案

證書檔案需要有:

  • 3rd Party Mac Developer Application

  • 3rd Party Mac Developer Installer

  • Developer ID Application

  • Apple Distribution

  • provisionprofile檔案(蘋果開發者後臺生成並匯出https://developer.apple.com/account/resources/profiles/list

  • Mac Developer(此證書為本地測試,非必要)

將證書安裝到構建mac電腦上面,在鑰匙串中顯示如圖:

如顯示證書不受信任或者無效,安裝Apple全球開發者關係認證媒介中間證書AppleWWDRCA

證書連結
https://developer.apple.com/certificationauthority/AppleWWDRCA.cer
https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
https://www.apple.com/certificateauthority/AppleWWDRCAG4.cer

2、準備構建檔案

2.1:建立entitlements.mas.inherit.plist檔案

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>

2.1:建立entitlements.mas.plist檔案(檔案中替換自己的的團隊id和專案構建id,團隊ID一般為證書括號中的資料(2M******),專案構建id為appid(com.***.***))

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>團隊id.專案構建id</string>
</array>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

2.3、準備provisionprofile檔案,蘋果匯出的檔案

3、配置構建檔案package.json檔案或者build.config.js(具體資訊根據專案替換)

// bundleVersion 為 bundleNumber
// target 需要包括 mas
// extendInfo 需要增加 TeamId
// asarUnpack aras 壓縮時過濾.node檔案,否則無法對.node檔案簽名
// .provisioningProfile 檔案在開發者網站下載
mas: {
hardenedRuntime: false,
type: 'distribution',
category: 'public.app-category.productivity',
entitlements: 'build/mas/entitlements.mas.plist',
entitlementsInherit: 'build/mas/entitlements.mas.inherit.plist',
provisioningProfile: 'build/mas/*****.provisionprofile',
},
buildVersion: '7',

mac: {
icon: 'build/icons/icon.icns',
extendInfo: {
ElectronTeamID: '2M********',
},
target: [
{
target: 'mas',
arch: 'x64',
},
],
entitlementsInherit: 'build/mas/entitlements.mas.inherit.plist',
type: 'distribution',
},

專案因為原來生成的dmg檔案需要公證,已經指向了全域性的env證書位置,而mas商城簽名是根據provisionprofile自動呼叫的鑰匙串中的證書,所以我另啟了一個build.config.mas.js來構建mas

4、mas構建成功後新增auth.js對編譯好的app進行檔案許可權操作(上傳蘋果商店可能會提示某些檔案被root許可權了),auth.js內容如下(具體資訊根據專案替換)

var shell = require('child_process')
var path = './dist/mas/****.app'
var strRun = 'chmod -R 777 ' + path
shell.exec(strRun, function (code, stdout, stderr) {
console.log('Exit code:', code)
console.log('Program output:', stdout)
console.log('Program stderr:', stderr)
})

5、編寫pkg構建檔案bash.sh重新打包驗籤(具體資訊根據專案替換)

#!/bin/bash


# 你的應用名稱
APP="****"
# 要簽名的應用路徑
APP_PATH="./dist/mas/*****.app"
# APP_PATH="./dist/mas-arm64/*****.app"
# 生成安裝包路徑
RESULT_PATH="./dist/$APP.pkg"
# 開發者應用簽名證書
APP_KEY="3rd Party Mac Developer Application: ****. (2M****)"
INSTALLER_KEY="3rd Party Mac Developer Installer: ***. (2M******)"
# 授權檔案路徑
CHILD_PLIST="./build/mas/entitlements.mas.inherit.plist"
PARENT_PLIST="./build/mas/entitlements.mas.plist"

FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
LIBRARY_PATH="$APP_PATH/Contents/Library"

oldIFS=$IFS
IFS=$'\n'

#遞迴迴圈驗籤
read_dir(){
for file in `ls $1`
do
if [ -d $1"/"$file ]
then
read_dir $1"/"$file
else
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$1/$file"
#echo $1"/"$file
fi
done
}
# 注意如果有用到 .node 檔案,就需要簽名。如果沒有可以去掉
# codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/Resources/app.asar.unpacked/node_modules/XXX/XXX.node"



codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libEGL.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libvk_swiftshader.dylib"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper (GPU).app/Contents/MacOS/$APP Helper (GPU)"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper (Plugin).app/Contents/MacOS/$APP Helper (Plugin)"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper (Renderer).app/Contents/MacOS/$APP Helper (Renderer)"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$LIBRARY_PATH//LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"



#ALibrariesPath="$APP_PATH/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries"
#read_dir $ALibrariesPath

AResourcesPath="$APP_PATH/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources"
read_dir $AResourcesPath

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/Resources/app.asar"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/Resources/icon.icns"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/embedded.provisionprofile"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"

productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"

IFS=$oldIFS

其中codesign為shell命令,除了以上的檔案驗籤,可能還有別的檔案需要驗籤,根據提交到蘋果商店顯示的錯誤和郵件進行新增和修改

6、編寫上傳到appstore的js檔案uploadappstore.js,如下(具體資訊根據專案替換)

//appstore 上傳
var username = '***'
var password = '***'
// var shell = require('shelljs')
var shell = require('child_process')
var path = './dist/****.pkg'
var strUploading =
'xcrun altool --upload-app --file ' +
path +
' --type osx' +
' -u ' +
username +
' -p ' +
password
// var result = shell.exec(strUploading)
// console.log(result.stdout)
console.log('start----------uploading appstore')
shell.exec(strUploading, function (code, stdout, stderr) {
console.log('Exit code:', code)
console.log('Program output:', stdout)
console.log('Program stderr:', stderr)
console.log('end----------uploaded appstore')
})

構建並上傳(上傳之前需要先在蘋果後臺構建版本號)

"build:mas": "npm run clean && npm run build:web && npm run build:appmas",

.........

.........

"build:appmas": "electron-builder -p never -c build.config.mas.js",

(一系列的構建)

"upload:appstore":"node ./auth.js && bash ./build/mas/bash.sh && node ./uploadappstore.js"

(重新驗簽上傳)

--------------------------------------------------

成功後可以在App Store後臺中看到上傳的app