0%

功能

在用Unity开发项目时,每次编写或者修改C#脚本,Unity都会自动检查脚本,并进行自动编译。频繁的自动编译,无疑是会降低开发效率,基于这个出发点,我希望能够关闭自动编译功能。在Unity下有两个设置是和自动编译相关的,就是Preferences界面下的General里面的Auto RefreshScript Changes While Playing。前者是自动刷新,每次刷新的时候就会检查脚本是否需要编译,这时候我们可以把自动刷新关掉,然后使用手动的方式进行刷新。后者主要是控制运行时脚本自动编译的时机,是否在运行时进行自动编译。
wwwwwww
上图中的设置项的位置可能会因Unity的版本不同而有所改变,这里我用的Unity版本是Unity 2020.3.33f1c2 Personal
这里写了一个编辑器脚本,将上面的设置暴露在菜单栏中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using UnityEditor;

public class ScriptOptions
{
//Auto Refresh


//kAutoRefresh has two posible values
//0 = Auto Refresh Disabled
//1 = Auto Refresh Enabled


//This is called when you click on the 'Tools/Auto Refresh' and toggles its value
[MenuItem("Tools/Auto Refresh")]
static void AutoRefreshToggle()
{
var status = EditorPrefs.GetInt("kAutoRefresh");
if (status == 1)
EditorPrefs.SetInt("kAutoRefresh", 0);
else
EditorPrefs.SetInt("kAutoRefresh", 1);
}


//This is called before 'Tools/Auto Refresh' is shown to check the current value
//of kAutoRefresh and update the checkmark
[MenuItem("Tools/Auto Refresh", true)]
static bool AutoRefreshToggleValidation()
{
var status = EditorPrefs.GetInt("kAutoRefresh");
if (status == 1)
Menu.SetChecked("Tools/Auto Refresh", true);
else
Menu.SetChecked("Tools/Auto Refresh", false);
return true;
}


//Script Compilation During Play


//ScriptCompilationDuringPlay has three posible values
//0 = Recompile And Continue Playing
//1 = Recompile After Finished Playing
//2 = Stop Playing And Recompile


//The following methods assing the three possible values to ScriptCompilationDuringPlay
//depending on the option you selected
[MenuItem("Tools/Script Compilation During Play/Recompile And Continue Playing")]
static void ScriptCompilationToggleOption0()
{
EditorPrefs.SetInt("ScriptCompilationDuringPlay", 0);
}


[MenuItem("Tools/Script Compilation During Play/Recompile After Finished Playing")]
static void ScriptCompilationToggleOption1()
{
EditorPrefs.SetInt("ScriptCompilationDuringPlay", 1);
}


[MenuItem("Tools/Script Compilation During Play/Stop Playing And Recompile")]
static void ScriptCompilationToggleOption2()
{
EditorPrefs.SetInt("ScriptCompilationDuringPlay", 2);
}


//This is called before 'Tools/Script Compilation During Play/Recompile And Continue Playing'
//is shown to check for the current value of ScriptCompilationDuringPlay and update the checkmark
[MenuItem("Tools/Script Compilation During Play/Recompile And Continue Playing", true)]
static bool ScriptCompilationValidation()
{
//Here, we uncheck all options before we show them
Menu.SetChecked("Tools/Script Compilation During Play/Recompile And Continue Playing", false);
Menu.SetChecked("Tools/Script Compilation During Play/Recompile After Finished Playing", false);
Menu.SetChecked("Tools/Script Compilation During Play/Stop Playing And Recompile", false);


var status = EditorPrefs.GetInt("ScriptCompilationDuringPlay");


//Here, we put the checkmark on the current value of ScriptCompilationDuringPlay
switch (status)
{
case 0:
Menu.SetChecked("Tools/Script Compilation During Play/Recompile And Continue Playing", true);
break;
case 1:
Menu.SetChecked("Tools/Script Compilation During Play/Recompile After Finished Playing", true);
break;
case 2:
Menu.SetChecked("Tools/Script Compilation During Play/Stop Playing And Recompile", true);
break;
}
return true;
}
}

回到开头的问题,为了解决频繁自动编译的问题,这里我禁用用自动刷新的功能,但是这就导致了我每次都需要手动刷新,如果没有手动刷新,那么修改的代码就不会生效。
所以这里换个思路来解决问题,我们只在运行前和退出运行的时候,进行代码编译,而其他时候都不会进行代码编译。这样上面提到的设置都不用管,仍然可以启用自动刷新功能,但是自动刷新不会进行自动编译。刚好Unity提供是否启用自动编译的接口。所以在不需要任何设置的情况下,只需要将下面的编辑器脚本导入到Unity的Editor目录下,在运行前和运行结束的时候会自动检查代码进行自动编译。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEditor;

[InitializeOnLoad]
public class CompilerOptionsEditorScript
{
static CompilerOptionsEditorScript()
{
EditorApplication.playModeStateChanged += PlaymodeChanged;
}

static void PlaymodeChanged(PlayModeStateChange state)
{
//在切换运行模式的时候自动进行脚本编译
if (state == PlayModeStateChange.ExitingPlayMode
|| state == PlayModeStateChange.ExitingEditMode)
{
EditorApplication.UnlockReloadAssemblies();
}

//在运行时或编辑模型下,关闭脚本自动编译,解决频繁编译降低开发效率的问题
if (state == PlayModeStateChange.EnteredPlayMode
|| state == PlayModeStateChange.EnteredEditMode)
{
EditorApplication.LockReloadAssemblies();
}
}
}

参考

How to stop automatic assembly compilation from script

这篇文章讲了如何在Docker上安装GitLab,Jenkins,并且最终Jenkins从GitLab上拉取到项目文件。
我最终的目的是希望能够对Unity项目进行打包部署,所以我开始关联Jenkins和Unity。因为我的Unity是装在物理机上,而Jenkins是装在Docker上,所以Jenkins没办法调取Unity进行打包操作。
所以我后面采用的是GitLab部署在Docker上,而Jenkins和Unity都是安装在物理机上,这样Jenkins通过GitLab的Url拉取项目,然后通过Unity Puglin插件调用Unity进行打包,当然也可以使用windows的批处理命令build.bat的方式。采用Unity Plugin的方式的一个好处就是unity的log会直接显示到Jenkins的log界面上。

其中,虽然Jenkins和GitLab的安装位置不一样,但是他们之间的关联操作和之前的是一样的。这里我们讲一下Jenkins和Unity的关联步骤。
首先建一个Unity项目,然后在项目根目录下创建两个文件build_image_url_link.batmyqrcode.py
build_image_url_link.bat

1
2
3
4
set BASE_PATH=D:\ServicesData\Publish\%1\%2
set BASE_URL=http://192.168.31.186:8080/Publish/%1/%2
python myqrcode.py %BASE_URL%/%3_%4.apk %BASE_PATH%\qrcode.png
echo DESC_INFO:%BASE_URL%/qrcode.png,%BASE_URL%/%3_%4.apk

myqrcode.py

1
2
3
4
5
6
import qrcode
import sys
data = sys.argv[1]
path=sys.argv[2]
img = qrcode.make(data)
img.save(path)

wwwwwww
然后在Editor下创建BuildTools.cs脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;

public class BuildTools
{
public static class BuildTargetName
{
public const string android = "Android";
public const string window = "Window";
}
public static class EnvironmentParam
{
public const string projectName = "--projectName";
public const string productName = "--productName";
public const string version = "--version";
public const string target = "--target";
}
public static bool GetEnvironmentParam(string paramName, out string paramValue)
{
paramValue = null;
string[] args = System.Environment.GetCommandLineArgs();
foreach (var s in args)
{
if (s.Contains(paramName))
{
if (s.Split(':').Length > 1)
{
paramValue = s.Split(':')[1];
return true;
}
}
}
return false;
}

[MenuItem("Build/Build APK")]
public static int BuildApk()
{
try
{
if (!GetEnvironmentParam(EnvironmentParam.productName, out string productName))
{
productName = "productName";
}
if (!GetEnvironmentParam(EnvironmentParam.version, out string bundleVersion))
{
bundleVersion = "bundleVersion";
}
if (!GetEnvironmentParam(EnvironmentParam.projectName, out string projectName))
{
projectName = "projectName";
}
if (!GetEnvironmentParam(EnvironmentParam.target, out string target))
{
target = BuildTargetName.android;
}
string extention = ".exe";
PlayerSettings.productName = productName;
PlayerSettings.bundleVersion = bundleVersion;
BuildPlayerOptions opt = new BuildPlayerOptions();
opt.scenes = new string[] { "Assets/Scenes/SampleScene.unity" };
switch (target)
{
case BuildTargetName.android:
opt.target = BuildTarget.Android;
extention = ".apk";
break;
case BuildTargetName.window:
opt.target = BuildTarget.StandaloneWindows64;
extention = ".exe";
break;
}

opt.locationPathName = $"D:/ServicesData/Publish/{projectName}/{target}/{productName}_{bundleVersion}{extention}";

opt.options = BuildOptions.None;
BuildPipeline.BuildPlayer(opt);
Debug.Log("Build Done!");
}
catch(Exception e)
{
Debug.LogError(e.Message);
return -1;
}
return 0;
}
}

wwwwwww
到这一步Unity项目就建好了,然后将它提交的GitLab上。

创建一个打包项目,关联到GitLab,操作步骤参考上面的链接。进入当前打包项目的配置界面。按下图配置。
wwwwwww
wwwwwww
wwwwwww
wwwwwww
wwwwwww
wwwwwww
wwwwwww
-quit -batchmode -nographics -executeMethod BuildTools.BuildApk --productName:$productName --version:$version --projectName:JenkinsUnityForAndroid --target:$target
wwwwwww
build_image_url_link.bat JenkinsUnityForAndroid %target% %productName% %version%
wwwwwww
DESC_INFO:(.*),(.*)
<img src="\1" height="200" width="200" /> <a href="\2">点击下载</a>

这样就基本配置好Jenkins和Unity项目了。但是上面配置中多了很多奇怪的操作,像什么Python脚本之类的。这是因为我想将打包好的包发布到一个本地服务,然后通过二维码下载。
所以这里我需要搭建一个本地服务,看网上有说用蒲公英什么的来当作发布平台,但是我就想本地局域网用,所以使用我比较熟悉的HFS来冲动服务。
wwwwwww
前面打包代码里面会将好的包放到这个服务路径下面,然后可以通过Url来访问,假设当前打好的包在这个路径下,那么手机输入对应的Url就可以下载了。不过每次都要输入Url很麻烦。所以这里考虑使用二维码。
这里讲了使用qrcodeImage两个python插件来生成二维码,所以首先我们要安装Python,这里Python 3.7.7下载,安装默认安装,并勾选写入环境变量。
然后打开命令行窗口,分别输入pip install qrcodepip install Image两个命令,安装好两个插件。
然后回到Jenkins,设置Jenkins内部的环境变量。
wwwwwww
wwwwwww
这里因为我的python是安装在C:\Users\10524\AppData\Local\Programs\Python\Python37目录下的。都准备好后,就可以开始构建了,下面是最终效果。
wwwwwww

参考

docker+gitlab+jenkins从零搭建自动化部署
Jenkins生成APK链接的二维码
Jenkins构建Python项目提示:‘python‘ 不是内部或外部命令,也不是可运行的程序
Python 3.7.7下载Windows x86-64 executable installer,安装默认安装,并勾选写入环境变量。
HFS下载,搭建简易服务。

这里是介绍如何将GitLab和Jenkins关联到一起。其实主要是安装一些插件、再设置一些关键配置。
首先我们需要安装GitLab,还有Gitlab API、GitLab Authentication、Generic Webhook Trigger,其中GitLab是必须装的,后面几个我也装了,是不是必须的我也不知道。反正油多不坏菜。
装完之后,回到Configure System里面,应该可以看到Gitlab部分,设置好我们的GitLab服务的URL,如下图所示。
wwwwwww
其中我GitLab的Url如下:
wwwwwww

然后新建一个Jenkins项目,取名字、选第一个模式、确定。然后进入项目设置界面,这里我们会发现多了一个GitLab Connection,它下面有gitlab选项,这个就是前面在Configure System里面新建的。然后在源码管理Git里面,设置仓库路径,以及凭证。
wwwwwww

注意下面还有指定分支(为空时代表any),里面默认是master分支,你确认一下有没有这个分支,或者这个分支是否是你想部署的。以及下方的源码库浏览器也可以设置一下。
wwwwwww

还有就是,如果我们当前的Git项目有依赖其他Git项目,也就是git sub modules,那么我们要确保在构建前,所有的依赖项目都被拉取下来,所以需要额外的设置,如下:
wwwwwww

设置好后,保存,点击立即构建进行部署。因为我们这里没有设置具体的部署规则,所以目前的操作只是会从GitLab里面拉取相应的项目到Jenkins工作目录下,如果构建成功,说明拉取成功,也就是GitLab和Jenkins关联成功,从而完成了最基本的设置。

参考

docker+gitlab+jenkins从零搭建自动化部署

在Win10上安装完Docker后,就可以在Docker上安装GitLab了。
参考TaylorShiwindows下使用docker安装gitlab两篇教程,以后买这篇为主。单独根据其中某一篇我都没有安装成功。

这里记录一下最终采用的步骤:

  • 首先打开命令行窗口,然后输入docker pull gitlab/gitlab-ce:latest回车,会开始拉取GitLab镜像,拉去后我们可以在Docker的Image里面找到。
  • 然后执行docker run -d --publish 9980:80 --publish 9443:443 --publish 9922:22 --name gitlab --restart always --volume D:/ServicesData/GitLab/config:/etc/gitlab --volume D:/ServicesData/GitLab/logs:/var/log/gitlab --volume D:/ServicesData/GitLab/data:/var/opt/gitlab gitlab/gitlab-ce这行命令。会在Docker里面创建容器,这里有一个-d的参数可以加也可以不加,但是不加的话,创建后的容器就是跟这个控制台窗口绑定了,关闭控制台窗口也就等于关闭GitLab容器。这里我是加了,表示容器在后台运行。之后就可以在Docker的容器目录里面找到。另外就是--volume *:/var/*,冒号前面的表示实际的路径,冒号后面的表示虚拟的映射路径,这我将他们映射到D盘下。
  • 然后点击http://127.0.0.1:9980/跳转到我们搭建的GitLab的登录界面了(第一次可能会跳转失败,要多等一下,多试几次)。但是我们不知道账号密码,我们可以再次进入命令行窗口,输入 docker exec -it gitlab bash,进入linux的bash命令行,然后在输入gitlab-rails console -e production,然后是user=User.where(id:1).first查看账号是多少,然后user.password = 123456789,以及user.password_confirmation = 123456789修改密码,这里123456789是新密码,你也可以设置为其他。再使用user.save!命令保存设置,然后输入exit退出。刚刚修改密码的操作好像是Linux环境下的命令(ps:我不知道,我猜的),除了在这里修改,还可以在Docker界面上,里面每个容器右侧都有对应的terminal,可以直接输入。
    下面是修改密码的命令行输入输出:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    (c) Microsoft Corporation。保留所有权利。
    C:\Users\10524>docker ps
    PORTS NAMES
    f70589c630be gitlab/gitlab-ce "/assets/wrapper" 23 minutes ago Up 23 minutes (healthy) 0.0.0.0:9922->22/tcp, 0.0.0.0:9980->80/tcp, 0.0.0.0:9443->443/tcp gitlab
    9af9c4c71518 jenkins/jenkins "/usr/bin/tini -- /u…" 5 hours ago Up 5 hours 50000/tcp, 0.0.0.0:8000->8080/tcp jenkins

    C:\Users\10524>docker exec -it gitlab bash
    root@f70589c630be:/# gitlab-rails console -e production


    --------------------------------------------------------------------------------
    Ruby: ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
    GitLab: 15.3.1 (16f34bd10fc) FOSS
    GitLab Shell: 14.10.0
    PostgreSQL: 13.6
    ------------------------------------------------------------[ booted in 26.85s ]
    Loading production environment (Rails 6.1.6.1)
    irb(main):001:0>
    irb(main):002:0>
    irb(main):003:0> user=User.where(id:1).first
    => #<User id:1 @root>
    irb(main):004:0> user.password = 123456789
    => 123456789
    irb(main):005:0> user.password_confirmation = 123456789
    => 123456789
    irb(main):006:0> user.save
    => true
    irb(main):007:0> user.save!
    => true
    irb(main):008:0>

补充,我发现Docker 搭建 Gitlab 服务器 (完整详细版)教程好像更完整。其中修改IP那一步,我一直没有搞成功,后面突然有一次成功了,那一次我是用本机IP。之前没成功的,都是随便选的IP。甚至我还选了127.0.0.1,因为本地打开网页就是显示这个IP,修改后,网页正常打开等操作都正常,甚至本地拉去也正常。但是当使用Jenkins去关联GitLab路径时始终,都连接失败,后面IP改成本机实际的IP才成功。如下图:
wwwwwww
gitlab.rb

1
2
3
4
5
external_url 'http://192.**.***'
gitlab_rails['gitlab_ssh_host'] = '192.168.**.***'
gitlab_rails['gitlab_shell_ssh_port'] = 9922

## GitLab configuration settings

gitlab.yml

1
2
3
4
5
6
## GitLab settings
gitlab:
## Web server settings (note: host is the FQDN, do not include http://)
host: 192.168.'**.***'
port: 9980
https: false

重启后port自动改了

当我第二天重启打开电脑,启动我的Gitlab时,我发现进不去了,因为gitlab.yml中的端口号又自动变回80。为了让原本已经配置好的Gitlab正常运行,需要重新修改端口号为9980。
但是直接修改gitlab.yml并不行。需要在gitlab运行的时候,然后按照下面的步骤:

  • 打开命令行窗口
  • 输入docker exec -it gitlab /bin/bash,并运行,进入docker命令下。
  • 输入vi /etc/gitlab/gitlab.rb,在vi里面修改gitlab.rbIp,参考上面的代码。或者直接在本地找到gitlab.rb,使用本地文本编辑器修改。
  • 输入gitlab-ctl reconfigure,这个命令会自动修改gitlab.yml的ip,但是端口号仍然是80。
  • 输入vi /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml,在vi里面修改gitlab.yml端口,参考上面的代码。或者直接在本地找到gitlab.yml,使用本地文本编辑器修改。
  • 输入gitlab-ctl restart,这个命令会让最终修改的端口生效。
  • 最后输入exit,退出docker命令。

参考

Vim命令合集

在Win10上安装完Docker后,就可以在Docker上安装Jenkins了。
参考官网教程在Windows上

  • 打开命令提示符窗口。

  • 下载 jenkinsci/blueocean 镜像并使用以下 docker run 命令将其作为Docker中的容器运行 :

1
2
3
4
5
6
7
8
9
docker run ^
-u root ^
--rm ^
-d ^
-p 8080:8080 ^
-p 50000:50000 ^
-v jenkins-data:/var/jenkins_home ^
-v /var/run/docker.sock:/var/run/docker.sock ^
jenkinsci/blueocean

上面这段命令是官网上的案例,但是我并没有使用上面的,而是做了修改。后面的 ^只是表示一行命令多行显示。特别注意这里使用的是jenkinsci/blueocean这个是官方推荐的,也有其他版本的Jenkins,但是可能会出现插件安装失败的问题,我之前就看了别人使用其他版本的教程,导致一些奇奇怪怪的问题。

1
docker run -u root -d --name jenkins --restart always -p 8000:8080 -p 50000:50000 -v D:/ServicesData/Jenkins/.jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean

这里我加了--name jenkins表示我给这个容器取名为jenkins。这样创建的容器的名字就不是随机得了。
另外我删了--rm,因为这个表示关闭容器后会自动清理掉容器,也就是说在Docker上找不到了,下次再想开这个容器,还得重新敲命令,所以我就去掉这个。如果我真的想删掉这个容器,也可以直接在Docker容器界面上操作。
最后一个就是我将jenkins-data改成了D:/ServicesData/Jenkins/.jenkins,首先我们来看这个-v jenkins-data:/var/jenkins_home命令是干嘛的,因为Docker就相当与与一个虚拟机,里面有自己的文件管理系统,这里/var/jenkins_home就表示当前jenkins容器的工作目录,但是虚拟的毕竟是虚拟的,所以它搞了一个体的概念,就是Volume,专门用来春出数据的,而jenkins-data就是其中创建的一个体,是Docker在物理机上构建的一个私有文件目录,我们没办法管理与访问。直接安装Docker是装在C盘的,所以这些体数据,应该也是在C盘(猜的)。为了能够接管这些容器的工作数据,我们可以将虚拟文件目录映射到实际的物理机上,这里我在D盘建立一个目录,也就是说,之后Jenkins容器运行时产生的数据都会放到这个D盘目录下。
通过这个例子,我有点明白了Docker的一个基本运作方式了,打开Docker客户端,出现五个大选项,其中有三个就是容器、镜像、体。另外两个我没有用过,所以也不知道能干啥,但是这三个之间的关系似曾相识:MVC框架,嗯好像又不像。这么说吧,这三者其实是一件事情拆分成三个部分,其中镜像是我们的全局数据中心,然后容器是我们的控制总线,体是控制过程中产生的数据。在需要时,Docker会为我们创建任意个控制总线,相当与是一个壳子,然后向全局数据中心请求生产资料,最终产生的产品堆到各自的仓库里面,也就是体。

继续按照Post-installation setup wizard安装。这里我们在浏览器上输入http://localhost:8080/,会看到Jenkins的解锁界面,这里需要一个密码,如果安装在物理机下的话,我们能够找到对应的文件,但是现在是装在容器里面,所以要在Docker客户端里面找,我们首先找到Jienkins的容器,然后点击该容器,进入Logs界面,这里就是Jenkins控制台日志输出中,复制自动生成的字母数字密码(在两组星号之间),然后拿到解锁界面解锁。之后的操作就和物理机上安装差不多了。

然后在浏览器里面输入http://localhost:8000/就可进入了。
还有一个需要注意的是,如果启动容器后,网页访问不了Jenkins,可能是端口被占用了,换个端口试试。或者如果你知道怎么排查端口占用的情况就更直接了。

记录

这里假设我们已经在Win10系统上安装安装好了Jenkins和Bonobo Git Server,并且有一个Unity工程JenkinsTest,同时安装了Unity,我这里是Unity 2020.3.33f1c2 (64-bit),另外还装了Git,并且在Bonobo Git Server服务上搭建了JenkinsTest的版本仓库。

在这些都准备好之后,下面是需要操作的步骤:

  • 在Jenkins里面新建一个Item,也就是一个新的部署项目。随便给它取个名字,这里使用JenkinsTest,然后选FreeStyle Project,最后点确定。
  • 之后会自动跳转到一个设置界面,这里有很多设置,但是本教程只需要关注Git这个选项的配置,我们需要加一个Git仓库配置,勾选Git,然后点击Add Repository,会出现Repository URL,这里填JenkinsTest项目在Bonobo Git Server中的URL,我这里是htt://localhost:8888/JenkinsTest.git。然后是Credentials,这里需要填一个Git拉去的访问权限的东西,有几种选择,因为Bonobo Git Server只提供账号密码的访问形式,所以这里我们在下面添加按钮,打开新建一个凭证,这个凭证是采用账号密码的形式,然后在对应框中输入账号和密码,点击确定,然后回到Credentials下,选择新建好的凭证。
  • 到这里为止,如果我们保存配置,然后对Jenkins进行构建的话,Jenkins会自动将Jenkins项目拉取到它的工作区。除此之外不会做任何其他事情。
  • 为了最终打包工程,我们需要在上面那个设置界面下的构建设置里面,选择构建的方式。在Windows中,可以使用Execute Windows batch command来构建,主要是通过调用一些bat类型的可执行文件,来间接调用Unity项目中的打包脚本。这总方法在网上有很多,比如这个教程。
  • 但是还有一种方式,是直接使用Unity Editor的方式来打包,这种方式需要在Jenkins中安装Unity3D Plugin插件。然后在Jenkins的Global Tool Configuration的配置里面,找到Unity3d部分,那个有个Unity安装的按钮,点开,然后将电脑上已有的Unity配置上去。举个例子,我这里的Unity的安装路径是C:\Program Files\Unity\Hub\Editor\2020.3.33f1c2,然后别名随便。
  • 然后再会到JenkinsTest的配置界面,就会发现构建部分多了Invoke Unity3d Editor的选项,选它,然后Unity3d installation name这里会自动出现前面配置的Unity别名,意思是我们选择这个Unity版本来打包。
  • 然后在Editor command line arguments里面配置打包命令,这个是在Unity手册里面是有介绍到。我这里填的打包命令是-quit -batchmode - - executeMethod BuildTools.BuildApk。其中BuildTools是JenkinsTest工程下的编辑器脚本,BuildApk是该脚本下的一个打包函数,执行具体的打包操作。
  • 了解过Execute Windows batch command打包方式的人应该记得,打包命令里面一般会包含Unity的路径和需要打包的项目路径,但是这里并没有,这是因为前面已经配置了Unity的安装路径,而项目路径是Jenkins自动拉取的git目录,所以这两个目录Jenkins是知道的。我最开始配了这两个反而导致报错。
  • 最后,点击构建,开始打包JenkinsTest项目。

到这里整个流程就走完了,可以愉快的一键打包。但是打包的时候我发现打包前要构建Unity工程的Library文件夹,这个是Unity自动生成的,这个文件夹构建一次要花很长时间,所以需要部署资源缓存服务。我又开始找相应的教程,然后发现这个资源缓存服务不亚于Git服务的搭建,要装安多东西。
所以最终我还是决定方式Jenkins和Bonobo Git Server的组合。因为我都打算安装那么多服务了,就想直接使用Docker来作为容器,这样什么服务都可以搭,那就搭一个更牛逼的Git服务吧,比如说GitLab。
不过Jenkins和Bonobo Git Server的组合,整个安装过程都是非常简单的,适合初学者使用,或者需求没有那么复杂的个人使用。

参考

Unity-Jenkins打包部署工具(一)
Jenkins!自動建置Unity專案-本地建置
Unity为Git项目部署Jenkins

记录

因为最近想自己搭建个人自动部署服务,所以考虑采用Jenkins和Git结合的方式。其中Jenkins负责项目自动化部署,Git负责版本控制,两者相结合需要一个Git服务。目前我所了解到的Git服务有GitHubGitLabGiteegitblitBonobo Git Server
这里前面几个是比较知名的Git服务了,前三者有在线运营的服务,我们可以直接注册,功能相对比较完善,用的人也多,但是免费版的存储、流量限制比较大。后面两者可能很少人知道,但是可以作为小团队Git服务进行部署私服,当然GitLab作为开源项目也可以部署私服,但是部署方式会比较繁琐,相比而言,最后这两种方式部署更为简单。
因为我是个人使用,同时经济限制,只有一台笔记本,Windows系统,所以我选择Bonobo Git Server,第一次部署完成后,真的被她的简陋的功能给震惊了,一度怀疑被收了智商税,因为我发现除了上传、下载、commit、用户管理、仓库管理,就没了,我无法想象她是如何和Jenkins联动的。好在懒惰拯救了我,当我想放弃Bonobo Git Server的时候,我再转头研究gitblit,发现要下载一堆相关联的软件,所以我再一次抱着试一试的心态看有没有教程将如何将Bonobo Git Server与Jenkins关联起来,还真被我找到了,最终结果你们应该也猜到了,确实实现了两者的完美结合(ps:毕竟不完美的完美才是最大的完美)。好了废话有点多,进入正题吧。

首先安装Bonobo Git Server本地服务,可以看这篇文章,我找了很多篇教程,这篇无疑是最简单而且真实有效的。

当然我们也要提前安装号Jenkins,找到一篇真正意义上的保姆级教程,在这里谢谢这位无私的大佬。教程路径【游戏开发进阶】教你Unity通过Jenkins实现自动化打包,打包这种事情就交给策划了(保姆级教程 | 命令行打包 | 自动构建)

这里提一嘴,Jenkins安装完成后,默认工作路径一般是在C盘,也就是所有的需要部署的文件副本都会放在这个工作路径下,很显然C盘不适合当作工作路径,所以需要更改其工作路径。更改方式其实也不难,主要是有很多老旧不适用的方式在网络上混淆视听,给我们错误的引导。这里简单说一下,我们需要找到Jenkins的安装目录,这里我是D:\Program Files\Jenkins,在安装目录下找到jenkins.xml文件,然后修改其中的工作路径配置。注意这里使用的Jenkins版本是Jenkins 2.346.3。按下面更改,改前要关闭Jenkins,改后再重启。对了,我是参考的这里Jenkins 修改主目录 JENKINS_HOME

1
2
<!-- <env name="JENKINS_HOME" value="%ProgramData%\Jenkins\.jenkins"/> --> <!-- 这行是默认设置 -->
<env name="JENKINS_HOME" value="D:\ServicesData\Jenkins\.jenkins"/> <!-- 这行是我更换的路径,路径你也可以自己选 -->

重点来了,这篇文章不算很详细的介绍了如何配置的过程,但是相比于网络上稀缺的资料,蚊子再小也是肉。按照这篇文章大概能了解其中的基本步骤,但是其中还有有一些谬误,具体说就是post-receive这个文件,在该文章中写成了post_receive,导致我搞了半天也没成功。最后是在这里找到了解决方案。当然前面这篇中文教程也是有很大的参考意义的。前面说了Bonobo Git Server非常简陋,没有钩子之类的工具(ps:我其实不太懂什么是钩子,我猜应该是网站之间相互订阅、通知之类的事件传输)。因此需要借助curl来实现,搜了一下,curl应该是用来发送http这类网络协议的,所以可以实现两者通信。

目前为止,确实实现了Jenkins部署时,会自动拉取Git服务中的项目,但是教程里面提到的Git上传修改会自动触发Jenkins进行部署的方法,我还没有试验成功。在文章中提到的方式就是借用curl,然后还需要配置一个post-receive文件,在提交Git时,确实能看到控制台里面多打印了一些消息,但是Jenkins并没有触发自动部署。所以这个问题暂时先搁置,等我找到方法再补充。

这个博客有点简陋,没有评论交流的功能,所以有兴趣可以跳到知乎给我点个赞(哈哈哈,算了,知乎点赞好像也没什么用,等我有精力好好升级升级我这个破站)。

参考

Configure Git Hooks on Bonobo Git Server in Windows
curl
Jenkins+Bonobo.Git.Server自动部署.net core项目
Windows环境搭建 Gitlab 服务器
【游戏开发进阶】教你Unity通过Jenkins实现自动化打包,打包这种事情就交给策划了(保姆级教程 | 命令行打包 | 自动构建)

记录

自动化部署是项目开发中经常用到的,当部署完成后最好能够通知到相关人员部署情况,这里记录基于Jenkins的邮件通知配置。
这里假设已经安装部署好了Jenkins,并且创建了一个叫hello world的部署项目。
wwwwwww
关于邮件通知配置,只需要配两个地方,一个是Manage Jenkins->System Configuration->Configure System,这个是总的配置。另一个是hello world->配置,这个主要是针对特定项目的邮件设置。
Manage Jenkins->System Configuration->Configure System这里的设置,主要是针对Extended E-mail Notification邮件通知两部分的设置。具体设置如下:
wwwwwww
上面主要是设置了用于发送系统消息的邮箱账号,邮箱的类型,授权码等信息。这里我使用的是QQ邮箱,QQ邮箱的授权码获取方式可以参考这里开启邮箱的SMTP服务获取授权码(QQ邮箱、163邮箱)
为了让邮件看起来比较正式,相应的邮件格式可以配置一下,这里采用HTML的例子,直接配到Default Content里面。具体内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>    
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
offset="0">
<table width="95%" cellpadding="0" cellspacing="0" style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
<tr>
本邮件由系统自动发出,无需回复!<br/>
各位同事,大家好,以下为${PROJECT_NAME }项目构建信息</br>
<td><font color="#CC0000">构建结果 - ${BUILD_STATUS}</font></td>
</tr>
<tr>
<td><br />
<b><font color="#0B610B">构建信息</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>项目名称 : ${PROJECT_NAME}</li>
<li>构建编号 : 第${BUILD_NUMBER}次构建</li>
<li>触发原因: ${CAUSE}</li>
<li>构建状态: ${BUILD_STATUS}</li>
<li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>

<h4><font color="#0B610B">失败用例</font></h4>
<hr size="2" width="100%" />
$FAILED_TESTS<br/>

<h4><font color="#0B610B">最近提交(#$SVN_REVISION)</font></h4>
<hr size="2" width="100%" />
<ul>
${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="<li>%d [%a] %m</li>"}
</ul>
详细提交: <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a><br/>

</td>
</tr>
</table>
</body>
</html>

hello world->配置这里的设置,主要是针对构建后操作的设置。选择Editable Email Notification选项。配置可以保持默认,但是如果希望不同的项目发送邮件的对象、内容、发送触发条件不同的话,就需要在这里修改。

参考

jenkins邮件配置和邮件发送
开启邮箱的SMTP服务获取授权码(QQ邮箱、163邮箱)
Unity和Jenkins真是绝配,将打包彻底一键化!
如何搭建Jenkins导出Unity安卓环境