利用 Jenkins 自动生成 ipa 包

背景

项目进入测试阶段要不停的给测试的同学打包,我们就不得不停下手中的工作,Archive -> 导出 ipa 包 -> 发给测试的同学 -> 测试的同学通过 iTunes 装到手机上测试 -> 发现 bug,我们修改完后又需要重新打包,然后不停的重复上面的工作,你烦不烦?反正我是受够了。。。正是有了上面的痛点,才会去想能不能我们提交代码后让测试的同学自己打包,然后通过一个 url 直接安装到手机上?答案是必须的能,要不我也不用在这里逼逼逼了~~~,废话少说,开始。。。

我们可以用 Jenkins 来帮我们完成。首先介绍一下Jenkins,它是一个开源软件项目,是基于Java开发的,旨在提供一个开放易用的软件平台,用于监控持续重复的工作(比如上面的提到的打 ipa包),使持续集成变成可能。

本来想把 Jenkins 搭在公司的内部服务器上,但是这样的话不能装 xcodebuild 命令(至少我现在不知道怎么做,知道的话麻烦告诉我),于是放弃了,把 Jenkins 装在 mac 上,打完 ipa 包后再通过 ftp 传到服务器上。部署好以后,把 Jenkins 的地址和能下载 ipa 包的地址发给测试的同学,他们就可以自己打包,并且能通过 url 很简单的把 ipa 包装到手机上。从此,我的世界就能清净了。

1.使用 home-brew 安装 jdk
什么?没用过 home-brew,自己面壁去!!!

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Jenkins 是基于 Java 开发的,首先保证系统中已经安装了 jdk。
命令如下:

brew install Caskroom/cask/java

2.使用 homebrew 安装 jenkins

brew install jenkins

3.做软链接

ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents

4.启动

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

然后就可以在浏览器里通过 http://localhost:8080 来看到 Jenkins了。第一次安装会让输入密码,密码可以在这里查看

cat /var/lib/jenkins/secrets/initialAdminPassword

接着装好默认的插件后就可以使用了。界面如下:

jenkins1.jpg

现在来创建一个新任务:

jenkins1.jpg

这里以 svn 为例,git 当然也是可以的。配置源码 svn 如下所示

jenkins1.jpg

添加我们需要的插件

jenkins1.jpg

在可选插件里输入我们想要安装的插件,我们需要用的有:
1.Xcode Plugin 打 ipa 包要用到的
2.Publish Over FTP Plugin 上传 ftp 服务器要用到的

构建触发器,这里配置的是每 15 分钟检测一下 svn 的版本号,有变化的话就开始打包

jenkins1.jpg

配置 xcode

jenkins1.jpg

jenkins1.jpg

jenkins1.jpg

可以添加打包完成后执行本地 shell

jenkins1.jpg

配置 ftp
现在系统设置里配置,然后再到 jenkins_test 里面去配置
系统配置如下:

jenkins1.jpg

点开高级以后别忘了设置里面的端口号

jenkins1.jpg

jenkins1.jpg

然后回到 jenkins_test 做相关的配置

jenkins1.jpg

点击立即构建后,从 Console Output 可以看出先更新svn,然后打包,打包后把 ipa 包传到服务器上,

jenkins1.jpg

至此可以用 Jenkins 来自动打包上传了,接下来要做的就是测试的同学通过一个 url 来直接安装 ipa 到手机上,具体的步骤如下:
1.准备 manifest.plist 文件

jenkins1.jpg

2.准备 html 文件,目的是让测试同学通过这个下载 ipa 包,本 demo 如下:

jenkins1.jpg

源码如下:

jenkins1.jpg

注意:在 iOS7.1 后这个 manifest.plist 的地址必须要为 https 的,要不不能正确的安装到手机上。没有用 https 的可以在这里免费申请一个:
https://www.startssl.com

附件
html 文件:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<head>
    <title>OrderMeet</title>
</head>
<body>
    <ul>
        <li><a href="itms-services://?action=download-manifest&url=https://example.cn/soft/manifest.plist"> 点击下载</a>
        </li>
    </ul> 
</body>
</html>

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>https://abc.com/HelloJenkins.ipa</string>
            </dict>
            <dict>
                <key>kind</key>
                <string>display-image</string>
                <key>url</key>
                <string>https://abc.com/icon.png</string>
            </dict>
            <dict>
                <key>kind</key>
                <string>full-size-image</string>
                <key>url</key>
                <string>https://abc.com/icon%402x.png</string>
            </dict>
        </array>
        <key>metadata</key>
        <dict>
            <key>bundle-identifier</key>
            <string>test.com</string>
            <key>bundle-version</key>
            <string>1.0</string>
            <key>kind</key>
            <string>software</string>
            <key>title</key>
            <string>HelloJenkins</string>
        </dict>
    </dict>
</array>
</dict>
</plist>