1645 lines
661 KiB
HTML
1645 lines
661 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html><head><title>Jenkins</title><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><meta property="og:title" content="Jenkins"/><meta property="og:description" content="Jenkins 概述 § Jenkins 是什么 § Jenkins 是一种广泛使用的开源自动化服务器,旨在简化和自动化软件开发过程中的各种任务,特别是在持续集成(CI)和持续交付(CD)方面。 持续集成是一种软件开发实践,强调频繁地将代码集成到共享代码库中,并自动进行构建和测试,以尽早发现和解决集成问题。持续交付进一步扩展了这一概念,通过自动化部署管道,使得代码可以在任何时间点安全地部署到生产环境中。Jenkins 通过插件体系支持构建、测试和部署的自动化工作流,是 CI/CD 实践的重要工具。 Jenkins 的历史与发展 § Jenkins 的前身是 Hudson,由 Sun Microsystems 的开发者 Kohsuke Kawaguchi 于 2004 年创建。Hudson 在快速开发和社区支持下迅速流行,然而在 2011 年,由于与 Oracle(Sun Microsystems 被 Oracle 收购)在商标权和项目控制方面的分歧,Hudson 社区分裂,Kawaguchi 和大部分社区成员创建了一个新的项目 Jenkins。自此之后,Jenkins 迅速成为 CI/CD 领域的主流工具,并在全球范围内得到了广泛应用和支持。 Jenkins 的发展伴随着软件开发方式的演变,从最初的自动化构建工具,逐渐扩展为一个可以支持复杂持续交付和 DevOps 实践的平台。随着社区贡献的插件数量不断增加,Jenkins 的功能覆盖了从源码管理、编译、测试到部署的各个环节。近年来,Jenkins 社区推出了 Jenkins X,专注于云原生 CI/CD,进一步推动了 Jenkins 在容器化和微服务架构中的应用。 Jenkins 的架构及工作原理 § Jenkins 的核心架构由三部分组成:主服务器(Master)、构建代理(Agent/Slave) 和 工作节点(Node)。主服务器负责管理 Jenkins 的核心功能,包括调度构建作业、分配工作给构建代理、监控代理的执行情况以及提供用户接口。构建代理是实际执行构建、测试等任务的工作节点,可以分布在不同的物理或虚拟机器上。通过分布式架构,Jenkins 能够高效处理大规模并行任务。 Jenkins 的工作原理基于流水线(Pipeline)模型,流水线定义了构建、测试、部署等一系列任务的执行步骤。用户可以通过 Jenkins UI 或 Jenkinsfile(文本文件形式)来定义流水线。Jenkins 通过与源码管理系统(如 Git)、构建工具(如 Maven、Gradle)和部署工具(如 Kubernetes、Ansible)等的集成,实现自动化的端到端软件交付流程。 Jenkins 与其他 CI/CD 工具的对比 § Jenkins 作为 CI/CD 工具的代表,与其他流行的工具如 GitLab CI、Travis CI、CircleCI、Bamboo 等存在差异。Jenkins 的优势在于其高度的可扩展性和灵活性,通过数千种插件可以与各种工具和平台集成,适用于从小型团队到大型企业的各种规模的项目。然而,这种灵活性也带来了较高的配置和维护成本。 相比之下,GitLab CI 与 GitLab 紧密集成,适合使用 GitLab 进行源码管理的团队;Travis CI 和 CircleCI 提供简便的配置和云端执行,适合中小型团队的持续集成需求;Bamboo 则与 Atlassian 生态系统深度集成,适合使用 Jira、Bitbucket 等 Atlassian 工具链的团队。 选择哪种工具往往取决于团队的现有技术栈、规模、预算以及特定需求。 Jenkins 安装和配置 § Jenkins 提供 多种安装方式,用户可以根据需求和环境选择适合的 安装方法。 初始配置和界面概览 § 在完成 Jenkins 的安装后,用户需要进行初始配置。第一次启动 Jenkins 时,会提示输入管理员密码,之后进入配置向导。配置向导会引导用户安装推荐的插件、创建管理员用户、配置邮件通知等基础设置。 Jenkins 的用户界<EFBFBD>
|
|||
|
var _hmt = _hmt || [];
|
|||
|
(function() {
|
|||
|
var hm = document.createElement("script");
|
|||
|
hm.src = "https://hm.baidu.com/hm.js?94d8ccb156eb7c65abf317e6e01cdba9";
|
|||
|
var s = document.getElementsByTagName("script")[0];
|
|||
|
s.parentNode.insertBefore(hm, s);
|
|||
|
})();
|
|||
|
</script><script async src="https://www.googletagmanager.com/gtag/js?id=G-MHMEL0F832"></script><script>
|
|||
|
(function() {
|
|||
|
window.dataLayer = window.dataLayer || [];
|
|||
|
function gtag() {
|
|||
|
window.dataLayer.push(arguments);
|
|||
|
}
|
|||
|
gtag('js', new Date());
|
|||
|
gtag('config', 'G-MHMEL0F832');
|
|||
|
})();
|
|||
|
</script><link href="../../../index.css" rel="stylesheet" type="text/css" spa-preserve/><link href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" rel="stylesheet" type="text/css" spa-preserve/><link href="https://fonts.googleapis.com/css2?family=IBM Plex Mono&family=Schibsted Grotesk:wght@400;700&family=Source Sans Pro:ital,wght@0,400;0,600;1,400;1,600&display=swap" rel="stylesheet" type="text/css" spa-preserve/><script src="../../../prescript.js" type="application/javascript" spa-preserve></script><script type="application/javascript" spa-preserve>const fetchData = fetch(`../../../static/contentIndex.json`).then(data => data.json())</script></head><body data-slug="Technology/SoftwareEngineering/CI&CD/Jenkins"><div id="quartz-root" class="page"><div id="quartz-body"><div class="left sidebar"><h1 class="page-title "><a href="../../..">📚 X·Eden</a></h1><div class="spacer mobile-only"></div><div class="search "><div id="search-icon"><p>Search</p><div></div><svg tabIndex="0" aria-labelledby="title desc" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.9 19.7"><title id="title">Search</title><desc id="desc">Search</desc><g class="search-path" fill="none"><path stroke-linecap="square" d="M18.5 18.3l-5.4-5.4"></path><circle cx="8" cy="8" r="7"></circle></g></svg></div><div id="search-container"><div id="search-space"><input autocomplete="off" id="search-bar" name="search" type="text" aria-label="Search for something" placeholder="Search for something"/><div id="results-container"></div></div></div></div><div class="darkmode "><input class="toggle" id="darkmode-toggle" type="checkbox" tabIndex="-1"/><label id="toggle-label-light" for="darkmode-toggle" tabIndex="-1"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1" id="dayIcon" x="0px" y="0px" viewBox="0 0 35 35" style="enable-background:new 0 0 35 35;" xmlSpace="preserve"><title>Light mode</title><path d="M6,17.5C6,16.672,5.328,16,4.5,16h-3C0.672,16,0,16.672,0,17.5 S0.672,19,1.5,19h3C5.328,19,6,18.328,6,17.5z M7.5,26c-0.414,0-0.789,0.168-1.061,0.439l-2,2C4.168,28.711,4,29.086,4,29.5 C4,30.328,4.671,31,5.5,31c0.414,0,0.789-0.168,1.06-0.44l2-2C8.832,28.289,9,27.914,9,27.5C9,26.672,8.329,26,7.5,26z M17.5,6 C18.329,6,19,5.328,19,4.5v-3C19,0.672,18.329,0,17.5,0S16,0.672,16,1.5v3C16,5.328,16.671,6,17.5,6z M27.5,9 c0.414,0,0.789-0.168,1.06-0.439l2-2C30.832,6.289,31,5.914,31,5.5C31,4.672,30.329,4,29.5,4c-0.414,0-0.789,0.168-1.061,0.44 l-2,2C26.168,6.711,26,7.086,26,7.5C26,8.328,26.671,9,27.5,9z M6.439,8.561C6.711,8.832,7.086,9,7.5,9C8.328,9,9,8.328,9,7.5 c0-0.414-0.168-0.789-0.439-1.061l-2-2C6.289,4.168,5.914,4,5.5,4C4.672,4,4,4.672,4,5.5c0,0.414,0.168,0.789,0.439,1.06 L6.439,8.561z M33.5,16h-3c-0.828,0-1.5,0.672-1.5,1.5s0.672,1.5,1.5,1.5h3c0.828,0,1.5-0.672,1.5-1.5S34.328,16,33.5,16z M28.561,26.439C28.289,26.168,27.914,26,27.5,26c-0.828,0-1.5,0.672-1.5,1.5c0,0.414,0.168,0.789,0.439,1.06l2,2 C28.711,30.832,29.086,31,29.5,31c0.828,0,1.5-0.672,1.5-1.5c0-0.414-0.168-0.789-0.439-1.061L28.561,26.439z M17.5,29 c-0.829,0-1.5,0.672-1.5,1.5v3c0,0.828,0.671,1.5,1.5,1.5s1.5-0.672,1.5-1.5v-3C19,29.672,18.329,29,17.5,29z M17.5,7 C11.71,7,7,11.71,7,17.5S11.71,28,17.5,28S28,23.29,28,17.5S23.29,7,17.5,7z M17.5,25c-4.136,0-7.5-3.364-7.5-7.5 c0-4.136,3.364-7.5,7.5-7.5c4.136,0,7.5,3.364,7.5,7.5C25,21.636,21.636,25,17.5,25z"></path></svg></label><label id="toggle-label-dark" for="darkmode-toggle" tabIndex="-1"><svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" version="1.1" id="nightIcon" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background='new 0 0 100 100'" xmlSpace="preserve"><title>Dark mode</title><path d="M96.76,66.458c-0.853-0.852-2.15-1.064-3.23-0.534c-6.063,2.991-12.858,4.571-19.655,4.571 C62.022,70.495,50.88,65.88,42.5,57.5C29.043,44.043,25.658,23.536,34.076,6.47c0.532-1.08,0.318-2.379-0.534-3.23 c-0.851-0.852-2.15-1.064-3.23-0.534c-4.918,2.427-9.375,5.619-13.246,9.491c-9.447,9.447-14.65,22.008-14.65,35.369 c0,13.3
|
|||
|
<p><img src="https://static.7wate.com/2024/08/09/a76a2f574c2b5.svg" alt="Jenkins_logo_with_title.svg"/></p>
|
|||
|
<h3 id="jenkins-是什么">Jenkins 是什么<a aria-hidden="true" tabindex="-1" href="#jenkins-是什么" class="internal"> §</a></h3>
|
|||
|
<p><strong>Jenkins 是一种广泛使用的开源自动化服务器,旨在简化和自动化软件开发过程中的各种任务,特别是在持续集成(CI)和持续交付(CD)方面。</strong> 持续集成是一种软件开发实践,强调频繁地将代码集成到共享代码库中,并自动进行构建和测试,以尽早发现和解决集成问题。持续交付进一步扩展了这一概念,通过自动化部署管道,使得代码可以在任何时间点安全地部署到生产环境中。Jenkins 通过插件体系支持构建、测试和部署的自动化工作流,是 CI/CD 实践的重要工具。</p>
|
|||
|
<h3 id="jenkins-的历史与发展">Jenkins 的历史与发展<a aria-hidden="true" tabindex="-1" href="#jenkins-的历史与发展" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 的前身是 Hudson,由 Sun Microsystems 的开发者 Kohsuke Kawaguchi 于 2004 年创建。Hudson 在快速开发和社区支持下迅速流行,然而在 2011 年,由于与 Oracle(Sun Microsystems 被 Oracle 收购)在商标权和项目控制方面的分歧,Hudson 社区分裂,Kawaguchi 和大部分社区成员创建了一个新的项目 Jenkins。自此之后,Jenkins 迅速成为 CI/CD 领域的主流工具,并在全球范围内得到了广泛应用和支持。</p>
|
|||
|
<p>Jenkins 的发展伴随着软件开发方式的演变,从最初的自动化构建工具,逐渐扩展为一个可以支持复杂持续交付和 DevOps 实践的平台。随着社区贡献的插件数量不断增加,Jenkins 的功能覆盖了从源码管理、编译、测试到部署的各个环节。近年来,Jenkins 社区推出了 Jenkins X,专注于云原生 CI/CD,进一步推动了 Jenkins 在容器化和微服务架构中的应用。</p>
|
|||
|
<h3 id="jenkins-的架构及工作原理">Jenkins 的架构及工作原理<a aria-hidden="true" tabindex="-1" href="#jenkins-的架构及工作原理" class="internal"> §</a></h3>
|
|||
|
<p><strong><img src="https://static.7wate.com/2024/08/09/b662feac8fb27.gif" alt="jenkins-architecture.gif"/></strong></p>
|
|||
|
<p>Jenkins 的核心架构由三部分组成:<strong>主服务器(Master)</strong>、<strong>构建代理(Agent/Slave)</strong> 和 <strong>工作节点(Node)</strong>。主服务器负责管理 Jenkins 的核心功能,包括调度构建作业、分配工作给构建代理、监控代理的执行情况以及提供用户接口。构建代理是实际执行构建、测试等任务的工作节点,可以分布在不同的物理或虚拟机器上。通过分布式架构,Jenkins 能够高效处理大规模并行任务。</p>
|
|||
|
<p><img src="https://static.7wate.com/2024/08/09/b2cbab52bc188.png" alt="Jenkins Pipeline"/></p>
|
|||
|
<p>Jenkins 的工作原理基于流水线(Pipeline)模型,流水线定义了构建、测试、部署等一系列任务的执行步骤。用户可以通过 Jenkins UI 或 Jenkinsfile(文本文件形式)来定义流水线。Jenkins 通过与源码管理系统(如 Git)、构建工具(如 Maven、Gradle)和部署工具(如 Kubernetes、Ansible)等的集成,实现自动化的端到端软件交付流程。</p>
|
|||
|
<h3 id="jenkins-与其他-cicd-工具的对比">Jenkins 与其他 CI/CD 工具的对比<a aria-hidden="true" tabindex="-1" href="#jenkins-与其他-cicd-工具的对比" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 作为 CI/CD 工具的代表,与其他流行的工具如 GitLab CI、Travis CI、CircleCI、Bamboo 等存在差异。<strong>Jenkins 的优势在于其高度的可扩展性和灵活性,通过数千种插件可以与各种工具和平台集成,适用于从小型团队到大型企业的各种规模的项目。然而,这种灵活性也带来了较高的配置和维护成本。</strong></p>
|
|||
|
<p>相比之下,GitLab CI 与 GitLab 紧密集成,适合使用 GitLab 进行源码管理的团队;Travis CI 和 CircleCI 提供简便的配置和云端执行,适合中小型团队的持续集成需求;Bamboo 则与 Atlassian 生态系统深度集成,适合使用 Jira、Bitbucket 等 Atlassian 工具链的团队。</p>
|
|||
|
<p><strong>选择哪种工具往往取决于团队的现有技术栈、规模、预算以及特定需求。</strong></p>
|
|||
|
<h2 id="jenkins-安装和配置">Jenkins 安装和配置<a aria-hidden="true" tabindex="-1" href="#jenkins-安装和配置" class="internal"> §</a></h2>
|
|||
|
<p>Jenkins 提供 <a href="https://www.jenkins.io/doc/book/installing/linux/" class="external">多种安装方式</a>,用户可以根据需求和环境选择适合的 <a href="https://www.jenkins.io/doc/book/installing/linux/" class="external">安装方法</a>。</p>
|
|||
|
<h3 id="初始配置和界面概览">初始配置和界面概览<a aria-hidden="true" tabindex="-1" href="#初始配置和界面概览" class="internal"> §</a></h3>
|
|||
|
<p><img src="https://static.7wate.com/2024/08/09/88eaa910e3de8.png" alt="Updated-jenkins-view.png"/></p>
|
|||
|
<p>在完成 Jenkins 的安装后,用户需要进行初始配置。第一次启动 Jenkins 时,会提示输入管理员密码,之后进入配置向导。配置向导会引导用户安装推荐的插件、创建管理员用户、配置邮件通知等基础设置。</p>
|
|||
|
<p><strong>Jenkins 的用户界面直观且功能强大。</strong> 主界面分为多个部分,包括主菜单(Dashboard)、视图(Views)、构建队列(Build Queue)和系统管理(Manage Jenkins)。用户可以在主菜单中创建新的 Job、查看当前的构建状态和历史记录、配置 Jenkins 系统设置等。</p>
|
|||
|
<p><img src="https://static.7wate.com/2024/08/15/bf11ac9982e36.png" alt="Jenkins 的用户界面"/></p>
|
|||
|
<h3 id="系统配置全局安全设置系统信息环境变量配置">系统配置:全局安全设置、系统信息、环境变量配置<a aria-hidden="true" tabindex="-1" href="#系统配置全局安全设置系统信息环境变量配置" class="internal"> §</a></h3>
|
|||
|
<p>系统配置是 Jenkins 正常运行的核心,良好的系统配置有助于提升 Jenkins 的性能、安全性和易用性。</p>
|
|||
|
<ol>
|
|||
|
<li><strong>全局安全设置</strong>:Jenkins 提供多种安全控制机制,包括用户身份验证、授权策略、SSL/TLS 加密、Agent 通信加密等。管理员可以配置基于角色的访问控制(Role-Based Access Control,RBAC),限制用户对不同项目和资源的访问权限。</li>
|
|||
|
<li><strong>系统信息</strong>:Jenkins 系统信息页面显示了有关 Jenkins 实例的详细信息,包括 JVM 参数、系统属性、环境变量、插件版本等。这些信息对于故障排查和性能优化非常重要。</li>
|
|||
|
<li><strong>环境变量配置</strong>:Jenkins 支持配置全局和 Job 级别的环境变量,这些变量可以在构建过程中使用。例如,可以配置 JAVA_HOME、MAVEN_HOME 等环境变量,确保构建脚本在执行时能够找到正确的工具和依赖项。</li>
|
|||
|
</ol>
|
|||
|
<p><img src="https://static.7wate.com/2024/08/15/bf11ac9982e36.png" alt="Jenkins 系统配置"/></p>
|
|||
|
<h3 id="用户管理创建用户和角色权限分配">用户管理:创建用户和角色,权限分配<a aria-hidden="true" tabindex="-1" href="#用户管理创建用户和角色权限分配" class="internal"> §</a></h3>
|
|||
|
<p>用户管理是 Jenkins 系统配置中的重要部分。**Jenkins 支持多种用户管理方式,包括内置用户数据库、LDAP、Active Directory 等。**管理员可以创建用户账户,并通过角色策略分配权限,确保不同用户具有适当的操作权限。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>创建用户和角色</strong>:管理员可以通过 Jenkins UI 创建新用户,并为用户分配特定的角色。角色可以是系统管理员、开发人员、测试人员等,根据角色的不同,用户在 Jenkins 中的操作权限也会有所不同。</li>
|
|||
|
<li><strong>权限分配</strong>:Jenkins 通过授权策略控制用户的操作权限。常见的授权策略包括基于项目的矩阵权限策略、基于角色的权限策略等。管理员可以灵活配置用户对不同 Job、视图、节点的访问和操作权限,确保系统的安全性和管理的可控性。</li>
|
|||
|
</ul>
|
|||
|
<h2 id="jenkins-插件系统">Jenkins 插件系统<a aria-hidden="true" tabindex="-1" href="#jenkins-插件系统" class="internal"> §</a></h2>
|
|||
|
<p>Jenkins 的强大功能和灵活性主要得益于其丰富的插件系统。插件为 Jenkins 提供了各种扩展能力,如源码管理、构建工具、测试框架、部署工具的集成,以及 UI 增强、安全性增强等。通过插件,Jenkins 可以适应不同的开发流程、工具链和部署环境。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>插件的重要性</strong>:Jenkins 的核心非常轻量级,而其大部分功能都是通过插件实现的。这种设计使得 Jenkins 能够根据项目需求进行定制化,避免了功能冗余和系统过度复杂化。插件生态的活跃程度也是 Jenkins 社区的重要标志,数以千计的插件为全球用户提供了广泛的选择。</li>
|
|||
|
<li><strong>插件管理方法</strong>:插件管理是 Jenkins 系统维护的重要内容。管理员可以通过 Jenkins UI 的插件管理界面安装、更新和卸载插件。安装插件时,推荐选择通过官方插件库进行,确保插件的安全性和稳定性。管理员还需要定期检查插件的更新,并测试更新前后的兼容性,以避免系统问题。</li>
|
|||
|
</ul>
|
|||
|
<p><img src="https://static.7wate.com/2024/08/15/b69f41e5c3660.png" alt="Jenkins 插件系统"/></p>
|
|||
|
<h3 id="常用插件介绍与配置">常用插件介绍与配置<a aria-hidden="true" tabindex="-1" href="#常用插件介绍与配置" class="internal"> §</a></h3>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>插件</strong></th><th><strong>主要功能</strong></th><th><strong>应用场景</strong></th><th><strong>工作环节</strong></th><th><strong>额外说明</strong></th></tr></thead><tbody><tr><td><strong>Git Plugin</strong></td><td>支持 Jenkins 与 Git 版本控制系统的集成。</td><td>适用于使用 Git 作为版本控制系统的项目,实现代码的拉取、分支管理、触发基于 Git 事件的构建。</td><td>源码管理</td><td>与 GitHub、GitLab 等平台集成良好,支持 Webhook、Pull Request 构建触发。</td></tr><tr><td><strong>Pipeline Plugin</strong></td><td>允许用户使用代码(Jenkinsfile)定义构建、测试和部署流程。</td><td>适用于需要复杂 CI/CD 流水线的项目,支持 Declarative 和 Scripted 两种 Pipeline 语法,提升自动化程度和流程可重复性。</td><td>构建/流水线</td><td>Pipeline 是 Jenkins 自动化的核心插件,几乎所有复杂的 Jenkins 实践都依赖它。</td></tr><tr><td><strong>Blue Ocean</strong></td><td>提供现代化的 Jenkins UI,提升 Pipeline 可视化体验。</td><td>适用于希望通过直观的图形界面管理和监控 Pipeline 的团队,特别是在大型团队和复杂项目中。</td><td>用户界面/可视化</td><td>提供更好的 Pipeline 可视化和执行状态展示,便于调试和分析。</td></tr><tr><td><strong>Maven Integration Plugin</strong></td><td>提供对 Apache Maven 项目的集成支持。</td><td>适用于使用 Maven 进行构建的 Java 项目,简化 Maven 生命周期管理和依赖处理。</td><td>构建/编译</td><td>支持自动化处理 Maven 构建、测试、打包、部署,集成代码质量分析工具(如 SonarQube)。</td></tr><tr><td><strong>Docker Plugin</strong></td><td>支持在 Docker 容器中运行 Jenkins 构建任务。</td><td>适用于希望在隔离环境中运行构建任务的项目,特别是需要一致性构建环境的场景,如构建微服务、容器化应用等。</td><td>构建/环境管理</td><td>通过容器化技术确保构建环境的一致性,支持 Docker 镜像的构建、推送和运行。</td></tr><tr><td><strong>Credentials Plugin</strong></td><td>提供安全管理和存储凭证(如密码、SSH 密钥、API Tokens)。</td><td>适用于需要在构建过程中使用敏感信息的项目,如推送代码到 Git 仓库、访问 API、登录服务器等。</td><td>安全/凭证管理</td><td>与其他插件集成良好,支持在 Pipeline 中安全使用凭证,避免明文暴露敏感信息。</td></tr><tr><td><strong>GitHub Plugin</strong></td><td>提供与 GitHub 的深度集成支持,管理 Webhook、Pull Request 触发构建。</td><td>适用于在 GitHub 上托管代码的项目,自动化处理 Pull Request 流程、代码变更触发构建等。</td><td>源码管理/集成</td><td>与 Git Plugin 搭配使用,提供对 GitHub 特定功能的支持,如检查状态、自动合并等。</td></tr><tr><td><strong>Slack Notification Plugin</strong></td><td>支持将 Jenkins 构建状态通知发送到 Slack 频道。</td><td>适用于需要即时通知构建状态的团队,特别是在 DevOps 实践中,通过 Slack 实时通知团队成员构建成功或失败。</td><td>通知</td><td>提供消息格式化、频道选择等配置选项,支持根据构建结果触发不同的通知。</td></tr><tr><td><strong>JUnit Plugin</strong></td><td>解析并展示 JUnit 测试结果,生成测试报告。</td><td>适用于需要集成单元测试的项目,通过自动化测试提升代码质量,生成并展示测试结果和趋势分析。</td><td>测试/报告生成</td><td>支持解析 JUnit 格式的 XML 报告,适用于 Java 项目和使用类似测试框架的其他项目。</td></tr><tr><td><strong>SonarQube Plugin</strong></td><td>与 SonarQube 集成,进行代码质量分析。</td><td>适用于需要进行代码静态分析的项目,通过集成 SonarQube,自动化分析代码质量,生成报告。</td><td>代码质量/分析</td><td>适用
|
|||
|
<h3 id="插件的更新和备份策略">插件的更新和备份策略<a aria-hidden="true" tabindex="-1" href="#插件的更新和备份策略" class="internal"> §</a></h3>
|
|||
|
<p>插件的更新和备份策略是 Jenkins 管理中的关键环节。为了保证系统的稳定性和安全性,管理员需要定期更新插件,并在更新前后做好备份。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>插件更新</strong>:插件更新可以通过 Jenkins 的插件管理界面完成。更新前,管理员应先阅读插件的更新日志,了解新版本的改动和潜在影响。更新完成后,建议进行系统测试,确保新插件与现有配置和流水线兼容。</li>
|
|||
|
<li><strong>备份策略</strong>:定期备份 Jenkins 的配置和插件文件对于应对系统故障和数据丢失非常重要。备份内容包括 Jenkins 的配置文件、Job 定义、插件目录等。管理员可以使用 Jenkins 的备份插件(如 ThinBackup)或脚本定期备份这些数据,并将备份文件存储在安全的远程位置。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="插件冲突与兼容性问题的解决">插件冲突与兼容性问题的解决<a aria-hidden="true" tabindex="-1" href="#插件冲突与兼容性问题的解决" class="internal"> §</a></h3>
|
|||
|
<p>插件冲突和兼容性问题是 Jenkins 管理中常见的挑战。当多个插件同时作用于系统时,可能会出现功能冲突或性能问题。为了有效应对这些问题,管理员可以采取以下措施:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>隔离测试</strong>:在更新或安装新插件之前,建议先在测试环境中进行隔离测试。通过模拟生产环境的工作流,管理员可以检测到潜在的插件冲突,并在生产环境中更新前解决这些问题。</li>
|
|||
|
<li><strong>日志分析</strong>:Jenkins 提供了详细的日志功能,当系统出现问题时,管理员可以通过分析日志文件查找冲突的原因。常见的日志文件包括 Jenkins 主日志、Job 执行日志和插件日志等。</li>
|
|||
|
<li><strong>社区支持</strong>:Jenkins 社区是解决插件冲突和兼容性问题的重要资源。管理员可以通过 Jenkins 官方论坛、Stack Overflow 等平台寻求社区帮助,也可以直接联系插件的维护者报告问题或获取支持。</li>
|
|||
|
</ul>
|
|||
|
<h2 id="jenkins-job">Jenkins Job<a aria-hidden="true" tabindex="-1" href="#jenkins-job" class="internal"> §</a></h2>
|
|||
|
<h3 id="自由风格项目freestyle-project">自由风格项目(Freestyle Project)<a aria-hidden="true" tabindex="-1" href="#自由风格项目freestyle-project" class="internal"> §</a></h3>
|
|||
|
<p>自由风格项目是 Jenkins 中最基本的 Job 类型,也是使用最广泛的。它提供了高度的灵活性,允许用户通过图形用户界面(GUI)配置和管理构建、测试、部署等任务。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>简单配置</strong>:用户可以通过点击和选择的方式配置构建步骤,而无需编写代码。</li>
|
|||
|
<li><strong>多种构建步骤</strong>:支持执行 shell 脚本、批处理命令、调用 Ant、Maven、Gradle 等构建工具,以及集成单元测试和代码质量检查工具。</li>
|
|||
|
<li><strong>灵活的触发机制</strong>:支持 SCM 轮询、定时构建、Webhook 触发等多种构建触发机制。</li>
|
|||
|
<li><strong>插件支持</strong>:自由风格项目可以通过安装和配置插件,扩展其功能,如集成 Git、Subversion 版本控制,使用 SonarQube 进行代码质量分析等。</li>
|
|||
|
</ul>
|
|||
|
<p>自由风格项目适用于需要快速搭建和配置的简单构建任务,如小型项目的编译、测试和部署。它也是新手用户学习 Jenkins 基本操作的入门选择。</p>
|
|||
|
<h3 id="流水线项目pipeline-project">流水线项目(Pipeline Project)<a aria-hidden="true" tabindex="-1" href="#流水线项目pipeline-project" class="internal"> §</a></h3>
|
|||
|
<p>流水线项目是 Jenkins 提供的另一种强大的 Job 类型,它以代码的形式(通常存储在 Jenkinsfile 中)定义构建、测试、部署等整个流程。Pipeline 使用 Groovy 语言编写,提供了比自由风格项目更强大的功能和灵活性。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>Pipeline as Code</strong>:流水线定义存储在代码中(Jenkinsfile),并与项目的版本控制系统集成,使构建流程的版本管理、审查和协作成为可能。</li>
|
|||
|
<li><strong>复杂的流水线</strong>:支持定义多阶段(Stages)的流水线,可以串行、并行或条件性地执行不同任务。支持并行执行测试、自动化部署等高级功能。</li>
|
|||
|
<li><strong>两种语法模式</strong>:支持 Declarative 和 Scripted 两种语法模式。Declarative 语法更简洁,适合大多数场景;Scripted 语法则更灵活,适合高级用户编写复杂逻辑。</li>
|
|||
|
<li><strong>共享库</strong>:可以通过共享库(Shared Library)复用代码片段,提升流水线的可维护性和重用性。</li>
|
|||
|
</ul>
|
|||
|
<p>流水线项目适合需要高度定制化和自动化的复杂 CI/CD 流程,尤其是在大型团队和企业级项目中。它在微服务、容器化应用和云原生开发中尤为常用。</p>
|
|||
|
<h3 id="多分支流水线项目multibranch-pipeline-project">多分支流水线项目(Multibranch Pipeline Project)<a aria-hidden="true" tabindex="-1" href="#多分支流水线项目multibranch-pipeline-project" class="internal"> §</a></h3>
|
|||
|
<p>多分支流水线项目是对流水线项目的扩展,自动化管理版本控制系统中的多个分支,并为每个分支创建独立的 Pipeline Job。它自动检测新分支,并根据 Jenkinsfile 定义的流程执行构建和测试。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>自动分支检测</strong>:Jenkins 自动扫描版本控制系统中的所有分支,并为每个分支创建单独的 Job。这意味着新分支一旦创建,Jenkins 就会自动为其触发构建。</li>
|
|||
|
<li><strong>分支隔离</strong>:每个分支都有独立的构建历史和流水线,避免了不同分支间的冲突和干扰。</li>
|
|||
|
<li><strong>支持多种版本控制系统</strong>:支持 Git、Subversion 等版本控制系统,可以通过插件扩展更多 VCS 的支持。</li>
|
|||
|
<li><strong>Pull Request 构建</strong>:集成 GitHub、GitLab 等平台时,可以自动检测 Pull Request,并在合并之前执行构建和测试,确保代码质量。</li>
|
|||
|
</ul>
|
|||
|
<p>多分支流水线项目适合采用 Git Flow 或其他多分支开发模型的项目,特别是在需要频繁创建和合并分支的团队中。它在大规模、多团队协作的开发环境中表现出色。</p>
|
|||
|
<h3 id="maven-项目maven-project">Maven 项目(Maven Project)<a aria-hidden="true" tabindex="-1" href="#maven-项目maven-project" class="internal"> §</a></h3>
|
|||
|
<p>Maven 项目是专为 Apache Maven 构建工具设计的 Jenkins Job 类型。它集成了 Maven 的构建生命周期,简化了 Maven 项目的配置和管理。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>Maven 集成</strong>:自动化处理 Maven 的构建生命周期,包括编译、测试、打包、部署等步骤。Jenkins 能够直接解析和使用 <code>pom.xml</code> 文件中的配置信息。</li>
|
|||
|
<li><strong>依赖管理</strong>:通过 Maven 项目,Jenkins 可以自动管理项目的依赖关系,并在构建时下载所需的库和插件。</li>
|
|||
|
<li><strong>报告和分析</strong>:支持生成和展示 Maven 的构建报告、测试报告和代码覆盖率报告(如使用 JaCoCo、Cobertura)。</li>
|
|||
|
<li><strong>多模块支持</strong>:Maven 项目能够处理多模块的 Maven 项目,自动化管理每个模块的构建流程。</li>
|
|||
|
</ul>
|
|||
|
<p>Maven 项目专为使用 Maven 构建工具的 Java 项目设计,适合需要利用 Maven 的强大依赖管理和生命周期功能的开发团队。</p>
|
|||
|
<h3 id="外部任务external-job">外部任务(External Job)<a aria-hidden="true" tabindex="-1" href="#外部任务external-job" class="internal"> §</a></h3>
|
|||
|
<p>外部任务是 Jenkins 提供的一种特殊 Job 类型,主要用于监控和集成在 Jenkins 外部执行的任务。它允许 Jenkins 记录这些任务的执行状态和结果。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>任务监控</strong>:Jenkins 可以监控外部脚本或命令的执行状态,并记录它们的运行日志和结果。</li>
|
|||
|
<li><strong>轻量集成</strong>:外部任务不直接在 Jenkins 内部执行,但可以通过脚本或外部工具将任务状态反馈到 Jenkins。</li>
|
|||
|
<li><strong>灵活性</strong>:适合不希望或不能直接在 Jenkins 中执行的任务,如特定的系统任务、批处理作业或定制的自动化脚本。</li>
|
|||
|
</ul>
|
|||
|
<p>外部任务适合那些已经存在且不方便迁移到 Jenkins 内部的自动化任务,或需要与其他自动化工具集成的场景。</p>
|
|||
|
<h3 id="pipeline-as-code-项目pipeline-as-code-project">Pipeline as Code 项目(Pipeline-as-Code Project)<a aria-hidden="true" tabindex="-1" href="#pipeline-as-code-项目pipeline-as-code-project" class="internal"> §</a></h3>
|
|||
|
<p>Pipeline as Code 项目是 Jenkins 鼓励的一种 CI/CD 实践,它将整个 Pipeline 定义通过代码的方式管理,通常与多分支流水线项目结合使用。虽然在技术上,它并不是一个单独的 Job 类型,但它代表了一种管理和执行 Pipeline 的方式。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>代码版本化</strong>:Pipeline 定义与项目代码一起存储在版本控制系统中,所有变更都通过代码审查和版本控制管理。</li>
|
|||
|
<li><strong>自动触发</strong>:每次代码变更都会触发相应分支的 Pipeline 执行,确保代码在每次提交后都被自动测试和部署。</li>
|
|||
|
<li><strong>集成最佳实践</strong>:Pipeline as Code 项目通常集成了 DevOps 的最佳实践,如持续集成、持续交付、安全扫描、自动化测试等。</li>
|
|||
|
</ul>
|
|||
|
<p>Pipeline as Code 项目适合推行 DevOps 文化的团队,尤其是那些希望将自动化流程与代码管理无缝集成的团队。</p>
|
|||
|
<h3 id="组合项目matrix-project">组合项目(Matrix Project)<a aria-hidden="true" tabindex="-1" href="#组合项目matrix-project" class="internal"> §</a></h3>
|
|||
|
<p>组合项目,也称为矩阵项目,是 Jenkins 中的一种特殊 Job 类型,允许用户在多个维度(如操作系统、JDK 版本等)上并行运行多个构建配置。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>多维度构建</strong>:允许定义多个轴(如操作系统、编译器版本、依赖版本等),并为每个组合运行独立的构建。</li>
|
|||
|
<li><strong>并行执行</strong>:可以在多台机器或多个 Agent 上并行执行构建任务,大大加快测试和构建速度。</li>
|
|||
|
<li><strong>结果聚合</strong>:组合项目可以汇总和展示所有维度的构建结果,帮助用户全面了解构建的兼容性和性能。</li>
|
|||
|
</ul>
|
|||
|
<p>组合项目适合需要在不同环境中验证代码兼容性的大型项目,如跨平台应用的构建和测试、不同 JDK 版本下的 Java 应用构建等。</p>
|
|||
|
<h3 id="外部工作流external-workflow">外部工作流(External Workflow)<a aria-hidden="true" tabindex="-1" href="#外部工作流external-workflow" class="internal"> §</a></h3>
|
|||
|
<p>外部工作流是一种允许 Jenkins 与外部工作流引擎集成的 Job 类型。它类似于外部任务,但专注于与外部工作流系统的集成和监控。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>工作流集成</strong>:可以与外部工作流系统(如 Apache Airflow、Apache Oozie)集成,管理复杂的分布式任务。</li>
|
|||
|
<li><strong>状态监控</strong>:Jenkins 可以监控外部工作流的状态和进度,并在工作流完成时记录结果。</li>
|
|||
|
<li><strong>灵活扩展</strong>:支持通过脚本和插件与更多外部工作流工具集成。</li>
|
|||
|
</ul>
|
|||
|
<p>外部工作流适合需要与现有工作流系统集成的企业,特别是那些依赖分布式计算和批处理作业的场景。</p>
|
|||
|
<h3 id="构建流水线插件项目build-pipeline-plugin-project">构建流水线插件项目(Build Pipeline Plugin Project)<a aria-hidden="true" tabindex="-1" href="#构建流水线插件项目build-pipeline-plugin-project" class="internal"> §</a></h3>
|
|||
|
<p>构建流水线插件项目是 Jenkins 的一种扩展,通过 Build Pipeline Plugin,用户可以将多个自由风格项目或其他 Job 类型组合成一个流水线,定义复杂的构建、测试和部署流程。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>可视化流水线</strong>:提供图形化界面展示多个 Job 之间的依赖关系和执行顺序,便于管理和监控复杂的流水线流程。</li>
|
|||
|
<li><strong>任务编排</strong>:支持配置多个 Job 的触发条件和依赖关系,实现复杂任务的编排和自动化执行。</li>
|
|||
|
<li><strong>手动审批</strong>:支持在流水线的关键步骤中加入手动审批环节,适合需要人为干预的发布流程。</li>
|
|||
|
</ul>
|
|||
|
<p>构建流水线插件项目适合需要将多个 Jenkins Job 组合成复杂流水线的项目,尤其在 DevOps 实践中,通过可视化管理和监控多个任务的执行,提升团队协作效率。</p>
|
|||
|
<h3 id="配置源码管理gitsubversion">配置源码管理(Git、Subversion)<a aria-hidden="true" tabindex="-1" href="#配置源码管理gitsubversion" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 通过源码管理插件支持多种版本控制系统,包括 Git、Subversion、Mercurial 等。在配置 Job 时,用户可以指定项目的源码管理系统,以便 Jenkins 能够自动拉取最新代码进行构建。</p>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>源码管理系统</strong></th><th><strong>概述</strong></th><th><strong>主要特点</strong></th><th><strong>使用场景</strong></th></tr></thead><tbody><tr><td><strong>Git</strong></td><td>分布式版本控制系统,广泛用于开源和企业项目中。</td><td>分布式架构,支持离线操作、强大的分支管理功能、高效的合并与冲突解决、与 GitHub、GitLab 等平台无缝集成</td><td>适用于几乎所有类型的软件项目,特别是需要复杂分支管理、多团队协作、开源项目和 DevOps 流程的开发环境。</td></tr><tr><td><strong>Subversion (SVN)</strong></td><td>集中式版本控制系统,支持精细化权限控制,广泛应用于企业。</td><td>集中式架构,便于集中管理、精细的访问控制和权限管理、支持目录级版本控制、提供日志和版本历史的详细记录</td><td>适用于需要严格权限控制的企业级项目,特别是那些需要维护大量历史版本记录和对特定目录进行精确管理的情况。</td></tr><tr><td><strong>Mercurial</strong></td><td>分布式版本控制系统,类似于 Git,但更注重性能和易用性。</td><td>分布式架构,支持离线操作、易于使用,性能优异、良好的跨平台支持、简洁清晰的分支和合并模型</td><td>适用于对性能和易用性有较高要求的开发团队,尤其是中小型项目,或者在 Git 之外需要额外的分布式版本控制方案时。</td></tr><tr><td><strong>Perforce (Helix Core)</strong></td><td>商业化集中式版本控制系统,强大而复杂,支持大规模项目的版本控制。</td><td>强大的文件锁定和版本控制机制、集中式管理,支持大规模项目、高效处理大型文件、支持代码和数字资产的版本管理</td><td>适用于大型企业和游戏、影视制作等需要处理大型文件和复杂项目依赖的场景,特别是那些需要精确控制和严格管理的开发流程。</td></tr><tr><td><strong>ClearCase</strong></td><td>IBM 提供的集中式版本控制系统,适合复杂企业环境。</td><td>支持复杂的版本管理和配置管理、强大的访问控制、集成化管理开发和配置工具、支持多站点、多平台环境</td><td>适用于有严格配置管理要求的企业级项目,特别是在复杂企业环境中需要管理多种平台和分布式开发团队时。</td></tr><tr><td><strong>TFS (Azure DevOps Server)</strong></td><td>微软提供的版本控制系统,集成了项目管理和 CI/CD 工具。</td><td>集成了版本控制、构建、发布、测试和项目管理、支持 Git 和 TFVC、与 Azure DevOps 深度集成,支持 CI/CD 流水线</td><td>适用于使用微软技术栈的企业,特别是在使用 Azure 云服务的环境中,或者希望将版本控制与项目管理和 DevOps 工具无缝集成的团队。</td></tr><tr><td><strong>CVS (Concurrent Versions System)</strong></td><td>早期流行的集中式版本控制系统,现已逐渐被其他 VCS 取代。</td><td>集中式管理、简单易用、基本的版本控制功能、早期开发工具集成支持</td><td>适用于维护旧有的遗留系统或非常小型的项目,对于那些历史悠久的代码库或不需要复杂功能的项目依然可能有所使用。</td></tr><tr><td><strong>Bitbucket</strong></td><td>Atlassian 提供的 Git 版本控制系统,集成了项目管理工具和 CI/CD。</td><td>Git 支持、与 Jira、Confluence 集成、支持 Pull Request 审查、内置 CI/CD 管道(Bitbucket Pipelines)</td><td>适用于与 Atlassian 工具链(如 Jira、Confluence)深度集成的团队,特别是在使用 Bitbucket Cloud 或 Server 的开发环境中。</td></tr><tr><td><strong>GitHub</strong></td><td>全球最流行的 Git 托管平台,广泛应用于开源项目和企业开发。</td><td>Git 支持、强大的 Pull Request 和代码审查功能、支持 GitHub Actions 实现 CI/CD、大量社区插件和工具支持</td><td>适用于开源项目和需要与全球开发<EFBFBD><EFBFBD>
|
|||
|
<h3 id="构建触发器scm-轮询webhook定时任务">构建触发器:SCM 轮询、Webhook、定时任务<a aria-hidden="true" tabindex="-1" href="#构建触发器scm-轮询webhook定时任务" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 支持多种构建触发器,用户可以灵活配置 Job 的触发条件,确保构建流程在合适的时机自动启动。</p>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>构建触发器</strong></th><th><strong>概述</strong></th><th><strong>主要特点</strong></th><th><strong>使用场景</strong></th></tr></thead><tbody><tr><td><strong>SCM 轮询</strong> (Poll SCM)</td><td>定期检查源码管理系统(SCM)的变更,当检测到代码变更时触发构建。</td><td>使用 Cron 表达式配置轮询频率、自动检测源码变更并触发构建、简单易用,配置灵活</td><td>适用于需要定期检查代码变更的项目,特别是小型团队或不频繁的代码更新场景。</td></tr><tr><td><strong>Webhook</strong></td><td>通过 Webhook 通知直接触发 Jenkins 构建任务。</td><td>实时性强,无需轮询、减少服务器负载、与 GitHub、GitLab 等 VCS 平台无缝集成</td><td>适用于希望实时响应代码变更的项目,特别是在大型团队中需要快速反馈或与 GitHub、GitLab 集成的场景。</td></tr><tr><td><strong>定时构建</strong> (Scheduled Build)</td><td>在预设的时间点或周期性地触发构建任务。</td><td>使用 Cron 表达式配置构建时间、支持定时执行构建、可以用于生成每日构建、定期测试等任务</td><td>适用于需要定期生成构建版本、执行定期任务(如回归测试)或确保构建环境稳定的项目。</td></tr><tr><td><strong>手动触发</strong> (Manual Trigger)</td><td>由用户手动启动的构建任务。</td><td>灵活控制构建启动时间、支持用户通过 UI 或 API 手动触发、适用于测试和特殊场景</td><td>适用于需要人为控制构建时间的场景,如代码发布前的最后检查、手动执行特定测试等。</td></tr><tr><td><strong>上游/下游项目触发</strong> (Upstream/Downstream Trigger)</td><td>当一个 Job 完成时,自动触发另一个相关的 Job。</td><td>支持多 Job 之间的依赖关系、允许创建复杂的构建链、可以配置在上游任务成功、失败或完成时触发</td><td>适用于多个构建任务之间存在依赖关系的场景,特别是需要串联多个构建任务或在构建完成后自动执行测试、部署等后续任务的项目。</td></tr><tr><td><strong>构建后操作触发</strong> (Post-Build Actions)</td><td>在构建完成后根据结果触发后续操作或构建任务。</td><td>灵活配置不同结果的触发条件、支持在构建失败、成功、总是等不同情况下触发、适用于自动化发布、通知等后续操作</td><td>适用于需要根据构建结果自动执行某些操作的场景,如在构建失败时发送通知、在成功时发布 Artefact 或触发下游构建任务。</td></tr><tr><td><strong>远程触发</strong> (Remote Trigger)</td><td>通过 HTTP 请求远程触发 Jenkins 构建。</td><td>支持通过 URL 触发构建、可以配置触发器令牌进行安全控制、适用于系统集成和自动化脚本</td><td>适用于需要从外部系统或脚本中触发 Jenkins 构建的场景,如通过自动化测试平台、持续集成工具或其他应用直接触发 Jenkins Job。</td></tr><tr><td><strong>节点标签触发</strong> (Node Label Trigger)</td><td>根据特定节点或标签触发构建任务。</td><td>基于节点标签分配构建任务、支持在特定环境或机器上执行构建、提供更多构建调度的灵活性</td><td>适用于需要在特定机器或环境中执行构建的场景,特别是当不同的构建任务需要不同的硬件资源或软件配置时。</td></tr><tr><td><strong>参数化触发</strong> (Parameterized Trigger)</td><td>允许用户在触发构建时传递参数,实现动态构建。</td><td>用户可以在构建时输入参数、支持根据输入参数动态调整构建流程、适用于需要在不同环境中运行或根据用户输入动态配置的场景</td><td>适用于需要根据用户输入或外部条件调整构建流程的场景,如在不同环境中部署、生成不同配置的构建 Artefact 或执行特定的测试组合等。</td></tr><tr><td><strong>Pipeline 触发器</strong> (Pipeline Trigger)
|
|||
|
<h3 id="构建步骤编译测试打包部署">构建步骤:编译、测试、打包、部署<a aria-hidden="true" tabindex="-1" href="#构建步骤编译测试打包部署" class="internal"> §</a></h3>
|
|||
|
<p>构建步骤定义了 Job 的具体执行内容,是整个 Jenkins 自动化流程的核心部分。根据项目需求,构建步骤可以包括以下内容:</p>
|
|||
|
<pre><code class="mermaid">graph LR
|
|||
|
A[开始] --> B[编译]
|
|||
|
B --> C[测试]
|
|||
|
C --> D[打包]
|
|||
|
D --> E[部署]
|
|||
|
E --> F[结束]
|
|||
|
|
|||
|
subgraph 编译阶段
|
|||
|
B1[选择编译工具]
|
|||
|
B2[指定编译路径和选项]
|
|||
|
B --> B1 --> B2
|
|||
|
end
|
|||
|
|
|||
|
subgraph 测试阶段
|
|||
|
C1[单元测试]
|
|||
|
C2[集成测试]
|
|||
|
C3[端到端测试]
|
|||
|
C --> C1 --> C2 --> C3
|
|||
|
end
|
|||
|
|
|||
|
subgraph 打包阶段
|
|||
|
D1[生成 JAR/WAR 文件]
|
|||
|
D2[生成前端压缩包]
|
|||
|
D --> D1 --> D2
|
|||
|
end
|
|||
|
|
|||
|
subgraph 部署阶段
|
|||
|
E1[选择部署工具]
|
|||
|
E2[部署到测试或生产环境]
|
|||
|
E --> E1 --> E2
|
|||
|
end
|
|||
|
|
|||
|
</code></pre>
|
|||
|
<ul>
|
|||
|
<li><strong>编译</strong>:对于编程语言的编译项目,如 Java、C++ 等,构建步骤首先执行代码编译。Jenkins 支持多种编译工具,如 Maven、Gradle、Ant 等。配置编译步骤时,用户需要指定编译工具的路径、目标文件和编译选项。</li>
|
|||
|
<li><strong>测试</strong>:测试是 CI 流程中的关键环节,Jenkins 支持集成多种测试框架,如 JUnit、Testing、Selenium 等。用户可以配置单元测试、集成测试和端到端测试的执行步骤,并在构建过程中自动生成测试报告。</li>
|
|||
|
<li><strong>打包</strong>:编译和测试通过后,构建步骤通常包括打包操作。对于 Java 项目,打包步骤可能生成 JAR 或 WAR 文件;对于前端项目,可能生成压缩后的静态资源包。打包步骤可以集成版本控制,确保每个构建都生成唯一标识的可发布包。</li>
|
|||
|
<li><strong>部署</strong>:最后,Jenkins 可以自动将打包好的应用部署到测试环境或生产环境。部署步骤可以使用各种工具,如 Ansible、Docker、Kubernetes 等,实现从构建到发布的全流程自动化。</li>
|
|||
|
</ul>
|
|||
|
<h2 id="pipeline-脚本">Pipeline 脚本<a aria-hidden="true" tabindex="-1" href="#pipeline-脚本" class="internal"> §</a></h2>
|
|||
|
<p>Pipeline 是 Jenkins 用于定义和执行自动化流程的核心概念。通过 Pipeline,用户可以以代码形式定义从构建、测试到部署的整个流程。Pipeline 的优势包括:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>可维护性</strong>:由于 Pipeline 定义在代码中(Jenkinsfile),团队可以将其纳入版本控制,与项目源码同步管理。任何对 Pipeline 的修改都能通过代码审查流程进行,确保变更的安全性和可追溯性。</li>
|
|||
|
<li><strong>复用性</strong>:Pipeline 支持将常用的步骤和逻辑封装成共享库,供多个项目复用。这不仅提高了开发效率,还减少了重复配置带来的维护成本。</li>
|
|||
|
<li><strong>可视化</strong>:Jenkins 提供了强大的 Pipeline 可视化工具(如 Blue Ocean),帮助团队实时监控和管理 Pipeline 的执行状态,及时发现和解决问题。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="declarative-pipeline">Declarative Pipeline<a aria-hidden="true" tabindex="-1" href="#declarative-pipeline" class="internal"> §</a></h3>
|
|||
|
<p><strong>Declarative Pipeline 是 Jenkins 中使用最广泛的 Pipeline 语法,旨在提供更简洁、易读的语法结构,适合大多数项目的自动化需求。</strong></p>
|
|||
|
<p>Declarative Pipeline 的基本结构如下:</p>
|
|||
|
<pre><code class="mermaid">graph LR
|
|||
|
A[pipeline] --> B[agent any]
|
|||
|
B --> C[environment]
|
|||
|
C --> D[stages]
|
|||
|
D --> E1[Stage Build]
|
|||
|
E1 --> E2[Steps: Execute Build Tasks]
|
|||
|
D --> F1[Stage Test]
|
|||
|
F1 --> F2[Steps: Execute Test Tasks]
|
|||
|
D --> G1[Stage Deploy]
|
|||
|
G1 --> G2[Steps: Execute Deploy Tasks]
|
|||
|
D --> H[post]
|
|||
|
H --> I1[Always: Cleanup]
|
|||
|
H --> I2[Success: Success Notification]
|
|||
|
H --> I3[Failure: Failure Notification]
|
|||
|
|
|||
|
subgraph Declarative Pipeline Structure
|
|||
|
B -.-> C -.-> D -.-> H
|
|||
|
end
|
|||
|
</code></pre>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent any</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make build'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make test'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make deploy'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> post {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> always {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Cleaning up...'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> deleteDir()</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<ul>
|
|||
|
<li><strong>pipeline</strong>:定义 Pipeline 的顶级指令块,包含所有 Pipeline 相关的配置。</li>
|
|||
|
<li><strong>agent</strong>:定义 Pipeline 运行的执行环境。<code>any</code> 表示可以在任何可用的 Agent 上执行。也可以指定特定的 Agent 或容器。</li>
|
|||
|
<li><strong>stages</strong>:包含多个 <code>stage</code> 块,每个 <code>stage</code> 表示一个独立的构建阶段。</li>
|
|||
|
<li><strong>steps</strong>:在 <code>stage</code> 内部定义具体的执行步骤。<code>sh</code> 是执行 Shell 命令的常用指令。</li>
|
|||
|
<li><strong>post</strong>:定义在 Pipeline 结束后执行的步骤,如清理工作、通知、报告生成等。</li>
|
|||
|
</ul>
|
|||
|
<p>Declarative Pipeline 提供了丰富的条件控制(如 <code>when</code>、<code>input</code>)、并行执行(<code>parallel</code>)以及环境变量管理(<code>environment</code>),适合定义结构化和易维护的流水线。</p>
|
|||
|
<h3 id="scripted-pipeline">Scripted Pipeline<a aria-hidden="true" tabindex="-1" href="#scripted-pipeline" class="internal"> §</a></h3>
|
|||
|
<p><strong>Scripted Pipeline 提供了更大的灵活性和控制力,但其语法相对复杂,通常用于需要高度定制的场景。</strong></p>
|
|||
|
<p>Scripted Pipeline 的基本结构如下:</p>
|
|||
|
<pre><code class="mermaid">graph LR
|
|||
|
A[node] --> B[try]
|
|||
|
B --> C[stage Build]
|
|||
|
C --> D[Steps: Execute Build Tasks]
|
|||
|
B --> E[stage Test]
|
|||
|
E --> F[Steps: Execute Test Tasks]
|
|||
|
B --> G[stage Deploy]
|
|||
|
G --> H[Steps: Execute Deploy Tasks]
|
|||
|
B --> I[catch Exception]
|
|||
|
I --> J[Steps: Handle Failure]
|
|||
|
B --> K[finally]
|
|||
|
K --> L[Steps: Cleanup]
|
|||
|
|
|||
|
subgraph Scripted Pipeline Structure
|
|||
|
A -.-> B -.-> I -.-> K
|
|||
|
end
|
|||
|
</code></pre>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">node {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-color-text);"> {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make build'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make test'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make deploy'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> } </span><span style="color:var(--shiki-token-keyword);">catch</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-keyword);">Exception</span><span style="color:var(--shiki-color-text);"> e) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> currentBuild</span><span style="color:var(--shiki-token-keyword);">.</span><span style="color:var(--shiki-color-text);">result </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'FAILURE'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">throw</span><span style="color:var(--shiki-color-text);"> e</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> } </span><span style="color:var(--shiki-token-keyword);">finally</span><span style="color:var(--shiki-color-text);"> {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Cleaning up...'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> deleteDir()</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<ul>
|
|||
|
<li><strong>node</strong>:表示一个执行节点。所有的 Pipeline 步骤都在 <code>node</code> 块中定义。</li>
|
|||
|
<li><strong>stage</strong>:定义构建的不同阶段,与 Declarative Pipeline 类似。</li>
|
|||
|
<li><strong>try-catch-finally</strong>:Scripted Pipeline 中可以使用标准的 Groovy 语法进行异常处理和流程控制。</li>
|
|||
|
</ul>
|
|||
|
<p>由于 Scripted Pipeline 基于 Groovy 语言,用户可以在其中编写复杂的逻辑、调用自定义函数和类,适合高级用户和特殊需求。</p>
|
|||
|
<h3 id="stages-步骤">Stages 步骤<a aria-hidden="true" tabindex="-1" href="#stages-步骤" class="internal"> §</a></h3>
|
|||
|
<p><strong>Stages</strong> 是 Jenkins Pipeline 中的核心构建块,每个 <code>stage</code> 代表了 Pipeline 执行过程中的一个主要步骤或阶段。Stages 可以用于划分构建、测试、部署等不同的任务,帮助组织和管理复杂的构建流程。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>阶段划分</strong>:Stages 将整个 Pipeline 分割为多个独立的部分,每个部分都代表一个逻辑步骤,如编译代码、运行测试、部署应用等。</li>
|
|||
|
<li><strong>并行执行</strong>:多个 Stages 可以在 <code>parallel</code> 指令下并行执行,减少总的执行时间。</li>
|
|||
|
<li><strong>条件执行</strong>:Stages 可以基于条件(如环境变量、分支名称等)选择性地执行,提升 Pipeline 的灵活性。</li>
|
|||
|
<li><strong>可视化</strong>:Jenkins 提供了直观的界面展示 Stages 的执行情况,便于监控和调试。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent any</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make build'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make test'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make deploy'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>命令关键字</strong></th><th><strong>描述</strong></th><th><strong>使用场景</strong></th></tr></thead><tbody><tr><td><strong><code>stage</code></strong></td><td>定义 Pipeline 的一个阶段,每个阶段包含特定的构建、测试或部署任务。</td><td>用于将 Pipeline 划分为多个逻辑阶段,如“构建”、“测试”、“部署”等,便于组织和管理复杂的流程。</td></tr><tr><td><strong><code>steps</code></strong></td><td>在 <code>stage</code> 中定义具体执行的步骤或操作。</td><td>用于在一个 <code>stage</code> 内执行一组具体的任务,如运行 Shell 命令、调用外部服务、存档文件等。</td></tr><tr><td><strong><code>parallel</code></strong></td><td>并行执行多个 <code>stage</code>,提高 Pipeline 的执行效率。</td><td>用于同时执行多个任务,如并行运行测试、构建不同的模块或部署到多个环境。</td></tr><tr><td><strong><code>when</code></strong></td><td>基于条件执行某个 <code>stage</code> 或步骤。</td><td>用于根据分支、环境变量、文件存在与否等条件控制某个阶段的执行,如仅在特定分支上运行部署阶段。</td></tr><tr><td><strong><code>agent</code></strong></td><td>指定在哪个 Jenkins 节点或容器中运行该 <code>stage</code>。</td><td>用于为特定阶段分配执行环境,特别是在需要不同的构建环境或资源时,如在特定的 Docker 容器中运行测试。</td></tr><tr><td><strong><code>post</code></strong></td><td>定义在 <code>stage</code> 完成后执行的操作。</td><td>用于在阶段完成后触发清理、通知、存档等操作,确保即使阶段失败也能执行必要的后续步骤。</td></tr><tr><td><strong><code>environment</code></strong></td><td>为特定 <code>stage</code> 定义环境变量。</td><td>用于为某个阶段设置临时的环境变量,如 API 密钥、构建标志等,确保变量仅在该阶段有效。</td></tr><tr><td><strong><code>input</code></strong></td><td>在 <code>stage</code> 开始前等待用户输入或确认。</td><td>用于在高风险操作(如生产环境部署)前暂停并等待人工确认,确保安全性。</td></tr><tr><td><strong><code>options</code></strong></td><td>为特定 <code>stage</code> 配置选项,如超时时间、重试次数等。</td><td>用于控制某个阶段的行为,例如设置超时时间防止阶段长时间挂起,或在阶段失败时自动重试。</td></tr><tr><td><strong><code>tools</code></strong></td><td>指定特定阶段使用的构建工具版本,如 Maven、Gradle。</td><td>用于确保某个阶段使用正确版本的构建工具,特别是在不同阶段需要不同工具版本时,如不同版本的 JDK 或 Maven。</td></tr><tr><td><strong><code>timeout</code></strong></td><td>为特定 <code>stage</code> 设置执行超时时间,超时后自动终止。</td><td>用于防止某个阶段长时间执行,特别是在长时间运行的任务中,确保流程的整体执行时间在可控范围内。</td></tr><tr><td><strong><code>retry</code></strong></td><td>在 <code>stage</code> 中步骤失败时重试指定次数。</td><td>用于处理偶发的临时性错误,例如网络请求失败、外部服务响应超时等,确保任务的健壮性。</td></tr><tr><td><strong><code>failFast</code></strong></td><td>在并行执行的 <code>stage</code> 中,一旦某个 <code>stage</code> 失败,立即终止其他并行 <code>stage</code>。</td><td>用于节省资源,当某个关键阶段失败时立即停止所有并行任务,避免不必要的资源消耗。</td></tr><tr><td><strong><code>input</code></strong></td><td>在 <code>stage</code> 开始前暂停执行,等待用户输入或确认。</td><td>用于在关键阶段(如生产部署)前需要人工确认时,确保操作的安全性。</td></tr><tr><td><strong><code>lock</code></strong></td><td>在执行 <code>stage</code> 时获取锁,确保该阶段的操作是独占的。</td><td>用于在<EFBFBD>
|
|||
|
<h3 id="steps-步骤">Steps 步骤<a aria-hidden="true" tabindex="-1" href="#steps-步骤" class="internal"> §</a></h3>
|
|||
|
<p><strong>Steps</strong> 是 Pipeline 中执行具体任务的最小单元,每个 <code>step</code> 代表一个独立的操作,如执行命令、调用工具、发送通知等。Steps 是构建自动化流程的基础,可以根据需求灵活组合和配置。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>灵活组合</strong>:Steps 可以按需组合,构建出适合特定项目需求的执行流程。</li>
|
|||
|
<li><strong>参数化执行</strong>:许多 Steps 支持传入参数,实现动态配置和执行。</li>
|
|||
|
<li><strong>条件控制</strong>:Steps 可以与条件语句结合,实现复杂的逻辑控制,如在特定情况下跳过某些步骤。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'npm install'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'npm test'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> archiveArtifacts artifacts: </span><span style="color:var(--shiki-token-string-expression);">'**/target/*.jar'</span><span style="color:var(--shiki-color-text);">, fingerprint: </span><span style="color:var(--shiki-token-constant);">true</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>命令关键字</strong></th><th><strong>描述</strong></th><th><strong>使用场景</strong></th></tr></thead><tbody><tr><td><strong><code>sh</code></strong></td><td>在 Unix/Linux 系统上执行 Shell 命令。</td><td>用于执行 Shell 脚本、命令行操作,如编译代码、运行测试、部署应用等。</td></tr><tr><td><strong><code>bat</code></strong></td><td>在 Windows 系统上执行批处理命令。</td><td>适用于在 Windows 环境下执行构建、测试、部署任务。</td></tr><tr><td><strong><code>checkout</code></strong></td><td>从版本控制系统(如 Git、SVN)检出代码。</td><td>用于在 Pipeline 中拉取最新代码,以确保构建和测试基于最新的源码。</td></tr><tr><td><strong><code>echo</code></strong></td><td>在控制台输出消息。</td><td>用于在 Pipeline 中输出调试信息、状态消息或变量值,便于跟踪和分析执行过程。</td></tr><tr><td><strong><code>sleep</code></strong></td><td>暂停 Pipeline 执行指定时间。</td><td>用于在步骤之间插入延迟,例如等待外部服务响应、控制构建节奏等。</td></tr><tr><td><strong><code>dir</code></strong></td><td>切换到指定的工作目录,并在该目录中执行后续步骤。</td><td>用于在特定目录下执行构建任务,如切换到项目目录进行编译、测试等操作。</td></tr><tr><td><strong><code>withEnv</code></strong></td><td>设置环境变量,并在定义的步骤范围内使用。</td><td>用于临时改变环境变量,例如配置 PATH、设置 API 密钥等,确保这些变量仅在特定步骤中生效。</td></tr><tr><td><strong><code>archiveArtifacts</code></strong></td><td>存档构建生成的工件(如 JAR 文件、日志、报告等)。</td><td>用于将构建生成的文件存档,便于后续使用、分发或备份。</td></tr><tr><td><strong><code>junit</code></strong></td><td>解析 JUnit 测试结果并生成测试报告。</td><td>用于在 Jenkins 中展示单元测试结果,并生成测试趋势分析。</td></tr><tr><td><strong><code>mail</code></strong></td><td>发送电子邮件通知。</td><td>用于在 Pipeline 执行过程中发送通知,例如在构建失败时通知开发团队。</td></tr><tr><td><strong><code>input</code></strong></td><td>暂停 Pipeline 执行,等待用户输入或确认。</td><td>用于在关键步骤(如生产环境部署前)等待人工确认,确保操作安全。</td></tr><tr><td><strong><code>timeout</code></strong></td><td>为步骤或阶段设置超时时间,超时后自动终止。</td><td>用于限制步骤或阶段的最长执行时间,防止长时间挂起的任务阻塞 Pipeline。</td></tr><tr><td><strong><code>retry</code></strong></td><td>在失败时重试指定次数。</td><td>用于处理可能出现暂时性错误的操作,例如网络请求失败、依赖下载失败等。</td></tr><tr><td><strong><code>parallel</code></strong></td><td>并行执行多个步骤或阶段。</td><td>用于提高 Pipeline 执行效率,特别是在多任务并行的场景下,如同时在多个环境中运行测试。</td></tr><tr><td><strong><code>build</code></strong></td><td>在 Pipeline 中触发其他 Jenkins Job。</td><td>用于在一个 Pipeline 中调用其他 Job,例如在构建完成后触发部署 Job 或运行测试 Job。</td></tr><tr><td><strong><code>tool</code></strong></td><td>在 Pipeline 中指定构建工具(如 Maven、Gradle)。</td><td>用于配置和使用特定版本的构建工具,确保环境的一致性。</td></tr><tr><td><strong><code>withCredentials</code></strong></td><td>在 Pipeline 中使用存储的凭证进行操作。</td><td>用于在需要认证的操作中安全地使用敏感信息,如推送代码到 Git 仓库、访问 API、登录服务器等。</td></tr><tr><td><strong><code>script</code></strong></td><td>在 Declarative Pipeline 中执行 Groovy 脚本。</td><td>用于实现复杂的逻辑控制,或调用自定义的 Groovy 函数。</td></tr><tr><td><strong><code>sta
|
|||
|
<h3 id="post-actions-步骤">Post Actions 步骤<a aria-hidden="true" tabindex="-1" href="#post-actions-步骤" class="internal"> §</a></h3>
|
|||
|
<p><strong>Post Actions</strong> 是在 Pipeline 执行完毕后触发的操作,用于处理构建结果、清理资源、发送通知等。<code>post</code> 块根据构建的不同结果(如 <code>success</code>、<code>failure</code>、<code>always</code>)执行相应的操作,确保在任何情况下都能正确处理构建流程的结束阶段。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>结果驱动</strong>:Post Actions 根据构建结果自动触发相应的动作,确保在成功时发布、在失败时报警。</li>
|
|||
|
<li><strong>资源清理</strong>:Post Actions 可以用于释放资源、清理临时文件、关闭连接等,避免资源泄漏或积累。</li>
|
|||
|
<li><strong>通知机制</strong>:Post Actions 支持集成通知系统(如邮件、Slack),在构建完成后通知相关人员或系统。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">post {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> success {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Build succeeded!'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> mail to: </span><span style="color:var(--shiki-token-string-expression);">'team@example.com'</span><span style="color:var(--shiki-color-text);">,</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> subject: </span><span style="color:var(--shiki-token-string-expression);">"Build #${env.BUILD_NUMBER} succeeded"</span><span style="color:var(--shiki-color-text);">,</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> body: </span><span style="color:var(--shiki-token-string-expression);">"Great news! The build succeeded."</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> failure {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Build failed!'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> mail to: </span><span style="color:var(--shiki-token-string-expression);">'team@example.com'</span><span style="color:var(--shiki-color-text);">,</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> subject: </span><span style="color:var(--shiki-token-string-expression);">"Build #${env.BUILD_NUMBER} failed"</span><span style="color:var(--shiki-color-text);">,</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> body: </span><span style="color:var(--shiki-token-string-expression);">"Unfortunately, the build failed. Please check the logs."</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> always {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> cleanWs() </span><span style="color:var(--shiki-token-comment);">// 清理工作区</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h2 id="pipeline-实现动态参数化构建">Pipeline 实现动态参数化构建<a aria-hidden="true" tabindex="-1" href="#pipeline-实现动态参数化构建" class="internal"> §</a></h2>
|
|||
|
<p>参数化 Pipeline 是 Jenkins 提供的一种灵活机制,允许在执行构建时动态传入参数,以实现更为灵活的构建流程。Jenkins 支持多种类型的参数,如字符串、布尔值、选择列表、密码等。这种动态化的构建方式特别适用于多分支开发或多环境部署的场景。</p>
|
|||
|
<h3 id="使用参数">使用参数<a aria-hidden="true" tabindex="-1" href="#使用参数" class="internal"> §</a></h3>
|
|||
|
<p>在 Jenkinsfile 中,可以通过 <code>parameters</code> 块定义各种类型的参数。这些参数可以在构建时由用户输入,或者采用默认值。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> parameters {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> string(name: </span><span style="color:var(--shiki-token-string-expression);">'BRANCH'</span><span style="color:var(--shiki-color-text);">, defaultValue: </span><span style="color:var(--shiki-token-string-expression);">'master'</span><span style="color:var(--shiki-color-text);">, description: </span><span style="color:var(--shiki-token-string-expression);">'分支名称'</span><span style="color:var(--shiki-color-text);">)</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> booleanParam(name: </span><span style="color:var(--shiki-token-string-expression);">'DEPLOY'</span><span style="color:var(--shiki-color-text);">, defaultValue: </span><span style="color:var(--shiki-token-constant);">true</span><span style="color:var(--shiki-color-text);">, description: </span><span style="color:var(--shiki-token-string-expression);">'是否部署'</span><span style="color:var(--shiki-color-text);">)</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Building branch: ${params.BRANCH}"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>在 Pipeline 中,可以通过 <code>params</code> 对象访问传入的参数值。这些参数值可以用于控制构建流程中的各种逻辑,如条件判断、分支选择等。</p>
|
|||
|
<p>参数化 Pipeline 的主要优势在于其灵活性,能够适应不同环境需求或用户输入。这种方式特别适合多分支开发或针对不同部署环境的需求,使构建流程更加智能和可控。</p>
|
|||
|
<h3 id="条件语句">条件语句<a aria-hidden="true" tabindex="-1" href="#条件语句" class="internal"> §</a></h3>
|
|||
|
<p>条件语句用于根据不同的输入参数或环境变量,决定构建的执行路径。通过 <code>when</code> 指令,可以在 Declarative Pipeline 中实现条件执行,从而根据特定条件执行相应的构建步骤。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> when {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> branch </span><span style="color:var(--shiki-token-string-expression);">'master'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Deploying to production...'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="循环结构">循环结构<a aria-hidden="true" tabindex="-1" href="#循环结构" class="internal"> §</a></h3>
|
|||
|
<p>循环结构在处理重复性任务时非常有用,例如遍历文件列表或批量执行测试。在 Jenkins Pipeline 中,可以通过 <code>for</code> 循环实现这一功能,从而简化处理多个相似任务的代码复杂度。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Batch Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> script {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-keyword);">int</span><span style="color:var(--shiki-color-text);"> i </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">0</span><span style="color:var(--shiki-color-text);">; i </span><span style="color:var(--shiki-token-keyword);"><</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-color-text);">; i</span><span style="color:var(--shiki-token-keyword);">++</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Running test ${i}"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="并行执行">并行执行<a aria-hidden="true" tabindex="-1" href="#并行执行" class="internal"> §</a></h3>
|
|||
|
<p>并行执行是 Jenkins Pipeline 的一大优势,允许多个步骤或阶段同时运行,从而加快构建过程。这一功能特别适用于并行测试和多平台构建,能够显著缩短总的构建时间。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Parallel Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> parallel {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Unit Tests'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Running unit tests...'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Integration Tests'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">'Running integration tests...'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>通过并行执行,构建流程可以充分利用 Jenkins 的多核处理能力,提高整体效率,尤其是在大规模项目中,这种方式能够极大地提升构建速度并优化资源利用率。</p>
|
|||
|
<h2 id="groovy-语法">Groovy 语法<a aria-hidden="true" tabindex="-1" href="#groovy-语法" class="internal"> §</a></h2>
|
|||
|
<p>Jenkinsfile 采用 <strong>Groovy</strong> 作为脚本语言,其丰富的语法特性使 Jenkins Pipeline 具备高度的灵活性和表达能力。深入掌握 Groovy 语法在 Jenkinsfile 中的应用,是编写高效且复杂的 Pipeline 的基础。以下是 Groovy 语法在 Jenkinsfile 中的关键应用场景:</p>
|
|||
|
<h3 id="变量和常量的定义">变量和常量的定义<a aria-hidden="true" tabindex="-1" href="#变量和常量的定义" class="internal"> §</a></h3>
|
|||
|
<p>在 Jenkinsfile 中,可以使用变量和常量来存储数据和配置项。变量使用 <code>def</code> 关键字定义,而常量则通过 <code>final</code> 关键字来定义,使其在代码执行过程中不可更改。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> myVar </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'value'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-token-keyword);">final</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-keyword);">String</span><span style="color:var(--shiki-color-text);"> CONSTANT </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'constantValue'</span></span></code></pre></div>
|
|||
|
<h3 id="条件语句的使用">条件语句的使用<a aria-hidden="true" tabindex="-1" href="#条件语句的使用" class="internal"> §</a></h3>
|
|||
|
<p>条件语句是控制流程的核心。通过 <code>if-else</code> 语句,可以根据不同的条件在 Pipeline 中执行不同的构建步骤。例如,可以根据分支名称来决定是否执行生产环境的部署。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">if</span><span style="color:var(--shiki-color-text);"> (env</span><span style="color:var(--shiki-token-keyword);">.</span><span style="color:var(--shiki-color-text);">BRANCH_NAME </span><span style="color:var(--shiki-token-keyword);">==</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'master'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">// 执行生产环境的部署</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">} </span><span style="color:var(--shiki-token-keyword);">else</span><span style="color:var(--shiki-color-text);"> {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">// 执行测试环境的部署</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="循环结构的实现">循环结构的实现<a aria-hidden="true" tabindex="-1" href="#循环结构的实现" class="internal"> §</a></h3>
|
|||
|
<p>Groovy 支持多种循环结构,如 <code>for</code>、<code>while</code> 和 <code>each</code>,在 Jenkinsfile 中可以用于自动化重复任务。循环的使用能够大大简化处理多个相似任务的代码复杂度。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">for</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-keyword);">int</span><span style="color:var(--shiki-color-text);"> i </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">0</span><span style="color:var(--shiki-color-text);">; i </span><span style="color:var(--shiki-token-keyword);"><</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-constant);">5</span><span style="color:var(--shiki-color-text);">; i</span><span style="color:var(--shiki-token-keyword);">++</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Iteration ${i}"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="函数和闭包的封装">函数和闭包的封装<a aria-hidden="true" tabindex="-1" href="#函数和闭包的封装" class="internal"> §</a></h3>
|
|||
|
<p>函数和闭包是 Groovy 的强大特性之一。它们允许将重复或复杂的逻辑封装成模块化的代码段,从而提升代码的复用性和可维护性。在 Jenkinsfile 中,这种封装对于结构化和清晰的 Pipeline 编写尤为重要。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">greet</span><span style="color:var(--shiki-color-text);">(name) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Hello, ${name}!"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">greet(</span><span style="color:var(--shiki-token-string-expression);">'Jenkins'</span><span style="color:var(--shiki-color-text);">)</span></span></code></pre></div>
|
|||
|
<h3 id="异常处理机制">异常处理机制<a aria-hidden="true" tabindex="-1" href="#异常处理机制" class="internal"> §</a></h3>
|
|||
|
<p>为了保证 Pipeline 的健壮性,Groovy 提供了 <code>try-catch-finally</code> 结构来捕获和处理运行时可能发生的异常。通过异常处理机制,可以确保即使在错误发生时,Pipeline 也能进行适当的处理和资源清理,避免出现不可预料的问题。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-color-text);"> {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">// 可能抛出异常的代码</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">} </span><span style="color:var(--shiki-token-keyword);">catch</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-keyword);">Exception</span><span style="color:var(--shiki-color-text);"> e) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Caught exception: ${e.message}"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">} </span><span style="color:var(--shiki-token-keyword);">finally</span><span style="color:var(--shiki-color-text);"> {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Cleanup actions"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h2 id="使用-credentials-plugin-进行安全管理">使用 Credentials Plugin 进行安全管理<a aria-hidden="true" tabindex="-1" href="#使用-credentials-plugin-进行安全管理" class="internal"> §</a></h2>
|
|||
|
<p>**Credentials Plugin 是 Jenkins 用于安全存储和管理敏感信息(如密码、密钥、Token 等)的关键插件。**它确保在 Pipeline 中使用的凭证不会以明文形式暴露,保护敏感数据的安全性。</p>
|
|||
|
<h3 id="存储方式">存储方式<a aria-hidden="true" tabindex="-1" href="#存储方式" class="internal"> §</a></h3>
|
|||
|
<ul>
|
|||
|
<li><strong>Global credentials</strong>:可在 Jenkins 的全局范围内使用的凭证。</li>
|
|||
|
<li><strong>Domain-specific credentials</strong>:与特定域(如 Git 仓库、Docker 注册表)关联的凭证,只能在特定域中使用。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="使用方式">使用方式<a aria-hidden="true" tabindex="-1" href="#使用方式" class="internal"> §</a></h3>
|
|||
|
<p>在 Jenkins 管理界面中,管理员可以添加多种类型的凭证(如用户名密码、SSH 密钥、Secret Text 等)。在 Pipeline 中,可以通过 <code>withCredentials</code> 指令调用并使用这些凭证。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Checkout'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> withCredentials([usernamePassword(credentialsId: </span><span style="color:var(--shiki-token-string-expression);">'my-git-credentials'</span><span style="color:var(--shiki-color-text);">, usernameVariable: </span><span style="color:var(--shiki-token-string-expression);">'USER'</span><span style="color:var(--shiki-color-text);">, passwordVariable: </span><span style="color:var(--shiki-token-string-expression);">'PASS'</span><span style="color:var(--shiki-color-text);">)]) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'git clone https://${USER}:${PASS}@github.com/my-repo.git'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>为了确保凭证的安全性,在 Pipeline 中使用凭证时应避免以下情况:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>避免直接输出凭证</strong>:确保凭证不会出现在日志或控制台输出中。</li>
|
|||
|
<li><strong>使用安全的上下文</strong>:通过 <code>withCredentials</code> 封闭使用凭证的代码段,避免凭证泄露。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> withCredentials([string(credentialsId: </span><span style="color:var(--shiki-token-string-expression);">'SECRET_KEY'</span><span style="color:var(--shiki-color-text);">, variable: </span><span style="color:var(--shiki-token-string-expression);">'SECRET'</span><span style="color:var(--shiki-color-text);">)]) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'deploy --key $SECRET'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>Jenkins 支持与多种第三方工具集成,通过 Credentials Plugin 进行凭证管理,如:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>GitHub</strong>:使用 Personal Access Token 进行安全拉取和提交代码。</li>
|
|||
|
<li><strong>Docker</strong>:使用 Docker 凭证登录 Docker Registry,执行镜像推送和拉取。</li>
|
|||
|
<li><strong>AWS</strong>:集成 AWS IAM 凭证,进行云端资源管理和部署。</li>
|
|||
|
</ul>
|
|||
|
<p>通过与第三方工具的凭证集成,Jenkins 可以安全地执行各种自动化任务,避免敏感信息泄露。</p>
|
|||
|
<h3 id="注意事项">注意事项<a aria-hidden="true" tabindex="-1" href="#注意事项" class="internal"> §</a></h3>
|
|||
|
<p>在与第三方工具集成时,Jenkins 使用 Credentials Plugin 进行凭证管理,如 GitHub、Docker、AWS 等工具。这一功能极大地提升了自动化任务的安全性和效率,但在使用凭证管理时需注意以下安全事项:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>最小权限原则</strong>:为 Jenkins 配置凭证时,应仅授予执行任务所需的最低权限,以减少敏感资源的暴露风险。</li>
|
|||
|
<li><strong>定期更新凭证</strong>:定期轮换 API Key、SSH 密钥等凭证,以降低凭证泄露的风险,并确保安全性。</li>
|
|||
|
<li><strong>加密存储</strong>:确保 Jenkins 运行在受信任的环境中,并将凭证存储在加密的文件系统上,以防止未经授权的访问。</li>
|
|||
|
<li><strong>启用审计日志</strong>:开启 Jenkins 的安全审计日志功能,记录凭证的使用情况,有助于及时检测和应对异常行为。</li>
|
|||
|
</ul>
|
|||
|
<p>这些措施有助于保护敏感信息,确保与第三方工具的集成安全可靠。</p>
|
|||
|
<h2 id="基本的-ci-流程">基本的 CI 流程<a aria-hidden="true" tabindex="-1" href="#基本的-ci-流程" class="internal"> §</a></h2>
|
|||
|
<h3 id="使用-pipeline-实现持续集成流程">使用 Pipeline 实现持续集成流程<a aria-hidden="true" tabindex="-1" href="#使用-pipeline-实现持续集成流程" class="internal"> §</a></h3>
|
|||
|
<p>持续集成(CI)是现代软件开发中不可或缺的实践,旨在通过频繁的代码集成和自动化测试,快速发现和修复问题。Jenkins Pipeline 是实现持续集成的理想工具。</p>
|
|||
|
<p>典型的 CI 流程包括以下步骤:</p>
|
|||
|
<pre><code class="mermaid">graph TD
|
|||
|
A[代码提交] -->|开发者提交到版本控制系统| B[自动触发]
|
|||
|
B -->|通过 Webhook 或 SCM 轮询| C[拉取代码]
|
|||
|
C -->|从版本控制系统拉取最新代码| D[编译和测试]
|
|||
|
D -->|执行编译和单元测试| E[生成构建报告]
|
|||
|
E -->|生成测试报告和代码覆盖率报告,并发布构建结果| F[构建完成]
|
|||
|
</code></pre>
|
|||
|
<ol>
|
|||
|
<li><strong>代码提交</strong>:开发者将代码提交到版本控制系统(如 Git)。</li>
|
|||
|
<li><strong>自动触发</strong>:通过 Webhook 或 SCM 轮询,Jenkins 自动触发构建。</li>
|
|||
|
<li><strong>拉取代码</strong>:Jenkins 从版本控制系统中拉取最新代码。</li>
|
|||
|
<li><strong>编译和测试</strong>:Jenkins 执行编译和单元测试,确保代码质量。</li>
|
|||
|
<li><strong>生成构建报告</strong>:Jenkins 生成测试报告和代码覆盖率报告,并发布构建结果。</li>
|
|||
|
</ol>
|
|||
|
<p>通过持续集成流程,开发团队可以快速响应代码变更,确保代码库的稳定性。</p>
|
|||
|
<h3 id="集成单元测试">集成单元测试<a aria-hidden="true" tabindex="-1" href="#集成单元测试" class="internal"> §</a></h3>
|
|||
|
<p>单元测试是 CI 流程中的重要组成部分,Jenkins 提供了与多种测试框架的无缝集成。集成单元测试后,Jenkins 会在构建页面展示测试结果,包括测试通过率、失败的测试用例等信息,帮助开发者快速定位问题。</p>
|
|||
|
<h4 id="junit">JUnit<a aria-hidden="true" tabindex="-1" href="#junit" class="internal"> §</a></h4>
|
|||
|
<p>Jenkins 支持 JUnit 测试框架,用户可以通过 <code>junit</code> 指令自动解析和展示测试结果。在 Pipeline 中,可以这样集成 JUnit 测试:</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">stage(</span><span style="color:var(--shiki-token-string-expression);">'Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'mvn test'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> junit </span><span style="color:var(--shiki-token-string-expression);">'**/target/surefire-reports/*.xml'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h4 id="testing">Testing<a aria-hidden="true" tabindex="-1" href="#testing" class="internal"> §</a></h4>
|
|||
|
<p>Testing 是另一种流行的 Java 测试框架,与 JUnit 类似,用户可以通过 <code>publishTestNGResult</code> 插件解析 Testing 生成的 XML 测试报告。</p>
|
|||
|
<h3 id="构建失败后的错误处理与通知配置">构建失败后的错误处理与通知配置<a aria-hidden="true" tabindex="-1" href="#构建失败后的错误处理与通知配置" class="internal"> §</a></h3>
|
|||
|
<p>在 CI 流程中,构建失败是不可避免的。Jenkins 提供了多种机制帮助开发者及时处理构建失败。</p>
|
|||
|
<h4 id="错误处理">错误处理<a aria-hidden="true" tabindex="-1" href="#错误处理" class="internal"> §</a></h4>
|
|||
|
<p>在 Pipeline 中,用户可以使用 <code>try-catch</code> 块捕获构建中的异常,并执行相应的处理逻辑。例如,可以在构建失败后自动回滚到上一个稳定版本,或触发其他修复任务。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">try</span><span style="color:var(--shiki-color-text);"> {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'make deploy'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">} </span><span style="color:var(--shiki-token-keyword);">catch</span><span style="color:var(--shiki-color-text);"> (</span><span style="color:var(--shiki-token-keyword);">Exception</span><span style="color:var(--shiki-color-text);"> e) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> currentBuild</span><span style="color:var(--shiki-token-keyword);">.</span><span style="color:var(--shiki-color-text);">result </span><span style="color:var(--shiki-token-keyword);">=</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-string-expression);">'FAILURE'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-comment);">// 处理失败逻辑</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Deployment failed: ${e.message}"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h4 id="通知配置">通知配置<a aria-hidden="true" tabindex="-1" href="#通知配置" class="internal"> §</a></h4>
|
|||
|
<p>Jenkins 支持通过多种方式通知构建结果,如电子邮件、Slack、Webhooks 等。在 Pipeline 中,可以通过 <code>mail</code> 指令发送通知:</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">post {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> failure {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> mail to: </span><span style="color:var(--shiki-token-string-expression);">'team@example.com'</span><span style="color:var(--shiki-color-text);">,</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> subject: </span><span style="color:var(--shiki-token-string-expression);">"Build failed: ${env.JOB_NAME}"</span><span style="color:var(--shiki-color-text);">,</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> body: </span><span style="color:var(--shiki-token-string-expression);">"Build ${env.BUILD_NUMBER} failed. Please check the Jenkins logs."</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="生成和发布构建报告">生成和发布构建报告<a aria-hidden="true" tabindex="-1" href="#生成和发布构建报告" class="internal"> §</a></h3>
|
|||
|
<p>构建报告是 Jenkins CI 流程的重要输出,帮助团队了解构建状态、测试结果和代码质量。</p>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<p><strong>测试报告</strong>:Jenkins 可以自动生成和展示测试报告,如 JUnit、Testing 生成的测试结果。在 Pipeline 中,用户可以通过 <code>junit</code>、<code>publishTestNGResult</code> 等插件自动解析测试报告,并在构建页面展示详细的测试结果。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>代码覆盖率报告</strong>:通过集成代码覆盖率工具(如 JaCoCo、Cobertura),Jenkins 可以生成代码覆盖率报告,帮助团队了解测试覆盖情况。代码覆盖率报告可以与测试报告一起展示,提供全面的代码质量分析。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>构建工件存档</strong>:在构建完成后,Jenkins 可以自动存档构建生成的工件(如 JAR、WAR 文件),供后续发布或部署使用。通过 <code>archiveArtifacts</code> 指令,用户可以指定需要存档的文件或目录:</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">stage(</span><span style="color:var(--shiki-token-string-expression);">'Package'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'mvn package'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> archiveArtifacts artifacts: </span><span style="color:var(--shiki-token-string-expression);">'**/target/*.jar'</span><span style="color:var(--shiki-color-text);">, fingerprint: </span><span style="color:var(--shiki-token-constant);">true</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>生成和发布构建报告,确保了构建过程的透明性和可追溯性,帮助团队持续改进代码质量和构建流程。</p>
|
|||
|
<h2 id="多分支管道和并行作业">多分支管道和并行作业<a aria-hidden="true" tabindex="-1" href="#多分支管道和并行作业" class="internal"> §</a></h2>
|
|||
|
<p>多分支 Pipeline 是 Jenkins 支持多分支开发模式的重要功能,能够自动检测并为每个代码分支创建单独的 Pipeline Job。</p>
|
|||
|
<pre><code class="mermaid">graph TD
|
|||
|
A[创建 Multibranch Pipeline] --> B[配置源码管理]
|
|||
|
B --> C[分支策略]
|
|||
|
C --> D[Jenkinsfile 位置]
|
|||
|
</code></pre>
|
|||
|
<ol>
|
|||
|
<li><strong>创建 Multibranch Pipeline</strong>:在 Jenkins 中创建一个新的 Multibranch Pipeline 项目。</li>
|
|||
|
<li><strong>配置源码管理</strong>:指定 Git 或其他版本控制系统的仓库地址,Jenkins 会自动扫描该仓库的所有分支。</li>
|
|||
|
<li><strong>分支策略</strong>:配置分支发现策略,如只构建特定分支或忽略某些分支。</li>
|
|||
|
<li><strong>Jenkinsfile 位置</strong>:确保每个分支的根目录下有一个 Jenkinsfile,Jenkins 将根据该文件定义 Pipeline。</li>
|
|||
|
</ol>
|
|||
|
<p>多分支 Pipeline 的优势在于它自动适应 Git Flow 等多分支开发策略,每个分支可以独立运行自己的 CI/CD 流水线,极大提高了开发效率。</p>
|
|||
|
<h3 id="jenkins-对-git-分支的支持与自动化构建">Jenkins 对 Git 分支的支持与自动化构建<a aria-hidden="true" tabindex="-1" href="#jenkins-对-git-分支的支持与自动化构建" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 对 Git 的支持通过 Git 插件实现,能够自动化处理代码的拉取、构建和测试。对于多分支项目,Jenkins 可以在以下场景下自动触发构建:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>新分支创建</strong>:当新分支推送到远程仓库时,Jenkins 自动检测并触发构建。</li>
|
|||
|
<li><strong>分支变更</strong>:当现有分支发生变更(如代码提交、Merge),Jenkins 自动拉取最新代码并重新构建。</li>
|
|||
|
</ul>
|
|||
|
<p>通过 Webhook 与 Jenkins 集成,Git 仓库可以在代码变更时实时通知 Jenkins,进一步优化构建响应时间。</p>
|
|||
|
<h3 id="并行作业的配置与优化">并行作业的配置与优化<a aria-hidden="true" tabindex="-1" href="#并行作业的配置与优化" class="internal"> §</a></h3>
|
|||
|
<p>并行作业是在 Jenkins 中提升构建效率的关键技术,适合在 CI 流水线中并行执行不同的任务,如测试、代码分析、部署等。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>并行阶段</strong>:在 Pipeline 中使用 <code>parallel</code> 指令定义并行阶段。</li>
|
|||
|
<li><strong>资源管理</strong>:合理配置并行作业的资源分配,避免超载导致的系统性能下降。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> parallel {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Unit Tests'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'run-unit-tests.sh'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Integration Tests'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'run-integration-tests.sh'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>并行作业配置完成后,Jenkins 会自动分配可用的 Agent 节点执行任务,极大缩短构建时间。</p>
|
|||
|
<h3 id="实现高效的并行测试和部署">实现高效的并行测试和部署<a aria-hidden="true" tabindex="-1" href="#实现高效的并行测试和部署" class="internal"> §</a></h3>
|
|||
|
<p>通过并行执行,Jenkins 可以同时运行多组测试或部署任务,最大化资源利用率。具体优化策略包括:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>细粒度分割测试</strong>:将测试任务细分为多个小单元,分别在不同的 Agent 上并行执行。</li>
|
|||
|
<li><strong>自动化环境准备</strong>:通过并行配置自动化准备不同测试环境,减少环境切换时间。</li>
|
|||
|
<li><strong>并行部署到多环境</strong>:对于微服务架构的应用,Jenkins 可以并行部署到多个环境,如开发、测试和生产环境。</li>
|
|||
|
</ul>
|
|||
|
<p>这些优化策略有助于显著提升 Jenkins Pipeline 的执行效率和系统性能。</p>
|
|||
|
<h2 id="集成第三方服务">集成第三方服务<a aria-hidden="true" tabindex="-1" href="#集成第三方服务" class="internal"> §</a></h2>
|
|||
|
<h3 id="github">GitHub<a aria-hidden="true" tabindex="-1" href="#github" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 可以通过 Webhook 与 GitHub 集成,实现自动化的 CI/CD 流程。常见的集成方式包括:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>Webhook</strong>:GitHub 中配置 Webhook,当代码仓库发生事件(如代码提交、Pull Request 创建)时,通知 Jenkins 自动触发相应的构建。</li>
|
|||
|
<li><strong>Pull Request 触发</strong>:使用 GitHub Pull Request Builder 插件,当有新的 Pull Request 创建或更新时,Jenkins 自动拉取分支代码并触发 CI 流水线。</li>
|
|||
|
</ul>
|
|||
|
<p>通过这种集成,Jenkins 能够在代码变更时快速响应,并在 Pull Request 合并前执行必要的测试和代码质量检查。</p>
|
|||
|
<h3 id="docker">Docker<a aria-hidden="true" tabindex="-1" href="#docker" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 可以与 Docker 深度集成,充分利用容器化技术提高 CI/CD 流程的灵活性和可移植性。</p>
|
|||
|
<h4 id="构建-docker-镜像">构建 Docker 镜像<a aria-hidden="true" tabindex="-1" href="#构建-docker-镜像" class="internal"> §</a></h4>
|
|||
|
<p>通过 Docker Pipeline 插件,Jenkins 可以在流水线中自动构建、标记和推送 Docker 镜像。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> docker { image </span><span style="color:var(--shiki-token-string-expression);">'maven:3.6.3'</span><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'mvn clean package'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build Docker Image'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> script {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> docker</span><span style="color:var(--shiki-token-keyword);">.</span><span style="color:var(--shiki-color-text);">build(</span><span style="color:var(--shiki-token-string-expression);">'myapp:latest'</span><span style="color:var(--shiki-color-text);">)</span><span style="color:var(--shiki-token-keyword);">.</span><span style="color:var(--shiki-color-text);">push(</span><span style="color:var(--shiki-token-string-expression);">'myrepo/myapp:latest'</span><span style="color:var(--shiki-color-text);">)</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h4 id="使用-docker-容器执行构建">使用 Docker 容器执行构建<a aria-hidden="true" tabindex="-1" href="#使用-docker-容器执行构建" class="internal"> §</a></h4>
|
|||
|
<p>Jenkins 可以通过 Docker Agent 在容器中执行构建任务,确保构建环境的一致性,并隔离不同构建任务的依赖。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> docker { image </span><span style="color:var(--shiki-token-string-expression);">'node:14-alpine'</span><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Test'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'npm install'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'npm test'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>这种方法可以确保每次构建都在全新的、可控的环境中运行,减少因环境差异导致的构建失败。</p>
|
|||
|
<h3 id="kubernetes">Kubernetes<a aria-hidden="true" tabindex="-1" href="#kubernetes" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 与 Kubernetes 的集成使得 CI/CD 流水线可以轻松部署到云原生环境中,特别是在微服务架构下,Kubernetes 的动态调度和扩展能力与 Jenkins 的自动化能力结合,显著提升了软件交付效率。</p>
|
|||
|
<h4 id="jenkins-x">Jenkins X<a aria-hidden="true" tabindex="-1" href="#jenkins-x" class="internal"> §</a></h4>
|
|||
|
<p><strong>Jenkins X</strong> 是一个专为 Kubernetes 设计的 CI/CD 解决方案,简化了 Kubernetes 环境下的应用部署和管理。它基于 Jenkins,但提供了更高层次的抽象和开箱即用的 DevOps 工具链。</p>
|
|||
|
<h4 id="自动化部署到-kubernetes">自动化部署到 Kubernetes<a aria-hidden="true" tabindex="-1" href="#自动化部署到-kubernetes" class="internal"> §</a></h4>
|
|||
|
<p>通过 Kubernetes 插件,Jenkins 可以直接与 Kubernetes API 交互,实现应用的自动化部署和管理。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent any</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy to Kubernetes'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> script {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> kubernetesDeploy configs: </span><span style="color:var(--shiki-token-string-expression);">'k8s-deployment.yml'</span><span style="color:var(--shiki-color-text);">, kubeconfigId: </span><span style="color:var(--shiki-token-string-expression);">'kube-config'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<ul>
|
|||
|
<li><strong>Helm</strong>:Jenkins 还可以集成 Helm,通过 Helm Chart 管理 Kubernetes 应用的发布流程,进一步简化复杂应用的部署。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="其他服务集成">其他服务集成<a aria-hidden="true" tabindex="-1" href="#其他服务集成" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 支持集成各种第三方服务,通过插件扩展其功能,如 Slack、JIRA 等。</p>
|
|||
|
<h4 id="slack-通知">Slack 通知<a aria-hidden="true" tabindex="-1" href="#slack-通知" class="internal"> §</a></h4>
|
|||
|
<p>通过 Slack 插件,Jenkins 可以在构建状态发生变化时自动发送通知到指定的 Slack 频道,及时通知开发团队。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> post {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> success {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> slackSend(channel: </span><span style="color:var(--shiki-token-string-expression);">'#builds'</span><span style="color:var(--shiki-color-text);">, message: </span><span style="color:var(--shiki-token-string-expression);">"Build #${env.BUILD_NUMBER} succeeded"</span><span style="color:var(--shiki-color-text);">)</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> failure {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> slackSend(channel: </span><span style="color:var(--shiki-token-string-expression);">'#builds'</span><span style="color:var(--shiki-color-text);">, message: </span><span style="color:var(--shiki-token-string-expression);">"Build #${env.BUILD_NUMBER} failed"</span><span style="color:var(--shiki-color-text);">)</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h4 id="jira-工单自动化">JIRA 工单自动化<a aria-hidden="true" tabindex="-1" href="#jira-工单自动化" class="internal"> §</a></h4>
|
|||
|
<p>Jenkins 可以通过 JIRA 插件与 JIRA 项目管理工具集成,实现工单的自动创建、更新或关闭,配合 DevOps 流程。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> jiraNewIssue site: </span><span style="color:var(--shiki-token-string-expression);">'JIRA_SITE'</span><span style="color:var(--shiki-color-text);">, issue: [projectKey: </span><span style="color:var(--shiki-token-string-expression);">'PROJ'</span><span style="color:var(--shiki-color-text);">, summary: </span><span style="color:var(--shiki-token-string-expression);">'Build failed'</span><span style="color:var(--shiki-color-text);">, description: </span><span style="color:var(--shiki-token-string-expression);">'Build #${env.BUILD_NUMBER} failed'</span><span style="color:var(--shiki-color-text);">]</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h2 id="持续交付cd流程">持续交付(CD)流程<a aria-hidden="true" tabindex="-1" href="#持续交付cd流程" class="internal"> §</a></h2>
|
|||
|
<h3 id="持续交付与持续部署的区别">持续交付与持续部署的区别<a aria-hidden="true" tabindex="-1" href="#持续交付与持续部署的区别" class="internal"> §</a></h3>
|
|||
|
<p>**持续交付(Continuous Delivery, CD)<strong>和</strong>持续部署(Continuous Deployment)**是现代 DevOps 实践中常见的自动化软件发布策略,虽然二者名称相似,但在实际实施中存在关键区别:</p>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th></th><th><strong>持续交付(Continuous Delivery, CD)</strong></th><th><strong>持续部署(Continuous Deployment)</strong></th></tr></thead><tbody><tr><td><strong>定义</strong></td><td>软件开发实践,确保代码在通过所有自动化测试后随时可以部署到生产环境。</td><td>持续交付的进一步扩展,自动化流程不仅确保代码可以随时部署,还会在测试通过后立即部署到生产环境。</td></tr><tr><td><strong>部署触发方式</strong></td><td><strong>通常由人工操作触发,需通过手动审批或按需执行部署。</strong></td><td><strong>完全自动化,无需人工干预,测试通过后立即部署到生产环境。</strong></td></tr><tr><td><strong>自动化程度</strong></td><td>自动化测试覆盖,但部署步骤通常需要人工触发。</td><td>全面自动化,包括自动化测试和部署到生产环境。</td></tr><tr><td><strong>人工干预</strong></td><td>需要人工干预进行最终的部署决策。</td><td>无需人工干预,代码一旦通过测试,就会直接部署。</td></tr><tr><td><strong>适用场景</strong></td><td>适用于业务敏感度较高的项目,部署时间点需根据业务需求决定。</td><td>适用于频繁发布、变化快的产品,如 SaaS 应用。</td></tr><tr><td><strong>风险管理</strong></td><td>部署前有人工审核步骤,较容易控制风险。</td><td>需要非常严格的自动化测试和监控机制,因每次提交都会直接影响生产环境。</td></tr><tr><td><strong>典型使用者</strong></td><td>传统企业软件、金融系统等对生产环境变更非常敏感的项目。</td><td>快速迭代的互联网产品、SaaS 平台等。</td></tr><tr><td><strong>发布频率</strong></td><td>根据业务需求决定,可在经过人工审批后择机发布。</td><td>发布频率高,通常在每次代码提交后,立即发布到生产环境。</td></tr><tr><td><strong>稳定性要求</strong></td><td>高度关注生产环境的稳定性,部署前可能进行额外的手动验证。</td><td>依赖自动化测试和监控,生产环境的稳定性直接依赖于自动化机制的可靠性。</td></tr></tbody></table>
|
|||
|
<p>在实践中,持续交付适用于业务敏感度较高的项目,而持续部署则适用于频繁发布、变化快的产品,如 SaaS 应用。</p>
|
|||
|
<h3 id="实现自动化部署的最佳实践">实现自动化部署的最佳实践<a aria-hidden="true" tabindex="-1" href="#实现自动化部署的最佳实践" class="internal"> §</a></h3>
|
|||
|
<p>自动化部署是持续交付的核心环节,确保代码能快速、安全地发布到生产环境。以下是实现自动化部署的最佳实践:</p>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>最佳实践</strong></th><th><strong>描述</strong></th><th><strong>工具或技术</strong></th></tr></thead><tbody><tr><td><strong>基础设施即代码(IaC)</strong></td><td>将基础设施配置代码化,确保部署环境的一致性和可重复性。</td><td>Terraform、Ansible、CloudFormation</td></tr><tr><td><strong>环境标准化</strong></td><td>使用容器化和虚拟化技术,确保开发、测试、生产环境一致,减少因环境差异导致的部署失败。</td><td>Docker、Kubernetes、Vagrant</td></tr><tr><td><strong>无停机部署</strong></td><td>设计无停机的部署流程,避免服务中断,保持旧版本在新版本部署期间可用。</td><td>蓝绿部署、金丝雀发布、滚动更新</td></tr><tr><td><strong>自动化回滚</strong></td><td>部署过程中设计回滚机制,快速恢复到上一个稳定版本,确保业务连续性。</td><td>Jenkins、Spinnaker、ArgoCD</td></tr><tr><td><strong>安全集成</strong></td><td>在部署管道中集成安全扫描,确保在每次部署前检测并修复安全漏洞和配置问题。</td><td>Snyk、OWASP ZAP、Aqua Security</td></tr><tr><td><strong>监控与日志</strong></td><td>部署完成后自动更新监控和日志配置,实时监控和分析新版本的健康状况。</td><td>Prometheus、Grafana、ELK Stack(Elasticsearch, Logstash, Kibana)</td></tr></tbody></table>
|
|||
|
<h3 id="蓝绿部署金丝雀发布等策略的实现">蓝绿部署、金丝雀发布等策略的实现<a aria-hidden="true" tabindex="-1" href="#蓝绿部署金丝雀发布等策略的实现" class="internal"> §</a></h3>
|
|||
|
<p>蓝绿部署和金丝雀发布是两种常用的无停机部署策略,适用于在不断变化的生产环境中安全地发布新版本。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>蓝绿部署</strong>:蓝绿部署通过维护两套几乎相同的生产环境来实现无停机发布。当前版本在 <code>蓝色</code> 环境中运行,新版本在 <code>绿色</code> 环境中部署并验证,一旦验证通过,将流量切换到 <code>绿色</code> 环境。这样,即使新版本出现问题,也能快速切回“蓝色”环境。
|
|||
|
<ul>
|
|||
|
<li><strong>实现方式</strong>:可以使用 DNS 切换、负载均衡器调整等手段实现流量的切换。</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><strong>金丝雀发布</strong>:金丝雀发布是逐步将新版本部署给部分用户(通常是生产环境的一小部分流量),然后逐步增加新版本的用户比例。通过这种方式,可以在生产环境中观察新版本的表现,发现问题可以及时调整或回滚。
|
|||
|
<ul>
|
|||
|
<li><strong>实现方式</strong>:可以使用负载均衡器或特定的路由策略(如 Istio)逐步引入新版本流量。</li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<p>通过 Jenkins 的 Pipeline 和 Kubernetes 的滚动更新策略,可以自动化实现上述部署策略。</p>
|
|||
|
<h3 id="部署管道的监控与回滚机制">部署管道的监控与回滚机制<a aria-hidden="true" tabindex="-1" href="#部署管道的监控与回滚机制" class="internal"> §</a></h3>
|
|||
|
<p>部署管道不仅要确保软件顺利发布,还要能够监控发布后的状态,并在必要时快速回滚。有效的监控与回滚机制包括:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>实时监控</strong>:部署管道应集成应用性能监控工具(如 Prometheus、Grafana)和日志管理工具(如 ELK Stack),实时监控新版本的关键指标,如响应时间、错误率、资源消耗等。</li>
|
|||
|
<li><strong>健康检查</strong>:在部署结束后,自动触发健康检查脚本,验证应用的核心功能和服务状态。如果检测到异常,自动触发警报或启动回滚流程。</li>
|
|||
|
<li><strong>自动化回滚</strong>:在 Pipeline 中设计自动化回滚逻辑,一旦监控检测到严重问题,系统可以自动回滚到上一个稳定版本。例如,利用 Kubernetes 的回滚机制或通过 Jenkins 的 <code>rollback</code> 步骤触发回滚操作。</li>
|
|||
|
<li><strong>部署日志与审计</strong>:保持详细的部署日志和审计记录,确保所有部署操作都可追踪。这样在出现问题时,可以快速定位根本原因,并采取修复措施。</li>
|
|||
|
</ul>
|
|||
|
<h2 id="使用共享库提高管道重用性">使用共享库提高管道重用性<a aria-hidden="true" tabindex="-1" href="#使用共享库提高管道重用性" class="internal"> §</a></h2>
|
|||
|
<p><strong>共享库(Shared Library)</strong> 是 Jenkins 中的一种机制,允许用户将常用的 Pipeline 代码封装在一个集中管理的库中,供多个 Jenkins Pipeline 复用。共享库通过将通用的构建、测试、部署逻辑抽象出来,使得各项目的 Pipeline 定义更加简洁,并易于维护和更新。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>代码复用</strong>:将常用的 Pipeline 步骤、工具集成、通知机制等抽象为共享库函数,减少重复代码。</li>
|
|||
|
<li><strong>标准化</strong>:通过共享库,定义企业级的标准化流水线组件,确保所有项目遵循统一的流程和最佳实践。</li>
|
|||
|
<li><strong>快速迭代</strong>:当某个流程需要更新时,只需更新共享库即可同时影响所有使用该库的 Pipeline,减少了个别项目逐一修改的工作量。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="创建共享库"><strong>创建共享库</strong><a aria-hidden="true" tabindex="-1" href="#创建共享库" class="internal"> §</a></h3>
|
|||
|
<p>创建共享库需要按照 Jenkins 的特定目录结构和代码规范进行,通常使用 Git 存储和版本控制。目录结构:共享库的代码需要存放在指定目录中,并按约定组织结构:</p>
|
|||
|
<ul>
|
|||
|
<li><code>vars/</code> 目录:存放全局可用的脚本(如 <code>myStep.groovy</code>),可以直接在 Pipeline 中调用。</li>
|
|||
|
<li><code>src/</code> 目录:存放支持 Groovy 类的源码,便于复杂逻辑的封装。</li>
|
|||
|
<li><code>resources/</code> 目录:存放配置文件、模版等静态资源。</li>
|
|||
|
<li><code>Jenkinsfile</code>:用于本地测试的 Jenkinsfile。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-comment);">// vars/myStep.groovy</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-token-keyword);">def</span><span style="color:var(--shiki-color-text);"> </span><span style="color:var(--shiki-token-function);">call</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-keyword);">String</span><span style="color:var(--shiki-color-text);"> name) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> echo </span><span style="color:var(--shiki-token-string-expression);">"Hello, ${name}!"</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="管理共享库"><strong>管理共享库</strong><a aria-hidden="true" tabindex="-1" href="#管理共享库" class="internal"> §</a></h3>
|
|||
|
<ul>
|
|||
|
<li><strong>版本控制</strong>:共享库应存放在 Git 仓库中,便于版本管理和变更追踪。库的不同版本可以通过标签或分支管理。</li>
|
|||
|
<li><strong>加载共享库</strong>:在 Jenkinsfile 中,通过 <code>@Library</code> 注解加载共享库,并指定版本或分支。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">@Library</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-string-expression);">'my-shared-library@main'</span><span style="color:var(--shiki-color-text);">) _</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Greet'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> myStep(</span><span style="color:var(--shiki-token-string-expression);">'Jenkins'</span><span style="color:var(--shiki-color-text);">)</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<h3 id="在-pipeline-中使用共享库">在 Pipeline 中使用共享库<a aria-hidden="true" tabindex="-1" href="#在-pipeline-中使用共享库" class="internal"> §</a></h3>
|
|||
|
<p>在 Jenkins Pipeline 中使用共享库的方式包括全局加载和按需加载:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>全局加载</strong>:通过 Jenkins 管理界面配置共享库为全局库,所有 Pipeline 自动加载该库,无需在 Jenkinsfile 中显式声明。</li>
|
|||
|
<li><strong>按需加载</strong>:在 Pipeline 中通过 <code>@Library</code> 注解指定要加载的库,适用于不同项目使用不同版本或库的场景。</li>
|
|||
|
</ul>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-token-keyword);">@Library</span><span style="color:var(--shiki-color-text);">(</span><span style="color:var(--shiki-token-string-expression);">'my-shared-library@version-1.0'</span><span style="color:var(--shiki-color-text);">) _</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Build'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> buildApp() </span><span style="color:var(--shiki-token-comment);">// 调用共享库中的函数</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>通过共享库,团队可以将通用的流程和逻辑集中管理,并在各个 Pipeline 中简化实现,提高代码的可维护性和一致性。</p>
|
|||
|
<h3 id="版本控制与更新策略">版本控制与更新策略<a aria-hidden="true" tabindex="-1" href="#版本控制与更新策略" class="internal"> §</a></h3>
|
|||
|
<p>共享库的版本控制和更新策略对于确保稳定性和灵活性至关重要。</p>
|
|||
|
<p>为共享库设置版本标签或使用分支管理不同的版本,确保不同项目可以基于稳定的版本进行开发和构建。主流策略包括使用 Git 标签管理稳定版本,使用分支(如 <code>master</code>、<code>develop</code>)进行开发和测试。</p>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<table><thead><tr><th><strong>策略</strong></th><th><strong>描述</strong></th></tr></thead><tbody><tr><td><strong>渐进式更新</strong></td><td>在更新共享库时,避免直接修改主版本,先在开发分支或新版本标签上进行迭代和测试。确认稳定后,再将变更合并到主版本或在稳定分支中发布新版本,减少构建失败风险。</td></tr><tr><td><strong>回滚机制</strong></td><td>确保更新共享库后,所有依赖的 Pipeline 都能平稳过渡。如果新版本出现问题,可以快速回滚到旧版本,通过在 Pipeline 中指定旧版本或分支的方式实现回滚。</td></tr><tr><td><strong>文档与变更日志</strong></td><td>每次更新共享库时,附带详细的文档说明和变更日志,告知使用者新增功能、变更及可能的影响。良好的文档有助于团队更好地适应和采用新的库版本。</td></tr><tr><td><strong>向后兼容性</strong></td><td>更新共享库时,尽量保持向后兼容性。避免引入破坏性变更,或在引入破坏性变更时,提供过渡期和旧版支持,确保所有项目有足够的时间进行调整。</td></tr></tbody></table>
|
|||
|
<h2 id="部署到-kubernetes-和其他云平台">部署到 Kubernetes 和其他云平台<a aria-hidden="true" tabindex="-1" href="#部署到-kubernetes-和其他云平台" class="internal"> §</a></h2>
|
|||
|
<p>Jenkins 可以与 Kubernetes 实现深度集成,尤其是在自动化部署和容器化管理方面。Jenkins 的 Kubernetes 插件可以动态地在 Kubernetes 集群中启动 Jenkins Agent,以执行构建任务。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>Jenkins Agent 动态配置</strong>:Jenkins 可以利用 Kubernetes 插件在需要时自动启动容器化的 Jenkins Agent,并在任务完成后销毁这些容器。这种按需启动和销毁 Agent 的机制,提升了资源利用效率,特别适合处理高并发的构建任务。</li>
|
|||
|
<li><strong>Jenkins X</strong>:Jenkins X 是 Jenkins 的云原生扩展,专为 Kubernetes 环境设计。它简化了在 Kubernetes 上的 CI/CD 配置,自动管理应用的部署和环境,并提供开箱即用的 GitOps 流水线管理。</li>
|
|||
|
<li><strong>集群管理和资源调度</strong>:通过 Jenkins 与 Kubernetes 的集成,Jenkins 可以直接与 Kubernetes API 交互,进行容器编排、服务部署、扩展和滚动更新,实现高效的自动化运维。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="使用-helm-部署应用到-kubernetes">使用 Helm 部署应用到 Kubernetes<a aria-hidden="true" tabindex="-1" href="#使用-helm-部署应用到-kubernetes" class="internal"> §</a></h3>
|
|||
|
<p><strong>Helm</strong> 是 Kubernetes 的包管理工具,用于简化应用在 Kubernetes 上的部署和管理。通过 Helm,用户可以定义、安装和升级 Kubernetes 应用。</p>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<p><strong>创建 Helm Chart</strong>:一个 Helm Chart 是一个包含 Kubernetes 资源定义的模板包,描述了一个完整的应用及其依赖。开发者可以创建自定义的 Helm Chart 来管理应用的生命周期。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>Helm 与 Jenkins 集成</strong>:在 Jenkins Pipeline 中,用户可以通过 <code>helm</code> 命令自动化地管理 Helm Chart 的打包、发布和部署。例如,可以在 Pipeline 中执行以下步骤:</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent any</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Helm Package'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'helm package myapp'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Helm Deploy'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'helm upgrade --install myapp ./myapp-chart'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>自动化发布和升级</strong>:Helm 支持自动化的版本升级、回滚操作,配合 Jenkins 的 Pipeline,可以实现持续交付的完整生命周期管理。</p>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<h3 id="jenkins-部署-awsazuregcp-等云平台">Jenkins 部署 AWS、Azure、GCP 等云平台<a aria-hidden="true" tabindex="-1" href="#jenkins-部署-awsazuregcp-等云平台" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 可以通过各种插件和脚本集成来实现对 AWS、Azure、GCP 等主流云平台的自动化部署和管理。</p>
|
|||
|
<ul>
|
|||
|
<li>
|
|||
|
<p><strong>使用 AWS CLI 和 SDK</strong>:Jenkins 可以在 Pipeline 中通过 AWS CLI 进行 S3 存储管理、EC2 实例启动、Lambda 函数部署等操作。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>CloudFormation 和 Terraform</strong>:通过 Jenkins 自动化运行 CloudFormation 模板或 Terraform 脚本,管理 AWS 上的基础设施。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>Azure CLI 和 DevOps 集成</strong>:Jenkins 支持使用 Azure CLI 管理 Azure 资源,还可以通过 Azure DevOps 插件,直接与 Azure DevOps 服务进行集成,自动化管理应用的发布、资源的创建和配置。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>Google Cloud SDK</strong>:Jenkins 可以利用 Google Cloud SDK 在 GCP 上进行容器管理、虚拟机管理以及云函数的部署。</p>
|
|||
|
</li>
|
|||
|
<li>
|
|||
|
<p><strong>Terraform 集成</strong>:同样可以通过 Terraform 在 GCP 上定义和管理基础设施,配合 Jenkins 的自动化执行,实现 IaC。</p>
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
<h3 id="利用-infrastructure-as-code-实现自动化基础设施部署">利用 Infrastructure as Code 实现自动化基础设施部署<a aria-hidden="true" tabindex="-1" href="#利用-infrastructure-as-code-实现自动化基础设施部署" class="internal"> §</a></h3>
|
|||
|
<p><strong>Infrastructure as Code(IaC)</strong> 是通过代码定义和管理基础设施的实践。Jenkins 与 IaC 工具(如 Terraform、CloudFormation)的集成,可以实现从基础设施到应用的全自动化管理。</p>
|
|||
|
<h4 id="terraform">Terraform<a aria-hidden="true" tabindex="-1" href="#terraform" class="internal"> §</a></h4>
|
|||
|
<p>使用 Terraform 脚本定义云资源,在 Jenkins Pipeline 中通过 <code>terraform</code> 命令执行资源创建、更新和销毁。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent any</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Terraform Apply'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'terraform init'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'terraform apply -auto-approve'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>Terraform 管理基础设施的状态,并支持自动化的回滚机制,在 Jenkins 中配置 <code>terraform plan</code> 和 <code>terraform apply</code> 步骤,实现安全的基础设施更新。</p>
|
|||
|
<h4 id="cloudformation">CloudFormation<a aria-hidden="true" tabindex="-1" href="#cloudformation" class="internal"> §</a></h4>
|
|||
|
<p>使用 CloudFormation 模板定义 AWS 资源,并在 Jenkins 中通过 <code>aws cloudformation</code> 命令自动化执行栈的创建和更新。</p>
|
|||
|
<div data-rehype-pretty-code-fragment><pre style="background-color:var(--shiki-color-background);" tabindex="0" data-language="groovy" data-theme="default"><code data-language="groovy" data-theme="default"><span data-line><span style="color:var(--shiki-color-text);">pipeline {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> agent any</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stages {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> stage(</span><span style="color:var(--shiki-token-string-expression);">'Deploy Stack'</span><span style="color:var(--shiki-color-text);">) {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> steps {</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> sh </span><span style="color:var(--shiki-token-string-expression);">'aws cloudformation deploy --template-file stack.yml --stack-name my-stack'</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);"> }</span></span>
|
|||
|
<span data-line><span style="color:var(--shiki-color-text);">}</span></span></code></pre></div>
|
|||
|
<p>配置 CloudFormation 事件监控,通过 Jenkins Pipeline 自动化响应失败的栈操作,并触发回滚或重新部署。通过 IaC 的实践,开发和运维团队可以通过 Jenkins 实现基础设施的全生命周期管理,确保环境的一致性和自动化的高效性。</p>
|
|||
|
<h2 id="性能优化和故障排查">性能优化和故障排查<a aria-hidden="true" tabindex="-1" href="#性能优化和故障排查" class="internal"> §</a></h2>
|
|||
|
<h3 id="jenkins-性能瓶颈识别与优化策略">Jenkins 性能瓶颈识别与优化策略<a aria-hidden="true" tabindex="-1" href="#jenkins-性能瓶颈识别与优化策略" class="internal"> §</a></h3>
|
|||
|
<p>随着项目规模的增长,Jenkins 的性能优化变得至关重要。常见的性能瓶颈及优化策略包括:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>Master 性能优化</strong>:Jenkins Master 服务器的性能直接影响到整个系统的响应速度。优化 Master 性能的关键在于提升 CPU 和内存资源配置,使用高性能磁盘以加快 Job 的读取和日志存储。可以通过增加 Master 节点的资源或分离部分非核心任务到专用节点来缓解负载。</li>
|
|||
|
<li><strong>Agent 管理优化</strong>:通过合理配置 Agent 的数量和资源,确保并发任务能够高效执行。可以使用 Kubernetes 动态扩展 Agent 的机制,根据需求自动调整 Agent 数量。</li>
|
|||
|
<li><strong>数据库与存储优化</strong>:Jenkins 的历史记录、构建日志、Artifact 存储等会消耗大量的存储资源。可以使用专用的数据库系统(如 MySQL)管理 Jenkins 的元数据,定期清理旧的构建记录,压缩存储空间。</li>
|
|||
|
<li><strong>插件管理</strong>:尽量减少不必要的插件,避免插件冲突或兼容性问题引发的性能问题。定期更新插件版本,以利用最新的性能优化和功能改进。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="分布式构建master-slave-架构的优化">分布式构建:Master-Slave 架构的优化<a aria-hidden="true" tabindex="-1" href="#分布式构建master-slave-架构的优化" class="internal"> §</a></h3>
|
|||
|
<p>Jenkins 支持 Master-Slave(Agent)架构,通过分布式构建提升系统的并发能力和资源利用率。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>水平扩展</strong>:通过增加 Slave 节点,可以水平扩展 Jenkins 的构建能力,将大量并发构建任务分散到多个 Slave 节点执行,减少 Master 的负载。</li>
|
|||
|
<li><strong>专用 Slave</strong>:为特定任务(如测试、部署)配置专用的 Slave 节点,以提高特定任务的执行效率。可以根据任务的资源需求选择不同类型的 Slave(如高内存、GPU 支持的 Slave)。</li>
|
|||
|
<li><strong>负载均衡</strong>:合理分配构建任务,避免某些 Slave 节点负载过高。可以使用标签(Label)机制,将不同类型的任务分配到适合的 Slave 上执行。</li>
|
|||
|
<li><strong>网络优化</strong>:确保 Master 和 Slave 之间的网络连接稳定可靠,使用高速网络和专用通道,减少构建数据传输的延迟。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="jenkins-日志分析">Jenkins 日志分析<a aria-hidden="true" tabindex="-1" href="#jenkins-日志分析" class="internal"> §</a></h3>
|
|||
|
<p>日志是 Jenkins 故障排查的关键工具,通过分析 Jenkins 日志,团队可以快速定位问题并采取相应的解决措施。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>主日志</strong>:Jenkins 的主日志包含了系统启动、插件加载、任务调度等核心信息。通过分析主日志,可以发现系统启动错误、插件兼容性问题、任务调度冲突等问题。</li>
|
|||
|
<li><strong>构建日志</strong>:每个 Jenkins Job 都有独立的构建日志,记录了从源码拉取、构建、测试到部署的详细过程。通过构建日志可以分析构建失败的原因,排查脚本错误、环境问题或外部依赖的故障。</li>
|
|||
|
<li><strong>插件日志</strong>:某些插件会生成独立的日志文件,分析插件日志可以帮助解决插件相关的错误,如身份验证失败、外部服务连接超时等。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="jenkins-故障排查">Jenkins 故障排查<a aria-hidden="true" tabindex="-1" href="#jenkins-故障排查" class="internal"> §</a></h3>
|
|||
|
<ul>
|
|||
|
<li><strong>重现问题</strong>:通过复现问题,可以确认问题的触发条件和影响范围。可以使用相同的输入和配置,在测试环境中重现问题,收集更多调试信息。</li>
|
|||
|
<li><strong>日志级别调整</strong>:在某些情况下,可以通过提高日志级别(如将默认的 INFO 级别提升为 DEBUG),获取更详细的调试信息,帮助分析复杂的问题。</li>
|
|||
|
<li><strong>结合监控系统</strong>:将 Jenkins 与系统监控工具(如 Prometheus、Grafana)结合,实时监控 Jenkins 的性能指标、资源消耗、错误率等,提前发现并预警潜在的问题。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="构建队列管理">构建队列管理<a aria-hidden="true" tabindex="-1" href="#构建队列管理" class="internal"> §</a></h3>
|
|||
|
<p>随着构建任务的增加,构建队列的管理和资源优化变得至关重要。有效的队列管理可以避免任务积压,提升系统整体效率。</p>
|
|||
|
<ul>
|
|||
|
<li><strong>优先级队列</strong>:通过 Jenkins 的优先级队列插件,可以为不同类型的任务设置优先级,确保高优先级任务优先执行,减少关键任务的等待时间。</li>
|
|||
|
<li><strong>队列限流</strong>:通过配置最大并发构建数,限制资源消耗高的任务同时执行,防止资源争用导致的系统性能下降。</li>
|
|||
|
<li><strong>任务分配策略</strong>:使用 Label 和 Node Affinity 机制,将特定任务分配到最合适的节点执行,提高执行效率并减少不必要的资源占用。</li>
|
|||
|
</ul>
|
|||
|
<h3 id="资源优化">资源优化<a aria-hidden="true" tabindex="-1" href="#资源优化" class="internal"> §</a></h3>
|
|||
|
<ul>
|
|||
|
<li><strong>缓存机制</strong>:通过使用缓存(如 Docker 镜像缓存、依赖包缓存),减少重复下载和构建时间,提升构建速度。</li>
|
|||
|
<li><strong>构建资源池化</strong>:将资源(如数据库、外部服务)池化处理,避免频繁启动和销毁资源带来的开销。</li>
|
|||
|
<li><strong>动态扩展</strong>:使用自动化扩展工具,根据实际负载动态调整 Jenkins 的资源配置,确保在高峰期自动扩展,在低负载时自动缩减,节省成本。</li>
|
|||
|
</ul></article></div><div class="right sidebar"><div class="graph "><h3>Graph View</h3><div class="graph-outer"><div id="graph-container" data-cfg="{"drag":true,"zoom":true,"depth":1,"scale":1.1,"repelForce":0.5,"centerForce":0.3,"linkDistance":30,"fontSize":0.6,"opacityScale":1,"showTags":true,"removeTags":[]}"></div><svg version="1.1" id="global-graph-icon" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 55 55" fill="currentColor" xmlSpace="preserve"><path d="M49,0c-3.309,0-6,2.691-6,6c0,1.035,0.263,2.009,0.726,2.86l-9.829,9.829C32.542,17.634,30.846,17,29,17
|
|||
|
s-3.542,0.634-4.898,1.688l-7.669-7.669C16.785,10.424,17,9.74,17,9c0-2.206-1.794-4-4-4S9,6.794,9,9s1.794,4,4,4
|
|||
|
c0.74,0,1.424-0.215,2.019-0.567l7.669,7.669C21.634,21.458,21,23.154,21,25s0.634,3.542,1.688,4.897L10.024,42.562
|
|||
|
C8.958,41.595,7.549,41,6,41c-3.309,0-6,2.691-6,6s2.691,6,6,6s6-2.691,6-6c0-1.035-0.263-2.009-0.726-2.86l12.829-12.829
|
|||
|
c1.106,0.86,2.44,1.436,3.898,1.619v10.16c-2.833,0.478-5,2.942-5,5.91c0,3.309,2.691,6,6,6s6-2.691,6-6c0-2.967-2.167-5.431-5-5.91
|
|||
|
v-10.16c1.458-0.183,2.792-0.759,3.898-1.619l7.669,7.669C41.215,39.576,41,40.26,41,41c0,2.206,1.794,4,4,4s4-1.794,4-4
|
|||
|
s-1.794-4-4-4c-0.74,0-1.424,0.215-2.019,0.567l-7.669-7.669C36.366,28.542,37,26.846,37,25s-0.634-3.542-1.688-4.897l9.665-9.665
|
|||
|
C46.042,11.405,47.451,12,49,12c3.309,0,6-2.691,6-6S52.309,0,49,0z M11,9c0-1.103,0.897-2,2-2s2,0.897,2,2s-0.897,2-2,2
|
|||
|
S11,10.103,11,9z M6,51c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S8.206,51,6,51z M33,49c0,2.206-1.794,4-4,4s-4-1.794-4-4
|
|||
|
s1.794-4,4-4S33,46.794,33,49z M29,31c-3.309,0-6-2.691-6-6s2.691-6,6-6s6,2.691,6,6S32.309,31,29,31z M47,41c0,1.103-0.897,2-2,2
|
|||
|
s-2-0.897-2-2s0.897-2,2-2S47,39.897,47,41z M49,10c-2.206,0-4-1.794-4-4s1.794-4,4-4s4,1.794,4,4S51.206,10,49,10z"></path></svg></div><div id="global-graph-outer"><div id="global-graph-container" data-cfg="{"drag":true,"zoom":true,"depth":-1,"scale":0.9,"repelForce":0.5,"centerForce":0.3,"linkDistance":30,"fontSize":0.6,"opacityScale":1,"showTags":true,"removeTags":[]}"></div></div></div><div class="toc desktop-only"><button type="button" id="toc" class><h3>Table of Contents</h3><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="fold"><polyline points="6 9 12 15 18 9"></polyline></svg></button><div id="toc-content"><ul class="overflow"><li class="depth-0"><a href="#jenkins-概述" data-for="jenkins-概述">Jenkins 概述</a></li><li class="depth-1"><a href="#jenkins-是什么" data-for="jenkins-是什么">Jenkins 是什么</a></li><li class="depth-1"><a href="#jenkins-的历史与发展" data-for="jenkins-的历史与发展">Jenkins 的历史与发展</a></li><li class="depth-1"><a href="#jenkins-的架构及工作原理" data-for="jenkins-的架构及工作原理">Jenkins 的架构及工作原理</a></li><li class="depth-1"><a href="#jenkins-与其他-cicd-工具的对比" data-for="jenkins-与其他-cicd-工具的对比">Jenkins 与其他 CI/CD 工具的对比</a></li><li class="depth-0"><a href="#jenkins-安装和配置" data-for="jenkins-安装和配置">Jenkins 安装和配置</a></li><li class="depth-1"><a href="#初始配置和界面概览" data-for="初始配置和界面概览">初始配置和界面概览</a></li><li class="depth-1"><a href="#系统配置全局安全设置系统信息环境变量配置" data-for="系统配置全局安全设置系统信息环境变量配置">系统配置:全局安全设置、系统信息、环境变量配置</a></li><li class="depth-1"><a href="#用户管理创建用户和角色权限分配" data-for="用户管理创建用户和角色权限分配">用户管理:创建用户和角色,权限分配</a></li><li class="depth-0"><a href="#jenkins-插件系统" data-for="jenkins-插件系统">Jenkins 插件系统</a></li><li class="depth-1"><a href="#常用插件介绍与配置" data-for="常用插件介绍与配置">常用插件介绍与配置</a></li><li class="depth-1"><a href="#插件的更新和备份策略" data-for="插件的更新和备份策略">插件的更新和备份策略</a></li><li class="depth-1"><a href="#插件冲突与兼容性问题的解决" data-for="插件冲突与兼容性问题的解决">插件冲突与兼容性问题的解决</a></li><li class="depth-0"><a href="#jenkins-job" data-for="jenkins-job">Jenkins Job</a></li><li class="depth-1"><a href="#自由风格项目freestyle-project" data-for="自由风格项目freestyle-project">自由风格项目(Freestyle Project)</a></li><li class="depth-1"><a href="#流水线项目pipeline-project" data-for="流水线项目pipeline-project">流水线项目(Pipeline Project)</a></li><li class="depth-1"><a href="#多分支流水线项目multibranch-pipeline-project" data-for="多分支流水线项目multibranch-pipeline-project">多分支流水线项目(Multibranch Pipeline Project)</a></li><li class="depth-1"><a href="#maven-项目maven-project" data-for="maven-项目maven-project">Maven 项目(Maven Project)</a></li><li class="depth-1"><a href="#外部任务external-job" data-for="外部任务external-job">外部任务(External Job)</a></li><li class="depth-1"><a href="#pipeline-as-code-项目pipeline-as-code-project" data-for="pipeline-as-code-项目pipeline-as-code-project">Pipeline as Code 项目(Pipeline-as-Code Project)</a></li><li class="depth-1"><a href="#组合项目matrix-project" data-for="组合项目matrix-project">组合项目(Matrix Project)</a></li><li class="depth-1"><a href="#外部工作流external-workflow" data-for="外部工作<E5B7A5>
|
|||
|
function toggleCallout() {
|
|||
|
const outerBlock = this.parentElement;
|
|||
|
outerBlock.classList.toggle(`is-collapsed`);
|
|||
|
const collapsed = outerBlock.classList.contains(`is-collapsed`);
|
|||
|
const height = collapsed ? this.scrollHeight : outerBlock.scrollHeight;
|
|||
|
outerBlock.style.maxHeight = height + `px`;
|
|||
|
let current = outerBlock;
|
|||
|
let parent = outerBlock.parentElement;
|
|||
|
while (parent) {
|
|||
|
if (!parent.classList.contains(`callout`)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
const collapsed2 = parent.classList.contains(`is-collapsed`);
|
|||
|
const height2 = collapsed2 ? parent.scrollHeight : parent.scrollHeight + current.scrollHeight;
|
|||
|
parent.style.maxHeight = height2 + `px`;
|
|||
|
current = parent;
|
|||
|
parent = parent.parentElement;
|
|||
|
}
|
|||
|
}
|
|||
|
function setupCallout() {
|
|||
|
const collapsible = document.getElementsByClassName(
|
|||
|
`callout is-collapsible`
|
|||
|
);
|
|||
|
for (const div of collapsible) {
|
|||
|
const title = div.firstElementChild;
|
|||
|
if (title) {
|
|||
|
title.removeEventListener(`click`, toggleCallout);
|
|||
|
title.addEventListener(`click`, toggleCallout);
|
|||
|
const collapsed = div.classList.contains(`is-collapsed`);
|
|||
|
const height = collapsed ? title.scrollHeight : div.scrollHeight;
|
|||
|
div.style.maxHeight = height + `px`;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
document.addEventListener(`nav`, setupCallout);
|
|||
|
window.addEventListener(`resize`, setupCallout);
|
|||
|
</script><script type="module">
|
|||
|
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
|
|||
|
const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark'
|
|||
|
mermaid.initialize({
|
|||
|
startOnLoad: false,
|
|||
|
securityLevel: 'loose',
|
|||
|
theme: darkMode ? 'dark' : 'default'
|
|||
|
});
|
|||
|
document.addEventListener('nav', async () => {
|
|||
|
await mermaid.run({
|
|||
|
querySelector: '.mermaid'
|
|||
|
})
|
|||
|
});
|
|||
|
</script><script src="https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js" type="application/javascript"></script><script src="../../../postscript.js" type="module"></script></html>
|