我该如何在本地测试对Jenkinsfile所做的更改?

306
当编写 Jenkins 流水线时,每次为了查看是否有效而提交每个新更改似乎非常不方便。
有没有一种方式可以在不提交代码的情况下本地执行这些流水线?
16个回答

196

由于Pipeline脚本的目的是编写Jenkins脚本,因此您无法在本地执行它。这也是为什么最好将您的Jenkinsfile保持简短,并将其限制为实际涉及Jenkins功能的代码;您的实际构建逻辑应该通过您通过一行shbat步骤调用的外部进程或构建工具来处理。

如果您想测试Jenkinsfile的更改但不想提交它,请使用1.14中添加的Replay功能

JENKINS-33925跟踪自动化测试框架的功能请求。


2
博客文章中提到有一个“重播”按钮。你知道在哪里吗?我好像找不到它。 - BoltzmannBrain
9
请前往您构建作业的Jenkins页面。在左侧,您应该会看到以前构建运行的列表。将鼠标悬停在一个构建运行ID(例如“#123”)或构建运行的日期上时,会出现一个小向下箭头。单击它会显示一个上下文菜单,其中包含“重新运行”的选项。该选项也可以在构建运行页面中找到。 - Good Night Nerd Pride
2
Concourse允许您针对目标构建服务器执行本地脚本,以便在提交更改之前验证它实际上也可以在远程服务器上工作。https://concourse.ci/fly-cli.html。Jenkins的重放功能与此有些类似,但它具有一定的限制,并且您必须先创建一个构建才能重放它。 - mdo123
2
你可以看一下这个项目,它旨在提供你所需要的功能。链接 - Romain
1
请查看JenkinsPipelineUnit(https://github.com/jenkinsci/JenkinsPipelineUnit)的内容。 - user864279
显示剩余4条评论

126
我有一个适合我的解决方案。它包括在Docker中运行的本地Jenkins和一个Git Web Hook,以触发每次提交时在本地Jenkins中运行管道。您不再需要将内容推送到GitHub或Bitbucket存储库以测试管道。 此解决方案仅在Linux环境下进行过测试。 虽然这些说明有点长,但使其工作相当简单。大多数步骤都在以下内容中。

所需内容

  • 已安装并运行的Docker这不是本说明的一部分。
  • 在Docker中运行的Jenkins。如下所述。
    • 为您的本地Jenkins Docker用户授予从本地git存储库中拉取的适当权限(SSH访问密钥)。 如下所述。
    • 从您的本地git存储库中提取的Jenkins管道项目。 如下所述。
    • 在本地Jenkins中具有最小权限的git用户。 如下所述。
  • 具有后提交Web Hook的git项目,可触发管道项目。 如下所述。

操作步骤

Jenkins Docker

在所选位置创建名为Dockerfile的文件。我将其放在/opt/docker/jenkins/Dockerfile,并填写以下内容:

FROM jenkins/jenkins:lts
USER root
RUN apt-get -y update && apt-get -y upgrade
# Your needed installations goes here
USER jenkins

构建本地 Jenkins 镜像

这只需要在第一次或者在 Dockerfile 中添加内容后进行一次即可。

$ docker build -t local_jenkins /opt/docker/jenkins/

启动和重启本地Jenkins

有时您想要轻松地启动和重启Jenkins。例如,在计算机重新启动后。为此,我创建了一个别名,并将其放在我的主目录下的.bash_aliases文件中。

$ echo "alias localjenkinsrestart='docker stop jenkins;docker rm jenkins;docker run --name jenkins -i -d -p 8787:8080 -p 50000:50000 -v /opt/docker/jenkins/jenkins_home:/var/jenkins_home:rw local_jenkins'" >> ~/.bash_aliases
$ source .bash_aliases  # To make it work

请确保 /opt/docker/jenkins/jenkins_home 文件夹存在,并且您拥有对其的用户读写权限。

要启动或重新启动 Jenkins,只需输入:

$ localjenkinsrestart

您在本地Jenkins中所做的一切都将存储在文件夹/opt/docker/jenkins/jenkins_home中,并在重新启动时保留。

在您的Docker Jenkins中创建SSH访问密钥

这是使其正常工作的非常重要的部分。首先,我们启动Docker容器并创建一个bash shell:

$ localjenkinsrestart
$ docker exec -it jenkins /bin/bash

你现在已经进入了Docker容器,可以通过终端中类似于jenkins@e7b23bad10aa:/$的内容看到。@后面的哈希值肯定是不同的。
创建密钥。
jenkins@e7b23bad10aa:/$ ssh-keygen

在所有问题上按回车键,直到您收到提示返回

将密钥复制到您的计算机上。从Docker容器内部,您的计算机应该是172.17.0.1,如果您想知道的话。

jenkins@e7b23bad10aa:/$ ssh-copy-id user@172.17.0.1

user = 您的用户名,172.17.0.1 是您在 Docker 容器内部访问计算机的 IP 地址。

此时您需要输入密码。

现在让我们尝试通过在 Docker 容器内部 ssh 到您的计算机来完成循环。

jenkins@e7b23bad10aa:/$ ssh user@172.17.0.1
这次你不需要输入密码。如果需要输入密码,说明出了问题,需要再试一次。

现在你将进入计算机的主文件夹。尝试使用 ls 命令并查看。

不要停留在这里,因为我们有一系列的 SSH shell 需要退出。

$ exit
jenkins@e7b23bad10aa:/$ exit

没错! 现在我们回来了,准备继续。

安装Jenkins

Jenkins本地地址为http://localhost:8787。在首次使用本地浏览器访问Jenkins时,将出现安装向导。默认设置即可,但确保在安装过程中安装流水线插件。

配置Jenkins

非常重要的一点是,在http://localhost:8787/configureSecurity上启用基于矩阵的安全性,并通过添加自己到矩阵并选中所有框来赋予权限。(最右边有一个选中所有框的图标)

  • 将“Jenkins自己的用户数据库”作为安全域
  • 在授权部分选择“基于矩阵的安全性”
  • 在“添加用户/组”的字段中写入您的用户名,然后单击“[添加]”按钮
  • 在上面的表格中,您的用户名应该弹出一个人物图标。如果它被划掉了,那么您输入的用户名不正确。
  • 转到表格的最右侧,单击选中所有按钮或手动选中您行中的所有框。
  • 请验证未选中“防止跨站点请求伪造漏洞”复选框。(由于此Jenkins仅可从您的计算机访问,因此这不是太大的问题)
  • 单击“[保存]”,并注销Jenkins并重新登录以确保它可以正常工作。如果不能,请从头开始,并清空/opt/docker/jenkins/jenkins_home文件夹后重新启动。

添加git用户

我们需要允许我们的git挂钩使用最少的权限登录到本地Jenkins。只需查看和构建作业即可满足要求。因此,我们创建一个名为git的用户,密码为login

将浏览器直接指向http://localhost:8787/securityRealm/addUser,将git作为用户名,login作为密码添加。然后点击“[创建用户]”。

将权限添加到git用户

在浏览器中转到http://localhost:8787/configureSecurity页面。将git用户添加到矩阵中:

  • User/group to add:字段中输入git,然后点击[ Add ]

现在是时候勾选最小权限的框了。只需要这些权限:

  • overall:read
  • job:build
  • job:discover
  • job:read

确保未选中Prevent Cross Site Request Forgery exploits复选框,然后点击[ Save ]

创建流水线项目

我们假设我们有用户名user,并且我们启用了 git 的项目名为project,位于/home/user/projects/project目录下,其中包含Jenkinsfile文件。

在您的http://localhost:8787 Jenkins中添加一个新的流水线项目。我将其命名为hookpipeline以供参考。

  • 在Jenkins菜单中单击New Item
  • 将项目命名为hookpipeline
  • 单击Pipeline
  • 单击[ OK ]
  • 在构建触发器部分中选中Poll SCM复选框,留空计划表。
  • 在流水线部分中:
    • 选择Pipeline script from SCM
    • Repository URL字段中输入user@172.17.0.1:projects/project/.git
    • Script Path字段中输入Jenkinsfile
  • 保存hookpipeline项目
  • 手动构建一次hookpipeline,这是为了让Poll SCM开始工作。

创建git hook

进入/home/user/projects/project/.git/hooks文件夹,创建一个名为post-commit的文件,其中包含以下内容:

#!/bin/sh
BRANCHNAME=$(git rev-parse --abbrev-ref HEAD)
MASTERBRANCH='master'

curl -XPOST -u git:login http://localhost:8787/job/hookpipeline/build
echo "Build triggered successfully on branch: $BRANCHNAME"

将此文件设为可执行:

$ chmod +x /home/user/projects/project/.git/hooks/post-commit

测试提交后钩子:

$ /home/user/projects/project/.git/hooks/post-commit

在Jenkins中检查您的hookpipeline项目是否被触发。

最后对您的项目进行任意更改,添加更改并提交。这将在本地Jenkins中触发流水线。

愉快的一天!


1
我在Mac上遇到了这个错误。有人可以帮我吗?>> 错误:ssh:连接到主机172.17.0.1端口22被拒绝 - - Manoj Shrestha
@ManojShrestha:IP地址172.17.0.1是运行Docker容器的机器的默认IP地址。您可以使用您机器的MAC地址代替。 - javabeangrinder
@ManojShrestha:你也可以尝试像这样找到你设置的网关IP:$ docker inspect jenkins | grep Gateway - javabeangrinder
3
如果您的Docker主机安装在macOS上,并且希望从Docker容器内部进行ssh登录,则应该使用ssh user@docker.for.mac.localhost而不是使用IP地址。还要确保您已经从macOS系统偏好设置->共享文件夹菜单启用了远程登录功能。 - pangiole
1
注意:对于较新版本的Jenkins,post-commit CURL命令已更改。在通过用户配置页面(右上角)从UI检索API令牌值后,请使用curl -v -XPOST -u git:$API_TOKEN http://localhost:8787/job/VMInit/build。请参见https://www.jenkins.io/doc/book/system-administration/authenticating-scripted-clients/。 - millebi
显示剩余3条评论

76

简而言之

详细解释

Jenkins流水线测试变得越来越麻烦。与传统的声明式作业配置方法不同,用户受限于UI暴露的内容,新的Jenkins流水线是构建过程的编程语言,您可以在其中混合声明性部分和自己的代码。作为优秀的开发人员,我们也希望对此类代码进行一些单元测试。

当开发Jenkins流水线时,有三个步骤需要遵循。第一步应覆盖80%的使用情况。

  1. 尽可能多地在构建脚本中处理(例如 Maven、Gradle、Gulp 等)。然后在您的流水线脚本中按正确顺序调用构建任务。构建流水线只是协调和执行构建任务,但没有任何需要特殊测试的重要逻辑。
  2. 如果无法完全应用前面的规则,则转到Pipeline共享库,在其中可以开发和测试自定义逻辑,并将其集成到流水线中。
  3. 如果前面的两个步骤都无法解决问题,则可以尝试最近出现的这些库(2017年3月)。Jenkins Pipeline单元测试框架pipelineUnit(有示例)。自2018年起还有Jenkinsfile Runner,一个用于从命令行工具执行Jenkins流水线的软件包。

示例

pipelineUnit GitHub 仓库包含一些 Spock 示例,用于演示如何使用Jenkins Pipeline 单元测试框架


2
你能否同时包含这两个库的简要比较呢? - sorin

31

Jenkins具有“重播”功能,可使您在不更新源代码的情况下快速重播作业:

重播功能


3
请注意,它显示在构建页面上,而不是项目或分支页面上。 - ArtOfWarfare

23

截至2017年7月底,使用Blue Ocean插件,您可以直接在可视化流水线编辑器中检查声明性流水线的语法。当您点击“配置”时,该编辑器仅适用于github项目(这是一个已知问题,他们正在努力使其也适用于git等)。

但是,如此问题所述,您可以通过浏览以下内容打开编辑器:

[Jenkins URL]/blue/organizations/jenkins/pipeline-editor/

然后在页面中间单击并按下Ctrl+S,这将打开一个文本区域,您可以在其中粘贴管道声明脚本。当您单击更新时,如果存在语法错误,编辑器将告诉您语法错误的位置。就像这张截图中一样:

As a quick test I wrongly typed "stepps" instead of "steps"

如果没有语法错误,文本框将关闭并且页面将呈现您的流水线。不用担心它不会保存任何东西(如果是github项目,则会提交Jenkinsfile更改)。我对Jenkins很陌生,这很有帮助,没有这个我必须多次提交Jenkinsfile,直到它能够工作(非常烦人!)。希望这有所帮助。干杯。

2
这是因为截至2017年,Jenkins仍旧致力于解决点对点软件工程师的问题;)... 至少Atom有一个不错的Groovy语言检查器。虽然只支持Groovy但它确实有所帮助。 - sorin
具有语法高亮功能的编辑器也是经典 Jenkins 用户界面的一部分。 - Vad1mo
看起来这只适用于声明式流水线,而不适用于脚本流水线(Groovy)。 - drizin

9

没有冒犯之意,但是除非您不断更新您的东西,否则它将会变得相当无用,因为当前管道语法似乎处于不断变化的状态。 - krad
没有问题。就我所见,流水线语法在基本的流水线步骤中已经非常标准化了(https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/)。我现在使用它已经两年了,没有遇到过任何不兼容的变化。Jenkins插件不应该被使用,在共享库中可以使用自定义命令抽象API的更改,这里你将有API保证。如果你说的是声明式语法,那可能是真的。在我的流水线中,我只使用编程API,这也是Jenny支持的。非常坚实可靠 :) - bogdan.mustiata

8
在我的开发环境中,由于缺乏适当的Groovy编辑器,许多Jenkinsfile问题都源于简单的语法错误。为了解决这个问题,您可以针对您的Jenkins实例(运行在$JENKINS_HTTP_URL)验证Jenkinsfile:
curl -X POST -H $(curl '$JENKINS_HTTP_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') -F "jenkinsfile=<Jenkinsfile" $JENKINS_HTTP_URL/pipeline-model-converter/validate 上述命令是从https://github.com/jenkinsci/pipeline-model-definition-plugin/wiki/Validating-(or-linting)-a-Declarative-Jenkinsfile-from-the-command-line稍微修改的版本。

4
这正是我正在寻找的东西 - 不幸的是它只适用于声明式流水线而不是脚本式流水线 :( - thom_nic

6
据我所知,Pipeline插件是新的Jenkinsfile机制的“引擎”,因此我非常确信您可以使用它来本地测试脚本。
我不确定将其复制到Jenkinsfile中是否需要任何其他步骤,但语法等应该完全相同。 编辑:找到关于“引擎”的参考,请查看特性描述,最后一段第一项。

3

使用VS Code的Jenkins Jack扩展,您可以通过本地文件在本地或远程运行的Jenkins上测试您的Jenkinsfile,而无需使用git push方式。而且您将在VS Code中获得作业的运行日志,能够在Jenkins中创建作业等等。我希望这对于更多寻找开发Jenkinsfile的人有所帮助。


3
为了简便起见,您可以在git存储库的根目录下创建一个Jenkinsfile,类似于以下基于声明性流水线groovy语法的示例'Jenkinsfile'。
pipeline {

    agent any

    stages {
        stage('Build the Project') {
            steps {
                git 'https://github.com/jaikrgupta/CarthageAPI-1.0.git'
                echo pwd()
                sh 'ls -alrt'
                sh 'pip install -r requirements.txt'
                sh 'python app.py &'
                echo "Build stage gets finished here"
            }
        }
        stage('Test') {
            steps {
                sh 'chmod 777 ./scripts/test-script.sh'
                sh './scripts/test-script.sh'
                sh 'cat ./test-reports/test_script.log'
                echo "Test stage gets finished here"
            }
        }
}

https://github.com/jaikrgupta/CarthageAPI-1.0.git

现在你可以在Jenkins中设置一个新的项目作为Pipeline job。 将Definition选项选择为Pipeline script from SCM,将SCM选项选择为Git。 将项目的git仓库链接粘贴到Repository URL中,并将Jenkinsfile粘贴到脚本名称框中。 然后点击lightweight checkout选项并保存项目。 这样,每当您提交更改到git仓库时,都可以通过在Jenkins中每次运行Build Now来测试更改。请按照以下视觉指南中的说明轻松设置Jenkins Pipeline的作业。

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接