267

在编写 jenkins 管道时,提交每个新更改以查看它是否有效似乎非常不方便。

有没有办法在不提交代码的情况下在本地执行这些?

4

15 回答 15

174

您不能在本地执行 Pipeline 脚本,因为它的全部目的是编写 Jenkins 脚本。(这就是为什么最好保持Jenkinsfile简短并仅限于实际处理 Jenkins 功能的代码的原因之一;您的实际构建逻辑应该由您通过单行shbat步骤调用的外部流程或构建工具来处理。)

如果您想测试更改为Jenkinsfilelive 但不提交,请使用1.14 中添加重播功能

JENKINS-33925跟踪所需的自动化测试框架。

于 2016-03-31T11:16:37.603 回答
105

我有一个适合我的解决方案。它由一个在 docker 中运行的本地 jenkins 和一个 git web hook 组成,用于在每次提交时触发本地 jenkins 中的管道。您不再需要推送到您的 github 或 bitbucket 存储库来测试管道。

这只在linux环境中测试过。

尽管这条指令有点长,但完成这项工作相当简单。大多数步骤都在那里。

这就是你需要的

  • Docker 已安装并正常工作。这不是本说明的一部分。
  • 在本地运行在 docker 中的 Jenkins。下面解释如何。
    • 本地 Jenkins docker 用户从本地 git 存储库中提取的正确权限(ssh 访问密钥)。 下面解释如何。
    • 从本地 git 存储库中提取的 Jenkins 管道项目。下面解释。
    • 本地 Jenkins 中具有最低权限的 git 用户。下面解释。
  • 具有触发管道项目的提交后 Web 挂钩的 git 项目。下面解释。

这就是你的做法

詹金斯码头工人

创建一个名为 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

构建 local_jenkins 镜像

您只需执行一次或在向 Dockerfile 添加内容之后执行此操作。

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

启动并重启 local_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文件夹存在并且您对它具有用户读写权限。

要启动或重新启动您的詹金斯,只需输入:

$ 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-ing 到您的计算机来完成循环。

jenkins@e7b23bad10aa:/$ ssh user@172.17.0.1

这次您不需要输入密码。如果这样做,则出现问题,您必须重试。

您现在将位于您的计算机主文件夹中。试试看ls

不要停在这里,因为我们需要摆脱一系列 ssh shell。

$ exit
jenkins@e7b23bad10aa:/$ exit

正确的!现在我们回来了,准备继续。

安装你的詹金斯

您将在浏览器中的http://localhost:8787中找到您的本地 Jenkins 。

当您第一次将浏览器指向本地 Jenkins 时,您会非常喜欢安装向导。默认值很好,但请确保在设置期间安装管道插件。

设置你的詹金斯

在http://localhost:8787/configureSecurity上激活基于矩阵的安全性并通过将自己添加到矩阵并勾选所有框来授予自己所有权利非常重要的。(最右边有一个勾选所有框图标)

  • 选择Jenkins’ own user database作为安全领域
  • Matrix-based security在授权部分中选择
  • 在字段中输入您的用户名,User/group to add:然后单击[ Add ]按钮
  • 在上面的表格中,您的用户名旁边应该会弹出一个人物图标。如果它被交叉,您输入了错误的用户名。
  • 转到表格的最右侧并单击全部勾选按钮或手动勾选行中的所有框。
  • 请确认该复选框Prevent Cross Site Request Forgery exploits未选中。(因为这个 Jenkins 只能通过您的计算机访问,所以这没什么大不了的)
  • 单击[ Save ]并注销 Jenkins,然后再次登录以确保它正常工作。 如果不是,您必须从头开始并/opt/docker/jenkins/jenkins_home在重新启动之前清空文件夹

添加 git 用户

我们需要让我们的 git 钩子以最少的权限登录到我们的本地 Jenkins。仅仅看到和建立工作就足够了。因此,我们创建了一个名为gitpassword的用户login

将浏览器定向到http://localhost:8787/securityRealm/addUser并添加git为用户名和login密码。点击[ Create User ]

给 git 用户添加权限

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

  • git在字段中写入User/group to add:并单击[ Add ]

现在是时候检查 git 用户的最小权限框了。只需要这些:

  • 总体:阅读
  • 工作:建造
  • 工作:发现
  • 工作:阅读

确保Prevent Cross Site Request Forgery exploits未选中该复选框并单击[ Save ]

创建管道项目

我们假设我们有用户名user和启用 git 的项目,Jenkinsfile其中被调用project并位于/home/user/projects/project

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

  • New Item在 Jenkins 菜单中单击
  • 为项目命名hookpipeline
  • 点击管道
  • 点击[ OK ]
  • 勾选Poll SCM构建触发器部分中的复选框。将计划留空。
  • 在管道部分:
    • 选择Pipeline script from SCM
    • Repository URL字段中输入user@172.17.0.1:projects/project/.git
    • Script Path字段中输入Jenkinsfile
  • 保存 hookpipeline 项目
  • 手动构建一次钩子管道,轮询 SCM 开始工作需要这样做。

创建 git 钩子

转到/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

如果您的 hookpipeline 项目被触发,请签入 Jenkins。

最后对您的项目进行一些任意更改,添加更改并进行提交。现在这将触发您本地 Jenkins 中的管道。

快乐的时光!

于 2017-12-06T10:06:20.527 回答
72

TL;博士

长版
Jenkins 流水线测试变得越来越痛苦。与经典的声明性作业配置方法不同,用户仅限于 UI 暴露的内容,新的 Jenkins Pipeline 是一种用于构建过程的成熟编程语言,您可以将声明性部分与您自己的代码混合在一起。作为优秀的开发人员,我们也希望对这类代码进行一些单元测试。

在开发 Jenkins Pipelines 时,您应该遵循三个步骤。第1 步应涵盖 80% 的用例。

  1. 尽可能多地使用构建脚本(例如 Maven、Gradle、Gulp 等)。然后在您的管道脚本中以正确的顺序调用构建任务。构建管道只是编排和执行构建任务,但没有任何需要特殊测试的主要逻辑。
  2. 如果无法完全应用之前的规则,则转到管道共享库,您可以在其中自行开发和测试自定义逻辑并将它们集成到管道中。
  3. 如果上述所有方法都失败了,您可以尝试最近出现的那些库之一(2017 年 3 月)。Jenkins 流水线单元测试框架pipelineUnit(示例)。自 2018 年以来,还有Jenkinsfile Runner,这是一个从命令行工具执行 Jenkins 管道的包。

例子

pipelineUnit GitHub repo 包含一些关于如何使用Jenkins Pipeline 单元测试框架的Spock 示例

于 2017-03-18T14:15:30.743 回答
30

Jenkins 有一个“重播”功能,它使您能够快速重播作业而无需更新源:

重播功能

于 2018-07-04T13:41:07.817 回答
18

在使用Blue Ocean插件撰写本文时(2017 年 7 月末) ,您可以直接在可视化管道编辑器中检查声明性管道的语法。当您单击“配置”仅针对github 项目时,编辑器在 Blue Ocean UI 中工作(这是一个已知问题,他们正在努力使其在 git 等上也能工作)。

但是,正如在这个问题中所解释的,您可以打开编辑器浏览到:

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

然后单击页面中间,然后按Ctrl+S,这将打开一个文本区域,您可以在其中粘贴管道声明性脚本。当你点击更新时,如果有语法错误,编辑器会告诉你语法错误在哪里。就像在这个屏幕截图中一样:

作为一个快速测试,我输入错误

如果没有语法错误,文本区域将关闭,页面将可视化您的管道。不用担心它不会保存任何东西(如果它是一个 github 项目,它会提交 Jenkinsfile 更改)。

我是 Jenkins 的新手,这很有帮助,没有这个我不得不多次提交 Jenkinsfile,直到它起作用(非常烦人!)。希望这可以帮助。干杯。

于 2017-07-26T15:00:19.770 回答
8

聚会有点晚了,但这就是我写的原因jenny,对一些核心 Jenkinsfile 步骤的小重新实现。(https://github.com/bmustiata/jenny

于 2018-05-11T20:59:01.237 回答
6

据我所知,这个管道插件是新 Jenkinsfile 机制的“引擎”,所以我非常肯定你可以用它来本地测试你的脚本。

我不确定将其复制到 Jenkinsfile 时是否需要任何其他步骤,但是语法等应该完全相同。

编辑:在“引擎”上找到参考,检查功能描述,最后一段,第一个条目。

于 2016-03-30T16:07:00.067 回答
6

在我的开发设置中——缺少合适的 Groovy 编辑器——大量 Jenkinsfile 问题源于简单的语法错误。要解决此问题,您可以针对您的 Jenkins 实例验证 Jenkinsfile(运行于$JENKINS_HTTP_URL):

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的略微修改版本

于 2017-04-20T08:47:31.680 回答
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 中将新项目设置为流水线作业。为选项选择DefinitionasPipeline script from SCM和。将项目的 git repo 链接粘贴到存储库 URL 和脚本名称框中。然后单击该选项并保存项目。因此,每当您将提交推送到 git 存储库时,您始终可以测试每次在 Jenkins 中运行的更改。GitSCMJenkinsfilelightweight checkoutBuild Now

请按照以下视觉效果中的说明轻松设置 Jenkins Pipeline 的工作。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

于 2020-08-21T18:54:07.330 回答
2

将 SSH 密钥放入 Jenkins 配置文件中,然后使用声明性 linter,如下所示:

ssh jenkins.hostname.here declarative-linter < Jenkinsfile

这将对您的 Jenkinsfile 进行静态分析。在您选择的编辑器中,定义自动运行该命令的键盘快捷键。在我使用的 Visual Studio Code 中,转到 Tasks > Configure Tasks,然后使用以下 JSON 创建Validate Jenkinsfile命令:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Validate Jenkinsfile",
      "type": "shell",
      "command": "ssh jenkins.hostname declarative-linter < ${file}"
    }
  ]
}
于 2018-02-16T11:26:47.740 回答
2

除了其他人已经提到的重播功能(同样有用!),我发现以下内容也很有用:

  1. 创建一个测试流水线作业,您可以在其中输入流水线代码或指向您的 Jenkinsfile 的存储库/分支以快速测试某些内容。要进行更准确的测试,请使用指向您自己的分支的多分支管道,您可以在其中快速进行更改和提交,而不会影响产品。BRANCH_NAME env 之类的东西仅在 Multibranch 中可用。
  2. 由于 Jenkinsfile 是 Groovy 代码,只需使用“groovy Jenkinsfile”调用它即可验证基本语法。
于 2017-07-21T21:17:45.817 回答
1

您可以验证您的管道以找出语法问题。Jenkins 有很好的用于Jenkisfile 验证的 API - https://jenkins_url/pipeline-model-converter/validate

使用 curl 并传递您的 .Jenkinsfile,您将立即获得语法检查

curl --user username:password -X POST -F "jenkinsfile=<jenkinsfile" https://jenkins_url/pipeline-model-converter/validate

您可以将此工作流程添加到编辑器:

于 2021-02-08T21:00:18.323 回答
0

我正在使用 replay future 进行一些更新并快速运行。

于 2018-07-03T12:19:39.353 回答
0

有一些限制和脚本管道我使用这个解决方案:

  1. 带有内联 groovy 脚本的流水线作业:

node('master') {
    stage('Run!') {
                def script = load('...you job file...')
    }
}

  1. 用于测试的 Jenkinsfile 与 lesfurets 具有相同的结构:

def execute() {
 ... main job code here ...
}
execute()
于 2018-08-01T13:03:36.380 回答
0

这是一个简短的解决方案,可以让我非常快速地测试管道代码:

pipeline {
    agent any
    options {
        skipDefaultCheckout true
        timestamps()
    }
    parameters {
        text(name: 'SCRIPT', defaultValue: params.SCRIPT,
            description: 'Groovy script')
    }
    stages {
        stage("main") {
            steps {
                script {
                    writeFile file: 'script.groovy', 
                        text: params.SCRIPT
                    def groovyScript = load 'script.groovy'
                    echo "Return value: " + groovyScript
                }
            } // steps
        } // stage
    } // stages
} // pipeline
  1. skipDefaultCheckout true因为我们不需要这个工具 git 存储库中的文件。
  2. defaultValue: params.SCRIPT将默认设置为最新执行。如果仅由一个用户使用,它可以实现非常快速的短期测试周期。
  3. 给定的脚本被写入文件,并加载并使用load.

通过这个设置,我可以测试我在其他 Jenkinsfile 中可以做的所有事情,包括使用共享库

于 2021-12-01T09:00:44.730 回答