惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Latest news
Latest news
T
Troy Hunt's Blog
V
Vulnerabilities – Threatpost
L
LINUX DO - 热门话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
V
V2EX
博客园 - 司徒正美
B
Blog RSS Feed
AWS News Blog
AWS News Blog
MyScale Blog
MyScale Blog
Scott Helme
Scott Helme
Cisco Talos Blog
Cisco Talos Blog
Last Week in AI
Last Week in AI
NISL@THU
NISL@THU
博客园 - Franky
P
Proofpoint News Feed
博客园_首页
C
CERT Recently Published Vulnerability Notes
雷峰网
雷峰网
S
Schneier on Security
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
G
GRAHAM CLULEY
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
WordPress大学
WordPress大学
The Hacker News
The Hacker News
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
A
Arctic Wolf
Microsoft Azure Blog
Microsoft Azure Blog
T
The Exploit Database - CXSecurity.com
Engineering at Meta
Engineering at Meta
罗磊的独立博客
T
The Blog of Author Tim Ferriss
D
Darknet – Hacking Tools, Hacker News & Cyber Security
I
Intezer
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
K
Kaspersky official blog
SecWiki News
SecWiki News
云风的 BLOG
云风的 BLOG
美团技术团队
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 【当耐特】
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
C
Cyber Attacks, Cyber Crime and Cyber Security
B
Blog
S
Security Affairs

博客园 - 观无明

IE9 + django开发版WEB服务器 不响应或Socket报错 google chrome 下django用户登录失败的问题 django 开发多语言网站 不愁男女比例不协调 Word文件如源码一样也可比较和合并 python 的字符编码和中文处理 - 观无明 - 博客园 djang 测试心得 my django development environment (virtualenv+pip+django) nginx+fastcgi+django实践笔记 django 开发 - 小心模板文件的编码格式(utf-8) 汉王电子书D20使用笔记 使用south实现Django的数据库升级迁移 VIM 笔记 (for python ) 在Windows上使用Linux命令 cygwin 仍有人在真心关注这灾难 CruiseControl中应用NCover和NCoverExplore CruiseControl中使用NUnit中测试WEB服务 Resharper封装(Encapsulate)域Field为属性Property的命名问题 数据库开发的持续集成 - Liquibase的简介和应用
数据库开发的持续集成 - CruiseControl.Net的项目配置
观无明 · 2008-06-25 · via 博客园 - 观无明

本系列文章目录
    数据库开发的持续集成 - Sql Server 部署升级工具
    数据库开发的持续集成 - Sql Server数据库结构比较
    数据库开发的持续集成 - 方法和流程
    数据库开发的持续集成 - Liquibase的简介和应用
    数据库的持续集成 - CruiseControl.Net的项目配置

继续数据库的持续集成-方法和流程, 下面来说一下如何配置

CruiseControl.Net的项目。

流程和配置详解
CC项目包括Trunk项目和Studio项目,由于Studio项目相对简单,下面只详解Trunk项目。
先回顾一下流程:

该流程直接操作基线数据库,需要使用脚本(ChangLog)升级基线数据库,然后在其上做测试等等工作。其中主要步骤详解如下:
* 首先用CCNetLabel给基线数据库打Tag(ci.proj中Tag属性缺省值为$(CCNetLabel)),为的是集成失败时将基线数据库回滚到集成之前的状态
* 之于其他工作前编译解决方案,是为了能够尽早发现编译错误
* 使用liquibase执行数据库部署脚本root.changelog.xml后,基线数据结构就能用于后续测试了

这样的流程,有几个好处:
* 由于基线数据和已发布出去的产品数据库结构相同,直接操作基线数据库可以保证即将发布的实体类、访问层和数据库升级脚本可用于平滑升级现有产品数据库和系统
* 集成失败的数据库回滚可保证失败的集成不在基线数据库中留下垃圾
* 在SVN上打Tag,可方便开发人员回溯系统发布历史上的任何一个时间点,可满足对产品系统打补丁的需求

关键点
 1 数据库回滚 TagRollbackCC   该任务放在CC项目的

publishers节中,保证无论集成成功还是失败都能执行到
   其执行的条件是持续集成失败 Condition="$(CCNetIntegrationStatus) != 'Success'"

    <!-- 按标记回滚(for CC.Net) -->
    
<Target Name="TagRollbackCC" Condition="$(CCNetIntegrationStatus) != 'Success'">
    
<Exec Command="$(LiquiBase) $(ConnectionParam) $(ChangeLogParam) rollback $(Tag) > $(ExecLog)" ContinueOnError="false"/> 
    
<CallTarget Targets="CheckExec"/>

    
</Target>    


 2 保证同一份测试代码在本地,CC上的Studio项目和Trunk项目都能应用  需要满足的条件包括:
  * 测试代码在Studio项目中使用测试数据库GTCATest,在本地和Trunk中使用GTCA(本地数据库和基线数据同名,方便结构比较)
  * 测试代码在Trunk项目中不能修改数据库结构,否则将破坏基线数据库的状态

  解决的方案:
  * 测试代码中通过预编译指令CC_Studio,CC_Trunk区分三种场景
  * 要保证测试在不通场景使用不用的数据库,就不能把数据连接配置放在测试项目的app.config中,使用

InPlaceConfigurationSource替代

            Dictionary<stringstring> properties = new Dictionary<stringstring>();

            properties.Add(
"connection.driver_class""NHibernate.Driver.SqlClientDriver");
            properties.Add(
"dialect""NHibernate.Dialect.MsSql2000Dialect");
            properties.Add(
"connection.provider""NHibernate.Connection.DriverConnectionProvider");

#if CC_STUDIO
            
/* CC 上的Studio编译,对GTCATest数据进行测试 */
            properties.Add(
"hibernate.connection.connection_string""Data Source=.;Initial Catalog=GTCATest;Integrated Security=SSPI");
#else
            
/* 本地编译和CC 上的Trunk编译,对GTCA数据进行测试 */
            properties.Add(
"connection.connection_string""Data Source=.;Initial Catalog=GTCA;Integrated Security=SSPI");
#endif
            InPlaceConfigurationSource source 
= new InPlaceConfigurationSource();
            source.Add(
typeof (ActiveRecordBase), properties);
            ActiveRecordStarter.Initialize(Assembly.Load(
"GTCA.Entities"), source);

  * 对于CreateSchem/UpdateSchema/DropSchema等函数提供统一的工具类给开发人员使用

        public static void PrepareSchema()
        
{
#if !CC_TRUNK
            
/* 只有非CC上的Trunk编译,才允许对数据库结构发生变化*/
            ActiveRecordStarter.UpdateSchema();
#endif
        }


        
public static void DropSchema()
        
{
#if !CC_TRUNK
            
/* 只有非CC上的Trunk编译,才允许对数据库结构发生变化*/
            ActiveRecordStarter.DropSchema();
#endif
        }


CC项目配置

<project name="Database-trunk" webURL="http://192.168.1.44/ccnet/server/local/project/Database-trunk/ViewProjectReport.aspx" >
    
<workingDirectory>D:\GTCA\Database\trunk</workingDirectory>
    
<artifactDirectory>D:\GTCA\Database\trunk</artifactDirectory>
    
<category>GTCA</category>

    
<labeller type="taoLabeller">
         
<majorVersion>1</majorVersion>
         
<minorVersion>0</minorVersion>
    
</labeller>
    
    
<triggers/>
    
<sourcecontrol type="filtered">
        
<sourceControlProvider type="svn" autoGetSource="true" tagOnSuccess="true">
            
<trunkUrl>svn://192.168.1.4/Database/trunk</trunkUrl>
            
<workingDirectory>D:\GTCA\Database\trunk</workingDirectory>
            
<tagBaseUrl>svn://192.168.1.4/Database/tags</tagBaseUrl>
        
</sourceControlProvider>
        
<inclusionFilters>
            
<userFilter>
                
<names><name>zt</name></names>
            
</userFilter>
        
</inclusionFilters>
        
<exclusionFilters>
            
<pathFilter><pattern>/**/test/**</pattern></pathFilter>
            
<pathFilter><pattern>/**/document/**</pattern></pathFilter>
        
</exclusionFilters>        
    
</sourcecontrol>
    
    
<prebuild>
        
<!--tag GTCA with CCNetLabel-->
        
<msbuild>
            
<workingDirectory>D:\GTCA\Database\trunk\deploy</workingDirectory>
            
<projectFile>ci.proj</projectFile>
            
<buildArgs>/noconsolelogger /t:tag </buildArgs>
            
<logger>D:\GTCA\reference\libs\MSBuild\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        
</msbuild>
    
</prebuild>
    
    
<tasks>
        
<!-- build source -->
        
<msbuild>
            
<workingDirectory>D:\GTCA\Database\trunk</workingDirectory>
            
<projectFile>Database.sln</projectFile>
            
<buildArgs>/noconsolelogger /t:rebuild /p:configuration=release /p:DefineConstants=CC_TRUNK</buildArgs>
            
<logger>D:\GTCA\reference\libs\MSBuild\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        
</msbuild>
    
        
<!-- deploy GTCA -->
        
<msbuild>
            
<workingDirectory>D:\GTCA\Database\trunk\deploy</workingDirectory>
            
<projectFile>ci.proj</projectFile>
            
<buildArgs>/noconsolelogger /t:deploy </buildArgs>
            
<logger>D:\GTCA\reference\libs\MSBuild\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        
</msbuild>    
        
        
<!-- test entities and DAL on GTCA -->
        
<nunit>
            
<path>D:\GTCA\reference\tools\nunit\nunit-console.exe</path>
            
<assemblies>
                
<assembly>D:\GTCA\Database\trunk\test\TestEntities\bin\Release\TestEntities.dll</assembly>
            
</assemblies>
        
</nunit>    
        
<nunit>
            
<path>D:\GTCA\reference\tools\nunit\nunit-console.exe</path>
            
<assemblies>
                
<assembly>D:\GTCA\Database\trunk\test\TestDal\bin\Release\TestDal.dll</assembly>
            
</assemblies>
        
</nunit>    
        
        
<!-- generate database document on GTCA-->
        
<msbuild>
            
<workingDirectory>D:\GTCA\Database\trunk\deploy</workingDirectory>
            
<projectFile>ci.proj</projectFile>
            
<buildArgs>/noconsolelogger /t:doc /p:DocDir=D:\dbdoc</buildArgs>
            
<logger>D:\GTCA\reference\libs\MSBuild\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        
</msbuild>            
        
        
<!--publish GTCA -->
        
<msbuild>
            
<workingDirectory>D:\GTCA\Database\trunk\deploy</workingDirectory>
            
<projectFile>ci.proj</projectFile>
            
<buildArgs>/noconsolelogger /t:publish</buildArgs>
            
<logger>D:\GTCA\reference\libs\MSBuild\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        
</msbuild>    
    
</tasks>
    
<publishers>
        
<xmllogger />
        
<modificationHistory  onlyLogWhenChangesFound="true" />
        
<!-- tagrollback on error( if CCNetIntegrationStatus isn't Success) -->
        
<msbuild>
            
<workingDirectory>D:\GTCA\Database\trunk\deploy</workingDirectory>
            
<projectFile>ci.proj</projectFile>
            
<buildArgs>/noconsolelogger /t:TagRollbackCC</buildArgs>
            
<logger>D:\GTCA\reference\libs\MSBuild\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
        
</msbuild>            
    
</publishers>
    
<externalLinks>
        
<externalLink name="Database Document" url="http://192.168.1.44/dbdoc/" />
    
</externalLinks>    
</project>    

这个系列到此告一段落,回顾整个探索过程,曾经满世界的寻找数据库比较和同步的工具,自己也写过升级部署工具。直到liquibase进入视野,给了我足够的支撑,这才能够气定神闲的设计和丰满流程和方法,并将其转为实现。

衷心感谢liquibase的贡献者提供了如此出色的工具。