Jenkins 是什么?
Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建、测试和部署软件。 Jenkins 支持各种运行方式,可通过系统包、Docker 或者通过一个独立的 Java 程序。
Jenkins 是一个 Java 程序,那么安装 Jenkins 就分为两步:
- 安装 Java 环境
- 安装 Jenkins
具体安装方式有两种:
这里为了方便管理,本文采用 Homebrew 进行安装,手动安装过程稍有差异,不过安装完后 Jenkins 的配置过程完全一致。
安装 Jenkins
没有 Java 环境的话,执行 brew install jenkins
会提示没有 Java 环境:
~ brew install jenkins
jenkins: Java 1.8 is required to install this formula.
Install AdoptOpenJDK 8 with Homebrew Cask:
brew cask install homebrew/cask-versions/adoptopenjdk8
Error: An unsatisfied requirement failed this build.
按照提示:
- 执行
brew cask install homebrew/cask-versions/adoptopenjdk8
安装 Java - 执行
brew install jenkins
安装 Jenkins
启动 Jenkins
通过 Homebrew 安装 Jenkins 的 log 来看,可以通过执行 jenkins
手动启动,也可以通过 brew services
来启动。
To have launchd start jenkins now and restart at login:
brew services start jenkins
Or, if you don't want/need a background service you can just run:
jenkins
还有一种方式,就是自己手动维护:
# 当前用户登录时自动启动 Jenkins
ln -sfv /usr/local/opt/jenkins/homebrew.mxcl.jenkins.plist ~/Library/LaunchAgents
# 手动启动 Jenkins
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist
如果需要外部访问,可以把 plist 文件里的 httpListenAddress
改为广播地址
<?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>Label</key>
<string>homebrew.mxcl.jenkins</string>
<key>ProgramArguments</key>
<array>
<string>/usr/libexec/java_home</string>
<string>-v</string>
<string>1.8</string>
<string>--exec</string>
<string>java</string>
<string>-Dmail.smtp.starttls.enable=true</string>
<string>-jar</string>
<string>/usr/local/opt/jenkins/libexec/jenkins.war</string>
<string>--httpListenAddress=127.0.0.1</string>
<string>--httpPort=8080</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
附上一张安装配置 Jenkins 的终端截图
Jenkins 初始化
启动了 Jenkins 后,就可以用浏览器打开 plist 配置的 httpListenAddress
:httpPort
来访问 Jenkins 了
默认为 localhost:8080
解锁 Jenkins
打开网页后经过一段初始化后,会出现如下界面,按照提示找到密码输入即可
安装插件
可以自己选择插件进行安装,也可以选择安装推荐的插件。如果不太了解,请选安装推荐的插件。
创建管理员用户
这里按照自己的要求来配置即可
到这里 Jenkins 的初始化就已经完成了
Jenkins 基本配置
安装 Xcode 打包需要的插件
通过点击 Manage Jenkins
> Manage Plugins
进入插件管理页面,勾选好插件之后点击直接安装即可
配置 Keychains and Provisioning Profiles Management
- 上传login.keychain,具体获取方式如下
~ ls ~/Library/Keychains
AE7B340D-384F-56B5-A4A5-91174B979B21
metadata.keychain-db
login.keychain-db
~ cp ~/Library/Keychains/login.keychain-db ~/Desktop/Jenkins/login.keychain
- 添加 Code Signing Identity,获取方式: 打开钥匙串,找到相应的证书,显示简介,细节里的常用名称即为 Code Signing Identity
-
添加 Provisioning Profiles Directory Path,
mobileprovision
文件一般在~/Library/MobileDevice/Provisioning\ Profiles
文件夹内 - 上传 Provisioning Profiles,这个根据自己需要选择文件上传即可
配置 Jenkins 全局的 PATH 和 Provisioning Profiles Directory Path
Manage Jenkins
> Configure System
- PATH:新增键值对 key 为 PATH,value 可以通过命令获得:
~ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
- Provisioning Profiles Directory Path:路径和上一步一致
打包任务
新建任务
点击左上角的新建按钮,选择 Freestyle project
, 填写任务名称,点击确定。
任务基本配置
在首页点击刚才创建的任务进入任务详情页,再点击配置按钮进入任务配置页
先做好项目的一些基本配置:
忽略旧的构建
一般会选中这个,保持每次构建的独立性
给项目添加一些参数
可以在每次触发任务的时候填入一些参数,比如分支名、版本号等等
自定义工作空间
一般不需要,默认 Jenkins 会在
~/.jenkins/workspace
下创建一个和任务名相同的文件夹作为工作空间
源码管理
Git、Subversion 等等
构建触发器
一些条件触发的自动构建
构建环境
构建相关的环境配置项
每个项目的配置稍有不同,这里就不细说了,大体参考下图:
任务构建配置
Xcode 任务有两种构建方式可供选择:
- 使用 Xcode 插件:构建 > 添加构建步骤 > Xcode
这种方式如果 Xcode 有相关的更新变化,就要依赖于 Jenkins Xcode 插件的更新,所以不太推荐这种构建方式,这里就不多做介绍了
- 自己编写构建脚本:构建 > 添加构建步骤 > Execute shell
脚本的优势在于灵活度高、可定制
比如自动生成 Build Version、pod install、配置一些路径、上传 ipa 到 蒲公英、fir.im、TestFlight 等等
主要通过 xcodebuild
来构建,这里放一个 Demo
打包方式 project 和 workspace 二选一即可
#!/bin/sh
AUTO_BUILD_VERSION=$(date +"%Y%m%d%H%M")
INFO_PLIST_PATH=$WORKSPACE/jenkins/Info.plist
PROJECT_NAME=$WORKSPACE/jenkins.xcodeproj
# WORKSPACE_NAME=$WORKSPACE/jenkins.xcworkspace
TARGET_NAME=jenkins
CONFIGURATION_NAME=Release
ARCHIVE_PATH=$WORKSPACE/$TARGET_NAME.xcarchive
IPA_PATH=$WORKSPACE/IPA
EXPORT_OPTIONS_PATH=$WORKSPACE/ExportOptions.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $AUTO_BUILD_VERSION" "$INFO_PLIST_PATH"
xcodebuild -project ${PROJECT_NAME} -scheme ${TARGET_NAME} -archivePath ${ARCHIVE_PATH} -configuration ${CONFIGURATION_NAME} clean archive
# pod install --project-directory=$WORKSPACE
# xcodebuild -workspace ${WORKSPACE_NAME} -scheme ${TARGET_NAME} -archivePath ${ARCHIVE_PATH} -configuration ${CONFIGURATION_NAME} clean archive
xcodebuild -exportArchive -archivePath ${ARCHIVE_PATH} -exportPath ${IPA_PATH} -exportOptionsPlist ${EXPORT_OPTIONS_PATH} -allowProvisioningUpdates
ExportOptions.plist 的获取方式
其实 Xcode 手动打包导出的文件里就包含了该文件,直接拿过来用就好了
<?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>compileBitcode</key>
<false/>
<key>destination</key>
<string>export</string>
<key>method</key>
<string>enterprise</string>
<key>provisioningProfiles</key>
<dict>
<key>app.bundle.id</key>
<string>Provisioning Profile Name</string>
</dict>
<key>signingCertificate</key>
<string>iPhone Distribution</string>
<key>signingStyle</key>
<string>manual</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>XXXXXXXXXX</string>
<key>thinning</key>
<string><none></string>
</dict>
</plist>
还有一种方式就是利用 build + PackageApplication 打包,不过这种方式因为 PackageApplication 被弃用了,所以有坑,除非特殊情况不推荐使用
TARGET_NAME=XXX
WORKSPACE_NAME=XXX.xcworkspace
CONFIGURATION_NAME=Release
CODE_SIGN_IDENTITY="iPhone Distribution: XXX Co., Ltd."
IPA_PATH=$WORKSPACE/IPA
xcodebuild -workspace ${WORKSPACE_NAME} -scheme ${TARGET_NAME} -sdk iphoneos -configuration ${CONFIGURATION_NAME} PBXBuildsContinueAfterErrors=NO CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" SYMROOT="${WORKSPACE}" clean build
if [ ! -d $IPA_PATH ]; then
mkdir -p $IPA_PATH
fi
xcrun -sdk iphoneos PackageApplication -v "$WORKSPACE/Debug-iphoneos/XXX.app" -o "$IPA_PATH/XXX.ipa"
- 坑在此,如果使用 PackageApplication 的话会提示
xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH
- 原因:在 Xcode 8.3 的版本 PackageApplication 被弃用了
- 解决办法:将 Xcode 8.2.1 的 PackageApplication 拷贝过来使用
# 我这里准备了一个 Xcode 8.2.1 的 PackageApplication 的备份
# https://gist.github.com/Dwarven/b75f8a8c593d5e1faff51e6d4e179542
# 将此文件保存为 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication
# 并添加执行权限 chmod +x
# 下边是两条命令,可直接使用
sudo curl -fsSL https://gist.github.com/Dwarven/b75f8a8c593d5e1faff51e6d4e179542/raw/8b1d6a2b1159223cd54d1ff276e854e333405b6c/PackageApplication -o /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication
sudo chmod +x /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication
如果需要上传到 TestFlight 的话 可以使用 altool
/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool --validate-app -f /Path/To/Your/IPA/xxx.ipa -t osx|ios|appletvos -u itunesconnectUserName -p itunesconnectPassword --output-format xml
/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool --upload-app -f /Path/To/Your/IPA/xxx.ipa -t osx|ios|appletvos -u itunesconnectUserName -p itunesconnectPassword --output-format xml
Xcode 11 移除了 Application Loader,可直接使用 xcrun altool
xcrun altool --validate-app -f /Path/To/Your/IPA/xxx.ipa -t osx|ios|appletvos -u itunesconnectUserName -p itunesconnectPassword --output-format xml
xcrun altool --upload-app -f /Path/To/Your/IPA/xxx.ipa -t osx|ios|appletvos -u itunesconnectUserName -p itunesconnectPassword --output-format xml
任务构建后操作
在构建完成后按自己需要添加一些处理操作,比如发送通知邮件、做一些Git操作等等
都是一些已经集成好的功能,如不满足需求,Jenkins 拥有强大的插件库,可以通过寻找合适的插件解决,实在不行可以在上一步的最后添加自己编写的 shell 脚本解决
Comments