不做Git小白–WorkFlow(工作流)

WorkFlow 的字面意思,工作流,即工作流程。正因为Git有分支的存在,才构成了多工作流的特色。因为项目开发中,多人协作,分支很多,虽然各自在分支上互不干扰,但是我们总归需要把分支合并到一起,而且真实项目中涉及到很多问题,例如版本迭代,版本发布,bug 修复等,为了更好的管理代码,需要制定一个工作流程,这就是我们说的工作流,也有人叫它分支管理策略。工作流不涉及任何命令,因为它就是一个规则,完全由开发者自定义并自遵守。

目前使用度最高的工作流前三名分别是以下三种:

  • Git Flow
  • GitHub Flow
  • GitLab Flow

其中 Git Flow 出现的最早,GitHub Flow 在 Git Flow 的基础上,做了一些优化,适用于持续版本的发布,而 GitLab Flow 出现的时间比较晚,所以综合前面两种工作流的优点,制定而成的一个工作流。

这个工作流,是 Vincent Driessen 2010 年发布出来的他自己的分支管理模型,到现在为止,使用度非常高。

Git Flow 的分支结构很特别,按功能来说,可以分支为5种分支,从5 种分支的生命时间上,又可以分别归类为长期分支和暂时分支,或者更贴切描述为,主要分支和协助分支。

主要分支:

在采用 Git Flow 工作流的项目中,代码的中央仓库会一直存在以下两个长期分支:

  • master
  • develop

其中 origin/master 分支上的最新代码永远是版本发布状态。origin/develop 分支则是最新的开发进度。

当 develop 上的代码达到一个稳定的状态,可以发布版本的时候,develop上这些修改会以某种特别方式被合并到 master 分支上,然后标记上对应的版本标签。

协助分支:

除了主要分支,Git Flow 的开发模式还需要一系列的协助分支,来帮助更好的功能的并行开发,简化功能开发和问题修复。是的,就是下面的三类分支。这类分支是暂时分支非常无私奉献,在需要它们的时候,迫切地创建,用完它们的时候,又挥挥衣袖地彻底消失。协助分支分为以下几类:

  • Feature Branch
  • Release Branch
  • Hotfix Branch

Feature 分支用来做分模块功能开发,命名看开发者喜好,不要和其他类型的分支命名弄混淆就好,举个例子,命名为 master 就是一个非常不妥当的举动。模块完成之后,会合并到 develop 分支,然后删除自己。

Release 分支用来做版本发布的预发布分支,建议命名为 release-xxx。例如在软件 1.0.0 版本的功能全部开发完成,提交测试之后,从 develop 检出release-1.0.0 ,测试中出现的小问题,在 release 分支进行修改提交,测试完毕准备发布的时候,代码会合并到 master 和 develop,master 分支合并后会打上对应版本标签 v1.0.0, 合并后删除自己,这样做的好处是,在测试的时候,不影响下一个版本功能并行开发。

Hotfix 分支是用来做线上的紧急 bug 修复的分支,建议命名为 hotfix-xxx。当线上某个版本出现了问题,将检出对应版本的代码,创建 Hotfix 分支,问题修复后,合并回 master 和 develop ,然后删除自己。这里注意,合并到 master 的时候,也要打上修复后的版本标签。

Merge 加上 no-ff 参数

需要说明的是,Git Flow 的作者 Vincent Driessen 非常建议,合并分支的时候,加上 no-ff 参数,这个参数的意思是不要选择 Fast-Forward 合并方式,而是策略合并,策略合并会让我们多一个合并提交。这样做的好处是保证一个非常清晰的提交历史,可以看到被合并分支的存在。

下面是对比图,左侧是加上参数的,后者是普通的提交:

Git Flow 示意图

在刚学习 Git 的时候,看到很多次这个图,一直都没看懂过,也不知道这张图来自 Git Flow ,只能说,我当初学 Git 的方式的确不怎么正确 。下面来分析一下。

图中画了 Git Flow 的五种分支,master,develop,feature branchs ,release branchs , hoxfixes,其中 master 和 develop 字体被加粗代表主要分支。master 分支每合并一个分支,无论是 hotfix 还是 release ,都会打一个版本标签。通过箭头可以清楚的看到分支的开始和结束走向,例如 feature 分支从 develop 开始,最终合并回 develop ,hoxfixes 从 master 检出创建,最后合并回 develop 和 master,master 也打上了标签。

GitHub Flow 是大型程序员交友社区 GitHub 制定并使用的工作流模型,由 scott chacon 在 2011 年 8月 31 号正式发布。

文章中说,因为 Git Flow 对于大部分开发人员和团队来说,稍微有些复杂,而且没有 GUI 图形页面,只能命令行操作,所以为了更好的解决这些问题,GitHub Flow 应运而生了。

GitHub Flow 示意图

对比上面那张 Git flow 分支模型图,真的可以称得上简单明了啦,因为 GitHub Flow 推荐做法是只有一个主分支 master,团队成员们的分支代码通过 pull Request 来合并到 master 上。

github flow 示意图

GitHub Flow 模型简单说明

  1. 只有一个长期分支 master ,而且 master 分支上的代码,永远是可发布状态,一般 master 会设置 protected 分支保护,只有有权限的人才能推送代码到 master 分支。
  2. 如果有新功能开发,可以从 master 分支上检出新分支。
  3. 在本地分支提交代码,并且保证按时向远程仓库推送。
  4. 当你需要反馈或者帮助,或者你想合并分支时,可以发起一个 pull request。
  5. 当 review 或者讨论通过后,代码会合并到目标分支。
  6. 一旦合并到 master 分支,应该立即发布。

特 Pull Request

在我看来,GitHub Flow 最大的特色就是 Pull Request 的提出,这是一个伟大的发明,它的用处并不仅仅是合并分支,还有以下功能:

  • 可以很好控制分支合并权限。 分支不是你想合并就合并,需要对方同意
  • 问题讨论 或者 寻求其他小伙伴们的帮助。 和拉个讨论组差不多,可以选择相关的人参与,而且参与的人还可以向你的分支提交代码,可以说,是非常适合代码交流了。
  • 代码 Review 。 如果代码写的很烂,有了 pull request 提供的评论功能支持,准备好接受来自 review 的实时吐槽吧。当然你如果写的很棒,肯定也会得到认可。

特 issue tracking 问题追踪

日常开发中,会用到很多第三方库,然后使用过程中,出现了问题,是不是第一个反应是去这个第三方库的 GitHub 仓库去搜索一下 issue ,看没有人遇到过,项目维护者修复了没有,一般未解决的 issue 是 open 状态,已解决的会被标记为 closed。这就是 issue tracking。

如果你是一个项目维护者,除了标记 issue 的开启和关闭,还可以给它标记上不同的标签,来优化项目。当提交的时候,如果提交信息中有 fix #1 等字段,可以自动关闭对应编号的 issue。

issue 标签

issue tracking 真的是非常适合开源项目。

如果你想体验 GitHub Flow

GitHub 社区使用的就是这个工作流模型,而且帮助文档非常详细。

这个工作流十分地年轻,是 GitLab 的 CEO Sytse Sijbrandij 在 2014 年 9月 29 正式发布出来的。因为出现的比前面两种工作流稍微晚一些,所以它有个非常大的优势,集百家之长,补百家之短。

GitLab 既支持 Git Flow 的分支策略,也有 GitHub Flow 的 Pull Request( Merge Request ) 和 issue tracking。

Git Flow & GitHub Flow 的瑕疵

当 Git Flow 出现后,它解决了之前项目管理中很让人头疼的分支管理问题,但是实际使用过程中,也暴露了很多问题:

  • 默认工作分支是 develop,但是大部分版本管理工具默认分支都是 master,开始的时候总是需要切换很麻烦。
  • Hotfix 和 Release 分支在需要版本快速迭代的项目中,几乎用不到,因为刚开发完就直接合并到 master 发版,出现问题 develop 就直接修复发布下个版本了。
  • Hotfix 和 Release 分支,一个从 master 创建,一个从 develop 创建,使用完毕,需要合并回 develop 和 master。而且在实际项目管理中,很多开发者会忘记合并回 develop 或者 master。

GitHub Flow 的出现,非常大程度上简化了 Git Flow ,因为只有一个长期分支 master,并且提供 GUI 操作工具,一定程度上避免了上述的几个问题,然而在一些实际问题面前,仅仅使用 master 分支显然有点力不从心,例如:

  • 版本的延迟发布(例如 iOS 应用审核到通过中间,可能也要在 master 上推送代码)
  • 不同环境的部署 (例如:测试环境,预发环境,正式环境)
  • 不同版本发布与修复 (是的,只有一个 master 分支真的不够用)

GitLab Flow 解决方案

为了解决上面那些毛茸茸的小问题,GitLab Flow 给出了以下的解决方法。

版本的延迟发布–Prodution Branch

master 分支不够,于是添加了一个 prodution 分支,专门用来发布版本。

产品发布分支

不同环境的部署–Environment Branches & Upstream First

每个环境,都对应一个分支,例如下图中的 pre-production 和 prodution 分支都对应不同的环境,我觉得这个工作流模型比较适用服务端,测试环境,预发环境,正式环境,一个环境建一个分支。

这里要注意,代码合并的顺序,要按环境依次推送,确保代码被充分测试过,才会从上游分支合并到下游分支。除非是很紧急的情况,才允许跳过上游分支,直接合并到下游分支。这个被定义为一个规则,名字叫 “upstream first”,翻译过来是 “上游优先”。

部署环境分支

版本发布分支–Release Branches & Upstream First

只有当对外发布软件的时候,才需要创建 release 分支。作为一个移动端开发来说,对外发布版本的记录是非常重要的,如果线上出现了一个问题,需要拿到问题出现对应版本的代码,才能准确定位问题。

在 Git Flow ,版本记录是通过 master 上的 tag 来记录。发现问题,创建 hotfix 分支,完成之后合并到 master 和 develop。

在 GitLab Flow ,建议的做法是每一个稳定版本,都要从master分支拉出一个分支,比如2-3-stable、2-4-stable等等。发现问题,就从对应版本分支创建修复分支,完成之后,先合并到 master,才能再合并到 release 分支,遵循 “上游优先” 原则。

版本发布分支

.NET Core/.NET5/.NET6 开源项目:工作流组件

前言

开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激、尊重。请严格遵守每个项目的开源协议后再使用。尊重知识产权,共建和谐开源社区。

ELSA

Elsa Core是一个工作流库,支持在任何.NET Core应用程序中执行工作流。工作流不仅可以使用代码定义,还可以定义为JSON、YAML或XML。

1、设计器。提供了一个设计器:Elsa Designer 用于通过可视化方式定制流程。

2、持久化。工作流几乎可以使用任何存储机制持久化。将支持以下提供程序:

    • In Memory
    • File System
    • SQL Server
    • MongoDB
    • CosmosDB

Elsa对长期运行的工作流具有本机支持。一旦工作流因为某些阻塞活动而停止,工作流就会被持久化。当发生适当的事件时,工作流将从存储加载并恢复。

Elsa的主要目标之一是以最小的工作量和最大的可扩展性在任何.NET应用程序中启用工作流。这意味着将工作流功能集成到您的应用程序中应该很容易。

Gitee:https://gitee.com/imlyqmayun/elsa-core

Workflow-Core

Workflow-Core是一个基于.NET Standard的轻量级工作流引擎,目前有超过3100+个star。它提供了FluentAPI、多任务、持久化以及并行处理的功能,适合于小型工作流、责任链的需求开发。

由于Workflow-Core支持工作流长期运行,因此Workflow-Core支持以下多种数据源格式的持久化,可以通过安装不同的Provider包来实现对应的持久化:

  • (默认提供,用于测试和开发)内存
  • MongoDB
  • MS SQL Server
  • MySql
  • Sqlite
  • Redis
  • PostgreSQL

GitHub:https://github.com/danielgerlag/workflow-core

mxGraph

mxGraph包包含一个用JavaScript编写的客户端软件,以及各种语言的一系列后端(.NET、Java、PHP)。客户端软件是一个图形组件,它具有可选的应用程序包装器,该应用程序包装器集成到现有的web界面中。客户端需要Web服务器将所需文件传递给客户端,或者可以在没有webserver的情况下从本地文件系统运行。后端可以原样使用,也可以以支持的语言之一嵌入到现有服务器应用程序中。

如果存在后端,则可以将客户端配置为以各种方式使用此后端,例如:

  • 创建图像
  • 存储和加载图表
  • 创建图形的对象表示

上面的场景可能以各种方式组合,例如在发生更改时将每个更改的XML描述发送到后端,或者自动保存图表以避免客户端上的数据丢失。客户机也可以在脱机模式下运行,不需要后端或Web服务器。

Visor.js

Visor.js 基于JjQuery,在Canvas上制作在线绘图应用的核心基础文件。它支持鼠标的拖拽移动,伸缩,旋转和各种事件。

Gitee:https://gitee.com/zhouyig/Visor.js

VFD

VFD基于Vue + Ant Design Vue +JSPlumb,作为一款流程设计器组件,可作为流程图、泳道图等绘图工具,面板组件布局合理,功能强大,操作方便快捷(可拖拽且快捷键丰富),保存后为一段json数据,便于保存及控制版本,也可保存为图片,安装使用方便,集成难度较小,有交流群。

Gitee:https://gitee.com/yjblogs/VFD

Easy-Flow

easy-flow 基于VUE+ElementUI+JsPlumb的流程设计器,通过 vuedraggable 插件来实现节点拖拽。

功能介绍

  • 支持拖拽添加节点
  • 点击线进行设置条件
  • 支持给定数据加载流程图
  • 支持画布拖拽
  • 支持连线样式、锚点、类型自定义覆盖
  • 支持力导图

Gitee:https://gitee.com/xiaoka2017/easy-flow

转自:张传宁

链接:cnblogs.com/SavionZhang/p/14863772.html

极简 Java 工作流概念入门

关于 Flowable 松哥已经更新了好几篇文章了,不过考虑到有的小伙伴可能还从来没接触过流程引擎,因此有一些基础的内容我再来和小伙伴们梳理一下。

松哥将之前的文章转发到朋友圈后,有小伙伴评论说一直不理解为什么需要工作流,今天我们就先来说说这个话题。

假设我有一个请假需求,流程如下:

请假可以提交给我的上司,上司可以选择批准或者拒绝,无论批准还是拒绝,都会给我一个通知。

这个流程比较简单,我们很容易想到解决方案,不用工作流也能解决,有一个专门的请假表,当 A 要请假的时候,就往请假表中添加一条记录,这条记录的内容包含了请假的天数、原因、请假的审批人 B 以及一个名为 status 的字段,这个 status 字段表示这个请假申请目前的状态(待审批、已批准还是已拒绝),然后 B 登录系统之后,在请假表中查询到了 A 的请假信息,然后选择批准,此时将 status 字段的值改一下就行了。

这个流程很简单,相信小伙伴们都能想到。

然而,这是一个非常简单的流程,对于这样的流程,一般来说也确实没有必要使用工作流,但是现实中,我们涉及到的工作流往往都是非常复杂的,我举个例子,就说报销审批吧,这个可能很多小伙伴都经历过。

小伙伴们看到,这个流程相对来说还是比较复杂的,此时你再用一个 status 字段去描述,就很难说的请到底是怎么回事了。每一步审批,都有可能批准也有可能拒绝,拒绝并不意味着流程结束,员工修改报销资料之后,还可以继续提交。此时如果还用 status 去描述,那么 status 将有 N 多个值去表示不同的情况,这个维护起来非常不便。

这就复杂了吗?非也非也,我们再来看一个生产笔记本电脑的例子,假设公司研发了一款新型笔记本电脑,整个研发到生产的流程可能是这样:

相比上面两个,这个就更复杂一些了,不仅有串行任务还有并行任务,如何去设计这样一个系统?单纯的通过状态字段去描述显然已经不够用了,此时我们就得考虑一种通用的、更易维护的方案来实现这样的系统了,这种通用的、易维护的方案,也就是工作流。

一个比较早的工作流是 jBPM,这是一个由 Java 实现的企业级流程引擎,是 JBoss 公司开发的产品之一。

jBPM 的创建者是 Tom Baeyens,这个大佬后来离开了 JBoss,并加入到 Alfresco,并推出了基于 jBPM4 的开源工作流系统 Activiti,而 jBPM 则在后续的代码中完全放弃了 jBPM4 的代码。从这个过程中也能看出来,jBPM 在发展过程中,由于意见相左,后来变成了两个 jBPM 和 Activiti。

然而戏剧的是,Activiti5 没搞多久,从 Activiti 中又分出来一个 Camunda,Activiti 继续发展,又从中分出来一个 Flowable。。。

由于开发 jBPM、Activiti、Camunda 以及 Flowable 的人多多少少有一些关联性,让人不得不猜测意见相左拉一票人出来单干是他们的企业文化。

所以现在市面上主流的流程引擎就一共有三个:

  • Activiti
  • Flowable
  • Camunda

这三个各有特点:

  1. Activiti 目前是侧重云,他目前的设计会向 Spring Cloud、Docker 这些去靠拢。
  2. Flowable 核心思想还是在做一个功能丰富的流程引擎工具,除了最最基础的工作流,他还提供了很多其他的扩展点,我们可以基于 Flowable 实现出许多我们想要的功能(当然这也是小伙伴们觉得 Flowable 使用复杂的原因之一)。
  3. Camunda 相对于前两个而言比较轻量级,Camunda 有一个比较有特色的功能就是他提供了一个小巧的编辑器,基于 bpmn.io 来实现的(松哥之前已经发文讲过了)。如果你的项目需求是做一个轻巧的、灵活的、定制性强的编辑器,工作流是嵌入式的,那么可以选择 Camunda。

如果仔细比较起这三个的差异,能列一个长长的表格,这个网上也有不少人都总结过了,松哥这里也就不啰嗦了。

既然有三个不同的工作流,那么三个不同的工作流画出来的流程图是否都各不相同呢?

不是的。

工作流程图这块其实有一个统一的标准,那就是 BPMN。BPMN 全称是 Business Process Model and Notation,中文译作业务流程模型和标记法,这个中文太绕口了,还是简称 BPMN 吧。

这是一套图形化表示法,用图形来表示业务流程模型。BPMN 最初由业务流程管理倡议组织(BPMI, Business Process Management Initiative)开发,BPMI 于 2005 年与对象管理组织(OMG, Object Management Group)合并,并于 2011 年 1 月 OMG 发布 2.0 版本,同时改为现在的名称。

一句话,就是流程图这块有一个特别古老的规范,那就是 BPMN,而我们前面所说的无论是 Activiti、Flowable 还是 Camunda,都是支持这个规范的,所以呢,无论你使用哪一个流程引擎,都可以使用同一套流程图。

那么这个规范究竟都说了些什么事情呢?

我们以上面生产笔记本的流程图为例,来和小伙伴们做一个简单介绍:

从上图中可以看到,一个流程图中主要包含四方面的内容:

  • 事件
  • 连线
  • 任务
  • 网关

我们一个一个来说。

事件

首先在一个流程图中应该有开始事件和结束事件,也就是上图大家看到的两个圆圈。另外还有一些中间事件、边界事件等。举个中间定时事件的例子,比如用户下单之后,可以有一个中间定时事件,延迟 5 分钟发货。

连线

连线就是将事件、任务、网关等连在一起的线条,一般情况下就是普通连线,有的时候连线会有一些条件,例如松哥之前文章和大家分享的请假,如果经理同意请假申请,就走哪一个线条,如果经理不同意请假申请,就走哪一个线条。对应上图的笔记本生产,如果经理审批通过,就载入图纸准备生产,如果经理审批不通过,就重新设计。

任务

任务这块其实有很多分类。

如果细分大致上可以分为如下几种:

  • 接收任务

在上面的流程图中,等待准备工作完成这一项就是一个接收任务。这个任务里并不需要额外做什么事情,流程到这一步就自动停下来了,需要人工去点一下,推动流程继续向下执行。

  • 发送任务

这个一般用来把消息发送给外部参与者。

  • 服务任务

这个一般由系统自动完成,其实说白了就是我们的一个自定义类,可以在一个自定义类里边完成想要做的事情。

  • 脚本任务

一个自动化活动。当流程执行到脚本任务时,自动执行相应的脚本。

  • 业务规则任务

BPMN2.0 新引入用来对接业务规则引擎,业务规则任务用于同步执行一个或多个规则。

  • 用户任务

用于为那些需要由人工参与者完成的工作建模。

虽然细分类别很多,但是仔细看,其实这几种又可以归为两大类:

  1. 用户任务:表示人工要介入做的事情。比如同意与否,或者输入一些参数,要让人工完成任务,就需要一个表单系统,让人工输入数据,或者显示数据给人看,这也是为什么用户任务和表单系统结合在一起的原因,用户任务需要用户向引擎提交一个完成任务的动作,否则流程会暂停在这里等待。
  2. 服务任务:表示机器自动做的事情。调用服务的任务,这个服务可以是一个 Spring JavaBean,也可以是一个远程 REST 服务,流程会自动执行服务任务。

活动

活动可以算是一种特殊的任务。活动可以调用另外一个流程使之作为当前流程的子流程去运行。活动也可以分为用户活动、脚本活动等等。从显示上来说,活动比任务边框深一些。仅此而已。

网关

网关要是细分起来,也有很多不同类型的网关。

  • 互斥网关

这种网关也叫排他性网关,我们之前请假流程中的那个网关,就是互斥网关。这种网关有且仅有一个有效出口。

  • 相容网关

这种网关会有多个出口,只要条件满足,都会执行。

  • 事件网关

事件网关是通过中间事件驱动,它在等待的事件发生后才会触发决策。基于事件的网关允许基于事件作出决策。

  • 并行网关

并行网关一般是成对出现的,上面生产笔记本的那个流程中,生产屏幕、键盘等并行操作,就是通过并行网关来实现的。

好啦,这就是关于流程引擎的一些基本概念,捋顺了这些基本概念,在回过头看我们前面几篇关于流程引擎的文章,应该会有一些不一样的理解:

  • Spring Boot 整合流程引擎 Flowable,so easy!
  • SpringBoot+Vue+Flowable,模拟一个请假审批流程!
  • 49张图带领小伙伴们体验一把 Flowable-UI
  • Spring Security + Vue + Flowable 怎么玩?

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。