一、Sonatype Nexus基本介绍与安装

1.1 Nexus基本概念与仓库管理

1.1.1 Nexus工能介绍

  • 私服仓库:本地maven私服加快构建速度
  • 代理仓库:将公网等第三方提供的仓库代理到本地

Alt Image Text

1.1.2 Components - 组件

  • 组件是一种资源,在构建过程中需要依赖。它可以是整 个应用程序,也可以是静态资源(例如图片)。
  • 通常,这些组件是各种文件的存档,包括:
    • 类文件中的Java字节码
    • C对象文件
    • 文本文件,例如属性文件,XML文件,JavaScript代码,HTML, CSS
    • 二进制文件,例如图像,PDF文件,声音文件
  • 组件的多种格式,例如
    • Java JAR, WAR, EAR格式
    • 普通ZIP或.tar. gz文件
    • 其他软件包格式,例如NuGet软件包,Ruby gems, NPM软件包
    • 可执行文件格式,例如.exe.sh文件,Android APK文件,各种安装程序格式

Alt Image Text

  • 组件可以由多个嵌套组件本身组成。
  • 组件提供了所有构建块和功能。
    • 可以通过组装并添加自己的业务相关组件来创建功能强大的完整应用程序。
  • 在不同的工具链中,组件称为工件,程序包,捆绑包,归档和其他术语。
  • 概念和想法保持不变,组件用作通用术语。 组件由一组特定值(坐标)标识。这些坐标的通用集是组,名称和版本的用法。这些坐标的名称和用法随所使用的工具链而变化。组件也可以成为其他 元数据的基础。

Alt Image Text

1.1.3 Components - 组件

  • 例如Maven项目中的pom文件算是资产一部分,包含元数据的重要字补充。
  • 实际的存档文件(pom. xml)是与组件(jar/war包)关联 约资产。
  • 但是,更复杂的格式具有与组件(jar包)关联的众多资产 (pom)。例如,Maven存储库中的典型JAR组件至少由POMJAR文件定义一两者均构成属示同一组件的单独资产。其他文件(例如JavaDocSources JAR文件)是属于同一组件的资产。
  • 另一方面,Docker格式为资产提供唯一的标识符,并将其称为Docker层。这些资产可用于不同的组件一Docker映像。 例如,一个Docker层可以是多个Docker映像引用约特定操作系统。

Alt Image Text

1.1.4 仓库格式

  • Maven格式存储库中二进制组件的主要类型是包含Java字节码的JAR文件。
  • 每个软件组件均由称为项目对象模型(POM)的XML文档描述。
  • POM包含描述项目的信息,并列出项目的依赖项一二进制软件组件,给定组件成功进行编译或执行所依赖的组件。

Alt Image Text

1.1.5 下载机制

  • Maven从存储库下载组件(如依赖项或插件) 时,它也会下载该组件的POM
  • 给定组件的POM, Maven然后河以下载该组件所 需的任何其他组件。
  • Maven和其他工具(例如IvyGradle)与Maven存储库进行交互以搜索二进制软件组件, 对它们管理的项目进行建模,并从存储库按需检索软件组件。

Alt Image Text

1.1.6 中央仓库

  • 当您下载并安装Maven而没有进行任何自定义时,它将从中央存储库中检索组件。
  • 中央存储库是用于Java的组件的最大存储库。也可以从其他构建工具轻松使用它。
  • 以下是发行存储库(例如中央存储库)的一些属性:
  • 组件元数据:添加到中头存储库的所有软件组件都需要适当的元数据,包括每个组件的项目对象模型(POM),这些对 象描述组件本身以及该软件组件可能具有的任何依赖关系。
  • 释放稳定性:一旦发布到中央存储库,组件和描述该组件的元数据就永远不会改变。发行版存储库(例如中央存储库) 的此属性可确保依赖发行版的项目随着时间的推移将可重复且稳定。在每天发布新软件组件的过程中,一旦在中央存储 库中为组件分配了发行号,就有严格的政策禁止在发行后修改软件组件的内容。
  • 组件安全:中央存储库包含加密哈希和PGI,签名,可用于验证所提供软件组件的真实性和完整性,并通过HTTPS以安全方 式支持连接。
  • 性能:中央存储库通过服务器的高性能内容交付网络向全球用户开放。 除了中央存储库外,还有许多主要组织,例如Red Hat,OracleApache Software Foundation,它们维护着单独的其他存储库。

1.1.7 组件坐标

  • 制品坐标为每个制品创建唯一的标识符
  • Maven坐标使用以下值:groupId, artifactId, versionpackaging。这组坐标通常称为GAV坐标,它是“组”,“工件”,“版本”坐标的缩写。
  • GAV坐标标准是Maven管理依赖关系的基础。下面描述了此坐标系的四个元索:

    • groupld:组标识符将一组组件分为一个逻辑组。
    • 通常将组设计为反映生产特定软件组件所依据的组织。
    • 例如,由Apache Software FoundationMaven项目生产的软件组件可在groupId下获得org. apache. maven
    • artifactId:artifactId是软件组件的标识符,应为描述性名称。
    • groupIdartifactId的组合对于特定项目必须是唯一的
    • version:项目的版本理想地应该遵循已建立的语义版本工作管理惯例。
    • 例如,如果您的简亘库组件具有的主发行版1,次发行版2和发行版3,则您的版本将是1.2.3
    • 版本也可以具有字母数字限定符,通常用于表示发行状态。
    • 这种限定符的一个示例是类似“1.2.3-BETA”的版本,其中BETA表示对软件组件的使用者有意义的测试阶段。
    • packaging: Maven最初是为了处理JAR文件而创建的,但是Maven存储库完全不了解其管理的组件类型。
    • packaging可以是描述任何二进制软件格式的任何内容,包括:zip,nar,war,ear,sa和aar
    • Maven存储库进行交互的工具将组件坐标转换为与Maven存储库中的位置相对应的URL
  • 如果诸如Maven之类的工具正在该组中寻找JAR版本1.2.0,则此请求将转换为:commons-langorg.apache.commons

<repoURL> /org/apache/commons/commons-lang/1.2.0/commons-lang-1.2.0.jar 
<repoURL> /org/apache/commons/commons-lang/1.2.0/commons-lang-1.2.0.pom 

1.1.8 Release与Snapshot

  • Maven存储库存储两种类型的组件:版本和快照。

    • 发布存储库用于稳定的静态发布组务
    • 快照存储库是经常更新的存储库,用于存储不断开发的项目中的二进制软件组件。
    • 虽然可以创建一个同时服务于发布和快照组件的存储库,但通常将存储库分为多个发布库或快照存储库,这些发布库或快照存储库服务于不同的使用者并维护用于部署组件的不同标准和过程。就像网络之间的差异一样,发布存储库被视为生产网络,快照存储库被视为开发或测试网络。尽管存在与部署到发布存储库 相关联的更高级别的过程和仪式,但决照组件可以被须繁部署和更改,而无需考虑稳定性和可重复性。
  • 存储库管理一器管理的两种类型的组件是:

    • 发布:发布组件是由特定版本的发布创建的组件。
    • 例如,考虑1.2.0释放commons-lang存储在中央存储库中的库。
    • 此发行组件commons-lang-1.2.0.pom和相关的POM commons-lang-1.2.0.pom是静态态对象,它们在中央存储库中永远不会更改。
    • 释放的组件被认为是坚固,稳定和永久的,以确保依赖于它们的构建随着时句的推移可重复。
    • 已发布的JAR组件与PGP签名,MD5SHA校验和相关联,可用于验证二进制软件组件的真实性和完整性。
    • 快照:快照组件是在软件项目的开发过程中生成的组件。
    • Snapshot组件的名称中既带有版本号(例如1.3.0或),1.3又带有时间戳。
    • 例如,快照组件commons-lang 1.3.0的名称可能commons-lang-1.3.0.-20090314.182342-1.jar与关联的POM MD5SHA哈希值也具有相似的名称。
    • 为了在软件组件的开发过程中促进协作,Maven和其他知道如何从存储库使用快照组件的.客户端也知道如何查询与Snapshot组件关联的元数据,以从存储库检索快照依赖关系的最新版本。
  • 处于活从开发中的项目会生成随时间变化的快照组件。一个发行版包含一些组件,这些组件将随着时间的推移保持不变。

1.2 安装Nexus OSS On Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nexus
  namespace: nexus
spec:
  selector:
    matchLabels: 
      app: nexus-server
  replicas: 1
  template:
    metadata:
      labels:
        app: nexus-server
    spec:
      containers:
        - name: nexus
          image: sonatype/nexus3:latest
          resources:
            limits:
              memory: "2Gi"
              cpu: "500m"
            requests:
              memory: "2Gi"
              cpu: "500m"
          ports:
            - containerPort: 8081
            - containerPort: 5000
          volumeMounts:
            - name: nexus-data
              mountPath: /nexus-data
      volumes:
        - name: nexus-data
          emptyDir: {}

1.3 安装Nexus OSS SVC

apiVersion: v1
kind: Service
metadata:
  name: nexus-service
  namespace: nexus
spec:
  selector: 
    app: nexus-server
  type: NodePort  
  ports:
    - port: 8081
      targetPort: 8081
      nodePort: 32000
      name: http
    - port: 5000
      targetPort: 5000
      nodePort: 32500
      name: docker
$ kuebctl create ns nexus

$ kubectl get pod -n nexus 
NAME                     READY   STATUS    RESTARTS   AGE
nexus-54664bd559-hk892   1/1     Running   0          4m56s

$ kubectl get svc -n nexus 
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
nexus-service   NodePort   10.102.246.235   <none>        8081:32000/TCP,5000:32500/TCP   22h
  • admin
  • password
$ kubectl exec -it nexus-84fcd99c46-5d5mk bash -n nexus
$ cd /nexus-data
$ cat admin.password
effb42fe-3c17-459a-b489-e905ea1794d5
  • admin
  • admin

Alt Image Text

http://127.0.0.1:32000/#admin/repository

1.4 Nexus系统配置管理

1.4.1 LDAP认证-链接信息

Alt Image Text

1.4.2 LDAP认证-用户/组信息

Alt Image Text

1.4.3 邮件通知

Alt Image Text

1.4.4 Webhook

Alt Image Text

二、制品管理

2.1 制品管理

2.2 制品是什么

所谓制品,到底是什么呢?

An artifact is one of many kinds of tangible by-products produced during the development

换句话说,制品是软件开发过程中产生的多种有形副产品之一。另外,直译artifact,是人工制品的意思。所以,广义的制品还包括用例、UML图、设计文档等

而狭义的制品就可以简单地理解为二进制包。虽然有些代码是不需要编译就可以执行的,但是我们还是习惯于将这些可执行文件的集合称为二进制包。

本章讨论的是狭义的制品。行业内有时也将制品称为产出物或工件。

2.3 制品管理仓库

最简单的制品管理仓库就是将制品统一放在一个系统目录结构下。但是很少有人这样做,更多的做法是使用现成的制品库。

制品管理涉及两件事情:

  • 一是如何将制品放到制品库中。
  • 二是如何从制品库中取出制品。

由于每种制品的使用方式不一样,因此下面我们分别进行介绍。 目前现成眨制品库有:Nexus、Artifactory。

2.4 过渡到制品库

从手工打包到自动化打包,再将打好的包放到制品库中。这看似简单,但是要在团队中从无 到有地落地其实是一个很漫长的过程,特别是对于存在很多遗留项目的团队。每个团队都应该按 照自己当前情况进行调整,有时统一的解决方案不一定适合你。

曾经,笔者所在团队已经将部分项目的编译和单元测试放到Jenkins上执行,然而并没有人力及能力搭建Nexus。但是又期望能将自动打包好的JAR包放到各个环境中使用,以马上从持续集成中获益,怎么办? 这时,archiveArtifacts步骤(https://www.jenkins.io/doc/pipeline/steps/core/)就派上用场了。它能对制品进行归档,然后你就可以从Jenkins页面上下载制品了

#!groovy
@Library('jenkinslib@master') _

def build = new org.devops.buildtools()
def sonar = new org.devops.sonarqube()

pipeline {
    agent { node { label "hostmachine" }}
    parameters {
        string(name: 'srcUrl', defaultValue: 'http://192.168.33.1:30088/root/demo-maven-service.git', description: '') 
        choice(name: 'branchName', choices: 'master\nstage\ndev', description: 'Please chose your branch')
        choice(name: 'buildType', choices: 'mvn', description: 'build tool')
        choice(name: 'buildShell', choices: 'clean package -DskipTest\n--version', description: 'build tool')
    }
    stages{
        stage('Checkout') {
            steps {
                script {
                    checkout([$class: 'GitSCM', branches: [[name: "${branchName}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-admin-user', url: "${srcUrl}"]]])
                } 
            }
        }

        stage('Build') {
            steps {
                script {
                    build.Build(buildType,buildShell)
                } 
            }
        }
    }
        post{
            always{
                archiveArtifacts artifacts: 'target/**/*.jar', fingerprint: true
            }
        }    
 }
-------------------------------------------------------
Running com.mycompany.app.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.094 sec

Results :

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

[INFO] 
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ my-app ---
[INFO] Building jar: /home/vagrant/workspace/workspace/chap9_1/target/my-app-1.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  6.910 s
[INFO] Finished at: 2020-08-02T18:18:44Z
[INFO] ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] archiveArtifacts
Archiving artifacts
Recording fingerprints

接下来,我们详细介绍几个常用的archiveArtifacts的参数用法

  • artifacts(必填):字符串类型,需要归档的文件路径,使用的是Ant风格路径表达式。
  • fingerprint(可选):布尔类型,是否对归档的文件进行签名。
  • excludes(可选):字符串类型,需要排除的文件路径,使用的也是Ant风格路径表达式。
  • caseSensitive(可选):布尔类型,对路径大小写是否敏感。
  • ontylfSuccessful(可选):布尔类型,只在构建成功时进行归档。

值得提的是,archiveArtifacts。步骤并不只用于归档JAR包,事实上,它能归档所有类型的制品 团队初期可以考虑使用这种方式管理简单的制品。

console output

Alt Image Text

2.5 管理Java栈制品

目前Java栈的构建工具以MavenGradle为主且Maven的用户最广泛。接下来我们使 用Maven作为主要工具来讲解制品管理。

2.5.1 使用Maven发布制品到Nexus

Nexus搭建好后就可以使用Maven Dep!oy插件上传JARWAR包到Nexus中了Deploy 插件是Apache Maven团队提供的官方插件,能将JAR包及POM文件发布到Nexus中口目前该插件的最新版本是3.25.1。在POM文件中这样定义:

<plugins> 
    <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven—deploy—plugin</artifactld> 
        <versSon>3.25.1</version> 
    <plugin> 
</plugins> 

如果不需要自定义Deploy插件配置,则不需要在POM文件中定义。

使用Deploy插件发布需要以下几个步骤

  • (1)配置发布地址。在Maven项目的POM文件中加人:
<distributionManagement> 
    <snapshotRepository> 
        <id>nexus-snapshot</id> 
        <name>nexus snapshot</name> 
        <url>http://<Nexus的地址>/repository/maven—snapshot</url> 
    </snapshotRepository> 
    <repository> 
        <id>nexus-release</id> 
        <name>my nexus relesse</name> 
        <url>http://<Nexus的地址>/repository/maven—releasese</url> 
    </repository> 
</distributionManagement> 

完成此步骤后我们就可以通过执行mvn clean deploy进行发布了。

Deploy插件会根据Maven项目中定义的version值决定是使用nexus-seapshot仓库还是nexus-release仓库。

version值是以-SNAPSHOT后缀结尾时,则发布到nexus-seapshot仓库

  • (2)配置访问Nexus的用户名和密码。在Nexus中,我们配置了只有授权的用户名和密码才 能发布制品。这时需要在Mavensettings.xml中加人配置:
<servers> 
    <server> 
        <id>nexus—snapshot</id> 
        <username>admin</username> 
        <password>admin</password> 
    </server> 
    <server> 
        <id>nexus—relesse</id> 
        <username>admin</username> 
        <password>admin</password> 
    </server> 
</servers> 

2.5.2 使用Nexus插件发布制品

除了可以通过Maven发布JAR包,还可以使用Nexus Platform来插件实现。最新版本的Nexus Platform(3.9.20200722-164144.e3a1be0)已经同时支持Nexus 2.xNexus 3.x,只是它的文档更新不及时,大家都不知道它支持3.x版本了。

在安装好Nexus Platform插件后,根据以下步骤来使用。

  • (1)进入Manage Jenkins - Configure System - Sonatype Nexus页,设置Nexus 3.x的服务地址

Alt Image Text

  • neuxs3
  • http://192.168.33.1:32000/

需要注意的是:

  • Credentials选项处增加了一个具有发布制品到Nexus中的权限的用户名和密码凭证
  • Server ID字段的值设置完成后单击,在Jenkinsfile中会引用

Test connection按钮测试设置是否正确

Alt Image Text

  • (2)在Jenkinsfile中加入nexusPublisher步骤。
stage('Build') {
            steps {
                script {
                    build.Build(buildType,buildShell)
                } 
                nexusPublisher( 
                        nexusInstanceId: 'nexus3', 
                        nexusRepositoryId: 'mavenreleases', 
                        packages: [ 
                            [ 
                            $class: 'MavenPackage',
                            mavenAssetList: [
                                [ classifier: '',
                                    extension: '',
                                    filePath: './target/my-app-1.1-SNAPSHOT.jar' 
                                ]
                            ], //end of mavenAssetList
                        mavenCoordinate: [ 
                            artifactId: 'my-app', 
                            groupId: 'com.mycompany.app', 
                            packaging: 'jar', version: '1.1-SNAPSHOT' ] 
                        ] // end of packages 
                    ])
            }
        }

下面简单介绍一下nexusPublisher的参数。

  • nexusInstanceId:在Jenkins中配置Nexus 3.x时的Server ID
  • nexusRepositoryId:发布到Nexus服务器的哪个仓库。
  • mavenCoordinate: Maven包的坐标,packaging值与Maven中的packaging值一致,可以是 jarwarpomhpi等。
  • mavenAssetList:要发布的文件,如果是pom.xml,则extension必须填“xml"

在实际工作中,笔者并不常使用此插件。原因如下:

  • 每个Maven项目都可能不同,必须为每个Maven项目写nexusPublisher方法。
  • 对于多模块的Maven项目,nexusPublisher的参数写起来十分锣唆。

但是介绍这个插件还是有必要的,一是大家可以根据实际情况进行选择;二是可以了解JenkinsNexus的集成程度。

2.6 使用Nexus管理Docker镜像

本节假设Jenkins机器上已经安装了Docker CE。检查在Jenkins上能否运行Docker的方法是:在Jenkinsfile中加人sh "docker PS",语句,如果没有报错,就说明可以运行Docker

2.6.1 1 Nexus:创建Docker私有仓库

首先进人Nexus的仓库列表页:Administration -> Repository -> Repositories

Alt Image Text

单击“docker(hosted)",进人Docker:私有仓库创建页,

Alt Image Text

  • http://192.168.33.1:32000/repository/dockerrepo/
  • dockerrepo
pipeline { 
    agent any 
    environment { 
        registry = "http://192.168.33.1:32500" 
        registryCredential = 'dockernexus' 
    } 
    stages { 
        stage('Build') { 
            steps { 
                withDockerRegistry([ 
                credentialsId: "${registryCredential}", 
                url: "${registry}" ]) { 

                sh "docker build . -t ${registry}/hello:v2"
                sh "docker push ${registry}/hello:v2" 
                } 
            } 
        } 
    } 
} 

2.7 管理原始制品

Nexus 提供了对raw仓库的支持。raw仓库可以被理解为一个文件系统,我们可以在该仓库中创建目录。

2.7.1 创建raw仓库

进入Administration -> Repository -> Repositories页。

单击“raw(hosted)",进人raw仓库创建页。

Alt Image Text

输入仓库名称raw-example,单击“Create rcpository”按钮,确认后创建成功。

Alt Image Text

该仓库的地址是:<你的Nexus地址>/repository/raw-example/

2.7.2 上传制品获取制品

使用HTTP客户端就可以将制品上传到raw仓库中。我们使用Linux curl命令。几体步骤如下

  • (1)在Jenkins上添加Userame with password凭证
  • (2)在Jenkinsfile中加人上传制品的步骤
pipeline { 
    agent { node { label "hostmachine" }}
    environment { 
        nexusRawUsernamePassword = credentials('nexus') 
    } 
    stages { 
        stage('Build') 
        { 
            steps { 
                sh "curl --user '${nexusRawUsernamePassword}' -T ../../readme.md http://192.168.33.1:32000/repository/raw-example/${BUILD_NUMBER}/readme.md" 
            } 
        } 
    }
} 

为简单起见,我们直接使用构建号作为目录名称来区分每次上传的制品。curl命令的格式为:

curl --user '<username:password>' --upload-file <待上传制品的路径> <将制品保存到Nexus上的全路径> 

Alt Image Text

Alt Image Text

将制品保存到Nexus上的全路径:如果目录不存在,Nexus将会自动创建。

  • (3)在Nexus中,我们看到readme.md文件已经上传成功,

Jenkins pipeline中获取原始制品时,我们同样使用curl命令。

sh "curl --user '${nexusRawUsernamePassword}' -o readme.md http://192.168.33.1:32000/repository/raw-example/2/readme.md" 

Alt Image Text

2.8 从其他pipeline中拷贝制品

在某些场景下,我们需要从另一个pipeline中拷贝制品。Copy Artifact插可以帮助我们实现。具体代码如下:

steps { 
    copyArtifacts( 
        projectName: "core", 
        selector: lastSuccessful(true) 
    ) 
} 
  • core项目中拿到最后一次构建成功的制品。

接下来,我们详细介绍copyArtifacts步骤的参数。

  • projectname:字符串类型,Jenkins jobpipeline名称。
  • selector: BuildSelector类型,从另一个pipeline中拷贝制品的选择器,默认拷贝最后一个制品。
  • parameters:字符串类型,使用逗号分隔的键值对字符串(name1=value1 ,name2=value2),用于过滤从哪些构建中拷贝制
  • filter:字符串类型,Ant风格路径表达式,用于过滤需要拷贝的文件。
  • excludes:字符串类型,Ant风格路径表达式,用于排除不需要拷贝的文件。
  • target:字符串类型,拷贝制品的目标路径,默认为当前pipeline的工作目录。
  • optional:布尔类型,如果为true,则拷贝失败,但不影响本次构建结果。
  • fingerprintArtifacts:布尔类型,是否对制品进行签名,默认值为true
  • resultVariableSuffix:上例中,无法得知我们到底拿的是core项目的哪次构建的制品。CopyArtifact插件的设计是将其构建次数放到一个环境变量中。这个环境变量名就是在 COPYARTIFACT_BUILD_NUMBER_后拼上resultVariabiLeSuffix,比如resultVariableSuffix值为corejob,那么就在pipeline中通过变量COPYARTIFACT_BUILD_NUMBER_corejob拿到源pipeline的构建次数了。

projectname参数是必填的外,其他参数都是可选的。

下而介绍几种常用的获取选择器的方法。

  • lastSuccesSful:最后一次构建成功的制品。方法签名为lastSuccessful(boolean stable)。stabletrue表示只取构建成功的制品,为false表示只要构建结果比UNSTABLE好就行。
  • specific:指定某一次构建的制品。方法签名为specific(String bulidNumber)buildNumber表示指定取第n次构建的制品。
  • lastCompleted:最后一次完成构建的制品,不论构建的最终状态如何。方法签名为 lastCompleted()
  • latestSavedBuild:最后一次被标记为keep forever的构建的制品。方法签名为latestSavedBuild()

2.9 版本号管理

谈到制品,就必须谈到版本号的管理。版本号的制定并没有所谓的行业标准。比如谷歌浏览 器当前版本号为70.0.3538.110; Ubuntu操作系统当前版本号为18.10;由美国计算机教授高德纳 (Donald Ervin Knuth)编写的功能强大的排版软件TEX系统的版本号不断趋近于π,类似于这样:3.1415926

2.9.1 1语义化版本

GitHub提出了一种具有指导意义、统一的版本号表示规则,称为Semantic Versioning(语义化版本表示)。这也被人们称为三段式版本号。有了这套规则,用户一看版本号,就大概能猜到 一个软件两个版本之间的可能变化。

语义化版本格式为:主版本号、次版本号、修汀号。

版本号递增规则如下:

  • 主版本号:当作了不兼容的API修改时。
  • 次版本号:当作了向下兼容的功能性新增时。
  • 修订号:当作了向下兼容的问题修正时。

先行版本号及版本编译元数据可以加到主版本号、次版本号、修订号”的后面,作为延伸。 以下是常用的修饰词。

  • alpha: 内部版本。
  • beta: 测试版本。
  • rc: 即将作为正式版本发布。
  • lts: 长期维护。

2.9.2 2方便生成版本号的Version Number插件

VersionNumber (https://plugins.jenkins.io/versionnumber/)是一款用于生成版本号的插件,它 提供了VersionNumber步骤。具体使用方法如下:

script { 
    def version = VersionNumber versionPrefix: ${JOB_NAME}-", versionNumberString: 'v1.1.1.${BUILDS_ALL_TIME}' 
    echo "${version}" 
}

注意:BUILDS_ALL_TIME只是占位符,并不是JenkinsVersion Number插件提供的环境变量。

VersionNumber步骤支持以下参数。

  • versionNumberString:字符串类型,版本号格式,用于生成版本号。只能使用单引号,以防格式中的占位符被转义。版本号格式支持多种占位符,稍后介绍。
  • versionPrefix:字符串类型,版本号的前缀。
  • projectStartDate:字符串类型,项目开始时间,格式为yyyy-MM-dd,用于计算项目开始后的月数和年数。
  • worstResultForIncrement:字符串类型,如果本次构建状态比上一次构建状态更糟糕,则 BUILDS_TODAYBUILDS_THIS_WEEKBUILDS_THIS_MONTHBUILDS_THIS_YEAR 占位符的值不会增加。worstResultForIncrement可以设置的值有SUCCESSUNSTABLEFAILUREABORTEDNOT_BUILT(默认)。此参数较少使用。

versionNumberString参数使用占位符生成版本号。部分占位符本身支持参数化。接下来分别介绍它们。

  • BUILD_DATE_FORMATTED:格式化的构建日期,支持参数化,如${BUILD_DATE_FORMATTED,"yyyy-MM-dd"}
  • BUILD_DAY:构建日期,支持xxx参数。比如是12月2日,${BUILD_DAY}将返回2, ${BUILD_DAY,X}将返回2,${BUILD_DAY,XX}将返回03。
  • BUILD_WEEK:今年构建的星期数,支持xxx参数。
  • BUILD_MONTH:今年构建的月数,支持xxx参数。
  • BUILD_YEAR:今年构建的年份。

比如构建的时间为2018-12-02,那么BUILD_DAY的值为2, BUILD_WEEK的值为49,BUILD_MONTH的值为12, BUILD_YEAR的值为2018

接下来是一组和构建数相关的占位符:BUILDS_TODAYBUILDS_THIS_WEEKBUILDS_THIS_MONTHBUILDS_THIS_YEAR,它们分别表示当天、本星期、本月、本年完成的构建数。BUILDS_ALL_TIME表示自从项目开始后完成的总构建数。

MONTHS_S工NCE_PROJECT_STARTYEARS_SINCE_PROJECT_START分别表示自项目开始日期起已过去的日历月数和年数。