前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次早期自动化构建的搭建过程

一次早期自动化构建的搭建过程

作者头像
用户1593318
发布2019-11-19 22:13:17
1.1K0
发布2019-11-19 22:13:17
举报

这是老王07年进入腾讯接手的第一个项目---自动化构建AutoBuild(06年就已经在上线运行),当年还不知道有Hudson,以及后来更名的Jenkins。做完这个项目之后再去反思传统的软件工程就有了很多新的感悟,只有从根源上提出解决方案,并配合最佳的实践才能解决软件交付的质量问题。

也因为腾讯web端项目基本上都是使用的CGI,所以花了不少时间写整套的自动化编译脚本(全部是perl写的),当然里面对研发提出了编译文件Makefile的规范(后面有原理)。

在后续的版本演进中,把自动化测试、代码安全扫描、持续发布都加入了整体过程,真正的做到全过程持续交付,直到今天和客户去讲持续交付整体过程的时候,很多实践和感悟都是来源于此。

1. 编译环境的搭建

1.1. 整体框图

注:ARS是腾讯的Auto Release System,早期我也是作为运维主要需求方参与这个平台的构建和推广,直到所有的业务页面端发布都接入了这一平台。持续部署的过程也就真正成为现实。

说明:

1编译机器支持每天自动编译,以及手工触发编译两种构建方式.

1.2. SVN Server端的配置

每加入一个工程,需要找PM给自动化编译用户isd_webadmin授权只读访问该工程的权限。具体的申请方法:告诉对方工程和用户即可。

1.3. 公共代码配置

/data/auto_build/ // 主目录

|-- bin // 公共程序目录

| |-- svntools.pl // 拉取svn服务器中代码文件,获取最后更新信息的工具,编译

| |-- confgen.pl // 根据qzone项目源码根目录中的makfile文件,生成构建脚本构造文件(make.conf)的工具

| |-- mkgen.pl // 根据构建脚本构造文件(make.conf)生成全构建脚本build.sh的工具,编译环境的关键脚本

| |-- postmessage.pl // 发送邮件的工具(详见后边说明)

| |-- readlog.pl // 读取编译过程中的日志文件,生成编译结果报告buildres.xml的工具,关键脚本

| `-- writemail.pl // 根据编译结果报告build.sh生成通知邮件的工具

|-- config // 项目工程配置目录

| |-- abs_profile.conf // 所有工程的配置

`-- mbox // 存放每天所有工程编译结果的汇总邮件

1.4. 编译机的配置

编译机的这边需要的软件有:

l Apache (版本没有特殊要求) + PHP模块的支持

l PHP 4.4.2 (或者高版本) + DOM + ICONV

l PERL 5.8 (或者高版本) + DOM + ENCODE + HASHINI

建议使用官方源码包编译安装,编译顺序和选项请参考

编译环境的目录结构如下,我们以/data/项目_build做为编译环境的主目录,实际部署中可以修改脚本中的变量设置改变这个目录,只要相应的分区空间足够大,可以支持整个项目的全编译即可.

/data/qzone_build/ // 主目录

|-- admin // 编译管理目录(详见后边说明)

| |-- bin // 编译控制脚本的存放目录

| |-- cgi-bin // qzone.build.isd.com 的cgi程序目录

| |-- htdocs //qzone.build.isd.com 的页面文件目录

|-- source // 项目代码,编译结果的实际存放位置

| |-- qzone_20060829 // 这些以日期作为后缀的子目录,存放着相应日期参加日构建的源码和编译结果

| `-- qzone_20060831 // 可以根据需要保留近几天的历史结果,太早的通过简单脚本删除或者打包备份

`-- temp // 存放一些临时文件或者动态目录

|-- mbox // 发送编译结果通知邮件的信箱(详见后边说明)

`-- src -> /data/qzone_build/source/qzone_20060831 // 一个到当前代码存放目录的软连接, svntools默认会向这里

// 更新最新的代码 (详见后边说明).

admin目录下的文件有:

/data/qzone_build/admin/

|-- bin

| |-- autobuild.sh // 自动编译的总控制脚本,可以直接写到crontab中定时自动运行

| |--buildall.sh // 完整的一次编译过程的控制脚本, 不包含更新代码,发送邮件的过程

| |-- buildres.xsl // buildres.xml需要的xsl风格表单(详见后边说明)

| |-- svntools -> svntools.pl // 为方便使用做的一个软连接

| |-- svntools.conf // svntools.pl的配制文件,它应该始终和svntools.pl放在同一个目录下

| |-- svntools.pl // 拉取svn服务器中代码文件,获取最后更新信息的工具,编译

| | // 环境的关键控制脚本(详见后边说明)

| |-- confgen.pl // 根据qzone项目源码根目录中的makfile文件,生成构建脚本构造文件(make.conf)的工具

| |-- crlf // 将单个文件中每行的结尾标志字符\n(UNIX习惯),替换为\r \n(WINDOWS习惯)的工具

| |-- crlf.c // crlf工具的源代码

| |-- make.conf.def // 构建脚本构造文件(make.conf)的缺省设置文件,供confgengen.pl参考使用

| |-- message.conf // postmessages.pl的配制文件,它应该始终和postmessages.pl放在同一个目录下

| |-- mkgen.pl // 根据构建脚本构造文件(make.conf)生成全构建脚本build.sh的工具,编译环境的关键脚本

| |-- postmessage.pl // 发送邮件的工具(详见后边说明)

| |-- readlog.pl // 读取编译过程中的日志文件,生成编译结果报告buildres.xml的工具,关键脚本

| |-- setroot.sh // 设置文件更新/编译目录连接的工具,关键脚本(详见后边说明)

| |-- u2wlog.sh // 批量转换文件换行字符 \nà \r \n的工具 (内部循环调用crlf程序)

| `-- writemail.pl // 根据编译结果报告build.sh生成通知邮件的工具

|-- cgi-bin

`-- htdocs

|-- buildres.xsl ->/data/qzone_build/admin/bin/buildres.xsl //xsl表单的软连接,将原始文件放在bin中是为方便编辑

|-- index.php // build.qzone.isd.com的入口页面

|-- mainlist.php // 生成目录列表页面的工具脚本

|--slist.php // 文件列表页面

`--test.php // php测试页面 (非必需)

需要的环境变量:

PATH_QZONE_PRJ="/usr/local/qzone_v3.0"

export PATH_QZONE_PRJ

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/c4a/bin:/usr/lib

PATH_SVNTOOLS="/data/qzone_build/admin/bin"

export PATH=$PATH:$PATH_SVNTOOLS

PATH_QZONE_PRJ是qzone编译时必需的环境变量, PATH_SVNTOOLS加入路径中是为了使用方便(非必要).

整个编译环境中各个工具都可以普通用户执行,比如user_*,但应该保证相应的源码目录有足够的读写权限.

1.5. 编译过程

上边是编译的总体流程图,图中黄色圆形标注是编译过程的顺序,依次说明如下(各个控制脚本都放在admin/bin下):

1. 通过setroot.sh在source目录下选取或建立一个日构建的代码存放目录,比如qzone_20060831,并且将它软连接到/usr/local/qzone_v3.0(编译代码的目录),/data/qzone_build/temp/src(svntools.pl更新代码的目录). (注:将代码保存路径,编译目录,更新目录分开是为了支持历史编译结果备份和灵活更新)

2. 使用svntools.pl拉取远程svn服务器上的项目代码,更新到本地的/data/qzone_build/temp/src目录. svntools.pl更新文件的时候会将文件的最后更新信息(时间,更新人,CC事件)写到它所在的的目录下的ccversion.xml中

3. 自动编译系统一般是使用编译配置文件make.conf (位于源代码根目录)生成全编译脚本,但是如果项目代码根目录中有整体makefile文件,则可以使用confgen.pl读取这个makefile生成编译配制文件make.conf

4. 使用mkgen.pl读取源代码根目录下边的编译配置文件make.conf (这个文件中定义了要参加编译的子目录,以及这些目录间的依赖关系,即编译顺序,它可以通过makefile生成,也可以手工编写),在源代码根目录下生成全编译脚本build.sh

5. 上一步生成的build.sh是个可执行的bash脚本,直接运行就可以编译整个qzone代码,编译过程中的提示信息会被写入每个参加编译的子目录下,保存为build_***.log名字的文件,其中***代表build.sh的时间戳(详见后边说明)

6. 编译结束后,使用readlog.pl读取参加编译的各个子目录中的log文件,生成一份报告文件buildres.xml,记录编译结果(出错/异常/警告信息等)

7. 编译机同时兼做编译结果的发布WEB站点,允许大家查看参加编译的代码目录和各个log文件,因为UNIX环境下文本文件的换行符号\n与windows环境下的\r\n不一致,所以这些log在windows下查看时格式比较乱,使用u2wlog.sh可以对各个log文件做UNIXàWINDOWS的换行符替换

8. writemail.pl可以读取编译结果报告文件builres.xml中的关键信息,生成一封发给qzone开发组的通知邮件build_***.mail(其中***是build.sh的时间戳),邮件会放在约定好的发件箱/data/qzone_build/temp/mbox中

9. 最后调用postmessage.pl,它会将发件箱中的所有邮件(*.mail)发送出去(成功发送后将删除原始邮件).

注: admin/bin下边的autobuild.sh中按照上边的顺序串联了整个编译过程, 可以当作总的控制脚本,直接写到crontab中每天定时运行,实现自动编译; 另一个工具buildall.sh是一次完整的编译过程的控制脚本, 不包含更新代码,发送邮件的过程

1.6. build.qzone.isd.com

这是由几个简单的php页面构成的编译结果发布站点,需要在Apache的httpd.conf中作如下配置:

<VirtualHost *>

DocumentRoot /data/qzone_build/admin/htdocs

ServerName build.qzone.isd.com

DirectoryIndex index.php

ScriptAlias /cgi-bin/ "/data/qzone_build/admin/cgi-bin/"

Alias /src/ "/data/qzone_build/source/"

AddType text/plain .cpp .c .h .sh .js .vbs .css .conf .ini .log

ErrorLog logs/build.qzone.isdcom-error_log

</VirtualHost>

全部的页面都放在/data/qzone_build/admin/htdocs下:

/data/qzone_build/admin/htdocs/

|-- buildres.xsl ->/data/qzone_build/admin/bin/buildres.xsl // xsl表单的软连接,将原始文件放在bin中是为方便编辑

|-- index.php //build.qzone.isd.com的入口页面

|-- mainlist.php //生成目录列表页面的工具脚本

|-- slist.php // 文件列表页面

`-- test.php // php测试页面 (非必需)

发布页面的入口如下:

这个页面的信息主要来自/data/qzone_build/source下的每个目录下的buildres.xml,

通过第一列各个日期的连接可以进入查看相应的编译目录,通过查看详细信息,可以了解具体的编译情况:

上图页面的信息主要来自各个目录的ccversion.xml文件,ccversion.xml文件本身不会出现在列表中.

上图页面的信息来自相应的buildres.xml

注:由于源码目录下文件可能会被手工增删或改动,有时有些信息文件无法正确读取,这时php会发出警告,这些都是可以忽略的,可以通过/usr/local/lib/php.ini改变php的告警级别(仅显示错误):

error_reporting = E_ERROR

2. 关键工具的使用说明

2.1. svntools.pl的用法

用途: 拉取svn工程源代码的工具脚本.

配置文件: svntools.conf, 需要和svntools.pl放在同一个目录下, 其中设置远程SVN服务器的连接信息(IP,USER,PASSWD等).

使用方法: svntools [[-i|-u] local_directory|local_file]|[-e]|[-h]

-i local_directory|local_file 显示目录或文件在远程和本地的版本信息;

-u local_directory|local_file 更新本地目录或文件;

-e 查看或编辑配制文件;

-h 显示帮助信息.

注意: 命令行中的目录和文件参数支持相对和绝对路径;路径字符串中不支持通配符(*)和正则表达式.

其中srcroot定义了本地的源代码更新位置和远端svn地址, -i, -u选项后边的文件路径都应该在srcroot以内.

使用[svntools.pl -u 目录名]更新时不会删除服务器上不存在而在本地存在的目录内部文件;但使用[svntools.pl -u 文件名]时会做删除. 如果文件以及父目录都在服务器上不存在,只会删除文件而不会删除父目录.

cctool.pl –i 文件名可以比较本地文件和服务器上相应文件的CC信息,输出内容分两行显示,分别以L和S开头,L (local)代表本地文件信息,S (server)代表服务器端文件信息

2.2. setroot.sh的用法

用途: 设置更新和(或)编译目录的软连接

使用方法: setroot.sh[-b][-u][-d date|-p directory [-f]][-h]

-b set build source root

-u set update source root

-ddate use /data/qzone_build/source/qzone_$dateas base dir (fmt: YYYYMMDD)

-pdir use specified directory as basedir

-f use with -d or -p, force createdirectory if not exists

-h show help information

说明: 如果没有(用-d或者-p)指定具体目录,则会使用当天的日期当作-d的参数,即缺省采用–d + 当天日期

-f选项会在 –d或者-p指定的目录不存在时创建目录

-b会将指定的目录软连接到/usr/local/qzone_v3.0; -u会将指定的目录软连接到/data/qzone_build/temp/src

2.3. confgen.pl的用法

用途: 根据makefile生成make.conf

使用方法:confgen.pl [-i original_makefile|-o outputfile_confile] [-h hint_file]

-i original_makefile, original makefile tobuild conf file;

-o outputfile_confile, name of output makeconfig file;

-f hint_file, a file in which includedefault conf values;

-h, print help messages.

说明: 缺省的输入文件是/usr/local/qzone_v3.0/makefile, 但可以通过-i选项指定输入文件;缺省的输出文件是/usr/local/qzone_v3.0/make.conf, 但可以通过-o选项指定输出文件; -f 用来指定缺省配置所在的文件,如果不指定的话,则会尝试使用confgen.pl同一目录下的make.conf.def,其中可以指定编译目录的依赖关系,以及包括,排除列表的缺省值,这些值会合并到最终生成的make.conf文件中(参见mkgen.pl的用法说明)

2.4. mkgen.pl的用法

用途: 根据make.conf生成全构建脚本build.sh

使用方法: mkgen.pl [-i include_list|-e exclude_list][-h] [-f hint_file] source_directory

-i include_list, ';' splited list forinclude sub_dirs;

-e exclude_list, ';' splited list forexclude sub_dirs;

-f hint_file, a file in which listinginclude/exclude sub_dirs;

-h, print help messages.

说明: 不一定要使用make.conf文件,(但是如果在没有用-f 明确指定配制文件名,而/usr/local/qzone_v3.0/make.conf存在,则会尝试使用它), 可以在命令行中通过 –i,-e指定参加构建的或者不参加构建的子目录(如果-i,-e指定了同一个目录,则以-e为准)

make.conf一个很重要的用途是用来指明编译中的依赖关系,帮助确定编译顺序,下边是一个例子:

[order]

platform/src/comm=16

comm=8

platform=4

main=2

[include]

portal/src/fcg

blog/src/blog

music/src/discuss/fcg

main/src/mall

izone/src/favor

其中order一节定义了不同目录的优先级,数值越大越先编译,(也就是说,越多的其他的代码依赖于它).

优先级的设置使用目录关键字=级别的形式定义,当目录中包含关键字时(同一个关键字多次出现仅计算一次),会将相应的级别加到该目录的总级别,最终的编译脚本build.sh会按照各个目录的级别由高到低依次编译(级别相同的目录意味着他们之间的编译顺序不影响结果,因此只按照目录字母顺序做简单排序), 不含关键字的目录级别为0, 比如:

platform/src/comm 级别 16

platform/src/c5a/c5atool 级别 4

main/src/comm 级别 10

blog/src/comm 级别 8

izone/src/favor 级别 0

music/src/comm 级别 8

建议使用2的幂做为级别的数字,以便拉开差距,防止低级别的目录级别相加后超过更优先的级别.

mkgen.pl每次生成的build.sh都有一个不同的时间戳(选用当前系统时间),这个时间戳相当于build.sh的版本,不同版本的build.sh生成的log文件名不同,这些log的名称格式是: build_***.log其中***就是它的时间戳

2.5. writemail.pl,postmessage.pl的用法

用途: 这两个工具脚本联合起来完成邮件通知编译结果的功能.它们应该放在同一个目录下,并且还会在同一目录下寻找message.conf文件,其中包含发送邮件配制信息,例如:

[server]

ip=192.168.?.?

user=qzonebuilder@tencent.com

port=25

[local]

msgbox=/data/qzone_build/temp/mbox

其中msgbox指定了发件箱的位置,writemail.pl缺省会将新建的邮件放进这里.

l writemail的使用方法: writemail.pl [-i build resultfile] [-h] [-o output mail file]

-i build result file's path & name

-o output mail file's path & name

-h print help messages

说明: 如果没有用-i 指定编译结果文件,则尝试使用/usr/local/qzone_v3.0/buildres.xml,如果没有用-o指定生成的邮件的存放位置,则会根据build.sh的时间戳生成一封名为build_$timestamp.mail的文件放进message.conf中定义的msgbox中.

l postmessage.pl的使用方法: postmessage.pl [-fmessage_box|message_file ]|[-a]|[-e]|[-h]

-f message_box|message_file 指定邮箱路径或者邮件文件名,邮件文件必须以.mail做为名称后缀

-a 自动发送缺省配置的邮箱内的所有邮件和消息;

-e 查看或编辑配制文件;

-h 显示帮助信息.

3. crontab使用说明

3.1. crontab脚本

工程编译crontab脚本:

工程清理crontab脚本(保留一天的工程):

每天的译结果汇总邮件:

至此整个过程结束!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 互联网运维杂谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 编译环境的搭建
    • 1.1. 整体框图
      • 1.2. SVN Server端的配置
        • 1.3. 公共代码配置
          • 1.4. 编译机的配置
            • 1.5. 编译过程
              • 1.6. build.qzone.isd.com
              • 2. 关键工具的使用说明
                • 2.1. svntools.pl的用法
                  • 2.2. setroot.sh的用法
                    • 2.3. confgen.pl的用法
                      • 2.4. mkgen.pl的用法
                        • 2.5. writemail.pl,postmessage.pl的用法
                        • 3. crontab使用说明
                          • 3.1. crontab脚本
                          相关产品与服务
                          持续部署
                          CODING 持续部署(CODING Continuous Deployment,CODING-CD)用以管理软件在经过构建之后的发布和部署交付过程,可以无缝对接上游 Git 仓库、制品仓库实现全自动化部署,同时支持 Webhook 等外部对接能力,方便集成各种开发、运维工具。在配以合适的技术架构、运维工具的基础上,可以方便地实现蓝绿发布、灰度发布(金丝雀发布)、滚动发布、快速回滚等功能。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档