Skip to content

Instantly share code, notes, and snippets.

@linyize
Last active December 31, 2015 19:38
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save linyize/8034386 to your computer and use it in GitHub Desktop.
Save linyize/8034386 to your computer and use it in GitHub Desktop.
Bash shell to package inhouse/development/adhoc/appstore ios app (then upload to inhouse webserver) Usage: ./xctool_archive.sh PathToProject Scheme
#!/bin/sh -ex
# install xctool : brew install xctool
inhouseserver="http://inhouse.xxx.com/upload"
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
projectpath=$1
scheme=$2
projectname=$(basename "${projectpath}")
cd "${projectpath}"
projectpath=$(pwd)
# archive
xctool -project "${projectname}".xcodeproj -scheme "${scheme}" clean archive -sdk iphoneos
# find xcscheme file
schemefile="${projectpath}"/"${projectname}".xcodeproj/xcshareddata/xcschemes/"${scheme}".xcscheme
if [ ! -f "${schemefile}" ]
then
schemefile=$(ls -dt "${projectpath}"/"${projectname}".xcodeproj/xcuserdata/*.xcuserdatad/xcschemes/"${scheme}".xcscheme | head -1)
fi
if [ ! -f "${schemefile}" ]
then
echo "scheme not found!"
exit 1
fi
# find mobileprovision file
plist=/tmp/"${scheme}".plist
rm -f "${plist}"
plutil -convert xml1 -o "${plist}" "${projectpath}"/"${projectname}".xcodeproj/project.pbxproj
customArchiveName=$(xmllint --xpath Scheme/ArchiveAction/@customArchiveName "${schemefile}" | cut -d '"' -f2)
targetid=$(xmllint --xpath Scheme/BuildAction/BuildActionEntries/BuildActionEntry/BuildableReference/@BlueprintIdentifier "${schemefile}" | cut -d '"' -f2)
buildConfigurationList=$(/usr/libexec/PlistBuddy -c "Print objects:"${targetid}":buildConfigurationList" "${plist}")
buildConfiguration=$(/usr/libexec/PlistBuddy -c "Print objects:"${buildConfigurationList}":buildConfigurations:1" "${plist}")
profileuuid=$(/usr/libexec/PlistBuddy -c "Print objects:"${buildConfiguration}":buildSettings:PROVISIONING_PROFILE" "${plist}")
profile=~/Library/MobileDevice/Provisioning\ Profiles/"${profileuuid}".mobileprovision
if [ ! -f "${profile}" ]
then
echo "mobileprovision file not found!"
exit 1
fi
if [ ! -n "${customArchiveName}" ]
then
customArchiveName="${scheme}"
fi
# find certname (first valid certificate in mobileprovision file)
mpplist=/tmp/"${profileuuid}".plist
certdata=/tmp/"${profileuuid}".cer
validcerts=/tmp/"${profileuuid}".txt
security cms -D -i "${profile}" > "${mpplist}"
security find-identity -v -p codesigning | cut -d ' ' -f4 > "${validcerts}"
count=$(xmllint --xpath "count(plist/dict/array/data)" "${mpplist}")
maxidx=$[${count} - 1]
for idx in $(seq 0 ${maxidx})
do
/usr/libexec/PlistBuddy -c "Print DeveloperCertificates:${idx}" "${mpplist}" > "${certdata}"
certfingerprint=$(openssl x509 -inform der -in "${certdata}" -noout -fingerprint | cut -d '=' -f2 | sed 's/://g')
if [ $(cat "${validcerts}" | grep "${certfingerprint}" | wc -l) -gt 0 ]
then
certsubject=$(openssl x509 -inform der -in "${certdata}" -noout -subject)
certname=$(echo "${certsubject}" | cut -d '/' -f3 | cut -d '=' -f2)
break
fi
done
if [ ! -n "${certname}" ]
then
echo "valid certificate not found!"
exit 1
fi
# package ipa
archive=$(ls -dt ~/Library/Developer/Xcode/Archives/*/"${customArchiveName}"*.xcarchive|head -1)
app=$(ls -dt "${archive}"/Products/Applications/*.app|head -1)
ipa=/tmp/"${scheme}".ipa
rm -f "${ipa}"
/usr/bin/xcrun -sdk iphoneos PackageApplication \
-o "${ipa}" \
-v "${app}" \
-s "${certname}" \
--embed "${profile}"
# upload ipa to inhouse webserver
#curl -F ipa=@"${ipa}" "${inhouseserver}"
@linyize
Copy link
Author

linyize commented Dec 23, 2013

TODO:
1、加强错误检验
2、找到一个快速检验证书+私钥是否有效的途径,目前的方式比较慢
3、如果工程中指定了CodeSigning,使用指定的CodeSigning来签名打包

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment