IOS build脚本

generate_manifest.py

  
  
   
   
#!/usr/bin/python
from optparse import OptionParser
import shutil
import fileinput
import os
import sys
import glob
import subprocess
import plistlib
import urlparse
import string
import fnmatch
parser = OptionParser ()
parser . add_option ( '-f' , '--app-bundle' , action = 'store' , dest = 'app_bundle' , help = 'Path to app bundle' )
parser . add_option ( '-a' , '--archive-name' , action = 'store' , dest = 'archive_name' , help = 'Legacy archive filename' )
parser . add_option ( '-d' , '--deployment-address' , action = 'store' , dest = 'deployment_address' , help = 'Remote deployment path, where the app will eventually be hosted' )
parser . add_option ( '-c' , '--changes-page-url' , action = 'store' , dest = 'changes_page_url' , help = 'URL describing the changes that went into this build' )
( options , args ) = parser . parse_args ()
if options . app_bundle == None :
parser . error ( "Please specify the file path to the app bundle." )
elif options . deployment_address == None :
parser . error ( "Please specify the deployment address." )
elif options . archive_name == None :
parser . error ( "Please specify the filename of the legacy archive." )
elif options . changes_page_url == None :
parser . error ( "Please specify a URL to a page listing the changes in this build." )
class IPAGenerator ( object ):
"Generate index.html"
def generate_html ( self , app_name ):
HTML_FILENAME = 'index.html'
index_file = open ( HTML_FILENAME , 'w' )
index_file . write ( self . template ( app_name ))
return HTML_FILENAME
"Locates the app's Info.plist"
def info_plist_filename ( self ):
filename = 'Info.plist'
for file in os . listdir ( options . app_bundle ):
if fnmatch . fnmatch ( file , '*Info.plist' ):
filename = file
break
return filename
"Generate manifest by parsing values from the app's Info.plist"
def generate_manifest ( self , app_name ):
filename = self . info_plist_filename ()
info_plist_filepath = os . path . join ( options . app_bundle , filename )
info_plist_xml_filename = 'info_plist.xml'
# Use plutil to ensure that we are dealing with XML rather than the binary format
subprocess . Popen ( 'plutil -convert xml1 -o ' + info_plist_xml_filename + ' ' + "'" + info_plist_filepath + "'" , shell = True ) . wait ()
info_plist_xml_file = open ( info_plist_xml_filename , 'r' )
app_plist = plistlib . readPlist ( info_plist_xml_file )
os . remove ( info_plist_xml_filename )
MANIFEST_FILENAME = 'manifest.plist'
manifest_plist = {
'items' : [
{
'assets' : [
{
'kind' : 'software-package' ,
'url' : urlparse . urljoin ( options . deployment_address , app_name + '.ipa' ),
}
],
'metadata' : {
'bundle-identifier' : app_plist [ 'CFBundleIdentifier' ],
'bundle-version' : app_plist [ 'CFBundleVersion' ],
'kind' : 'software' ,
'title' : app_plist [ 'CFBundleName' ],
}
}
]
}
plistlib . writePlist ( manifest_plist , MANIFEST_FILENAME )
return MANIFEST_FILENAME
"Template from http://github.com/HunterHillegas/iOS-BetaBuilder"
def template ( self , app_name ):
template_html = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>[BETA_NAME] - Beta Release</title>
<style type="text/css">
body {background:#fff;margin:0;padding:0;font-family:arial,helvetica,sans-serif;text-align:center;padding:10px;color:#333;font-size:16px;}
#container {width:300px;margin:0 auto;}
h1 {margin:0;padding:0;font-size:14px;}
p {font-size:13px;}
.link {background:#ecf5ff;border-top:1px solid #fff;border:1px solid #dfebf8;margin-top:.5em;padding:.3em;}
.link a {text-decoration:none;font-size:15px;display:block;color:#069;}
</style>
</head>
<body>
<div id="container">
<h1>iOS 4.0 Users:</h1>
<div class="link"><a href="itms-services://?action=download-manifest&url=[DEPLOYMENT_PATH]">Tap here to install<br />[BETA_NAME]<br />On Your Device</a></div>
<p><strong><em><a href="[BUILD_CHANGES_URL]">Tap here to view changes in this build</a></em></strong><br /></p>
<p><strong>Link didn't work?</strong><br />
Make sure you're visiting this page on your device, not your computer.</p>
<p><strong>On a version of iOS before 4.0?</strong><br />
Reload this page in your computer browser and download a zipped archive and provisioning profile here:
</p>
<div class="link"><a href="[BETA_ARCHIVE_FILENAME]">[BETA_NAME]<br />Archive w/ Provisioning Profile</a></div>
</div>
</body>
</html>
"""
TEMPLATE_PLACEHOLDER_NAME = '[BETA_NAME]'
TEMPLATE_PLACEHOLDER_DEPLOYMENT_PATH = '[DEPLOYMENT_PATH]'
TEMPLATE_PLACEHOLDER_ARCHIVE_FILENAME = '[BETA_ARCHIVE_FILENAME]'
TEMPLATE_PLACEHOLDER_BUILD_CHANGES_URL = '[BUILD_CHANGES_URL]'
template_html = string . replace ( template_html , TEMPLATE_PLACEHOLDER_NAME , app_name )
template_html = string . replace ( template_html , TEMPLATE_PLACEHOLDER_DEPLOYMENT_PATH , options . deployment_address )
template_html = string . replace ( template_html , TEMPLATE_PLACEHOLDER_ARCHIVE_FILENAME , options . archive_name )
template_html = string . replace ( template_html , TEMPLATE_PLACEHOLDER_BUILD_CHANGES_URL , options . changes_page_url )
return template_html
generator = IPAGenerator ()
app_name = os . path . splitext ( options . app_bundle )[ 0 ]
html_filename = generator . generate_html ( app_name )
manifest_filename = generator . generate_manifest ( app_name )


build_ipa.sh:

  
  
   
   
#!/bin/bash
# Below are required environment variables with some example content:
# XCODE_BUILD_COMMAND='xcodebuild -sdk iphoneos4.1 -alltargets -configuration "Ad Hoc" clean build'
# XCODE_BUILD_CONFIGURATION='Ad Hoc'
# DISTRIBUTION_CERTIFICATE='iPhone Distribution: Your Company Pty Ltd'
# PROVISIONING_PROFILE_PATH='/Users/tomcat/Library/MobileDevice/Provisioning Profiles/Your_Company_Ad_Hoc.mobileprovision'
# GIT_BINARY='/usr/local/git/bin/git'
# REMOTE_HOST='your.remote.host.com'
# REMOTE_PARENT_PATH='/www/docs/ios_builds'
# MANIFEST_SCRIPT_LOCATION='http://github.com/baz/ios-build-scripts/raw/master/generate_manifest.py'
# ROOT_DEPLOYMENT_ADDRESS='http://your.remote.host.com/ios_builds'
# ARCHIVE_FILENAME='beta_archive.zip'
# KEYCHAIN_LOCATION='/Users/tomcat/Library/Keychains/Your Company.keychain'
# KEYCHAIN_PASSWORD='Password'
# Build project
security default-keychain -s "$KEYCHAIN_LOCATION"
security unlock-keychain -p $KEYCHAIN_PASSWORD "$KEYCHAIN_LOCATION"
eval $XCODE_BUILD_COMMAND
GIT_HASH = "$($GIT_BINARY log --pretty=format:'' | wc -l)-$($GIT_BINARY rev-parse --short HEAD)"
GIT_HASH = ${ GIT_HASH //[[: space :]] }
BUILD_DIRECTORY = "$(pwd)/build/${XCODE_BUILD_CONFIGURATION}-iphoneos"
cd "$BUILD_DIRECTORY" || die "Build directory does not exist."
MANIFEST_SCRIPT = $(curl -fsS $MANIFEST_SCRIPT_LOCATION )
MANIFEST_OUTPUT_HTML_FILENAME = 'index.html'
MANIFEST_OUTPUT_MANIFEST_FILENAME = 'manifest.plist'
for APP_FILENAME in *.app; do
APP_NAME = $( echo "$APP_FILENAME" | sed -e 's/.app//' )
IPA_FILENAME = "$APP_NAME.ipa"
DSYM_FILEPATH = "$APP_FILENAME.dSYM"
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "$APP_FILENAME" -o "$BUILD_DIRECTORY/$IPA_FILENAME" --sign "$DISTRIBUTION_CERTIFICATE" --embed "$PROVISIONING_PROFILE_PATH"
# Create legacy archive for pre iOS4.0 users
cp "$PROVISIONING_PROFILE_PATH" .
PROVISIONING_PROFILE_FILENAME = $(basename "$PROVISIONING_PROFILE_PATH" )
zip "$ARCHIVE_FILENAME" "$IPA_FILENAME" "$PROVISIONING_PROFILE_FILENAME"
rm "$PROVISIONING_PROFILE_FILENAME"
# Output of this is index.html and manifest.plist
python -c "$MANIFEST_SCRIPT" -f "$APP_FILENAME" -d "$ROOT_DEPLOYMENT_ADDRESS/$APP_NAME/$GIT_HASH/$MANIFEST_OUTPUT_MANIFEST_FILENAME" -a "$ARCHIVE_FILENAME" -c "$JOB_URL/$BUILD_NUMBER"
# Create tarball with .ipa, dSYM directory, legacy build and generated manifest files and scp them all across
PAYLOAD_FILENAME = 'payload.tar'
tar -cf $PAYLOAD_FILENAME "$IPA_FILENAME" "$DSYM_FILEPATH" "$ARCHIVE_FILENAME" "$MANIFEST_OUTPUT_HTML_FILENAME" "$MANIFEST_OUTPUT_MANIFEST_FILENAME"
QUOTE = '"'
ssh $REMOTE_HOST "cd $REMOTE_PARENT_PATH; rm -rf ${QUOTE}$APP_NAME${QUOTE}/$GIT_HASH; mkdir -p ${QUOTE}$APP_NAME${QUOTE}/$GIT_HASH;"
scp "$PAYLOAD_FILENAME" "$REMOTE_HOST:$REMOTE_PARENT_PATH/${QUOTE}$APP_NAME${QUOTE}/$GIT_HASH"
ssh $REMOTE_HOST "cd $REMOTE_PARENT_PATH/${QUOTE}$APP_NAME${QUOTE}/$GIT_HASH; tar -xf $PAYLOAD_FILENAME; rm $PAYLOAD_FILENAME"
# Clean up
rm "$IPA_FILENAME"
rm "$ARCHIVE_FILENAME"
rm "$MANIFEST_OUTPUT_HTML_FILENAME"
rm "$MANIFEST_OUTPUT_MANIFEST_FILENAME"
rm "$PAYLOAD_FILENAME"
done

转帖分析:

build_ipa.sh稍微修改一下,将该sh文件以及py文件全部放到文件目录下,直接在Terminal中运行./build_ipa.sh就能生成所需要的ipa文件和manifest.plist文件,将这两个文件放入服务器,并在服务器的网页地址中加入<a href="itms-services://?action=download-manifest&url=http://服务器地址目录/manifest.plist">,这个时候你就可以通过手机客户端进入服务器网址下载程序了。


参考资料:

https://github.com/baz/ios-build-scripts/blob/master/generate_manifest.py

https://github.com/baz/ios-build-scripts

猜你喜欢

转载自blog.csdn.net/rsp19801226/article/details/7383566