背景
本人Android程序员一枚,之前未接触过Linux服务器,也未部署过jenkins持续集成环境,此次接到该任务需要从零开始学习,因此写下此文以作记录。如果你有跟我一样的任务和目标,或者你有更好的方案,都欢迎留言与我一起讨论。
前置准备
1、Linux服务器一台:作为主服务器,用于Java/Android持续集成
我使用的版本是:CentOS Linux release 7.4.1708 (Core)
2、MacOS机器一台:作为从服务器,用于Ios持续集成
我使用的版本是:macOS 10.13.6
3、Windows系统机器一台:开发环境
我使用的版本是:Win7_64位旗舰版
环境配置
我的Linux服务器是无界面的,所以通过windows机器连接和操作Linux服务器。
SecureCRT
首先找管理人员获取到Linux服务器的IP地址和账号,然后通过windows上安装的连接工具连接到Linux。连接工具我这边用的同事推荐的 SecureCRT
打开SecureCRT,新建连接,输入Linux服务器的IP地址、账号、密码等进行连接,随后进入Linux命令窗口,至此完成第一步。
Linux安装jdk
去Oracle 官方网站 下载合适的 JDK ,注意是下载Linux平台的。接下来是常规操作,在指定目录/usr/local/下创建java文件夹,可以用命令或者使用SecureCRT自带的SecureFX可视化窗口创建。创建命令网上都有查,我是新手还不太会用Linux命令,一般都是结合可视化工具操作,可根据个人习惯自行选择。
创建文件夹后,将之前下载的jdk通过SecureFX上传到刚刚创建的/usr/local/java文件夹中,并使用命令进行解压。解压完成后,需要修改/etc/profile,进行环境变量的配置,可参考网上的 博客, 配置完成后需要执行如下命令让修改生效:
source /etc/profile
最后输入 java -version验证安装结果。
Linux安装Android-SDK
去 官网 下载最新的 Linux平台的SDK, 下载完成后将SDK通过 SecureFX上传到某个目录下,我的目录是 /usr/local ,然后使用如下命令解压:
tar -zvxf android-sdk_r24.4.1-linux.tgz
解压之后,需要配置环境变了,修改/etc/profile文件,再末尾添加如下三行:
export ANDROID_HOME=/usr/local/android-sdk-linux
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH
执行命令,让修改立即生效:
source /etc/profile
执行命令,安装所有包:
android update sdk --no-ui
Linux安装Gradle
去 Gradle官网 下载相应版本的Gradle,我下载的是gradle-5.4.1-all.zip。下载完成后,将zip包通过SecureFX上传到/usr/local/目录下,使用如下命令解压:
unzp gradle-5.4.1-all.zip
如果没有unzip命令,先执行命令
yum install -y unzip zip
最后也是gradle环境变量的配置,修改/etc/profile文件,在末尾添加一下两行,并执行立即生效命令。
export GRADLE_HOME=/usr/local/gradle-5.4.1
export PATH=$PATH:$GRADLE_HOME/bin:$PATH
Linux安装Jenkins
首先去 Jenkins官网 下载对应平台的安装包,我下载的稳定版 jenkins-2.176.3-1.1.noarch.rpm。将下载的rpm包使用SecureFX上传到Linux服务器任意位置,然后使用命令进行安装(需要将命令中的版本号改成你的):
sudo rpm -ih jenkins-2.176.3-1.1.noarch.rpm
安装完成后,因为jenkins默认端口是8080,我们可以找到/etc/sysconfig/目录下的jenkins文件,修改默认端口,熟悉Linux操作的一般都用vi命令直接修改。跟我一样不熟悉的可以将该文件通过SecureFX工具导出到windows下进行修改,如下所示(导出文件时选择SACII):
文件导出后,在熟悉的windows下,用记事本或者其他工具打开jenkins文件,找到“JENKINS_PORT”,对默认的8080进行修改。
端口修改完毕后,再使用SecureFX工具将该文件导入到Linux服务器的/etc/sysconfig/目录下,替换原来的文件(这种方式比vi命令修改要麻烦些)。完成之后,即可使用命令启动jenkins服务:
sudo service jenkins start
结果显示OK后,就可以在windows平台使用Linux服务器的IP+配置的jenkins端口号(如:http://192.168.6.194:8090/),进入jenkins操作页面,首次登录jenkins,会要求解锁,找到对应路径的文件,导出并打开就是当前的密码。
登录成功后,会要加载很多插件,由于网络的限制,有可能会加载失败(失败后可以选择跳过,后续用其他方案加载插件)。接下来就是配置新账号,完成后进入jenkins工作台。
Jenkins插件安装
由于网络限制,之前初始化时插件安装失败,进入工作台后,选择 系统管理—>插件管理—>可选插件中选择所需插件。像Android需要的有:
Android Emulator Plugin
Gradle Plugin
Subversion Plug-in
IOS需要:
Xcode integration Plugin
等等,根据所需自行筛选。选择插件下载依然有可能会失败,这时我们可以通过查看详情,获取到对应的下载连接,以其他方式下载,得到对应的hpi文件后,通过系统管理—>插件管理—>高级—>上传插件,选择对应的文件上传。所需插件都加载完成之后,重启Jenkins服务即可生效。
Jenkins系统设置
Jenkins主页—>系统管理—>系统设置,进入jenkins系统设置页面,找到全局属性,勾选环境变量,新增ANDROID_HOME路径并保存(记得自行对应Linux系统中的ANDROID_HOME路径,可以用命令 echo $ANDROID_HOME 查看)。
Jenkins全局工具配置
Jenkins主页—>系统管理—>全局工具配置,进入Jenkins全局工具配置页面,需要配置JDK、Git、Gradle等,没有出现选项的需要先安装对应的插件,没有配置环境变量的,先去linux配置环境变量,最后点击应用和保存。
Linux Jenkins配置MacOS节点
为了统一管理,我们在Linux上添加MacOS为从节点,这样就可以在Linux上完成IOS项目的构建工作。详细配置请参考:Jenkins配置节点(解决Linux上iOS打包)
首先在Windows平台上输入Linux服务器IP+Jenkins端口号,进入Linux Jenkins的控制台,通过系统管理—>节点管理,进入节点列表,当前master为Linux系统。接下来我们新建节点,输入节点名称,并勾选固定节点,然后我们到MacOS上面找到 系统偏好设置☞共享☞勾选☞远程登录,并获取远程登录的IP
接下来回到windows平台配置节点信息,创建完成后节点会自动连接。
构建项目
构建Android项目
jenkins首页选择新建任务,输入任务名称,选择构建一个自由风格的软件项目。可配置的功能项有 | General | 源码管理 | 构建触发器 | 构建环境 | 构建 | 构建后操作 | 。
General
填写项目描述
源码管理
可以选择Git或Subversion,需要事先安装对应的插件。都比较类似,输入代码库地址,配置账号密码,一般不会出现问题。
触发构建器
构建环境
构建
我的配置如下图所示:
构建后操作
上传蒲公英和发送通知右键
构建IOS项目
Jenkins构建IOS项目的前提条件是需要一台MacOS机器,我们的主服务器是Linux,所以参考上面的步骤,建立一个MacOS从节点。节点配置完成后,回到Jenkins首页新建任务,输入任务名称并选择构建一个自由风格的软件项目。
General
配置描述内容,并且勾选 限制项目的运行节点 标签表达式输入你之前配置的MacOS节点名称,如图所示:
源码管理
同Android的一样。
触发构建器
构建环境
构建
增加构建步骤,选择执行shell,然后编写执行的shell脚本。以下是网上找的脚本内容,将文件路径和一些配置项改成自己项目的。
###############配置内容###############
buildConfig="Release" #编译的方式,有Release,Debug,自定义的AdHoc等
target_name="校园一卡通" #设置需编译的项目配置名称
macpassword="qzkj" #mac的登录密码
projectDir="/Users/Shared/Jenkins/workspace/app_platform_client_ios/platforms/ios" #项目所在目录的绝对路径
isWorkSpace=false #判断是用的workspace还是直接project,workspace设置为true,否则设置为false
##########################################################################################
##############################以下部分为自动生产部分,不需要手动修改############################
##########################################################################################
workspace_name="${target_name}.xcworkspace"
scheme="$target_name"
ExportOptionsPlistPath="./$target_name/$target_name-Info.plist"
scheme_name="$target_name"
# 指定输出ipa路径
export_path=./$scheme_name-IPA
# 指定输出归档文件地址
export_archive_path="$scheme_name.xcarchive"
# 指定输出ipa地址
export_ipa_path="$export_path"
# 强制删除旧的文件夹
rm -rf $export_path
buildAppToDir=$projectDir/build #编译打包完成后.app文件存放的目录
echo "~~~~~~~~~~~~~~~~~~~开始编译~~~~~~~~~~~~~~~~~~~"
###############进入项目目录
cd $projectDir
#rm -rf ./build
buildAppToDir=$projectDir/build #编译打包完成后.app文件存放的目录
###############开始编译app
echo -workspace
security unlock-keychain -p $macpassword ~/Library/Keychains/login.keychain
echo "~~~~~~~~~~~~~~~~~~~pod install~~~~~~~~~~~~~~~~~~~"
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
#第一次执行了pod之后就不用再次执行了
#pod install --verbose --no-repo-update
echo "开始编译workspace...."
echo "打包地址:$export_archive_path"
xcodebuild archive -workspace "$workspace_name" -scheme "$scheme" -configuration $buildConfig -archivePath $export_archive_path
echo "~~~~~~~~~~~~~~~~~~~ 编译完成~~~~~~~~~~~~~~~~~~~"
echo "~~~~~~~~~~~~~~~~~~~ 开始打包~~~~~~~~~~~~~~~~~~~"
appDir=$projectDir/ #app所在路径
echo "打包地址$export_archive_path"
echo "输出地址$export_ipa_path"
xcodebuild -exportArchive -archivePath $export_archive_path -exportPath $export_ipa_path -exportOptionsPlist $ExportOptionsPlistPath -allowProvisioningUpdates
构建后操作
上传蒲公英和发送通知右键
踩坑记录
java.io.IOException: Cannot run program "/var/lib/jenkins/workspace/test-android/gradlew" (in directory "/var/lib/jenkins/workspace/test-android"): error=13, Permission denied.
没有权限,有两种可能,一种是linux下该文件夹没有授权给用户,按网上的做法即可。另一种是因为配置构建的时候没有 勾选Make gradlew executable,我在这里卡了很久。
Failed to install the following Android SDK packages as some licences have not been accepted.
没有同意许可,在Linux中输入以下命令解决(参考博客):
echo y | android update sdk --no-ui --all --filter build-tools-26.0.2,extra-android-m2repository
Could not determine the dependencies of task ':app:preDebugBuild'.
Could not resolve all dependencies for configuration ':app:debugRuntimeClasspath'.
Could not determine artifacts for com.jakewharton:butterknife:10.1.0: Skipped due to earlier error
依赖库加载失败,这个是由于网络问题起的。我的解决办法是在项目的build.gradle中 buildscript 和 allprojects 都加入 mavenCentral(),提交后重新构建,如下图所示:
Could not find an installed version of Gradle either in Android Studio,
or on your system to install the gradle wrapper. Please include gradle
in your path, or install Android Studio
Build step 'Execute shell' marked build as failure
网上很多都说是因为没有安装gradle,而我这里是安装了gradle,并且配置了环境变量,还反复出现这个问题。经过多次尝试,在jenkins—>系统管理—>系统设置—>全局属性—>环境变量中添加服务器的PATH路径解决。(这里奇怪的是单独配置Gradle无效)
Failed to find 'ANDROID_HOME' environment variable. Try setting it manually.
Failed to find 'android' command in your 'PATH'. Try update your 'PATH' to include path to valid SDK directory.
按照教程配置好环境变量后,还出现了该问题,发现是执行shell命令时,使用的是sudo cordova build android,将前面的sudo去掉后即可正常运行。
Error Domain=IDEProvisioningErrorDomain Code=9 ""校园一卡通.app" requires a provisioning profile." UserInfo={NSLocalizedDescription="校园一卡通.app" requires a provisioning profile., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}
IOS踩坑,据说是xcode9之后,需要再XXinfo.plist中加入provisionProfiles,才可以打包通过,如图所示:
其中红色框框内为要添加的部分,key为项目的Bundle Identifier,在XCode中查看,String的内容为签名文件的加密名称(iOS Provisioning Profiles Name),可在XCode配置签名的地方查看。
补充:经过尝试,这里用描述文件名称的明文也可以打包成功。配置内容如下图所示: