前言

Daily Build是一件非常有意义的事情,也是敏捷开发中关于“持续集成”的一个实践。Daily Build对于开发来说有如下好处:

  • 保证了每次check in的代码可用,不会造成整个工程编译失败。
  • 进度跟进。产品经理可以每天看到最新的开发进度,并且试用产品,调整一些细节。很多时候,一个新功能,你真正用了一下才能有体会好或不好,所以daily build也给产品经理更多时间来调理他的设计。
  • 需求确认。产品经理可以确认开发的功能细节是他的预期。因为我们的开发比较紧凑,所以都没有传统的需求说明文档,所以daily build也给产品经理用于尽早确认开发的功能细节是他的预期,我就遇到一次产品经理发现开发出的一个功能细节和他的预期不一致,但是因为有daily build,使得我可以尽早做修改,把修改的代价减小了。
  • 测试跟进。如果功能点是独立的话,测试同事完全可以根据daily build来进行一些早期的测试。越早的Bug反馈可以使得修改bug所需的时间越短。

步骤

xcodebuild命令

如何做daily build呢?其实Xcode就提供了命令行build的命令,这个命令是xcodebuild,用xcodebuild -usage 可以查看到所有的可用参数,如下所示:

1
2
3
4
5
6
7
[tangqiao ~]$xcodebuild -usage
Usage: xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild [-project <projectname>] -scheme <schemeName> [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild -workspace <workspacename> -scheme <schemeName> [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [<buildsetting>=<value>]... [<buildaction>]...
       xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [<infoitem>] ]
       xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]]
       xcodebuild -showsdks

一般情况下的命令使用如下:

1
xcodebuild -configuration Release -target "YourProduct"

但在daily build中,用Release用为configuration其实不是特别好。因为Release的证书可能会被经常修改。我们可以基于Release的Configuation,建一个专门用于daily build的configuration。方法是:在工程详细页面中,选择Info一栏,在Configurations一栏的下方点击“+”号,然后选择”Duplicate Release Configuration”, 新建名为”DailyBuild”的Configuration, 如下图所示:

之后就可以用如下命令来做daily build了

1
xcodebuild -configuration DailyBuild -target "YourProduct"

执行完命令后,会在当前工程下的 build/DailyBuild-iphoneos/目录下生成一个名为: YourProduct.app的文件。这个就是我们Build成功之后的程序文件。

生成ipa文件

接下来我们需要生成ipa文件,在生成ipa文件这件事情上,xcode似乎没有提供什么工具,不过这个没什么影响,因为ipa文件实际上就是一个zip文件,我们使用系统的zip命令来生成ipa文件即可。需要注意的是,ipa文件并不是简单地将编辑好的app文件打成zip文件,它需要将app文件放在一个名为Payload的文件夹下,然后将整个Payload目录打包成为.ipa文件,命令如下:

1
2
3
4
5
cd $BUILD_PATH
mkdir -p ipa/Payload
cp -r ./DailyBuild-iphoneos/$PRODUCT_NAME ./ipa/Payload/
cd ipa
zip -r $FILE_NAME *

生成安装文件

苹果允许用itms-services协议来直接在iphone/ipad上安装应用程序,我们可以直接生成该协议需要的相关文件,这样产品经理和测试同学都可以直接在设备上安装新版的应用了。相关的参考资料可以见:这里和 这里

具体来说,就是需要生成一个带 itms-services 协议的链接的html文件,以及一个 plist 文件。

生成html的示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat << EOF > install.html
<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>安装此软件</title>
  </head>
  <body>
    <ul>
      <li>安装此软件:<a href="itms-services://?action=download-manifest&url=http%3A%2F%2Fwww.yourdomain.com%2Fynote.plist">$FILE_NAME</a></li>
    </ul>
    </div>
  </body>
</html>
EOF

生成plist文件的代码如下,注意,需要将下面的涉及 www.yourdomain.com的地方换成你线上服务器的地址,将ProductName换成你的app安装后的名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
cat << EOF > ynote.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>items</key>
   <array>
       <dict>
           <key>assets</key>
           <array>
               <dict>
                   <key>kind</key>
                   <string>software-package</string>
                   <key>url</key>
                   <string>http://www.yourdomain.com/$FILE_NAME</string>
               </dict>
               <dict>
                   <key>kind</key>
                   <string>display-image</string>
                   <key>needs-shine</key>
                   <true/>
                   <key>url</key>
                   <string>http://www.yourdomain.com/icon.png</string>
               </dict>
           <dict>
                   <key>kind</key>
                   <string>full-size-image</string>
                   <key>needs-shine</key>
                   <true/>
                   <key>url</key>
                   <string>http://www.yourdomain.com/icon.png</string>
               </dict>
           </array><key>metadata</key>
           <dict>
               <key>bundle-identifier</key>
               <string>com.yourdomain.productname</string>
               <key>bundle-version</key>
               <string>1.0.0</string>
               <key>kind</key>
               <string>software</string>
               <key>subtitle</key>
               <string>ProductName</string>
               <key>title</key>
               <string>ProductName</string>
           </dict>
       </dict>
   </array>
</dict>
</plist>

EOF

定时运行

这一点非常简单,使用crontab -e命令即可。大家可以随意google一下crontab命令,可以找到很多相关文档。假如我们要每周1-5的早上9点钟执行daily build,则crontab的配置如下:

1
0 9 * * * 1-5 /Users/tangqiao/dailybuild.sh >> /Users/tangqiao/dailybuild.log 2>&1

失败报警

在daily build脚本运行失败时,最好能发报警邮件或者短信,以便能够尽早发现。发邮件可以用python的smtplib来写,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import smtplib

sender = 'sender@devtang.com'
receivers = ['receiver@devtang.com']

message = """From: Alert <sender@devtang.com>
To: Some one <receiver@devtang.com>
Subject: SMTP email sample

Hope you can get it.
"""

try:
    obj = smtplib.SMTP('server.mail.devtang.com')
    obj.sendmail(sender, receivers, message)
    print 'OK: send mail succeed'
except Exception:
    print 'Error: unable to send mail'

上传

daily build编译出来如果需要单独上传到另外一台web机器上,可以用ftp或者scp协议。如果web机器悲剧的是windows机器的话,可以在windows机器上开一个共享,然后用 mount -t smbfs来将这个共享mount到本地,相关的示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mkdir upload
mount -t smbfs //$SMB_USERNAME:$SMB_PASSWORD@$SMB_TARGET ./upload
if [ "$?" -ne 0 ]; then
    echo "Failed to mount smb directory"
    exit 1
fi
mkdir ./upload/$FOLDER
cp $FILE_NAME ./upload/$FOLDER/
if [ "$?" -eq 0 ]; then
    echo "[OK] $FILE_NAME is uploaded to $SMB_TARGET"
else
    echo "[ERROR] $FILE_NAME is FAILED to  uploaded to $SMB_TARGET"
fi
umount ./upload

遇到的问题

本来我写的自动化脚本在Mac OS X 10.6下运行得很好。但是升级到lion后,脚本在手动执行时很正常,但是在用crontab启动时就会出现找不到开发者证书的错误。在网上搜了很久也没有找到解决办法。最后我试了一下在“钥匙串访问”中把开发者证书从“登录”那栏拖动到“系统”那栏,居然就解决了,如下图所示:

另外我搜到2个类似的问题的解决方案,虽然对我这个没起作用,也一并放在这儿,或许对遇到类似问题的人有帮助:

  • http://stackoverflow.com/questions/7635143/cannot-build-xcode-project-from-command-line-but-can-from-xcode
  • http://shappy1978.iteye.com/blog/765842

总结

将以上各点结合起来,就可以用bash写出一个daily build脚本了。每天这一切都会自动完成,心情相当好。

给iOS工程增加Daily Build相关推荐

  1. 如何将 iOS 工程打包速度提升十倍以上

    如何将 iOS 工程打包速度提升十倍以上 过慢的编译速度有非常明显的副作用.一方面,程序员在等待打包的过程中可能会分心,比如刷刷朋友圈,看条新闻等等.这种认知上下文的切换会带来很多隐形的时间浪费.另一 ...

  2. [转]在.NET环境中实现每日构建(Daily Build)--NAnt篇

    本文转自:http://dragon.cnblogs.com/archive/2005/07/29/203189.html   前言 关于每日构建这个话题,也已经有很多很好的文章讨论了.本文的写作过程 ...

  3. iOS工程开发笔记二

    iOS工程开发笔记<二> 在Xcode 4, 5的模板工程中可以看到Precompile Prefix Header,但是在Xcode 6被去除了. Xcode 6去掉Precompile ...

  4. 【IOS】IOS工程自动打包并发布脚本实现

    网上看到一个build ios工程并打包的脚本,写的很不错,学习了下,并添加部分注释,方便理解 http://blog.csdn.net/ccf0703/article/details/8588667 ...

  5. Alibaba iOS 工程架构腐化治理实践

    " 业务开发遇到环境问题越来越多,严重影响开发效率,有些表面看似打包问题,背后却是工程架构的腐化." 背景 近年来,iOS工程复杂度高的负面影响逐渐暴露,很多同学都受到了iOS打包 ...

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

    文章首发地址:http://webfrogs.me/2013/02/18/ios-automation/ 作者:webfrogs 转载请注明出处. 前言 IOS的开发过程中,当需要给测试人员发布测试包 ...

  7. Flutter-现有iOS工程引入Flutter

    前言 Flutter 是一个很有潜力的框架,但是目前使用Flutter的APP并不算很多,相关资料并不丰富,介绍现有工程引入Flutter的相关文章也比较少.项目从零开始,引入Flutter操作比较简 ...

  8. 在.NET环境中实现每日构建(Daily Build)--ccnet,MSBuild篇

    每日构建,对我们团队来说一个全新的概念.随着项目开发的进展,在开发过程需要及时反馈一些BUG和功能要求的处理情况.而在这种情况下每天或隔一段时间Build一个版本,工作量还是比较大的,所以就特别有必要 ...

  9. 使用脚本删除ios工程中未使用图片

    使用脚本删除ios工程中未使用图片 最近在读唐巧大神的<iOS开发进阶>,学到了一个大招:使用脚本删除ios中未使用的图片(纸书上有点小问题,参考github上的issue:使用脚本删除i ...

最新文章

  1. 人际关系和谐交际的10个“音符”
  2. UILocalNotification详解
  3. Netty学习四:Channel
  4. docker etcd
  5. Android官方开发文档Training系列课程中文版:后台加载数据之处理CursorLoader的查询结果
  6. mysql命令实践_MySQL:常用命令行
  7. [中英对照]The sysfs Filesystem | sysfs文件系统
  8. 尤克里里怎么样_尤克里里入门简单教程
  9. 移动应用开发平台UDE上线V2.0,升级引擎,推出应用云托管服务
  10. PYTHON读取EXCEL内容再转变成HTML添加到OUTLOOK中
  11. 总线式布线、差分走线等布线方法
  12. 博图注册表删除方法_「博图+仿真+授权」西门子软件安装指南及注意事项
  13. 图像处理农业应用sci_SCI征稿通知
  14. 基于TCP/IP的展厅智能中控系统
  15. 豆瓣爬虫(从剧名获取ID)
  16. h5邮件的邮箱 支持_GitHub - cqjsqh/email: h5邮箱地址汇总
  17. 【Unity3D】人机交互Input
  18. 转-用Driver Studio工具包开发WDM型的USB设备驱动程序
  19. 一个循环实现冒泡法排序(并没有什么卵用)
  20. 伊达时计算机闹钟怎么取消,伊达时计算机如何取消闹钟

热门文章

  1. 美术0基础想快速入行游戏美术3d,需要学习哪些课程
  2. Select下拉框结合Ajax使用
  3. java计算机毕业设计微博网站源程序+mysql+系统+lw文档+远程调试
  4. (专升本)Word(重复标题行)
  5. 【Android开发】使用Bottom Navigation Activity去掉顶部栏(标题栏)
  6. centos amd双显卡_迎2020年双11大促,兼容机之家主机活动,10款电脑配置分享
  7. material theme 自定义_Angular Material 主题系统(二)-- 自定义主题
  8. Ceres Jet型
  9. 中科院和中科大计算机考研分数线,中国科学技术大学研究生院,中科大考研复试刷人太狠。...
  10. 用友t+畅捷通使用方法_北用友 南金蝶,谁才是中国财务软件的最强王者