项目管理工具的搭建与使用

2/19/2022 禅道MasterGoShowDocJenkins

# 1. 项目进度管理

# 1.1 禅道简介

# 1.1.1 基本介绍

禅道是一款国产的开源项目管理软件,它的核心管理思想基于敏捷方法scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

# 1.1.2 禅道安全漏洞

漏洞概述:该漏洞是由于禅道项目管理系统权限认证存在缺陷导致,攻击者可利用该漏洞在未授权的情况下,通过权限绕过在服务器执行任意命令。

项目地址:https://github.com/webraybtl/zentaopms_poc (opens new window)

影响范围:开源版、旗舰版、企业版均有所涉及

禅道系统 影响版本
开源版 17.4以下的未知版本<=version<=18.0.beta1
旗舰版 3.4以下的未知版本<=version<=4.0.beta1
企业版 7.4以下的未知版本<=version<=8.0.beta1 8.0.beta2

# 1.2 禅道部署

# 1.2.1 禅道服务部署

方式一:使用Docker方式部署

$ docker pull idoop/zentao
$ docker run -d -p 7777:80 -p 7776:3306 -e ADMINER_USER="root" -e ADMINER_PASSWD="password" -e BIND_ADDRESS="false"  --name zentao idoop/zentao:latest
$ docker logs -f zentao
1
2
3

方式二:使用一键脚本部署(开源版v18.5)

$ cd /opt                                    // 该一键脚本必须在 /opt 目录操作
$ wget https://www.zentao.net/dl/zentao/18.5/ZenTaoPMS.18.5.zbox_64.tar.gz
$ tar -zxvf  ZenTaoPMS.18.5.zbox_64.tar.gz -C /opt
$ /opt/zbox/zbox -ap 7777 -mp 7776           // -ap参数 可以修改Apache的端口,-mp参数 可以修改MySQL的端口
$ /opt/zbox/zbox start                       // 如果需要停止 /opt/zbox/zbox stop
1
2
3
4
5

注:如果执行 /opt/zbox/zbox 存在权限不足的问题,使用 sudo 即可。

启动完成后,打开Chrome访问http://ip:7777地址(默认用户名:admin,密码:123456;数据库用户:root,默认密码:123456)

禅道

# 1.2.2 更换数据库

自带的MySQL没有对外暴露数据库的端口,只能网页或命令行访问,非常不便,这里将一键脚本部署方式的MySQL换成自己的(支持MySQL5.x,但不支持8.x)

Step1:先按照官方的方式连接数据库并将sql导出(如果有了可以略过这一步)

$ cd /opt/zbox/auth/
$ ./adduser.sh        // 添加用户名及密码
1
2

登录页的“数据库管理”就是入口,网页访问的账号验证就是刚刚添加的那个。

之后的数据库连接信息填写如下:服务器 127.0.0.1:7776(必须写127.0.0.1,真实IP不行) zentao root / 12345

禅道原始数据库连接

连上去之后依次点击如下按钮,导出数据文件。

禅道原始数据库导出

然后在自己的MySQL上创建数据库,导入刚刚的sql数据。

$ CREATE DATABASE zentao DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_unicode_ci;
1

Step2:修改代码去除禅道自带的数据库功能

$ /opt/zbox/zbox stop          // 先停止禅道服务
$ cd /opt/zbox/bin/
$ cp zbox.php zbox.php.copy    // 把原来的文件拷一份备份
$ vim /opt/zbox/bin/zbox.php
1
2
3
4

将有关MySQL的指令删除,修改后的脚本如下:

#!/opt/zbox/bin/php
<?php
array_shift($argv);
$flipArgv = array_flip($argv);
$basePath = dirname(dirname(__FILE__));

if($basePath != '/opt/zbox') die("Run it in path /opt/zbox/\n");
if(empty($argv) or isset($flipArgv['--help']) or isset($flipArgv['-h']))
{
    echo <<<EOD
Usage: zbox.php {start|stop|restart|status}

Options:
    -h --help Show help.
    -ap --aport Apache port, default 80.
    -mp --mport Mysql port, default 3306.

EOD;
    exit;
}

if(is_dir("$basePath/app/zentao/"))
{
    `chmod -R 777 $basePath/app/zentao/tmp`;
    `chmod -R 777 $basePath/app/zentao/www/data`;
    `chmod 777 $basePath/app/zentao/www/`;
    `chmod 777 $basePath/app/zentao/config/`;
    `chmod -R a+rx $basePath/app/zentao/bin/*`;
}
if(is_dir("$basePath/app/zentaopro/"))
{
    `chmod -R 777 $basePath/app/zentaopro/tmp`;
    `chmod -R 777 $basePath/app/zentaopro/www/data`;
    `chmod 777 $basePath/app/zentaopro/www/`;
    `chmod 777 $basePath/app/zentaopro/config/`;
    `chmod -R a+rx $basePath/app/zentaopro/bin/*`;
}
if(is_dir("$basePath/app/zentaoep/"))
{
    `chmod -R 777 $basePath/app/zentaoep/tmp`;
    `chmod -R 777 $basePath/app/zentaoep/www/data`;
    `chmod 777 $basePath/app/zentaoep/www/`;
    `chmod 777 $basePath/app/zentaoep/config/`;
    `chmod -R a+rx $basePath/app/zentaoep/bin/*`;
}

/* Process argv. */
$params = array();
foreach($flipArgv as $key => $val)
{
    if(strpos($key, '-') !== 0) continue;
    if($key == '--aport') $key = '-ap';
    if($key == '--mport') $key = '-mp';
    if(isset($argv[$val + 1]) and is_numeric($argv[$val + 1]))
    {
        $params[$key] = $argv[$val + 1];
        unset($argv[$val]);
        unset($argv[$val + 1]);
    }
}

if(isset($params['-ap'])) changePort($basePath . '/etc/apache/httpd.conf', $params['-ap'], array('^Listen +([0-9]+)', '<VirtualHost +.*:([0-9]+)>'));

if(isset($params['-mp']))
{
    changePort($basePath . '/etc/mysql/my.cnf', $params['-mp'], '^port *= *([0-9]+)');
    changePort($basePath . '/app/htdocs/index.php', $params['-mp'], 'localhost\:([0-9]+)\&');

    $myReg = '^\$config->db->port *= *.([0-9]+)..*;';
    if(file_exists("$basePath/app/zentao/config/my.php"))
    {
        `chmod 777 $basePath/app/zentao/config/my.php`;
        $myFile = "$basePath/app/zentao/config/my.php";
        changePort($myFile, $params['-mp'], $myReg);
    }
    if(file_exists("$basePath/app/zentaopro/config/my.php"))
    {
        `chmod 777 $basePath/app/zentaopro/config/my.php`;
        $myFile = "$basePath/app/zentaopro/config/my.php";
        changePort($myFile, $params['-mp'], $myReg);
    }
    if(file_exists("$basePath/app/zentaoep/config/my.php"))
    {
        `chmod 777 $basePath/app/zentaoep/config/my.php`;
        $myFile = "$basePath/app/zentaoep/config/my.php";
        changePort($myFile, $params['-mp'], $myReg);
    }
}

if(!empty($argv)) $params['-k'] = reset($argv);
if(isset($params['-k']))
{
    if(strpos(file_get_contents('/etc/group'), 'nogroup') === false) echo `groupadd nogroup`;
    if(strpos(file_get_contents('/etc/passwd'), 'nobody') === false) echo `useradd nobody`;
    `chmod -R 777 $basePath/tmp`;
    `chmod -R 777 $basePath/logs`;
    `chown -R nobody $basePath/data/mysql`;

    switch($params['-k'])
    {
    case 'start':
        $httpd = `ps aux|grep '\/opt\/zbox\/run\/apache\/httpd '`;
        if($httpd)
        {
            echo "Apache is running\n";
        }
        else
        {
            echo `$basePath/run/apache/apachectl start`;
            sleep(2);
            $httpd = `ps aux|grep '\/opt\/zbox\/run\/apache\/httpd '`;
            echo empty($httpd) ? "Start Apache fail. You can see the log /opt/zbox/logs/apache_error.log\n" : "Start Apache success\n";
        }

        break;
    case 'stop':
        $httpd = `ps aux|grep '\/opt\/zbox\/run\/apache\/httpd '`;
        if($httpd)
        {
            echo `$basePath/run/apache/apachectl stop`;
            sleep(2);
            $httpd = `ps aux|grep '\/opt\/zbox\/run\/apache\/httpd '`;
            echo empty($httpd) ? "Stop Apache success\n" : "Stop Apache fail. You can see the log /opt/zbox/logs/apache_error.log\n";
        }
        else
        {
            echo "Apache is not running\n";
        }

        break;
    case 'restart':
        echo `$basePath/run/apache/apachectl restart`;
        sleep(2);
        $httpd = `ps aux|grep '\/opt\/zbox\/run\/apache\/httpd '`;
        echo empty($httpd) ? "Restart Apache fail. You can see the log /opt/zbox/logs/apache_error.log\n" : "Restart Apache success\n";

        break;
    case 'status':
        $httpd = `ps aux|grep '\/opt\/zbox\/run\/apache\/httpd '`;
        echo empty($httpd) ? "Apache is not running\n" : "Apache is running\n";
    }
}

function changePort($file, $port, $regs)
{
    if(!is_array($regs)) $regs = array($regs);
    $lines = file($file);
    foreach($lines as $i => $line)
    {
        foreach($regs as $reg)
        {
            if(preg_match("/$reg/", $line, $matches)) $lines[$i] = str_replace($matches[1], $port, $line);
        }
    }
    file_put_contents($file, join($lines));
}
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

修改连接MySQL的配置,重新启动禅道服务即可。服务能够正常使用的话,可以把/zbox目录里所有跟MySQL相关的文件删掉。

$ vim /opt/zbox/app/zentao/config/my.php
将里面的数据库连接信息换成你自己的
$ /opt/zbox/zbox start
1
2
3

# 1.2.3 调整登录首页

不需要什么专业版、企业版、数据库管理功能,可以通过去掉禅道访问地址中的zentao路径,使其自动选择开源版的登录首页。

Step1:修改Apache配置

/opt/zbox/etc/apache/httpd.conf

// 修改前:
# If you want visit zentao like http://localhost/, uncomment these lines.
#<VirtualHost *:80>
#  ServerAdmin [email protected]
#  DocumentRoot "/opt/zbox/app/zentao/www"
#  ServerName localhost
#  <Directory />
#    AllowOverride all
#    Require all granted
#  </Directory>
#  ErrorLog "/opt/zbox/logs/apache_error.log"
#  CustomLog "/opt/zbox/logs/apache_access.log" combind
#</VirtualHost>

// 修改后:
# If you want visit zentao like http://localhost/, uncomment these lines.
<VirtualHost *:80>
  ServerAdmin zentao@local.net
  DocumentRoot "/opt/zbox/app/zentao/www"
  ServerName localhost
  <Directory />
    AllowOverride all
    Require all granted
  </Directory>
  ErrorLog "/opt/zbox/logs/apache_error.log"
  CustomLog "/opt/zbox/logs/apache_access.log" combind
</VirtualHost>
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

重启服务

$ /opt/zbox/zbox restart
1

Step2:修改配置文件

/opt/zbox/app/zentao/config/my.php

// 修改前
$config->webRoot         = getWebRoot();
// 修改后
$config->webRoot         = '/';
1
2
3
4

/opt/zbox/app/zentao/www/.ztaccess

// 修改前
RewriteRule (.*)$ /zentao/index.php/$1 [L]
// 修改后
RewriteRule (.*)$ /index.php/$1 [L]
1
2
3
4

# 1.3 基本使用

# 1.3.1 配置用户及权限

[1] 配置角色权限

后台——人员管理——权限——按照自己单位的组织架构调整分组

禅道配置角色权限

对每个分组配置页面权限。

禅道配置界面查看权限

对每个分组配置功能权限。

禅道配置功能操作权限

[2] 批量添加用户

后台——人员管理—用户——“添加用户”按钮旁边的下拉选项里有“批量添加用户”。

禅道批量添加用户

# 1.3.2 最简使用指南

禅道的定位不是那种简单的任务管理软件,而是专业的协同管理软件。研发类的项目管理本身具有其复杂性,所以禅道提供的都是必备的功能。但这并不意味必须按照禅道的流程来使用,完全可以按照自己的实际情况来使用禅道。这里我们只用到它来管理产品提出的项目需求以及测试提出的功能bug。

[1] 创建项目集

点右上角的加号——项目集——填写表单并保存

禅道创建项目集

[2] 创建项目及产品

点右上角的加号——项目——项目管理方式选择“Scrum”(敏捷开发)——填写表单并保存(可以在这里直接把产品也创建了)

禅道创建项目及产品

[3] 设置团队

添加完项目和产品之后,会停留在项目列表页,点击该项目的“团队成员”按钮,再点击团队管理按钮,在这里配置团队成员。

禅道给项目设置团队

[4] 需求管理

点右上角的加号——研发需求——填写表单并保存(可以在这里把功能模块也添加上)

禅道提出研发需求

注:这里可以直接把评审者设置成自己,评审通过后指派人员进行开发。

禅道评审研发需求

[5] bug管理

点右上角的加号——Bug——填写表单并保存

禅道提出bug

注:提出bug之后,由被指派人对bug进行修复或二次指派,修复问题后修改状态为已修复(尽量描述下是如何修复的),然后指派给测试人员或bug提出人,复测通过后将该bug关闭。

# 2. 项目功能设计

# 2.1 原型设计工具

以下是一些非常知名的项目原型设计工具。各自都有各自的特点和优势,适用的场景也不尽相同。

  • MasterGo (opens new window):一款非常简洁、高效的原型设计工具,特别适合新手使用。它提供了丰富的组件库和模板,设计者可以方便地拖拽生成原型。
  • 墨刀 (opens new window):一款国内非常知名的在线协作原型设计工具,有良好的团队协作能力。它支持实时协作,方便团队成员之间的沟通和协作。
  • Figma (opens new window):一款国际知名的在线协作设计工具,同时支持原型设计和UI设计。其强大的协作能力、丰富的组件库和插件系统,使其成为许多设计团队的首选。
  • 蓝湖 (opens new window):一款集设计、原型、项目管理为一体的设计平台。它有丰富的组件库和模板,同时也有良好的团队协作能力。
  • Axure (opens new window):一款非常专业的原型设计工具,支持高度自定义和动态交互设计。其强大的功能和复杂性使其更适合有经验的设计者。

根据你的需求和经验,可以选择最适合你的设计工具。

  • 如果你是新手,可能会更喜欢MasterGo或墨刀。
  • 如果你是在团队中工作,并且需要实时协作,可能会更喜欢墨刀或Figma。
  • 如果你是一名经验丰富的设计者,并且需要高度自定义的设计,那么Axure可能会是你的首选。

MasterGo资源广场

# 2.2 文档共享工具

# 2.2.1 ShowDoc简介

简介:技术人员都很希望别人能写文档,而自己却很不希望要写文档。ShowDoc就是一个非常适合IT团队的在线文档分享工具,可以加快团队之间沟通的效率。

功能及特点:API文档、数据字典、说明文档、分享与导出、权限管理、编辑功能、多平台、可部署至自己服务器

项目地址及官方文档:ShowDoc from Github (opens new window)ShowDoc官方文档 (opens new window)ShowDoc在线版 (opens new window)

ShowDoc功能界面如下:

ShowDoc功能界面

注:可在使用Markdown编辑文档时在开头加一个[TOC],自动生成目录。

# 2.2.2 部署ShowDoc服务

Step1:从官网下载ShowDoc的服务器端部署脚本 showdoc (opens new window),将其上传到root目录并赋予700权限。

注:我们可以根据自己的需要对该一键部署脚本进行自定义修改,也可提取有效命令自行手动安装。后续的使用及配置以原始脚本为例。

Step2:输入命令安装ShowDoc,成功则如下图所示:

$ ./showdoc   # 默认安装中文版。如果想安装英文版,请加上en参数,如 ./showdoc en
1

部署ShowDoc服务

安装好后,showdoc的数据都会存放在 /showdoc_data/html目录下。

此时你可以打开 http://IP:4999 来访问showdoc,后续我们将配置反向代理用指定域名访问并开启HTTPS(不配置也能用)

账户密码是showdoc/123456,登录后便可以看到右上方的管理后台,建议修改管理员密码。

附:其他管理showdoc的命令

$ ./showdoc stop          #停止
$ ./showdoc restart       #重启
$ ./showdoc update        #升级showdoc到最新版
$ ./showdoc uninstall     #卸载showdoc
1
2
3
4

设置开机自启:

$ docker update showdoc --restart=always
1

# 3. 项目持续集成

# 3.1 Jenkins简介

Jenkins (opens new window) 是一个开源项目,基于Java开发的持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

Jenkins的主要功能是将项目中重复执行的工作自动化的执行。具体功能大概有:

  • 软件的持续构建和测试,Jenkins提供了一个系统,使开发人员可以很容易的将改变集成到工程中。自动化的,持续的构建有利于提高开发效率。
  • 项目源代码修改的检测,Jenkins能够从项目的CVS生成最近修改的集合列表,且不会增加CVS Repository的负载。
  • 分布式构建,Jenkins可以将工程构建到多台机器,更好地利用硬件资源,节省时间。

Jenkins代码开源,用户可以自己编写插件,所以Jenkins可以实现很多定制的功能。

# 3.2 部署Jenkins服务

首先需要在服务器上准备 Java Open JDK 8 及 Maven 3.8.4 环境,然后拉取镜像并创建容器。

$ docker pull jenkins/jenkins:lts
$ mkdir -p /mydocker/jenkins
$ docker run -itd  \
  -p 8080:8080 \
  --name jenkins \
  --privileged=true -u root \
  --restart=always \
  -v /etc/localtime:/etc/localtime \
  -v /mydocker/jenkins:/var/jenkins_home \
  -v /usr/lib/jvm/adoptopenjdk-8-hotspot-amd64:/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64 \
  -v /opt/apache-maven-3.8.4:/opt/apache-maven-3.8.4 \
  -v /etc/profile.d/maven.sh:/etc/profile.d/maven.sh \
  jenkins/jenkins:lts
$ docker exec -it jenkins /bin/bash
$ source /etc/profile.d/maven.sh
$ mvn --version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

注:jdk和maven环境要设置挂载 ,不然docker容器里找不到maven环境,后面的全局工具配置会出问题。

# 3.3 Jenkins的基本配置

# 3.3.1 初始化jenkins基本配置

[1] 解锁jenkins

打开Chrome,访问:https://IP:8080地址,按要求填写管理员密码(docker logs -f jenkins查日志即可,密码会打印出来)

解锁Jenkins

[2] 安装推荐插件

解锁之后,页面会提示安装插件,可以选择推荐插件,也可以按需选择适合的插件来安装。

我这里选择不安装插件,后续手动安装。先点击“选择插件来安装”,出现如下页面,点击那个“无”,再点击“安装”。

自定义插件安装

[3] 创建管理员用户并确认实例配置

再之后就是创建管理员用户,填写好信息后,点击“保存并完成”,下一步的实例配置使用默认的即可。

# 3.3.2 汉化并安装必备插件

[1] 安装汉化插件

Manage Jenkins —— Manage Plugins,搜索框输入“Chinese”,找到 Localization: Chinese (Simplified) (opens new window),勾选上再点击“Download now and install after restart”。

jenkins汉化插件

再次登录,页面就变成中文的了。

jenkins初始化

[2] 安装 Git、Maven Integration 插件

重复如上操作,安装 Git 和 Maven Integration 插件。

# 3.3.3 生成并设置 SSH KEY

Step1:生成SSH KEY

$ ssh-keygen -t rsa -C "[email protected]"     
$ ls -l /root/.ssh
$ cat /root/.ssh/id_rsa.pub
$ cat /root/.ssh/id_rsa
1
2
3
4

生成SSH-KEY

Step2:设置SSH KEY

Gitea:登录Gitea,找到右上角的图标,找到设置,再选中 SSH/GPG 密钥选项卡,增加密钥,然后密钥名称随便填,再把刚才 id_rsa.pub 里面的内容复制到密钥内容框里面,最后点击增加密钥,这样就完成了SSH Key 的加密。

Github:登录 Github ,找到右上角的图标,打开点进里面的 Settings ,再选中里面的 SSH and GPG KEYS ,点击右上角的 New SSH key,然后 Title 里面随便填,再把刚才 id_rsa.pub 里面的内容复制到 Title 下面的 Key 内容框里面,最后点击Add SSH key,这样就完成了SSH Key 的加密。

# 3.3.4 Jenkins设置凭据

登录 Jenkins,依次点击“系统管理”、“Manage Credentials”,然后再点击“Jenkins”、“全局凭据 (unrestricted)”、“添加一些凭据”。

类型选择“SSH Username with private key”,勾选“Enter directly”再点击“Add”,然后在文本框里粘贴上id_rsa的内容

# 3.3.5 全局工具配置

系统管理——全局工具配置——配置服务器上JDK和Maven的路径。

全局工具配置--JDK

全局工具配置--Maven

注:此处不能有任何爆红或警告,如果出现了请检查路径填写是否正确,或者maven是否成功挂载进容器内。

# 3.4 配置项目的持续集成

新建任务,输入任务名称,下面选择“构建一个自由风格的软件项目”。

jenkins新建任务

填写描述,源码管理填写Github仓库地址(如果是私有仓库就要用到之前配置好的凭据),构建选择“执行shell”,然后根据项目编写对应的构建shell脚本即可。

# 4. 参考资料

[1] CentOS 8 部署禅道,并使用自己的数据库 from CSDN (opens new window)

[2] linux一键安装包去掉禅道访问地址中的zentao from 禅道官方文档 (opens new window)

[3] linux用一键安装包安装禅道 from 禅道官方文档 (opens new window)

[4] ShowDoc自动脚本安装 from showdoc官方文档 (opens new window)

[5] 性能环境之Jenkins+Maven自动化部署SpringBoot压测环境 from 华为云 (opens new window)

[6] 持续集成:Jenkins自动化部署你的项目 之 私有coding.net Git仓库帐号配置 from webascii (opens new window)

[7] 安装Jenkins from Jenkins官方文档 (opens new window)

[8] docker搭建jenkins from CSDN (opens new window)

[9] 超详细 Docker 安装Jenkins from 稀土掘金 (opens new window)

[10] 微服务下的持续集成-Jenkins自动化部署GitHub项目 from 博客园 (opens new window)

Last Updated: 8/3/2023, 1:40:27 PM