Avoid preserving state in global variables
避免使用交互或保存状态的方法来定义全局变量。
使用静态类或实例化一个类的局部变量。
共享库也可以定义全局变量,和定义内置步骤的操作类似, 比如 sh 或 git 。定义在共享库中 的全局变量*must* 必须以全小写或 "camelCased" 命名以便于能够在流水线中正确的加载。
例如, 要定义 sayHello , 需要创建 vars/sayHello.groovy`文件并实现`call 方法。call 方法
允许全局变量以一种类似于步骤的方式被调用:
// vars/sayHello.groovy
def call(String name = 'human') {
// Any valid steps can be called from this code, just like in other
// Scripted Pipeline
echo "Hello, ${name}."
}
sayHello 'Joe'
sayHello() /* invoke with default arguments */
如果用块调用, call 方法会接收一个
Closure 。
应明确定义类型来说明该步骤的意义, 例如:
// vars/windows.groovy
def call(Closure body) {
node('windows') {
body()
}
}
然后流水线就能使用这个变量,就像内置的步骤一样,它接收一个块:
如果你有很多类似的流水线, 全局变量机制提供了一个便利的工具来构建更高级别的获取相似度的 DSL。 比如, 所有的Jenkins插件用同样的方式构建和测试, 所以我们可能会写一个名为
`buildPlugin`的步骤:
// vars/buildPlugin.groovy
def call(Map config) {
node {
git url: "https://github.com/jenkinsci/${config.name}-plugin.git"
sh 'mvn install'
mail to: '...', subject: "${config.name} plugin build", body: '...'
}
}
Jenkinsfile (Scripted Pipeline)
还有一个使用 Groovy的 Closure.DELEGATE_FIRST “构建模式” 技巧,
它允许 Jenkinsfile 看起来更像一个配置文件,而不是程序,
但它更复杂,容易出错,不推荐使用。
@Grab('org.apache.commons:commons-math3:3.4.1')
import org.apache.commons.math3.primes.Primes
void parallelize(int count) {
if (!Primes.isPrime(count)) {
error "${count} was not prime"
}
// …
}
在默认情况下,第三方库会被缓存到Jenkins主机的 ~/.groovy/grapes/ 文件中。
外部库可以使用`libraryResource` 步骤从 resources/ 目录加载附属的 文件。参数是相对路径名, 类似于Java资源加载:
def request = libraryResource 'com/mycorp/pipeline/somelib/request.json'
该文件做为字符串被加载,适合传递给某些 API或使用 `writeFile`保存到工作区。
建议使用一个独特的包结构,这样你就不会意外地与另一个库发生冲突。
如果你在构建一个不被信任的库时注意到一个错误,
只需点击 Replay 链接尝试编辑它的一个或多个源文件,
查看是否构建结果和预期一样。
一旦你对该结果感到满意, 就可以从构建的状态页追踪diff链接,
并将其应用到库的仓库并提交。
(即使请求库的版本是一个分支, 而不是像标记一样的固定版本,
重放构建将会使用与原始构建完全相同的修订:
库源不会被再次检出)。
目前,Replay 不支持受信任的库,在 _Replay_期间也不支持修改资源文件。
从2017年9月下旬发布的声明式 1.2开始, 你也可以在你的共享库里定义声明式流水线。下面是一个示例,
它将会执行一个不同的流水线,这取决于构建号是奇数还是偶数:
// vars/evenOrOdd.groovy
def call(int buildNumber) {
if (buildNumber % 2 == 0) {
pipeline {
agent any
stages {
stage('Even Stage') {
steps {
echo "The build number is even"
}
}
}
}
} else {
pipeline {
agent any
stages {
stage('Odd Stage') {
steps {
echo "The build number is odd"
}
}
}
}
}
}
// Jenkinsfile
@Library('my-shared-library') _
evenOrOdd(currentBuild.getNumber())
只有整个 流水线`s can be defined in shared libraries as of this time. This can only be done in `vars/*.groovy , 和 `call`方法。在单个构建中只有一个声明式流水线可以执行,如果你尝试执行第二个, 你的构建就会失败。
|