持续集成方案

大纲

  1. 构建

  2. 版本控制
  3. 部署
  4. 单元测试
  5. 架构文档化
  6. 命名约定
  7. 数据库伸缩性
  8. 自动化
  9. 反馈
  10. 实践
引言:
持续集成的前身:

在使用持续集成之前,很多开发团队都是用每日构建(nightly build)。当时,微软使用这个实践很多年了。谁破坏了构建,就要负责监视后续的构建构成,直至发现下一个破坏了构建的人。

为什么要使用持续集成?
    对于大多数项目来说,采纳持续集成实践是向高效率和高质量迈进的一大步。它保证那些创建大型复杂系统的团队具有高度的自信心和控制力。一旦代码提交引入了问题,持续集成就能为我们提供快速的反馈,从而确保我们作为一个团队所开发的软件是可以工作的。
    持续集成的主要关注对象是开发团队。持续集成系统的输出通常作为手工测试流程和后续发布流程的输入。在软件的发布过程中,很多浪费来自于测试和运维环节。
    例如:我们常常看到:
  • 构建和运维团队的人员一直在等待说明文档或缺陷修复

  • 测试人员等待"好的"版本构建出来
  • 在新功能开发完成一段时间后,才收到缺陷报告
  • 开发完成时,才发现当前的软件架构无法满足该系统的一些非功能需求
持续集成的一些实践:

采取一种更完整的端到端的方法来交付软件。我们通过一键式方式把软件的某个版本部署好,甚至可以将其一键式部署到生成环境中,这样就可以建立了一个非常有效的反馈环--由于很容易将应用程序部署到测试环境中,所以团队可以同时得到软件功能和部署流程两个方面的快速反馈。因为部署流程(无论是测试,集成)都是自动化的,所以可以频繁且有规律的运行并被测试,从而降低发布风险,也降低了向开发团队传递有关部署流程的知识时的风险。

从精益的角度来看,我们实现了一个"拉式系统",测试团队只要自己单击按钮,就能轻松部署。管理人员也能容易得到一些关键的度量指标,比如周期时间,吞吐量以及代码质量。

持续集成主要内容包括:
  • 将软件构建、集成、测试和部署全面实现自动化

  • 在团队和组织级别实现部署流水线
  • 改进开发人元、测试人员和运维人员间的协作
  • 在大型分布式团队中增量并发开发软件功能
  • 实施高效的配置管理策略
  • 分析并实现自动化验收测试
  • 容量测试和其他非功能需求的测试
  • 实现持续部署和零停机发布
  • 管理基础设施、数据、组件和依赖
  • 风险管理、符合度和审计
一.构建

什么是构建
在现代软件学中,可能经常听到CMMI,ISO(大型团队)、中小型团队(敏捷开发、XP编程)

构建工具:MSBuild、Maven、Ant、NAnt、Gradle

Unit是整个金字塔的基石(在建筑行业,基石是做建筑物基础的石头),如果基石不稳,Service和UI何谈有构建意义呢?只有基石稳如磐石,上层建筑才够坚固。
本来想拿瑞士做钟表的例子来说明下,但同事说的汽车例子更好。一辆汽车由许多配件组成,如果有以下两种选择,你会选择哪个呢?

1. 所有单元配件没有测试过,在4S店,销售人员告诉你:刚组装好,已经开了一天,能跑起来,你可以试试;
2. 所有单元配件在生产过程已经经过严格测试,在4S点,销售人员告诉你,已经通过国家认证,出厂合格,有质量保证,你可以试试;

MSBuild 是 Microsoft 和 Visual Studio的生成系统。它不仅仅是一个构造工具,应该称之为拥有相当强大扩展能力的自动化平台。MSBuild平台的主要涉及到三部分:执行引擎、构造工程、任务。其中最核心的就是执行引擎,它包括定义构造工程的规范,解释构造工程,执行“构造动作”;构造工程是用来描述构造任务的,大多数情况下我们使用MSBuild就是遵循规范,编写一个构造工程;MSBuild引擎执行的每一个“构造动作”就是通过任务实现的,任务就是MSBuild的扩展机制,通过编写新的任务就能够不断扩充MSBuild的执行能力。所以这三部分分别代表了引擎、脚本和扩展能力。
MSBuild的简单介绍与使用

二.版本控制

配置管理:使用版本控制
版本控制系统(源代码控制管理系统)是保存文件多个版本的一种机制。一般来说,包括Subversion、Git在内的开源工具就可以满足绝大多数团队的需求。所有的版本控制系统都需要解决这样一个基础问题: 怎样让系统允许用户共享信息,而不会让他们因意外而互相干扰?
如果没有版本控制工具的协助,在开发中我们经常会遇到下面的一些问题:
一、 代码管理混乱。
二、 解决代码冲突困难。
三、 在代码整合期间引入深层BUG。
四、 无法对代码的拥有者进行权限控制。
五、 项目不同版本发布困难。

对所有内容都进行版本控制

版本控制不仅仅针对源代码,每个与所开发的软件相关的产物都应该被置于版本控制下,应当包括:源代码、测试代码、数据库脚本、构建和部署脚本、文档、web容器(tomcat的配置)所用的配置文件等。

保证频繁提交可靠代码到主干

频繁提交可靠、有质量保证的代码(编译通过是最基本要求),能够轻松回滚到最近可靠的版本,代码提交之后能够触发持续集成构建,及时得到反馈。

提交有意义的注释

强制要求团队成员使用有意义注释,甚至可以关联相关开发任务的原因是。当构建失败后,你知道是谁破坏了构建,找到可能的原因及定位缺陷位置。这些附加信息,可以缩短我们修复缺陷的时间。示例:团队使用了svn和redmine。

有可以加强的部分

  • Git要求每次提交都必须写提交说明,可以借鉴

  • 测试代码、数据库脚本单独分支
  • 构建脚本化
三.部署
3.1 最基本的部署流水线


这个流程的起点是开发人员向版本控制库提交代码。此时,持续集成系统对这次提交做出响应,触发该流水线的一个实例。
第一个阶段会编译代码,运行单元测试,执行代码分析,创建软件二进制包。如果所有的单元测试都通过了,并且代码符合编码标准,就将可执行代码打包成可执行文件,并放到一个制品库里中。有些在提交而极端,还会执行另外一些任务,比如为验收测试准备数据库。
第二个阶段由运行时间较长的自动化验收测试组成。所以持续集成服务器最好支持将测试分成多组的做法,以便在构建网络中并行执行任务,提高执行效率。这个阶段在第一个阶段完成后自动触发的。
部署流水线可能有分支出现,这样就可以将该构建版本独立部署到多个不同的环境中,比如部署到用户验收环境、容量测试环境和生成环境。这时,部署到相应的环境,就需要用到自动化部署脚本来执行这种部署过程。测试人员应当能看到需要测试的所有构建版本,以及他们的状态。
目的:最快的得到反馈

3.2部署流水线的相关实践
  • 只生成一次二进制包
    我们将所有可执行代码的集合称作二进制包,例如.NET程序集。有时候代码不需要编译,那么这种情况下,二进制是所有文件的集合。一种相关的反模式就是一直使用源代码而不是二进制包。因此,每次讲一个修改部署时,需要自己亲自从发布分支迁出源代码并重新编译二进制包。同时,还可能因编译器和某个依赖的不同版本产生差异。

部署的可视化

四.单元测试(TDD)

测试分类:

BDD,TDD,ATDD
BDD主要是基于场景、面向需求的,ATDD面向验收的,这里不做过多介绍了。
这里主要介绍TDD的一些开发

什么是TDD?

测试驱动开发

TDD的优点
TDD从一开就保证了代码的质量:鼓励开发人员只开发”最小化“的代码完成特定测试功能。
遵循SOLID原则: SOLID (单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)
TDD确保了代码与业务需求之间的高度一致性。
TDD鼓励创建更简单,针对性更强的API
TDD鼓励更多的沟通,与企业,与团队内部。
TDD有助于清除冗余代码
TDD提供了内置的回归测试。

如果没有单元测试来帮助查找和诊断缺陷时,大多数开发人员会使用调试器,在他们认为出现缺陷的地方设置断点,有时将这种方法称为"散弹枪方法"。

单元测试的特征:

  • 与其他代码隔离

  • 有针对性
  • 与其他开发人员隔离
  • 可重复
  • 可预测
自动化单元测试原则:

提交代码、运行测试的重点是什么?快速捕获那些因修改向系统中引入的最常见错误,并通知开发人员,以便他们能快速修复他们。提交阶段提供反馈的价值在于,对它的投入可以让系统高效且更快地工作。

  • 隔离UI操作
    UI应当作为更高层次的测试Level,需要花费大量时间准备数据,业务逻辑复杂,过早进入UI阶段,容易分散开发的单元测试精力。

  • 隔离数据库以及文件读写网络开销等操作
    自动化测试中如果需要将结果写入数据库,然后再验证改结果是否被正确写入,这种验证方法简单、容易理解,但是它不是一个高效的方法。这个应当从集成测试的Level去解决。
    首先:与数据库的交互,是漫长的,甚至有可能要投入维护数据库的时间,那将成为快速测试的一个障碍,开发人员不能得到及时有效的反馈。假设,我需要花费一个小时,才能验证完毕与数据库交互的结果,这种等待是多么漫长呀。
    其次,数据管理需要成本,从数据的筛选(线上数据可能是T级)到测试环境的M级别,如何把筛选合适的大小,这都使得管理成本增加(当然在集成测试中可以使用DBUnit来解决部分问题)。
    最后,如果一定要有读写操作才能完成的测试,也要反思代码的可测试性做的如何?是否需要重构。
    单元测试决不要依赖于数据库以及文件系统、网络开销等一切外部依赖。
  • 使用隔离框架和依赖框架
    可以使用模拟工具集:Rhino.Mock、Moq、Type Mock等来解决,研发团队主要是基于Mockito的实践。与需要组装所有的依赖和状态相比,使用模拟技术的测试运行起来通常是非常快,这样子开发人员在提交代码之后,可以在持续集成平台快速得到反馈。
实践

常规
一个加密、解密方法的测试

[Test]
        [Ignore("这个测试有问题!")]
        public void TestEncrypt()
        {
            FileEncrypt fileEncrypt = new FileEncrypt();
            String ii = fileEncrypt.EncryptContext("Hello World", "123");

            ii = fileEncrypt.DecryptContext(ii, "123");
            Assert.Pass(ii);
        }

Ignore标志的方法,当我们运行测试实例时,可以忽略

Category

可以只运行指定目录的测试用例
Rhino.Mocks的简单实用

[Test]
        [Category("模拟对象")]
        public void TestCustomer()
        {
            MockRepository mocks = new MockRepository();
            ICustomer customer = mocks.StrictMock<ICustomer>();

            customer.Expect(c => c.ShowTitle("")).Return("567");
            Expect.Call(customer.Pid).Return(30);
            customer.Replay();

            Assert.AreEqual(customer.ShowTitle(""), "567");
        }

        [Test]
        public void SayHelloWorld()
        {
            MockRepository mocks = new MockRepository();
            INameSource nameSource = mocks.DynamicMock<INameSource>();

            Expect.Call(nameSource.CreateName(null, null))
                  .IgnoreArguments()
                  .Do(new NameSourceDelegate(Formal));

            mocks.ReplayAll();
            const string expected = "Hi, my name is Ayende Rahien";
            string actual = new Speaker("Bright", "Gong", nameSource).Introduce();
            Assert.AreEqual(expected, actual);
        }
        delegate string NameSourceDelegate(string first, string surname);

        public class Speaker
        {
            private readonly string _firstName;
            private readonly string _surname;
            private readonly INameSource _nameSource;

            public Speaker(string firstName, string surname, INameSource nameSource)
            {
                this._firstName = firstName;
                this._surname = surname;
                this._nameSource = nameSource;
            }

            public string Introduce()
            {
                string name = _nameSource.CreateName(_firstName, _surname);
                return string.Format("Hi, my name is {0}", name);
            }
        }
红灯、绿灯、重构

"红灯、绿灯、重构"明确了开发人员在实施TDD时所要遵循的工作流。

  • 红灯阶段
    在开始使用TDD时,许多开发人员会问:"我怎么能为不存在的代码编写测试呢?"事实上,许多测试都是针对当期不存在的类或方法的。这意味着这些测试甚至不能编译通过,其效果基本上与失败测试相同。这没问题,记住,这是因为有了这些测试,才需要有相应的代码存在。
    红灯阶段,主要是编写一个会测试失败的代码,
    比如

    [Category("simple")]
      [Test]
      public bool MyMEthod(int inputParameter)
      {
          throw new NotImplementedException();
      }
  • 绿灯阶段
    仅编写适量的代码,是新测试通过而不导致任何测试失败。

    [Category("simple")]
      [Test]
      public bool MyMEthod(int inputParameter)
      {
          return false;
      }

    有些人觉得是不是代码太少了,至少需要明白说什么,至少像

    [Category("simple")]
    [Test]
    public bool MyMEthod(int inputParameter)
    {
      if(inputParameter=60)
      {
          return false;
      }
      return true;
    }

    其实不然,返回false是我们的期望,我们希望在输入60的时候,返回false,明显只要返回false就足够了。后面增加的测试会让我们扩展方法。原则是,不要向代码引入不必要的复杂度。

  • 重构阶段:
    给我们的代码添砖加瓦,使代码具有可维护性、可读性或整体代码质量。
    重构示例
    我们用一个闯三关的游戏来简单介绍
    规则:胜方标记X或O,没有玩家获胜,则返回空字符
    我们创建了一个测试方法
    如下图
    private IGameWinnerService _gameWinnerService;
      private char[,] _gameBoard;
    
      [SetUp]
      public void SetupUnitTests()
      {
          _gameWinnerService = new GameWinnerService();
          _gameBoard = new char[3, 3]
                {
                    {‘ ‘, ‘ ‘, ‘ ‘},
                    {‘ ‘, ‘ ‘, ‘ ‘},
                    {‘ ‘, ‘ ‘, ‘ ‘}
                };
      }
      [Test]
      public void NeitherPlayerHasThreeInARow()
      {
          const char expected = ‘ ‘;
          var actual = _gameWinnerService.Validate(_gameBoard);
          Assert.AreEqual(expected, actual);
      }

    传递一个空数组,即没有一个玩家在一行中放入了3个标记,我们的期望是返回空字符,即没有人获胜
    但上面的代码不会编译通过,因为我们没有定义接口,IGameWinnerService

    public interface IGameWinnerService
      {
          char Validate(char[,] gameBoard);
      }

    但还是会失败,因为我们没有定义实现的类,GameWinnerService

    public class GameWinnerService : IGameWinnerService
      {
          public char Validate(char[,] gameBoard)
          {
              throw new NotImplementedException();
          }
      }

    编译可以通过了,但运行报错,接下来完善这个方法

    public class GameWinnerService : IGameWinnerService
      {
              private const char SymbolForNoWinner = ‘ ‘;
    
              public char Validate(char[,] gameBoard)
              {
                  return SymbolForNoWinner;
              }
      }
    五.架构代码的文档化
    1.文档有哪些

    开发文档、测试文档、需求文档、用户手册、技术手册等

    2.简化文档编写
  • 开发文档:GhostDoc有收费版,免费版,Free版,平时就够用了。
    GHost可以基于策略的,给注释添加规则,自定义宏
    随代码提交到版本库
  • 需求文档:
  • 测试用例的导出
3.文档的整合

知识库:
Wiki:
新闻:

4.文档的持续更新

很多项目忽视了文档,主要是因为团队大了以后,一个函数、方法会有很多人修改,无法保证注释文档的持续更新。

5.文档自动化发布

OneNote

6.文档的检索要方便

API函数、方法生成HTML文档
支持目录、索引、搜索

例子



新闻、维科的搜索

7.文档的权限控制
8.需求变更管理

实例:

  • 需求变更管理
    需求的变更要被记录下来
    历史记录应可以查询,并且结果清晰可见。

    项目跟进

  • 可以邮件提醒给相关人员
  • 需求变更的审核
    新建的需求,都是未审核需求,开发和测试人员都不可见,只有经过审核的需求才能看得到
8.实践
六.命名约定
主要内容:
  • 扩展型设计

  • 错误定义:
  • 类型设计规范
  • 成员设计规范
  • 框架设计规范
七.数据库伸缩性

采用分库的方法,可以把一个库的压力分担在若干不同的库上;这种方法很适用数据爆增的系统,只需要增加硬件就可以线性的解决性能和存储的问题;如果考虑以后增长会很快,可在在分库中增加分表;在分库的基础上可以在按功能或其他方式在分库

分库的几个原则:

  1. 按功能分割

  2. 水平切分
  3. 避免分布式事务
  4. 用异步策略解耦程序
  5. 将过程转变为异步的流
  6. 虚拟化所有层次
  7. 适当地使用缓存
八.自动化

SCRUM软件开发过程的创始人曾经说过:
如果某个过程能够确定下来(即能偶了解过程所涉及的所有细节,从而将其设计为可以重复地多次运行,并且安全能够预测其结果),那么该过程就被称为“确定过程”。从理论上讲,一切确定的工程都可以被自动完成。另一方面,人们并未了解某个过程中的所有细节,只是知道到在某些初始条件下,通过某些调节和控制就能得到想要的结果,这样的过程称为“经验过程”。

我们可以通过构建工具按照预定的设置,自动化运行,把错误信息报告给关键开发者,从而减少工作量。同时,自动化构建也是项目安全的保证。谁破坏了构建,一目了然。每当项目的核心代码被修改时,整个应用程序就会被重新构建,随后自动运行回归测试,已确保这次修改没有造成任何破坏。

  • 自动化脚本

  • 钩子
九.反馈

常用的持续集成平台:jenkins、Teamcity
反馈平台:jenkins&sonarqube、TFS&Project&Sharepoint、Teamcity&NotCover

目的:发现潜在的bug,分析找出项目里的坏味道等,从而提高代码质量

简单介绍下sonarqube

Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量
通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测
为什么选择Sonar

Developers‘ Seven Deadly Sins
1.糟糕的复杂度分布
文件、类、方法等,如果复杂度过高将难以改变,就会难以理解。同时,一般来说代码越复杂,就越容易出错。而且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试。

2.重复
显然程序中包含大量复制粘贴的代码是质量低下的。
sonar可以展示源码中重复严重的地方

3.缺乏单元测试
sonar可以很方便地统计并展示单元测试覆盖率

4.代码覆盖
5.代码标准
sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写。
sonar还支持多种语言C#,Java,Python,Android等
6.潜在问题代码
7.设计及注释架构

8.比较
可以根据基于指标,项目间的比较


9.扩展性:
sonar的集成是通过插件来扩展的。跟其他工具的集成



sonar支持的开发扩展

简单介绍下Jenkins

Jenkins,之前叫做Hudson,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,包括:
1、持续的软件版本发布/测试项目。
2、监控外部调用执行的工作。

  • 备份和恢复
    备份和恢复非常简单,就是简单的copy Jenkins的目录就好了:
    All the settings, build logs, artifact archives are stored under the JENKINS_HOME directory. Simply archive this directory to make a back up. Similarly, restoring the data is just replacing the contents of the JENKINS_HOME directory from a back up.

  • 自动运行Build
    触发一个build有三种方式:
    Builds in Jenkins can be triggered periodically (on a schedule, specified in configuration) 这里定义schedule的语法是unix常见的cron语法。
    Or when source changes in the project have been detected
    可以设置Jenkins定时检查SVN或TFS 是否发生了变化,也可以手动检查:http://YOURHOST/jenkins/job/PROJECTNAME/pollong。也可以设置Jenkins为post-commit,这个方式尤其适用于那些检查是否代码改变会花费很长时间的情况。
  • 因为性能问题,将build分布到多个slave节点去。
    到Jenkins的管理界面,就可以方便的添加节点。配置节点时,需要提供节点所在的机器,登陆用户名密码,使用的目录等。
    但是slave并不需要再安装Jenkins。jenkins会自动启用slave agent,将build需要tools考到远程机器上。
    需要注意的是:the build results and artifacts will always end up on the master server. 因此不需要跑到各个节点去查看build产生的文件,log等。
    其实在slave节点,会创建一个本地的workspace,并在运行时使用这个workspace。因为毕竟build运行在slave节点上,所以这个节点肯定要有运行build需要的所有因素。
  • 创建一个Project
    因为Jenkins可以用于运行各种CI,测试,批处理任务等等,所以在Jenkins中将这些任务统称为“free-style software project”.

目前:低成本的集成方案
Jenkins+MSTEST+MSBuild

十.实践

工具:TFS+jenkins+sonar
TFS 作为版本控制的核心
jenkins 自动化构建的关键
sonar 静态检测的执行者,代码质量反馈的中心
NUnit(推荐)或MSTEST 作为单元测试工具
依赖管理
工具:Nuget

时间: 2024-10-11 05:51:55

持续集成方案的相关文章

功能自动化接入持续集成方案

功能自动化接入持续集成方案 功能自动化一般用于项目集中测试.回归测试.dailybuild等,我们不可能通过IDE手动来运行case,一般可借助于jenkins或平台化的方式来批量执行case.下面介绍如何将功能自动化接入jenkins. 接入jenkins主要用到了其定时和轮询的功能,我们只要准备好构建jar(build.sh)和执行case(execCase.sh)的脚本,放入jenkins的Excute shell模块,然后配置定时或轮询的时间即可.build.sh和execCase.sh

小程序的持续集成方案

半年前,有机会开始接触微信小程序开发.却因为只是接触而并没投入开发小程序的过程中,因此对很多小程序的细节并未有充分的理解,仅仅停留在了解类似的理论层面,比如mpvue修改了 Vue.js 的 runtime 和 compiler 实现了编译及运行在原生小程序能力,比如原生小程序不支持npm包的使用及管理等,当然那时候的技术细节难点都是由非常给力的好同事解决消化了,所以也没多去细究. 最近,我开始投入到完成的小程序开发迭代里,却发现一个头痛的问题,如何准确并快速的的把小程序上传去后台,并让测试人员

手机APP自动化持续集成方案

自动化测试流程 自动化测试框架 版权声明:本文为博主原创文章,未经博主允许不得转载.

Qt Project的持续集成方案

作者:齐亮链接:http://www.zhihu.com/question/24314354/answer/27547787来源:知乎著作权归作者所有,转载请联系作者获得授权. PETER HARTMANN的一片博文:http://www.peter.hartmann.tk/#!Minimal-Continuous-Integration-for-Git-projects-with-Jenkins-and-a-Qt-example/cmzt/557e1b840cf298dc5b98f2a5 关于

[分享] 自动化测试与持续集成方案-- UI 检查

对于自动化测试中,UI 自动化测试估计是最有争议的,让人又爱又恨. UI 自动化做回归测试,可以省下很多人力.如果版本一直不稳定,投入跟产出不成比例的. 时机 一般是要版本稳定,界面改动不大.如果迭代版本一个接一个,界面改动大,这样就无法大规模投入 UI 自动化.因为你的维护成本大.也许你脚本还没改好,下一个版本又来了. 有些测试会说,还没有我手动快,没我手动发现的 bug 多.做 UI 自动化就是图个放心,测试的时候只测增量,原有的功能,用 UI 自动化去检测,看是否有改动,原有功能是否是好的

Jenkins Gitlab持续集成打包平台搭建

相关概念 Jenkins Jenkins,一个用Java编写的开源的持续集成工具,提供了软件开发的持续集成服务,可监控并触发持续重复的工作,具有开源,支持多平台和插件扩展,安装简单,界面化管理等特点.更多介绍参考[维基](https://en.wikipedia.org/wiki/Jenkins_(software)介绍. Gitlab GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目,更多介绍参考维基

持续集成之“分支策略”(续)

在前文中,咱们谈到生命周期长短不同的两种分支策略.对于不超过二十人的小团队来说,推荐使用短生命周期的分支策略.Joe的团队在首次发布之前,也一直使用这种方式.然而,首次发布之后,因市场反响非常好,公司决定加大开发投入,希望更快地推出升级平台,以及更多基于平台的游戏. 一.按特性分支的持续集成策略 现在,Joe的团队中,开发人员快速增加,已接近30人了.由于首次发布后的市场压力,大家一直在赶进度,持续集成的失败频率越来越高,修复构建的时间也越来越长,排队等待提交的代码也越积越多."这种状况不能再持

【iOS】Jenkins Gitlab持续集成打包平台搭建

Jenkins Gitlab持续集成打包平台搭建 SkySeraph July. 18th 2016 Email:[email protected] 更多精彩请直接访问SkySeraph个人站点:www.skyseraph.com 1. 相关概念 Jenkins Jenkins,一个用Java编写的开源的持续集成工具,提供了软件开发的持续集成服务,可监控并触发持续重复的工作,具有开源,支持多平台和插件扩展,安装简单,界面化管理等特点.更多介绍参考维基介绍. Gitlab GitLab是一个利用R

2、Jenkins持续集成之前期准备

2.Jenkins持续集成之前期准备.md 持续集成 互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI). 持续集成指的是,频繁地(一天多次)将代码集成到主干,它的好处主要有两个. (1)快速发现错误.每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易.     (2)防止分支大幅偏离主干.如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成 持续集成的目的,就是让产品可以快