团队开发项目时,经常要频繁地推拉、打包项目,如果能让机器自动去做这些重复的工作,将节省大量时间。
Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成,学会使用Jenkins是中高级开发人员必备技能。
自动化构建经验分享
- 一、自动化构建准备工作
- 1、需要哪些工具?
- 2、自动化构建原理
- 二、Jenkins安装与配置
- 1、Jenkins安装
- 2、进入Jenkins初始化页面
- 3、Jenkins各项配置
- 三、Jenkins的使用
- 1、创建构建流程任务
- 2、传递构建参数,命令Unity打包
- 3、Unity接收参数,自动打包
- 4、Jenkins其他功能
- 四、云效+Jenkins 实现持续集成
- 1、云效代码库创建、迁移与配置
- 2、获取Secret Token,创建Webhooks
- 3、创建流水线,添加执行命令
- 4、云效项目如何部署密钥
- 5、云效如何配置个人SSH密钥
- 五、其他问题解决办法
- 1、访问localhost:8080,提示无法访问此网站
- 2、构建项目报错
- 3、Jenkins插件安装失败处理方法
- 4、Jenkins防止跨站点请求伪造(CSRF)
- 5、Unity制作批量打包工具
- 6、查看本地或域用户
- 7、获取本机IP地址
一、自动化构建准备工作
1、需要哪些工具?
1、代码托管平台(如Github、码云、云效等)
用于对项目源码进行管理。(本文以云效进行举例 https://account.aliyun.com/)
2、一台用于安装Jenkins的服务器,如自己的电脑或者阿里云服务器等(需要安装并配置java环境)
3、Jenkins及其插件
用于接受触发事件,对项目进行打包、构建等操作。
(如导出.apk、.exe、.isa、.jar)
下载地址:https://www.jenkins.io/download/
4、Tomcat(本文未使用tomcat,不过建议安装,会比较方便)
Tomcat是一个免费的开放源代码的Web 应用服务器,可利用它响应HTML页面的访问请求。
下载地址:https://tomcat.apache.org/index.html
如果安装了tomcat,则无需安装Jenkins,将下载好的jenkins.war放进tomcat/webapps目录下,配置JAVA_HOME及JRE_HOME环境变量即可;
2、自动化构建原理
代码托管平台受到特殊指令,主动触发Jenkins,Jenkins收到指令做资源拉取、控制本地工具构建等操作。
比如我们提交代码到Github的时候,Github会帮我们发送一个关于Push的Post请求到我们的Jenkins服务器,然后Jenkins持续集成插件webhooks会接收到请求的参数,触发构建流程自动做项目打包等工作。
二、Jenkins安装与配置
注意:Jenkins和Tomcat安装之前需要确定电脑已经安装并配置了java环境,没安装的可以参考此篇博客,分享有JDK\SDK等的下载地址。
Win10环境部署Tomcat,不想装或者已经装过Tomcat的自行跳过。
部署方式参考这篇博客:https://blog.csdn.net/weixin_43720619/article/details/94769680
1、Jenkins安装
(1)安装了tomcat
如果安装了tomcat,则无需安装Jenkins,将下载好的jenkins.war放进tomcat/webapps目录下,配置JAVA_HOME及JRE_HOME环境变量即可;
(2)没安装tomcat看这里
Jenkins下载地址https://jenkins.io/download/,仅下载war包;
安装部分可以看我下面的介绍,也可以参考Jenkins官方文档: 传送门
下载好之后,cmd打开命令提示符窗口,进入jenkins.war存放的文件夹,运行命令 java -jar jenkins.war。
2、进入Jenkins初始化页面
注意:如果在使用Jenkins过程中遇到 “无法访问此网站” 等问题,参考此博客末尾的特殊问题解决办法。
浏览器浏览http://localhost:8080(或您在安装时为 Jenkins 配置的任何端口),等待Unlock Jenkins页面出现,第一次启动时间可能有点长,耐心等待,根据页面提示路径拿到管理员密码,单击继续。
解锁后可能出现如下图所示界面:
表示无法下载Jenkins插件,可能是因为防火墙导致,没关系,可以进入Jenkins内部下载指定插件。
接着进入用户创建页面,设置登陆用户和密码,设置成功后即进入Jenkins主界面:
3、Jenkins各项配置
Jenkins各项配置基本都在如下界面:
1.插件下载
除了默认插件以外,进行Unity构建还需要一些特定的插件。
打开插件设置(ManagerPlugins),以Unity3D开发为例,搜索栏输入unity,可以在可选插件中找到Unity打包构建的相关插件,勾选后点击左下角下载导入。
如下图导入成功
用Jenkins做持续集成时,一般会使用webhooks触发构建,比如我们每一次提交代码到云效、码云或Github的时候,这些平台会帮我们发送一个关于Push的Post请求到我们的Jenkins服务器,然后Jenkins持续集成插件webhooks会接收到请求的参数,触发构建流程自动做项目打包等工作。
搜索webhooks,导入
2.系统配置
(1)增加系统管理员邮件地址:
(2)添加编码全局属性,保存退出。(除了JDK必须配置,其他属性根据开发需要自行配置)
3.全局工具配置
打开Global ToolConfiguration,配置JDK和Unity3D的路径,
不勾选自动安装(Install automatically)
如果用到Maven同样配置一下。
4.全局安全配置
授权策略根据需求自行选择,指定某项授权可以用安全矩阵。
关于跨站点请求伪造(CSRF),如果安装的jenkins是2.204.6之前的版本,可以直接勾选关闭,2.204.6之后的版本删除了禁用 CSRF 保护的功能,如下图,需要特殊处理,暂时不管后面会说。
三、Jenkins的使用
1、创建构建流程任务
点击“新建Item”,命名任务名称,选择自由风格,确定。
创建完成进入如下界面,点击配置。
设置项目备注、构建规则、显示名称等,此处因为使用本地项目测试构建的,所以点击右侧高级设置,填入自定义的工作空间的地址,它的目录就是当前流程所涉及到操作的unity工程,如下图:
Disable Old Builds:
一个流程会被创建(Build)很多次,当到达一定的时间或者一定的构建次数时候,旧的创建是否被丢弃,一般这个是需要使用到的。
Git Hub 项目:这个流程是否使用到github上的项目,这里不勾选
This build requires lockable resources:如果有多个并发创建同时对一个资源有需求并且当前创建正在使用这个需求,则当前创建会将这个资源占为己有,等用完之后才释放给其他创建使用。
This project is parameterized:当前流程所操作的项目是否需要参数,可能会使用到
Throttle builds: 限制在规定时间内只能执行定义好次数的构建
关闭构建:不再使用当前构建
在必要时并发构建:是否运行当前构建能够和其他构建同时执行,这可能会引起一些问题,一般关闭
Build after other projects are built:指定某个流程, 当这个流程跑完之后,当前流程就会接着执行。
Build periodically:是否会后台周期性的执行流程,可以指定周期时长,在问号点开的地方可以查看写法,这个选项比较常用,因为unity的打包或者热更通常需要等待,而开发者这时通常不能做什么,所以通常设置在晚上的11点或者其他时间进行自动执行流程。
Poll SCM:流程的执行通常会有具体内容,这个内容是由开发者在流程中写好代码执行的,这个选项勾选之后,没一定时间会检查代码是否有更新,如果有更新则会重新执行流程。
如果需要下拉资源进行构建,配置URL
2、传递构建参数,命令Unity打包
构建步骤,在流程中涉及到的操作,这里只涉及到unity编辑器操作,也可以执行python、windows批处理命令。
命令行(注意空格)
-batchmode -executeMethod PerformBuild.CommandLineBuild AppName-TestAPK -quit
解释下这条命令的含义:
批处理执行Unity项目中PerformBuild脚本的CommandLineBuild方法,其中参数AppName值为TestAPK,构建完毕后退出(-quit)。
3、Unity接收参数,自动打包
注意:在构建过程中不能用unity开启此工程,否则会报错。
Jenkins构建步骤完毕,在Unity项目中创建一个Editor脚本,用来接收参数,执行构建。
源码如下:
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
public class PerformBuild
{
static string[] GetBuildScenes()
{
List<string> names = new List<string>();
foreach (EditorBuildSettingsScene e in EditorBuildSettings.scenes)
{
if (e == null)
continue;
if (e.enabled)
names.Add(e.path);
}
return names.ToArray();
}
/// <summary>
/// 此方法是从jienkins上接受 数据的 方法
/// </summary>
static void CommandLineBuild()
{
try
{
//获取需要打包的场景
string[] scenes = GetBuildScenes();
for (int i = 0; i < scenes.Length; ++i)
{
Debug.Log(string.Format("Scene[{0}]: \"{1}\"", i, scenes[i]));
}
//ProjectPackageEditor.BuildByJenkins(GetJenkinsParameter("Platform"), GetJenkinsParameter("AppID"), GetJenkinsParameter("Version"), GetJenkinsParameter("IPAddress"));
string target_dir = "E:/APK_测试服";//这里的路径是打包的路径, 定义
string target_name = GetJenkinsParameter("AppName") + ".apk";//通过GetJenkinsParameter()方法获取参数
if (Directory.Exists(target_dir))
{
if (File.Exists(target_name))
{
File.Delete(target_name);
}
}
else
{
Directory.CreateDirectory(target_dir);
}
//构建Android项目
BuildPipeline.BuildPlayer(scenes, target_dir + "/" + target_name, BuildTarget.Android, BuildOptions.None);
}
catch (Exception err)
{
Console.WriteLine("方法F中捕捉到:" + err.Message);
throw;//重新抛出当前正在由catch块处理的异常err
}
finally
{
Debug.Log("----------> I am copying! <--------------");
}
}
/// <summary>
///解释jekins 传输的参数
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
static string GetJenkinsParameter(string name)
{
foreach (string arg in Environment.GetCommandLineArgs())
{
if (arg.StartsWith(name))
{
return arg.Split("-"[0])[1];
}
}
return null;
}
}
回到Jenkins,打开之前创建的任务,点击BuildNow执行构建,可以在下方看到构建情况。构建完成即可在生成文件中看到打出的apk。
感谢这两位博主的分享,大家也可以参考一下:
http://www.u3d8.com/?p=1996
https://www.xuanyusong.com/archives/3349
4、Jenkins其他功能
1.查看Jenkins的系统属性和环境变量等配置信息
System Information
2.如何使用命令行操作Jenkins?
首页-系统管理-Jenkins CLI,点击下载jenkins-cli.jar保存至本地。
输入命令行 java -jar jenkins-cli.jar -s http://IP:8080/ help,即可弹出所有命令的用法说明。
四、云效+Jenkins 实现持续集成
尝试了在服务器上用Jenkins构建项目,下面接着尝试用云效来远程触发Jenkins构建项目。
1、云效代码库创建、迁移与配置
关于代码库迁移可参考云效官方文档:传送门
点击代码管理进入代码库,选择添加库,可以选择新建代码库或者导入GitHub/码云等其他代码托管平台的项目。
1、如果新建代码库,本地通过URL提交项目至该代码库。
2、如果导入其他平台仓库,如码云,则本地可以仍旧提交至原来平台,云效自动拉取该平台数据。
我这边是新建了代码库来测试,点击克隆下载,复制HTTPS,在本地使用PlasticSCM 推送了新建的项目,如下图。
需要安装plastic可参考此博客:https://blog.csdn.net/qq_43505432/article/details/108347792
用Jenkins做持续集成时,一般会使用webhooks触发构建,或者定时构建,这里记录用URL的方式触发Jenkins构建。
点击右边设置,先来设置以下WebHooks。
可以看到,创建webhooks需要URL(项目网址)和Secret Token(秘密令牌),下面教一下怎么获取。
2、获取Secret Token,创建Webhooks
可以参考此博客:https://www.cnblogs.com/tyrionyang/p/8183819.html
3、创建流水线,添加执行命令
添加执行命令
执行命令获取方式:
登录Jenkins,点击用户列表,选择指定用户,点击设置,点击"添加新Token",生成Token,及时复制保存,后面就看不到了。
打开之前创建的任务,勾选触发远程构建,输入身份验证令牌(自己随便定义)
根据以上信息,就可以创建一条这样的命令:
curl -X POST http://(用户名):(Token)@(IP地址:端口号)/jenkins/job/(任务路径)/build?token= (身份验证令牌)
如我创建的URL:
http://chengliang:11b7asd91cff77c690a6dcf1375634b4e@http://172.12.115.66:8080/jenkins/job/Test3/build?token= 123456
填入命令,保存并运行,即可在Jenkins中看到正在构建
可参考此博客:
https://blog.csdn.net/yaocsu/article/details/118528153
https://www.cnblogs.com/tyrionyang/p/8183819.html
4、云效项目如何部署密钥
云效官方文档: https://help.aliyun.com/document_detail/153876.html
5、云效如何配置个人SSH密钥
云效官方文档:https://help.aliyun.com/document_detail/153709.html?spm=a2cl9.codeup_devops2020_goldlog_projectSettings.0.0.60ea657aFsn0eO
根据路径找到公钥(id_rsa.pub)和私钥(id_rsa),可以直接用记事本等文本工具打开,注意私钥文件不要轻易泄露。
五、其他问题解决办法
1、访问localhost:8080,提示无法访问此网站
可能端口被占用,关闭这些进程
先查看端口占用情况
netstat -aon|findstr "8080"
端口“8080”被PID(进程号)为21808的进程占用,按进程号关闭进程
taskkill /pid 21808
taskkill /f /pid 21808//强制关闭进程
关闭后重新再查看一次端口占用情况,如果显示还未关闭,可以强制关闭此进程。
访问http://localhost:8080/,如果仍然提示无法访问此网站,那就运行java -jar jenkins.war,一直挂着命令提示符不要关闭,即可进入此网站。
命令行查看端口占用:https://www.cnblogs.com/rainman/p/3457227.html
2、构建项目报错
Aborting batchmode due to failure: Couldn’t set project path to: E:/***
因为在任务中没有配置工作空间,打开工程配置,点击右侧“高级”,填入项目路径,起个名称。
3、Jenkins插件安装失败处理方法
https://www.cnblogs.com/sxdcgaq8080/p/10489326.html
4、Jenkins防止跨站点请求伪造(CSRF)
在Jenkins启动前加入相关取消保护的参数配置后启动Jenkins,即可关闭CSRF,配置内容如下:
-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true
Jenkins若是跑在Tomcat下,只需在tomcat启动脚本中加入配置即可;若是以jar包形式部署的,只需在启动时加上配置参数即可。
配置后重启Jenkins,在全局安全配置中可看到CSRF保护功能已关闭。
5、Unity制作批量打包工具
参考此博客:https://blog.csdn.net/qq_43505432/article/details/118418767
6、查看本地或域用户
whoami
hostname
7、获取本机IP地址
ipconfig 或 ipconfig/all