用Python编写IOS工程的自动编译脚本

原创 2013年12月05日 14:27:38

    折腾了一周,终于用Python语言写好了项目工程的自动编译脚本,虽然最终脚本只有200多行代码,但中间遇到的一些问题还是折磨了我一番, 好了, 现在把过程记录下来, 以便加深自己的印象, 也可供需要的人参考.

    一.目标

    我写这个脚本是要做到下面几个目标:

    1.每次编译都从服务器更新最新代码;

    2.每次编译要自动修改info.plist里的bundle version;

    3.每次编译都要编译出debug版和可供发布的distribution版, debug供测试人员使用, 测试通过后直接使用对应的distribution版本提交到App Store;

    4.编译出的包上传到服务器, 并通过邮件通知相关人员, 邮件内容是安装包的地址, 如果编译失败, 邮件内容是失败信息.

    二. 开发环境

    我是在Mac下用Python开发的, 其实直接用shell脚本也行, 我是为了操作一些文件更方便, 编辑器用的Sublime text 2.

    三. 前提条件

    开发证书和发布证书请先安装好, 工程配置里添加Distribution项(复制Release), 并配置好对应的发布证书.

    四. check out工程代码.

    代码管理我用的是svn, 下载代码其实就是用Python执行shell命令, 代码如下:

def svnCheckout(self):
	print "svn checkout start"
	os.system('rm -frd %s'%codeDir)
	os.system('mkdir %s'%codeDir)
	os.system('svn checkout %s --username %s --password %s --non-interactive %s'\
		%(svnPath,svnUserName,svnPassword,codeDir))
	if os.path.exists('%s/YourProject'%codeDir) == False:
		msg = 'checkout code failed'
		print msg
		self.buildSucceed = False
		self.buildErrorDescription.append(msg)
		return False
	else:
		os.chdir(LifeSearchBuild.codeDir)
		return True
    需要导入os模块, os.system()方法是执行shell命令的, 代码中, codeDir变量是check out代码后存放的本地目录, buildErrorDescription是我定义的一个列表, 用来记录错误的信息的, 供后面发送邮件使用(编译失败时).

    五. 修改bundle version

    其实这一步是为了Distribution版, 因为提交到App Store的包, bundle version必须是递增的一个数, bundle version在工程的info.plist文件里, 操作plist, 可以直接用Mac自带的PlistBuddy, 代码如下:

def modifyBundleVersion(self,newBundleVersion):
	os.system('/usr/libexec/PlistBuddy -c "Set:CFBundleVersion %s" %s'%(newBundleVersion,infoPlistFilePath))
    其中infoPlistFilePath是你check out代码后工程里info.plist文件的路径. newBundleVersion需要你自己定义一个规则, 保证和上次编译的包的version是递增的就行, 编译完成后也需要持久化到本地, 以便下次做递增计算.

    六. 编译工程

    有了代码后, 就开始用xcodebuild命令来编译工程, 编译debug版的代码如下:

def build_debug(self):
	print "build debug start"
	os.system('rm -frd build')
	os.system('xcodebuild clean -configuration Debug')
	os.system('xcodebuild -configuration Debug')
	if os.path.exists('build/Debug-iphoneos/YourProject.app'):
		debugIpaName = 'debug_%s_%s.ipa'%(currAppVersion,self.buildVersion)
		os.system('mkdir Payload')
		os.system('cp -r ./build/Debug-iphoneos/YourProject.app ./Payload/')
		os.system('zip -r %s Payload'%debugIpaName)
		os.system('rm -frd build')
		os.system('rm -frd Payload')
		self.ipaNameList.append(debugIpaName)
	else:
		self.buildSucceed = False
		self.buildErrorDescription.append('build debug ipa failed')
    说明:app生成后需要放进一个Payload文件夹, 然后压缩成zip, 然后改后缀为ipa, Distribution的不用, 发布时直接用zip包提交.

    代码中ipaNameList是我定义的一个列表, 用来保存编好的包名字的, 以便后续上传服务器时使用.

    七. 上传到服务器

    我用到了ftp命令, 代码如下:

def uploadToFTP(self):
	if len(self.ipaNameList) == 0:
		self.buildSucceed = False
		print "no ipas to upload"
		return
		
	os.system('''
		ftp -niv %s << EOF
		user %s %s
		bin
		mkdir %s/%s
		cd %s/%s
		lcd %s
		mput %s
		bye
		EOF'''%(ftpAddress,
			ftpUserName, 
			ftpPassword, 
			currAppVersion, 
			self.buildVersion,
			currAppVersion, 
			self.buildVersion,
			codeDir,
			' '.join(self.ipaNameList)))
    其实大家不用细看这段代码, 这是我项目里直接拷贝过来的, 只要大家能用ftp命令上传到自己的服务器就行了.

    八. 邮件通知

    发邮件用到了smtplib, 我的邮件内容需是html格式的, 我就不直接拷贝我项目里的代码了, 写个例子代码如下:

smtp = smtplib.SMTP('mail.yourcompany.com')
smtp.login(emailSenderUserName, emailSenderPassword)
msg = MIMEMultipart()
msg['To'] = ";".join(emailAddressList)
msg['From'] = emailSender
msg['Subject']= "test mail"
text = "<p>build successful</p>"
body = MIMEText("%s"%text,_subtype='html',_charset='utf-8')
msg.attach(body)
smtp.sendmail(msg['From'], emailAddressList, msg.as_string())
smtp.quit()

    九. dailybuild

    编译脚本弄好后, 可以手动运行编译, 也可以添加计划任务来每日定时编译, 这就用到了crontab, 如果你想每天早上8点运行自动编译脚本, 则编辑crontab如下:

0 8 * * * python build.py >buildLog.txt
    buildLog.txt文件用来记录日志.

    注意!!用crontab的时候, 证书的问题折磨了我整整一天, 因为在crontab, 证书无法读取到, 导致签名失败, 上网查了大量的文章, 好像跟crontab无法读取到用户化境变量有关, 不过, 最终我的解决办法倒是很简单, 就是打开钥匙串, 把证书从"登录"里拷贝到"系统"里就可以了.

    ok, 完了, 希望对大家有帮助.

Jenkins自动打包IOS与分发fir

周末看了《大话测试2》突然有想法把公司的IOS打包做一下自动打包和分发,于是今天就开始行动啦!背景CI(持续集成)是现在非常流行的软件开发实践,可以自动化的持续打包部署代码或者安装包,减少了手工干预,...

jenkins xcodebuild命令行打包iOS项目问题汇总

这几天折腾了jenkins对iOS项目的持续集成,碰到了很多问题,记录下吧 xcodebuild: error: The project named “Foo” does not contain a ...
  • offbye
  • offbye
  • 2016年05月26日 12:45
  • 8821

IOS工程自动打包并发布脚本实现

文章首发地址:http://webfrogs.me/2013/02/18/ios-automation/ 作者:webfrogs 转载请注明出处。 前言 ...

IOS工程自动打包并发布脚本实现

作者:webfrogs 转载请注明出处。 前言 IOS的开发过程中,当需要给测试人员发布测试包的时候,直接使用xcode来做的效率是非常低下的。尤其是当有一点小改动需要重新出包时,那简直是个折磨...

IOS工程自动打包并发布脚本实现

文章首发地址:http://webfrogs.me/2013/02/18/ios-automation/ 作者:webfrogs 转载请注明出处。 前言 ...

iOS工程自动打包并发布通过脚本实现

作者:webfrogs 转载请注明出处。 前言 IOS的开发过程中,当需要给测试人员发布测试包的时候,直接使用xcode来做的效率是非常低下的。尤其是当有...

IOS工程自动打包并发布脚本实现

文章首发地址:http://webfrogs.me/2013/02/18/ios-automation/ 作者:webfrogs 转载请注明出处。 前言 IOS...
  • ccf0703
  • ccf0703
  • 2013年02月18日 17:35
  • 30477

iOS工程自动打包 (Shell脚本打包)

前提是要打包的项目在Xcode 配置好证书之后并且可以正常的打包。然后执行如下的操作 自动打包脚本设置: 去GitHub上下载xcode_shell,只需要“ipa-build”脚本就可以的,内容...

IOS工程自动打包并发布脚本实现

前言 思路 实现 使用 1.compile and package xcode project or workspace Usage: Options: Example: 2.comp...

IOS工程自动打包并发布脚本实现

网上看到一个build ios工程并打包的脚本,写的很不错,学习了下,并添加部分注释,方便理解 http://blog.csdn.net/ccf0703/article/details/8588...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用Python编写IOS工程的自动编译脚本
举报原因:
原因补充:

(最多只允许输入30个字)