自动构建环境搭建

因为最近一家公司接触到这些东西,这里总结一下,有些东西没有深入,了解了一下。没有做具体的展开,只做了一个流程整理。有空做一个详细的展开吧。

1 搭建代码管理工具比如git或者svn之类,在构建机上登陆一个账号能够获取需要构建的资源,方便后边在脚本里边自动update

2 针对不同的项目实现相应的更新编译打包脚本,方便后边web服务器调用,个人用vs用的比较多,这里用vs举例。

 第一步:编译

 第一种:用devenv做参数启动进行编译,网上又具体的例子,这个只能编译解决方案,也就是sln后缀的解决方案文件,只要是vs支持的项目都可以编译,比如C#、C++、VB.NET等。具体的项目设置可以预先在解决方案和项目配置中设置好,

       下边为具体的参数。这个devenv的路径可以写死或者直接写到环境变量中

    devenv {/build|/clean|/rebuild|/deploy} SolnConfigName SolutionName[/project ProjName] [/projectconfig ProjConfigName] 
第二种:可以用MSBuild来编译,这个是微软实现的开源编译工具,不过我个人看不大懂代码··这可以用来编译解决方案,也可以用来编译单独的项目:
    在bat脚本中如数下边的代码可以导入MSBuild:
set "str=HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0_Config"
for /f "tokens=2*" %%a in ('reg query "%str%" /v ShellFolder 2^>nul') do set "a=%%b"
set a=%a%VC\vcvarsall.bat

    示例:下边为调用示例

    MSBuild ..\ExercisePrj.sln /t:Rebuild /P:WarningLevel=2;Configuration=Release;Platform=x86;DebugType=none;outdir=..\Release\;ApplicationIcon=..\Release\Resources\test.ico /flp1:errorsonly;logfile=build.err

      上边两种方式都可以生成日志文件,指定生成的目录。

  第二步:打包,把刚才编译生成的结果文件打包成文件就可以了,

  根据不同的打包工具写脚本就可以了,打包就又很多选择了

  1 可以用vs来做打包项目,不过这玩意不好使··以前有用过,用的不多,得益于vs的傻瓜式操作,基本看下提示就知道了,网上也教程的。这个生成的是一个msi安装包和一个exe引导程序。exe没什么用。不是太支持定制化需求

  2 可以用advance,这个功能比较多,支持签名,注册,写注册表等等的操作,有可视化的界面来编辑他自己的项目文件,然后可以直接调用advance主程序做参数启动。可以生成msi或者exe程序

  3 NSIS,网上有通用的脚本,改改就可以了,支持很多操作,包括写注册表、com注册等等的复杂操作,好像只能生成exe。下边是一个ebook的示例,注释很详细了,具体可以改,这个支持卸载覆盖安装注册和写注册表之类的操作。很好很强大

;增加一个包含链接内容的7z压缩包到可执行文件头部,使7-Zip打开看不到其他内容。
!packhdr temp.dat 'cmd /c Copy /B temp.dat /B +轻狂志.7z temp.dat'

; 安装程序初始定义常量
!define PRODUCT_NAME "eBook Workshop"
!define PRODUCT_VERSION "v1.5简体中文增强版"
!define PRODUCT_PUBLISHER "轻狂志"
!define PRODUCT_WEB_SITE "http://www.flighty.cn"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
!define PRODUCT_UNINST_ROOT_KEY "HKLM"

SetCompressor lzma

; ------ MUI 现代界面定义 (1.67 版本以上兼容) ------
!include "MUI.nsh"

; MUI 预定义常量
!define MUI_ABORTWARNING
!define MUI_CUSTOMFUNCTION_GUIINIT onGUIInit
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_RIGHT
!define MUI_HEADERIMAGE_BITMAP "top.bmp"
!define MUI_PAGE_HEADER_TEXT "最终用户许可协议"
!define MUI_PAGE_HEADER_SUBTEXT "您必须接受此协议才能继续安装!"
!define MUI_LICENSEPAGE_TEXT_TOP "要阅读协议的其余部分请按 PgDn键 往下翻页。"
!define MUI_LICENSEPAGE_TEXT_BOTTOM "如果你已经仔细阅读了许可协议,点击 下一步(N) > 继续安装。"
!define MUI_LICENSEPAGE_BUTTON "下一步(&N) >"
!define MUI_ICON "eBook Workshop.ico"
!define MUI_UNICON "eBook Workshop.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "eBook Workshop.bmp"
!define MUI_WELCOMEPAGE_TITLE "\r\n  eBook Workshop v1.5安装向导"
!define MUI_WELCOMEPAGE_TEXT "\r\n    eBook Workshop(E书工场)是将 HTML 页面文件、图片、Flash等捆绑成 EXE 电子文档的制作软件。\r\n\r\n    相比原程序,本安装包主要进行了以下增强:\r\n    1、更换两套更为美观的E书工具栏图标,使用时更改安装目录下的Buttons文件夹即可;2、新增239个图标,分别位于Icon 2、Icon 3、Icon 4 这个3个文件夹内;3、集成了多个精美的E书主题界面,安装即可使用。4、安装过程中可以自动注册软件为正式版本,无任何功能限制。\r\n\r\n    $_CLICK"
!define MUI_FINISHPAGE_RUN_TEXT "运行 eBook Workshop"
!define MUI_FINISHPAGE_SHOWREADME_TEXT "查看 安装说明"

; 欢迎页面
!insertmacro MUI_PAGE_WELCOME
; 许可协议页面
!insertmacro MUI_PAGE_LICENSE "许可协议.rtf"
; 组件选择页面
!insertmacro MUI_PAGE_COMPONENTS
; 安装目录选择页面
!insertmacro MUI_PAGE_DIRECTORY
; 安装过程页面
!insertmacro MUI_PAGE_INSTFILES
; 安装完成页面
!define MUI_FINISHPAGE_RUN "$INSTDIR\MAKER.exe"
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\说明.txt"
!insertmacro MUI_PAGE_FINISH

; 安装卸载过程页面
!insertmacro MUI_UNPAGE_INSTFILES

; 安装界面包含的语言设置
!insertmacro MUI_LANGUAGE "SimpChinese"

; 安装预释放文件
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
; ------ MUI 现代界面定义结束 ------

Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "Setup.exe"
InstallDir "$PROGRAMFILES\eBook Workshop"
;读取注册中的键值,如果没有,就按默认路径。
InstallDirRegKey HKCU "Software\eBook Workshop" ""
ShowInstDetails show
ShowUnInstDetails show
BrandingText "轻狂志www.flighty.cn"

Section "主程序" SEC01
  SectionIn RO
  SetOutPath "$INSTDIR"
  SetOverwrite ifnewer
  File /r "eBook Workshop\主程序\*.*"
  CreateDirectory "$SMPROGRAMS\eBook Workshop"
  CreateShortCut "$SMPROGRAMS\eBook Workshop\eBook Workshop.lnk" "$INSTDIR\MAKER.exe"
  CreateShortCut "$DESKTOP\eBook Workshop.lnk" "$INSTDIR\MAKER.exe"
SectionEnd

Section "主题风格" SEC02
  SetOutPath "$INSTDIR\Themes"
  File /r "eBook Workshop\Themes\*.*"
SectionEnd

Section "按钮图标" SEC03
  SetOutPath "$INSTDIR"
  File /r "eBook Workshop\按钮图标\*.*"
SectionEnd

Section -AdditionalIcons
  WriteIniStr "$INSTDIR\轻狂志.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
  CreateShortCut "$SMPROGRAMS\eBook Workshop\轻狂志.lnk" "$INSTDIR\轻狂志.url"
  CreateShortCut "$SMPROGRAMS\eBook Workshop\卸载程序.lnk" "$INSTDIR\uninst.exe"
SectionEnd

Section -Post
  WriteUninstaller "$INSTDIR\uninst.exe"
  WriteRegStr HKCU "Software\eBook Workshop" "" $INSTDIR
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"

    WriteRegStr HKCU "Software\Ada99\eBook Workshop" "AdaName" "QVNXb3Jk"
    WriteRegStr HKCU "Software\Ada99\eBook Workshop" "AdaKey" "NzE5RkJGNzEtMzUzQjQzNDQtQjcwQ0IxQTk="
    WriteRegDWORD HKCU "Software\Ada99\eBook Workshop" "Language" 0x000003a8
SectionEnd

#-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--#

; 区段组件描述
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
  !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "将 HTML 页面文件、图片、Flash等捆绑成 EXE 电子文档的制作软件。"
  !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "多个精美的E书主题界面,安装即可使用。"
  !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "二百多个图标,分别位于Icon 2、Icon 3、Icon 4 这个3个文件夹内。"
!insertmacro MUI_FUNCTION_DESCRIPTION_END

/******************************
 *  以下是安装程序的卸载部分  *
 ******************************/

Section Uninstall
  Delete "$INSTDIR\*.*"

  Delete "$SMPROGRAMS\eBook Workshop\*.lnk"
  Delete "$DESKTOP\eBook Workshop.lnk"

  RMDir "$SMPROGRAMS\eBook Workshop"

  RMDir /r "$INSTDIR\Themes\银色苹果"
  RMDir /r "$INSTDIR\Themes\新奇前卫"
  RMDir /r "$INSTDIR\Themes\前卫幻想深绿色"
  RMDir /r "$INSTDIR\Themes\前卫幻想绿色"
  RMDir /r "$INSTDIR\Themes\前卫幻想蓝色"
  RMDir /r "$INSTDIR\Themes\灵界军团"
  RMDir /r "$INSTDIR\Themes\蓝色妖姬v2005"
  RMDir /r "$INSTDIR\Themes\蓝色妖姬"
  RMDir /r "$INSTDIR\Themes\蓝色心情"
  RMDir /r "$INSTDIR\Themes\金属时代"
  RMDir /r "$INSTDIR\Themes\简约之美"
  RMDir /r "$INSTDIR\Themes\黄色之旅"
  RMDir /r "$INSTDIR\Themes\黄昏幻想"
  RMDir /r "$INSTDIR\Themes\海洋之心v2005"
  RMDir /r "$INSTDIR\Themes\海洋之心"
  RMDir /r "$INSTDIR\Themes\古色古香"
  RMDir /r "$INSTDIR\Themes\半成卷轴"
  RMDir /r "$INSTDIR\Themes\Wood"
  RMDir /r "$INSTDIR\Themes\WinXP"
  RMDir /r "$INSTDIR\Themes\Water"
  RMDir /r "$INSTDIR\Themes\ThemeXP"
  RMDir /r "$INSTDIR\Themes\POPO2004_3"
  RMDir /r "$INSTDIR\Themes\POPO2004_2"
  RMDir /r "$INSTDIR\Themes\POPO2004"
  RMDir /r "$INSTDIR\Themes\Ocean"
  RMDir /r "$INSTDIR\Themes\Notepad"
  RMDir /r "$INSTDIR\Themes\New-Royale"
  RMDir /r "$INSTDIR\Themes\New-PantherS"
  RMDir /r "$INSTDIR\Themes\New-Mento"
  RMDir /r "$INSTDIR\Themes\New-Element"
  RMDir /r "$INSTDIR\Themes\New-Dogmax"
  RMDir /r "$INSTDIR\Themes\Mustang"
  RMDir /r "$INSTDIR\Themes\Metal"
  RMDir /r "$INSTDIR\Themes\MacOSX"
  RMDir /r "$INSTDIR\Themes\Love"
  RMDir /r "$INSTDIR\Themes\G-star"
  RMDir /r "$INSTDIR\Themes\GreenWinXP"
  RMDir /r "$INSTDIR\Themes\ExoBUD MP"
  RMDir /r "$INSTDIR\Themes\BlueWinXP"
  RMDir /r "$INSTDIR\Themes\BlueLove"
  RMDir /r "$INSTDIR\Themes\Apple"
  RMDir /r "$INSTDIR\LANGUAGE"
  RMDir /r "$INSTDIR\Buttons"
  RMDir /r "$INSTDIR\Buttons 2"
  RMDir /r "$INSTDIR\Icon"
  RMDir /r "$INSTDIR\Icon 4"
  RMDir /r "$INSTDIR\Icon 3"
  RMDir /r "$INSTDIR\Icon 2"
  
  RMDir "$INSTDIR\Themes"

  RMDir "$INSTDIR"
  
  ;卸载注册表中的软件注册键值
  DeleteRegKey /ifempty HKCU "Software\Ada99\eBook Workshop"
  ;卸载注册表中安装路径的键值
  DeleteRegKey /ifempty HKCU "Software\eBook Workshop"
  DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  SetAutoClose true
SectionEnd

#-- 根据 NSIS 脚本编辑规则,所有 Function 区段必须放置在 Section 区段之后编写,以避免安装程序出现未可预知的问题。--#

Function onGUIInit
   BrandingURL::Set /NOUNLOAD "200" "0" "0" "http://www.flighty.cn"
FunctionEnd

Function .onGUIEnd
BrandingURL::Unload
FunctionEnd

Function un.onInit
  MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "您确实要完全移除 $(^Name) ,及其所有的组件?" IDYES +2
  Abort
FunctionEnd

Function un.onUninstSuccess
  HideWindow
  MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除。"
FunctionEnd

     这里有几个问题:

  1》 定制需求:因为公司的产品会有标准本以及定制UI的定制需求,比如替换一些资源文件之类的,这些可以通过bat脚本来复制后替换,然后打包

  2》版本控制: 以上边的vs项目举例子,vs生成的dll和exe文件版本号可以通过AssemblyInfo来设置的,设置一些公司信息和版本号,也支持签名。这个如果用手动改的话就比较麻烦了没法做到自动化,因为这个文件的格式是已知的,所以可以写一个小程序每次动态的修改这个文件来控制编译,这样编译出来的文件就带相应的信息了。可以把定制的公司信息也通过svn来管理然后拷贝过来直接编译。至于版本号可以获取svn或者git的版本号来作为版本号。至于签名文件我没试过在vs中使用,可以尝试

  上边是编译的时候修改,这样有点麻烦,或者局限,还有一种是生成以后修改生成的exe程序,这样听起来有点想黑客一样,因为理论上编译以后的文件应该不能修改,有一个工具可以修改windows下的可执行文件的相关资源信息,百度下resource hacker,可以修改exe的相关信息,比如公司或者版本号。签名可以用微软官方提供的SignTool.exe程序。需要准备好证书文件。

      打包以后的文件可以拷贝的一个指定的目录。方便后边下载使用。

3  编译和打包脚本弄好,需要一个简单的web服务端来调用,同时控制脚本的执行,因为本人没有web开发的经验,这里用asp.net mvc写一个简单的页面,简单的实现下。在一个指定目录下获取所有bat脚本,然后显示到web页就行了。

 这里用了一个静态变量来缓存当前执行的任务,实际应该用一个简单的数据库来缓存,这样可以在web页查询执行的状态。这里可以随便用什么实现一个简单的web服务端就行了比如python或者java都行。

        const string root = @"E:\bats\";
        static List<string> TaskList = new List<string>();
        private static object lockobj = new object();
        public IActionResult BatList()
        {
            ViewData["Message"] = "Bat List page.";
            var dir = new DirectoryInfo(root);
            var bats = dir.EnumerateFiles("*.bat").Select(f=>f.Name).AsEnumerable() ;
            ViewData["Bats"] = bats;  
            return View();
        }
        [Produces("application/text")]
        [HttpPost]
        public IActionResult DoBat(string file)
        {
            var msg = $"{DateTime.Now.ToString()}:{file}";
            var fullpath = root + file;
            if(TaskList.Contains(fullpath))
                return new JsonResult($"{DateTime.Now.ToString()}:{file} allready run");

            ProcessStartInfo startInfo = new ProcessStartInfo(fullpath);
            startInfo.WindowStyle = ProcessWindowStyle.Normal;
            startInfo.CreateNoWindow = true;
            startInfo.UseShellExecute = true;
            var pro= Process.Start(startInfo);
            lock(lockobj)
            {
                TaskList.Add(fullpath);
            }
   
            pro.Exited += Pro_Exited;
            Log(msg);
            return new JsonResult(msg);
        }

        private void Pro_Exited(object sender, EventArgs e)
        {
            var pro = sender as Process;
            var task = pro.StartInfo.FileName;
            Remove(task);
        }

        void Log(string msg)
        {
            using (StreamWriter sw = new StreamWriter(root + "log.txt",true))
            {
                sw.WriteLine(msg);
            }
        }
        void Remove(string task)
        {
            lock (lockobj)
            {
                if (TaskList.Contains(task))
                    TaskList.Remove(task);
            }

        }

 cshtml文件主要代码如下:

@{

    var list = ViewData["Bats"] as IEnumerable<string>;
    foreach (var f in list)
    {
        <a  href="#" onclick="getInfo('@(f)')">@f</a>
        <br />

    }
}

链接的执行方法写的比较别扭,勉强能用吧:

function getInfo(file) {
    $.ajax({
        url: '/home/DoBat?file='+file,
        type: 'POST',
        data: JSON.stringify({file:file}),
        contentType: 'application/json;charset=UTF-8',
        datatype:"json",
        success: function (result) {
            alert(result);
        }
    })
}

 

4  web服务端弄好了,可以在局域网内访问,进行打包服务,下边需要一个下载安装包的途径,这里推荐两个方式:

  第一个搭一个ftp服务器,windows下可以直接用iis搭一个ftp服务器,很方便,吧生成安装包的目录挂上ftp就行了。

  或者http的文件服务器。比如hfs,很简单,可以直接指定目录,这玩意不稳定,死机了重启就好了。

到这自动构建的环境就完成。

 

除此之外:

   还需要的环境,下边的没什么研究,

   1 审批平台,svn或者git的审批平台,用来做代码review的。有一个开源的工具,这个暂时没研究

   2 测试平台,就用禅道就可以了,凑合使了, 

   3 wiki,文档之类的资源共享平台。


posted @ 2018-05-10 16:14  季末的寂寞  阅读(422)  评论(0编辑  收藏  举报