目录
Unity 工具 之 Jenkins 打包自动化工具的下载/安装/基本操作/任务创建执行/Unity打包自动化简单搭建的相关整理
一、简单介绍
二、Jenkins 的下载
三、Jenkins 的安装
四、登录安装插件,并创建账号
五、Jenkins 的几种任务的基本操作
无参任务创建和执行
带参任务创建和执行
执行 python 任务
周期性触发执行任务
附录:Schedule 中编写规则(周期性触发执行任务)1)格式:MINUTE HOUR DOM MONTH DOW
六、Unity + Jenkins 实现简单的自动化打包
构建 Unity 测试工程
手动 Build 打包
编辑 Editor 打包工具打包
命令行调用Unity静态函数:打包函数
jenkins 执行 bat 批处理Unity打包
拓展:jenkins 调用 python脚本打包
七、Jenkins 的其他操作
1、关闭 Jenkins 服务操作
2、开启 Jenkins 服务操作
3、修改Jenkins服务端口号
4、新建账号
5、账号密码修改/账号删除
Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。
本节介绍,Jenkins 自动化打包工具,包括下载安装,以及基本的操作等,这里简单说明,如果你有更好的方法,欢迎留言交流。
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
主要功能包括:
- 1、持续的软件版本发布/测试项目。
- 2、监控外部调用执行的工作。
这么说比较官方,说白了,它就是一种集承了多种常用的插件于一身的工具平台,通过这个平台你能很方便的管控你的项目!
它的强大之处在于它能直接调用外部的shell指令和bat。
案例操作环境:
官网:Jenkins
下载地址:Jenkins 的安装和设置
1、可以直接到 Jenkins 下载,选择自己的平台下载
2、下载完成后,双击即可安装
这里可能需要对应版本 JDK 环境,没有下载安装对应版本JDK 即可
1、双击安装包,进行安装
2、 选择安装目录
建议不要暗转在 C 盘
3、根据需要选择登陆方式
4、设置并测试端口
5、选择自己的 JDK 安装路径
注意提示的支持的 JDK 版本号,没有的话,可以到jdk 官网下载
JDK 11 下载地址:Java Downloads | Oracle
6、接下来,对应点击操作,安装即可
7、不久,就会安装成功
温馨提示:端口号是之前设置测试的端口号;一些安装软件需要科学上网环境安装
1、输入网址和端口号,登录
例如:http://localhost:5678
2、根据提示复制密码,点击继续即可
3、点击“安装推荐的插件”,根据需要选择也行
注意:这里软件安装需要科学上网环境哈
4、等待安装结束即可
5、插件安装完毕后,根据需要设置创建一个用户
6、设置 Jenkins URL
7、开始使用 Jenkins
1、点击 “开始使用Jenkins”,进入如下界面
1、新建 Item
2、编辑任务名称,选择 Freestyle project,点击确定
3、添加任务描述
4、其他默认,下拉 Build Steps ,选择 Execute Windows batch command
5、编写代码,然后保存即可
echo "Test with no parameter"
6、执行刚才的任务 ,点击 Build Now
7、选择任务,在控制台输出
1、回到 Dashboard ,新建Item
2、输入任务名,确定创建任务
3、添加任务描述,选择 This project is parameterized
4、添加选择参数
5、添加执行命令
6、执行 Build with Parameters
1、创建任务同无参任务创建类似
2、添加任务描述
3、添加任务命令
Test.py 脚本的内容如下:
print('this is a python')
4、Build Now 执行任务
5、如果如图执行任务报错,安装配置一下 python 环境即可
具体参见:https://blog.csdn.net/u014361280/article/details/128725241
有时候我们需要周期性地执行任务,比如每天8
点触发一次执行任务,或者每隔30
分钟触发一次执行任务。
在Build Triggers
(触发器)中勾选Build periodically
,
1、创建周期性任务
2、添加描述
3、勾选 Build periodically,编写规则
每分钟执行一次规则:*/1 * * * *
4、添加执行代码
5、Build Now 点击之后,就会每分钟执行一次了
Schedule
中编写规则(周期性触发执行任务)MINUTE HOUR DOM MONTH DOW
字段 | 说明 | 取值范围 |
---|---|---|
MINUTE | 分钟 | 0~59 |
HOUR | 小时 | 0~23 |
DOM | 一个月中的第几天 | 1~31 |
MONTH | 月 | 1~12 |
DOW | 星期 | 0~7(0和7代表的都是周日) |
2)语法:*
:匹配范围内所有值,例:* * * * *
M-N
:匹配M~N
范围内所有值,例:10-30 * * * *
M-N/X
:在指定M~N
范围内每隔X
构建一次,例:10-30/5 * * * *
*/X
:整个有效区间内每隔X
构建一次,例:*/30 * * * *
A,B,...,Z
:匹配多个值,例:10,20,30 * * * *
3)关于符号H:
为了在系统中生成定时任务,符号H
(代表Hash
,后面用散列
代替)应该用在可能用到的地方,例如:为十几个日常任务配置0 0 * * *
将会在午夜产生较大峰值。相比之下,配置H H * * *
仍将每天一次执行每个任务,不是都在同一时刻,可以更好的使用有限资源。
符号H
可用于范围,例如,H H(0-7) * * *
代表凌晨0:00
到 上午7:59
一段时间。
符号H
在一定范围内可被认为是一个随机值,但实际上它是任务名称的一个散列而不是随机函数。
4)案例:
(1)每30分钟
构建一次
H/30 * * * *
(2)每2小时
构建一次
H H/2 * * *
(3)每天早上8点
构建一次
0 8 * * *
(4)每天的8点
,12点
,22点
,一天构建3
次
0 8,12,22 * * *
(5)每前半小时中每隔10分钟
构建一次
H(0-29)/10 * * * *
(6)每个工作日从早上9点45分
开始到下午4点45分
结束这段时间内每间隔2小时
的45分钟
那一刻构建一次
45 9-16/2 * * 1-5
(7)每月(除了12月
)从1号
到15号
这段时间内某刻构建一次
H H 1,15 1-11 *
1、打开i Unity 创建一个测试工程
2、简单搭建一下场景
3、把场景添加到设置中
1、在 Build Settings 中,手动点击 Build 打包
2、打包成功如图
1、打开 TestJenkins 工程,新建脚本 BuildTool.cs
注意:脚本放在 Editor 文件夹下
using UnityEngine;
using UnityEditor;
public class BuildTools
{
[MenuItem("Build/Build APK")]
public static void BuildApk()
{
BuildPlayerOptions opt = new BuildPlayerOptions();
opt.scenes = new string[] { "Assets/Scenes/SampleScene.unity" };
opt.locationPathName = Application.dataPath + "/../Build/TestJenkens_BatEditorBuild.apk";
opt.target = BuildTarget.Android;
opt.options = BuildOptions.None;
BuildPipeline.BuildPlayer(opt);
Debug.Log("Build App Done!");
}
}
2、编写代码
3、回到 Unity 点击菜单栏 Build-Build APK 进行打包
4、最终打包如下
1、首先可以去官网查看Unity 相关 命令行打包的知识点
网址:Unity - Manual: Command line arguments
2、常用的命令参数解释
-batchmode
在 批处理模式下运行Unity
,它不会弹出窗口。当脚本代码在执行过程中发生异常或其他操作失败时Unity
将立即退出,并返回代码为1
。
-quit
命令执行完毕后将退出Unity
编辑器。请注意,这可能会导致错误消息被隐藏(但他们将显示在Editor.log
文件)
-buildWindowsPlayer
构建一个32位
的Windows
平台的exe
(例如:-buildWindowsPlayer path/to/your/build.exe
)
-buildWindows64Player
构建一个64位
的Windows
平台的exe
(例如:-buildWindows64Player path/to/your/build.exe
)
-importPackage
导入一个的package
,不会显示导入对话框
-createProject
根据提供的路径建立一个空项目
-projectPath
打开指定路径的项目
-logFile
指定输出的日志文件
-nographics
当运行在批处理模式,不会初始化显卡设备,不需要GPU
参与;但如果你需要执行光照烘焙等操作,则不能使用这个参数,因为它需要GPU
运算。
-executeMethod
在Unity
启动的同时会执行静态方法。也就是说,使用executeMethod
我们需要在编辑文件夹有一个脚本并且类里有一个静态函数。
-single-instance
在同一时间只允许一个游戏实例运行。如果另一个实例已在运行,然后再次通过-single-instance
启动它的话会调节到现有的这个实例。
-nolog
不产生输出日志。 通常output_log.txt
被写在游戏输出目录下的*_Data
文件夹中
3、知道,一个Unity
工程只能打开一个实例,所以如果我们已经手动用Unity
打开了工程,此时执行下面这个命令是会报错的
Aborting batchmode due to fatal error:
It looks like another Unity instance is running with this project open.
Multiple Unity instances cannot open the same project.
4、所以需要先判断Unity
是否在运行中,如果是,则先将旧的Unity
实例进程杀掉,对应的bat
代码如下
::判断Unity是否运行中
TASKLIST /V /S localhost /U %username%>tmp_process_list.txt
TYPE tmp_process_list.txt |FIND "Unity.exe"
IF ERRORLEVEL 0 (GOTO UNITY_IS_RUNNING)
ELSE (GOTO START_UNITY)
:UNITY_IS_RUNNING
::杀掉Unity
TASKKILL /F /IM Unity.exe
::停1秒
PING 127.0.0.1 -n 1 >NUL
GOTO START_UNITY
:START_UNITY
:: 此处执行Unity打包
另外,我们想要在执行打包时传入一些参数,比如APP名字、版本号等,可以在命令中加上,格式可以自定义,我们只需在后面的C#代码中进行相应的解析即可,例:
--productName:%1 --version:%2
其中%1表示参数1,%2表示参数2,
完整命令如下:
"D:\Program Files\Unity\2021.3.16f1\Editor\Unity.exe" ^
-quit ^
-batchmode ^
-projectPath "E:\Projects\UnityProjects\TestJenkins" ^
-executeMethod BuildTools.BuildApk ^
-logFile "E:\Projects\UnityProjects\TestJenkins\_buildoutput.log"
--productName:%1 ^
--version:%2
5、整合上面的Unity
进程判断,最终完整的bat
代码如下:
注意:^前有空格
::判断Unity是否运行中
TASKLIST /V /S localhost /U %username%>tmp_process_list.txt
TYPE tmp_process_list.txt |FIND "Unity.exe"
IF ERRORLEVEL 0 (GOTO UNITY_IS_RUNNING)
ELSE (GOTO START_UNITY)
:UNITY_IS_RUNNING
::杀掉Unity
TASKKILL /F /IM Unity.exe
::停1秒
PING 127.0.0.1 -n 1 >NUL
GOTO START_UNITY
:START_UNITY
:: 此处执行Unity打包
"D:\Program Files\Unity\2021.3.16f1\Editor\Unity.exe" ^
-quit ^
-batchmode ^
-projectPath "E:\Projects\UnityProjects\TestJenkins" ^
-executeMethod BuildTools.BuildApk ^
-logFile "E:\Projects\UnityProjects\TestJenkins\_buildoutput.log" ^
--productName:%1 ^
--version:%2
6、打开cmd 切换到 bat 路径,然后输入命令打包
UnityBuild.bat TT 0.1.3,其中 UnityBuild.bat 是批处理脚本,TT 会对应解析为App 名称,0.1.3 是App 版本号
7、输出日志可以找到打包成功的字样
8、其中,BuildTool 中添加对应应用名称和版本号的解析
using UnityEngine;
using UnityEditor;
public class BuildTools
{
[MenuItem("Build/Build APK")]
public static void BuildApk()
{
// 解析命令行参数
string[] args = System.Environment.GetCommandLineArgs();
foreach (var s in args)
{
if (s.Contains("--productName:"))
{
string productName = s.Split(':')[1];
// 设置app名字
PlayerSettings.productName = productName;
}
if (s.Contains("--version:"))
{
string version = s.Split(':')[1];
// 设置版本号
PlayerSettings.bundleVersion = version;
}
}
BuildPlayerOptions opt = new BuildPlayerOptions();
opt.scenes = new string[] { "Assets/Scenes/SampleScene.unity" };
opt.locationPathName = Application.dataPath + "/../Build/TestJenkens_BatEditorBuild.apk";
opt.target = BuildTarget.Android;
opt.options = BuildOptions.None;
BuildPipeline.BuildPlayer(opt);
Debug.Log("Build App Done!");
}
}
1、创建带参数的任务
2、添加代码命令
3、输出对应的应用名称和版本号,开始构建
4、构建成功如图
注意:在 Jenkins 中运行好似有问题,不过这里做个演示记录先
1、把前面的bat 类似转为 python
import os
import sys
import time
# 设置你本地的Unity安装目录
unity_exe = 'D:/Program Files/Unity/2021.3.16f1/Editor/Unity.exe'
# unity工程目录,当前脚本放在unity工程根目录中
project_path = 'E:/Projects/UnityProjects/TestJenkins'
# 日志
log_file = os.getcwd() + '/unity_log.log'
static_func = 'BuildTools.BuildApk'
# 杀掉unity进程
def kill_unity():
os.system('taskkill /IM Unity.exe /F')
def clear_log():
if os.path.exists(log_file):
os.remove(log_file)
# 调用unity中我们封装的静态函数
def call_unity_static_func(func):
kill_unity()
time.sleep(1)
clear_log()
time.sleep(1)
cmd = 'start %s -quit -batchmode -projectPath %s -logFile %s -executeMethod %s --productName:%s --version:%s'%(unity_exe,project_path,log_file,func, sys.argv[1], sys.argv[2])
print('run cmd: ' + cmd)
os.system(cmd)
# 实时监测unity的log, 参数target_log是我们要监测的目标log, 如果检测到了, 则跳出while循环
def monitor_unity_log(target_log):
pos = 0
while True:
if os.path.exists(log_file):
break
else:
time.sleep(0.1)
while True:
fd = open(log_file, 'r', encoding='utf-8')
if 0 != pos:
fd.seek(pos, 0)
while True:
line = fd.readline()
pos = pos + len(line)
if target_log in line:
print(u'监测到unity输出了目标log: ' + target_log)
fd.close()
return
if line.strip():
print(line)
else:
break
fd.close()
if __name__ == '__main__':
call_unity_static_func(static_func)
monitor_unity_log('Build App Done!')
print('done')
2、创建带参数任务
3、添加执行命令
4、Build with Parameters ,输入对应参数,开始构建即可
以管理员身份执行 net stop jenkins
1)以管理员身份运行 cmd
2)输入 net stop jenkins 关闭 Jenkins
3)或者打开 Jenkins 安装目录,在该目录下执行 jenkins.exe stop 也可以关闭服务
以管理员身份执行 net start jenkins
1)以管理员身份运行 cmd
2)输入 net start jenkins 开启 Jenkins
3)或者打开 Jenkins 安装目录,在该目录下执行 jenkins.exe start 也可以开启服务
4)jenkins.exe restart 重新开启服务
1)打开 Jenkins 安装目录,找到 jenkins.xml ,并打开
2)找到 httpPort ,对应就是当前的端口号
3)这里修改为 5578 试试这个端口号
4)重启 Jenkins 服务
5)Jenkins 服务就开始用 5578 这个端口号了
1)点击 Manage Jenkins
2)找到 Manage Users
3)点击 create user 创建新用户
4)对应补全信息,创建即可
5)创建成功
1)账号删除,点击 红色垃圾箱图标即可
2) 账号密码修改,点击蓝色齿轮
3)对应找到 password 选项修改即可
1、【游戏开发进阶】教你Unity通过Jenkins实现自动化打包,打包这种事情就交给策划了(保姆级教程 | 命令行打包 | 自动构建)-网络知识
2、Unity - Manual: Batch mode and built-in coroutine compatibility