从Jenkins迁移到Flow

本文将讲解如何在代码化编排的场景下,将 Jenkins 的任务迁移到阿里云云效流水线产品 Flow。通过对比两者的对应能力,帮助你快速理解 Flow 的设计,从而更容易完成迁移。

1. 快速开始

一个最简单的Jenkinsfile:

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                sh 'echo hello'
            }
        }
    }
}

这个例子中,使用sh解析器执行echo hello,因此只能在linux,unix和mac系统上执行。

下面是对应的Flow流水线定义:

stages:
  echo_stage:
    jobs:
      echo_job:
        steps:
          hello:
            step: Command
            with:
              run: echo hello

step 是 Flow 中的最小执行单元,上述步骤指定了这个 step 的类型为Command,可以在多个操作系统上执行,在不同的操作系统上会使用对应的默认解释器来执行命令。

进入 Flow 流水线首页,点击 新建流水线 ,选择「YAML 化编排」方式,选择空模板,点击 创建

image

将上述 YAML 内容填入流水线流程配置,点击右上角 保存并运行

image

2. 详细的能力映射

接下来会在以下几个方面对比 Jenkins 和 Flow:

  1. 编排能力:串并联,交互等能力,条件执行等。

  2. 构建环境调度:执行命令的工作空间如何分配,可以分配到哪些执行环境中等。

  3. 触发方式:可以以何种方式触发流水线。

  4. 构建环境软件安装:如何在构建环境中添加自己需要的软件工具。

  5. 密钥管理:包括三方密钥的管理,比如github,gitlab,以及私密配置项的管理。

  6. 插件机制:了解二者在扩展能力上的差异。

  7. 权限管理:对于系统管理及流水线操作的相关权限管理。

2.1 编排能力

串并联编排

Jenkinsfile可以定义多个stage,每个stage内包含多个step。默认所有step都在同一个agent的同一个工作空间上执行。不同stage中的step都是串行执行,如果希望并行执行stage,需要使用parallel函数。

Flow流水线的基本结构是流水线阶段(stages) ->流水线任务 jobs -> 流水线步骤(steps)。其中stages之间是串行的,jobs之间默认是并行的,也可以通过needs关键字定义依赖,steps之间是串行的。

交互式能力

Jenkins中可以使用input指令来暂停构建,并允许获得用户输入。然后继续执行,并在后续的构建中可以使用用户的输入。

Flow 没有完全对标的能力,但在触发流水线时,可以指定环境变量的值。

条件执行

Jenkinsfile中可以使用when指令来决定是否执行某一段step或者stage。

Flow中可以使用 condition 语法控制任务是否执行来完成类似的功能。

Post

Jenkins中,post支持在任务执行结束后,根据任务状态执行命令。

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
    post {
        always {
            echo 'I will always say Hello again!'
        }
    }
}

Flow中没有直接对标的能力,您可以使用condition来做条件控制,但需要注意,post是在任务结束后执行,而condition是在任务执行前判断是否需要执行任务。具体请参考使用 condition 语法控制任务是否执行

jobs:
      front_build_job:
        name: 前端应用构建
        # 根据自定义环境变量判断是否需要执行前端应用构建
        condition: |
          "${FRONT_APP_CHANGED}" == "true"
        steps:
          command_step:
            name: 执行命令
            step: Command
            with:
              run: |
                echo This is front app build job...

Matrix

Jenkinsfile提供matrix指令来生成各种维度的任务组合。

Flow 没有提供完全对标的matrix语法,但提供了更加通用的使用 template 语法动态配置流水线,可以实现matrix可以实现的所有场景。

2.2 触发方式

Jenkinsfile中使用triggers指定流水线的触发方式,原生支持定时、轮询scm、上游任务触发三种能力,基于插件又可以实现灵活的scm的webhook触发等。

Flow支持Webhook 触发流水线代码源触发定时触发流水线、流水线源触发、制品源触发

2.3 构建环境调度

Jenkinsfile中使用agent指令来指定当前stage运行在哪个agent上。agent本身是一个抽象,可以通过插件运行在vm上或者容器里等。agent指令可以用在pipeline级别或者stage级别。

Flow通过jobs关键字指定运行环境,支持运行在北京和中国香港的Flow管理的共享构建集群中,提供的是x86的容器环境。同时也支持通过安装runner运行在用户自己的vm上,支持Linux、Windows、macOS等操作系统。但只能用在job级别。

2.4 构建环境软件安装

Jenkinsfile 中使用 tools 指令来安装指定软件。

Flow 中使用步骤的形式安装指定软件,比如安装Java、安装Python等步骤。

2.5 密钥管理

Jenkins使用credentials管理凭证,以便于scm、部署系统等外部系统进行安全通信。credential的类型包括账密、密钥文件、github app等。

Flow使用服务连接管理来管理凭证,可以通过服务连接于阿里云的产品之间进行安全授权,同时也支持账密、token、ssh私钥等类型。Flow还支持通过环境变量来管理流水线或者跨流水线范围内的私密信息存储和引用的能力。

2.6 插件机制

Jenkins 有着强大的扩展能力,提供了很多的扩展点。

Flow提供了自定义步骤的能力,可以开发专属于云效企业的步骤。

3. 一个Github Java应用测试构建示例

假设我在 Github 上有一个私有 Java 项目,需要创建和 Github 之间的连接,并进行构建和测试。

  • 新建 Github 服务连接授权

    • 进入 Flow 首页 -> 全局设置 -> 服务连接管理 -> 新建服务连接,选择 Github;

    • 点击下一步,在服务授权/证书页面点击新建,完成 Github oauth 授权后,返回 Flow 并点击创建

    image

    image

  • 新建 YAML 流水线:添加 sources 代码源,并选择上述创建的 Github 服务连接;添加 Java 构建任务 YAML。YAML 示例如下:

    sources: 
      github_repo:
        type: github
        name: github代码源
        endpoint: https://github.com/flow-example/spring-boot.git  # 请替换成你的 Github 代码仓库地址 
        branch: master
        triggerEvents: push
        certificate:
          type: serviceConnection
          serviceConnection: cq8bubonpi5wixdw # 这里的服务连接就是前面创建出来的服务连接ID
    
    stages:
      build_test:
        jobs:
          build_test:
            runsOn:
              group: public/cn-hongkong
              container: build-steps-public-registry.cn-beijing.cr.aliyuncs.com/build-steps/alinux3:ffdb23fd-2024-02-26-17-42-35
            steps:
              setup:
                step: SetupJava
                with:
                  jdkVersion: "1.8"
                  mavenVersion: "3.9.3"
              test:
                step: Command
                with:
                  run: mvn test
              build:
                step: Command
                with:
                  run: mvn package -DskipTests
  • 保存并运行流水线,查看运行结果。

    image