2007年9月8日星期六

项目管理 nightli-build脚本一个


1#!/usr/bin/env perl
2
3use strict;
4use Config::IniFiles;
5use Date::Simple;
6use Net::FTP;
7
8# Global Var
9our $hIni;
10our $LOG;
11our $sLogFile= "/var/log/enightly-build.log";
12our $sIniFile="/root/workspace/cvsroot/install/smarteye/enterprise/tarbuild/ebuild.ini";
13our $sCurrDir=".";
14our $publishRoot=".";
15our $launchRoot=".";
16our $buildTime;
17our $productID="se8000";
18our $mainVersion="2";
19our $subVersion="1";
20our $buildCounter=1;
21our $distFtpIP;
22our $distFtpUser;
23our $distFtpPasswd;
24our $distFtpDir;
25our $distEdition;
26our $srcCvsRoot;
27our $srcWorkCopyRoot;
28our $confReposCvsRoot;
29our $confWorkCopyRoot;
30
31################### functions #########################
32sub Log
33{
34 print LOG "$_[0]";
35}
36sub LogAndExit
37{
38 print LOG "$_[0]";
39 close LOG;
40 exit 1;
41}
42sub InitBuild
43{
44 open (LOG, "+>> $sLogFile") or die "Open $sLogFile Failed\n";
45 open (CONFIG, "<$sIniFile") or LogAndExit ("Open $sIniFile Failed\n");
46 $hIni = new Config::IniFiles -file => \*CONFIG or LogAndExit ("Create IniFile Object Failed\n");
47
48 chomp ($buildTime = `date +%Y%m%d`);
49 #[launch]
50 $launchRoot = $hIni->val ("launch", "LaunchRoot");
51 #[product_version]
52 $productID = $hIni->val ("product_version", "ProductID");
53 $mainVersion = $hIni->val ("product_version", "MainVersion");
54 $subVersion = $hIni->val ("product_version", "SubVersion");
55 $buildCounter = $hIni->val ("product_version", "BuildCounter");
56 $buildCounter++;
57 #[publish]
58 $publishRoot = $hIni->val ("publish", "PublishRoot");
59 $distFtpIP = $hIni->val ("publish", "FtpIP");
60 $distFtpUser = $hIni->val ("publish", "FtpUser");
61 $distFtpPasswd = $hIni->val ("publish", "FtpPasswd");
62 $distFtpDir = $hIni->val ("publish", "FtpDistDir");
63 $distEdition = $hIni->val ("publish", "DistEdition");
64 #[src_path]
65 $srcCvsRoot = $hIni->val ("src_path", "CvsRoot");
66 $srcWorkCopyRoot = $hIni->val ("src_path", "WorkCopyRoot");
67 #[config_repository]
68 $confReposCvsRoot= $hIni->val ("config_repository", "CvsRoot");
69 $confWorkCopyRoot= $hIni->val ("config_repository", "WorkCopyRoot");
70 my $str = sprintf ("%03d", $buildCounter);
71 #Log ("*-----------------------------Sm\@rtEye-20070527-[001]-------------------------------*\n");
72 Log ("\n**************************************************************************************\n");
73 Log ("*------------------------------Sm\@rtEye-$buildTime-[$str]-------------------------------*\n");
74 Log ("**************************************************************************************\n\n");
75 $hIni->setval ("product_version", "BuildCounter", "$buildCounter");
76 chdir "$launchRoot";
77 $hIni->WriteConfig ($sIniFile);
78 my $cmd = "cvs commit -m \"Increase Build Counter To [$buildCounter]\" *";
79 Log (" $cmd In [$launchRoot]\n");
80 #must commit complete before tag
81}
82sub BuildProject
83{
84 my $project = $_[0];
85 my @modules = split /:/, $hIni->val ("$project", "Modules");
86 my $module;
87 my $distDir = "$publishRoot/$distEdition/$project";
88 chomp (my $cDir = `pwd`);
89 my $projectRoot = "$srcCvsRoot/$srcWorkCopyRoot";
90 chdir "$projectRoot";
91 Log (" Building [$project] In [$projectRoot]\n");
92 foreach $module (@modules)
93 {
94 Log (" Building Module:[$module]\n");
95 my $dir = $hIni->val ("$module", "Dir");
96 my $bin = $hIni->val ("$module", "Bin");
97 my $publishEdition = $hIni->val ("$module", "PublishEdition");
98 my $make = $hIni->val ("$module", "MakeCmd");
99 my $moduleroot = "$projectRoot/$dir";
100 chdir "$moduleroot" or Log (" Not Find $moduleroot\n") and next;
101 my $str = sprintf ("%03d", $buildCounter);
102 my $publishVer = "$mainVersion\.$subVersion\.$str";
103 `$make PUBLISH_VERSION=$publishVer`;
104
105 Log (" $moduleroot : $make\n");
106 if (! -f "$moduleroot/$publishEdition/$bin")
107 {
108 Log (" Not Found $moduleroot/$publishEdition/$bin , Build $module Failed\n");
109 #resume
110 next ;
111 }
112 my $cpcmd = "cp -f $moduleroot/$publishEdition/$bin $distDir/usr/sbin";
113 `$cpcmd`;
114 Log (" $cpcmd In [$moduleroot]\n");
115 }
116 chdir "$projectRoot";
117 my $webRoot = $hIni->val ("$module", "WebRoot");
118 if (length ($webRoot) != 0)
119 {
120 my $cpweb = "cp -rf $projectRoot/$webRoot/* $distDir/var/www/html";
121 `$cpweb`;
122 Log (" $cpweb In [$projectRoot]\n");
123 #clean CVS
124 my $rmCVS = "find $distDir/var/www/html -name \"CVS\" | xargs rm -rf ";
125 `$rmCVS`;
126 Log (" $rmCVS In [$projectRoot] \n");
127 }
128 #resume
129 chdir "$cDir";
130 return 1;
131}
132sub CvsUpdate
133{
134 chomp (my $cDir = `pwd`);
135 #update the config-repository
136 #chdir "$confReposCvsRoot/$confWorkCopyRoot";
137 chdir "$confReposCvsRoot";
138 my $cmd = "cvs update > /dev/null 2>&1";
139 `$cmd`;
140 Log (" $cmd In [$confReposCvsRoot]\n");
141 #update the nightly-build config
142 #chdir "$launchRoot";
143 #`$cmd`;
144 #Log (" $cmd In [$launchRoot]\n");
145 #update src
146 chdir "$srcCvsRoot/$srcWorkCopyRoot";
147 `$cmd`;
148 Log (" $cmd In [$srcCvsRoot]\n");
149 chdir "$cDir";
150}
151sub CvsTagCommit
152{
153 my $tagDir = $hIni->val ("cvs", "TagDir");
154 my @arr = split /$tagDir/, $srcWorkCopyRoot;
155 my $tDir = "$arr[0]";
156 my $count = sprintf ("%03d", $buildCounter);
157 chomp (my $cDir = `pwd`);
158 chdir "$srcCvsRoot/$tDir";
159
160 my $cmd = "cvs -q tag -F -c $productID-v_$mainVersion" . "_" . $subVersion . "_". "$count" . "-$buildTime" . " $tagDir";
161 `$cmd`;
162 Log (" $cmd In [$tDir]\n");
163 #resume
164 chdir "$cDir";
165}
166sub CreateTmpPublishDir
167{
168 my $project = $_[0];
169 chomp (my $cDir = `pwd`);
170 my $distDir = "$publishRoot/$distEdition";
171 mkdir "$publishRoot" if ! -d "$publishRoot";
172 mkdir "$publishRoot/$distEdition" if ! -d "$publishRoot/$distEdition";
173 #build packet
174 chdir "$distDir" or return 0;
175 if (! -d "$project")
176 {
177 my $cp = "cp -rf $confReposCvsRoot/$confWorkCopyRoot/$project .";
178 my $rmCVS = "find . -name \"CVS\" | xargs rm -rf > /dev/null 2>&1";
179 `$cp`;
180 Log (" $cp In [$distDir]\n");
181 `$rmCVS`;
182 Log (" $rmCVS In [$distDir]\n");
183 }
184 chdir "$cDir";
185 return 1;
186}
187# args : ip, user, passwd, dir, upload-file
188sub FtpUpload
189{
190 my ($IP, $user, $passwd, $rDir, $uploadFile) = @_;
191 my $ftp;
192 my $nRet = 1;
193 if ($ftp = Net::FTP->new ($IP))
194 {
195 if ($ftp->login ("$user", "$passwd"))
196 {
197 $ftp->binary ();
198 foreach my $dir (split /\//, $rDir)
199 {
200 if (! $ftp->cwd ("$dir"))
201 {
202 if (! ($ftp->mkdir ("$dir") and $ftp->cwd ("$dir")))
203 {
204 $nRet = 0;
205 last;
206 }
207 }
208 }
209 if ($nRet == 1)
210 {
211 if ($ftp->put ("$uploadFile"))
212 {
213 Log (" Upload $uploadFile To [$rDir]Success\n");
214 $nRet = 1;
215 }else
216 {
217 Log (" Upload $uploadFile To [$rDir] Failed\n");
218 $nRet = 0;
219 }
220 }else
221 {
222 Log (" Ftp [mkdir] or [cwd] to [$rDir] Failed\n");
223 $nRet = 0;
224 }
225 $ftp->quit ();
226 }else
227 {
228 Log (" Dist FtpServer Login Failed! User : $user PWD: $passwd\n");
229 $nRet = 0;
230 }
231 }else
232 {
233 Log (" Ftp Connect To $IP Failed\n");
234 $nRet = 0;
235 }
236 return $nRet;
237
238}
239sub PublishBuild
240{
241 my $project = $_[0];
242 chomp (my $currDir = `pwd`);
243
244 my $distDir = "$publishRoot/$distEdition";
245 chdir "$distDir";
246 #create build no
247 my $count = sprintf ("%03d", $buildCounter);
248 my $verdir = "v_$mainVersion" . "_". $subVersion . "_". "$count" . "-" . "$buildTime";
249 my $tarname = "$productID" . "-" . "$project" . "-" . "$verdir" . "\.tar\.gz";
250 my $cmd = "tar -czf $tarname $project > /dev/null 2>&1";
251 `$cmd`;
252 Log (" $cmd In [$distDir]\n");
253
254 #upload
255 my $nRet = FtpUpload ($distFtpIP, $distFtpUser, $distFtpPasswd, "$distFtpDir/$verdir", $tarname);
256
257 #resume
258 chdir "$currDir";
259 return $nRet;
260}
261sub main
262{
263 InitBuild ;
264 `alias cp='cp'`;
265 chdir "$launchRoot";
266 #[cvs]
267 my $cvsSvrIP =$hIni->val ("cvs", "CvsSvrIP");
268 my $cvsUser =$hIni->val ("cvs", "CvsUser");
269 my $cvsPasswd =$hIni->val ("cvs", "CvsPasswd");
270 my $cvsRoot =$hIni->val ("cvs", "CvsRoot");
271 #cmd=cvs -d :pserver:cuisw:000000@10.1.150.253:/cvsroot login
272 my $cmd = "cvs -d :pserver:" . $cvsUser . ":" . $cvsPasswd . "@" . $cvsSvrIP . ":/" . $cvsRoot . " login";
273 #check cvs login succ or no
274 my $tmpFile = "1234tmp4321";
275 `$cmd > $tmpFile 2>&1`;
276 open TMP, "$tmpFile";
277 while (<TMP>)
278 {
279 if (/.*failed/s)
280 {
281 Log (" CVS Login Failed, Then Cancel Build\n");
282 close TMP;
283 unlink "$tmpFile";
284 exit 1;
285 }
286 }
287 # cvs login succ
288 close TMP and unlink "$tmpFile";
289
290 LogAndExit (" Not Found Dir: [$srcCvsRoot/$srcWorkCopyRoot] Then Cancel Build\n") if ! -d "$srcCvsRoot/$srcWorkCopyRoot";
291 # check the project newer or no
292 my $today = new Date::Simple;
293 my $yesterday = $today - 1;
294 my $ret = `cvs -q diff --brief -D $yesterday > /dev/null ; echo $?`;
295 LogAndExit (" CVS No Newer Projects, Then Cancel Building\n") if ($ret eq "0");
296
297 #we must update the config-repository if we go-to build project
298 CvsUpdate;
299
300 #current path is working copy root
301 my @projects = split /:/, $hIni->val ("src_path", "Projects");
302 my $project;
303 foreach $project (@projects)
304 {
305 CreateTmpPublishDir ($project) and BuildProject ($project) and PublishBuild ($project);
306 }
307 CvsTagCommit;
308}
309 ################## start to run ########################
310 main;

第一次听说还有这么个名词儿.. 每天构建 ( nightly-build )
写了个脚本..这个是linux下的..window下的和这个差不多..就不贴出来了..
把这个脚本加入到crontab里就可以每天自动构建并上传到指定发布服务器上了..
挺不错的东西..

没有评论: