<!DOCTYPE html> <html class="no-js" lang="zh-CN"> <head> <meta charset="utf-8"> <link rel="preload" href="https://jenkins-zh.cn/files/muli-latin-200.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="https://jenkins-zh.cn/files/muli-latin-400.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="https://jenkins-zh.cn/files/muli-latin-800.woff2" as="font" type="font/woff2" crossorigin> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>在安全防火墙内通过 WebHook 触发构建 - Jenkins 中文社区</title> <meta name="HandheldFriendly" content="True"> <meta name="MobileOptimized" content="320"> <meta name="description" content="谁说局域网里就不能带 GitHub 的 WebHook 玩?"> <meta name="keywords" content="Jenkins,Jenkins中文社区,Jenkins官方公众号,持续集成,持续交付,开源社区,DevOps"> <meta name="viewport" content="width=device-width,minimum-scale=1"> <meta name="generator" content="Hugo 0.54.0" /> <META NAME="ROBOTS" CONTENT="INDEX, FOLLOW"> <link href='/dist/main.css' rel='stylesheet' type="text/css" /><style> img.avatar { width: 32px; display: inline; } </style> <meta property="og:title" content="在安全防火墙内通过 WebHook 触发构建" /> <meta property="og:description" content="谁说局域网里就不能带 GitHub 的 WebHook 玩?" /> <meta property="og:type" content="article" /> <meta property="og:url" content="https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-16-webhook-firewalls/" /> <meta itemprop="name" content="在安全防火墙内通过 WebHook 触发构建"> <meta itemprop="description" content="谁说局域网里就不能带 GitHub 的 WebHook 玩?"> <meta itemprop="wordCount" content="188"> <meta itemprop="keywords" content="jenkins,webhooks,security," /> <meta name="twitter:card" content="summary"/> <meta name="twitter:title" content="在安全防火墙内通过 WebHook 触发构建"/> <meta name="twitter:description" content="谁说局域网里就不能带 GitHub 的 WebHook 玩?"/> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-4216293-5"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-4216293-5'); var trackOutboundLink = function(id, url) { console.log("track:", id, url) gtag('event', 'click', { 'event_category': 'outbound', 'event_label': id, 'transport_type': 'beacon', 'event_callback': function(){document.location = url;} }); } </script> </head> <body class="ma0 sans-serif bg-primary-color-light"> <nav class="bg-primary-color-dark pv4 w-100" role="navigation"> <div class="center flex-ns flex-wrap items-center justify-start mw9"> <h1 class="dim f3 lh-solid ml0-ns mr0 mr4-l mv0 pl3 pl4-ns"> <a href="https://jenkins-zh.cn/" class="link white"> Jenkins 中文社区 </a> </h1> <ul class="list ma0 pa0 dn dib-l"> <li class="f5 dib mr4" role="menuitem"> <a href="/wechat/" class="dim link light-silver" > 博客 </a> </li> <li class="f5 dib mr4" role="menuitem"> <a href="/tutorial/" class="dim link light-silver" > 教程 </a> </li> <li class="f5 dib mr4" role="menuitem"> <a href="/event/" class="dim link light-silver" > 活动 </a> </li> <li class="f5 dib mr4" role="menuitem"> <a href="/partner/" class="dim link light-silver" > 合作伙伴 </a> </li> <li class="f5 dib mr4" role="menuitem"> <a href="/about/" class="dim link light-silver" > 关于我们 </a> </li> <li class="f5 dib mr4" role="menuitem"> <a href="http://jenkins.io/zh" class="dim link light-silver" target="_blank"> Jenkins 官网 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="10" height="10" viewBox="0 0 32 32" class="fill-current v-base" aria-label="External Link"> <path d="M25.152 16.576v5.696q0 2.144-1.504 3.648t-3.648 1.504h-14.848q-2.144 0-3.648-1.504t-1.504-3.648v-14.848q0-2.112 1.504-3.616t3.648-1.536h12.576q0.224 0 0.384 0.16t0.16 0.416v1.152q0 0.256-0.16 0.416t-0.384 0.16h-12.576q-1.184 0-2.016 0.832t-0.864 2.016v14.848q0 1.184 0.864 2.016t2.016 0.864h14.848q1.184 0 2.016-0.864t0.832-2.016v-5.696q0-0.256 0.16-0.416t0.416-0.16h1.152q0.256 0 0.416 0.16t0.16 0.416zM32 1.152v9.12q0 0.48-0.352 0.8t-0.8 0.352-0.8-0.352l-3.136-3.136-11.648 11.648q-0.16 0.192-0.416 0.192t-0.384-0.192l-2.048-2.048q-0.192-0.16-0.192-0.384t0.192-0.416l11.648-11.648-3.136-3.136q-0.352-0.352-0.352-0.8t0.352-0.8 0.8-0.352h9.12q0.48 0 0.8 0.352t0.352 0.8z"></path> </svg> </a> </li> </ul> <div class="db dib-ns pl3"><form id="site-search-form" action="" role="search"> <fieldset class="bn ma0 pa0"> <label class="clip" for="email-address">Search</label> <input type="search" id="search-input" class="needs-js bg-left bg-transparent bn f5 input-reset lh-solid mt3 mt0-ns pl4 pv2 w5 white" placeholder="搜索文档" type="text" name="email-address" value="" style="background-image:url('/images/icon-search.png');background-size:16px 16px;"> </fieldset> </form> </div> <div class="list ma0 pa0 dn dib-l"></div> <span class="absolute mt1 mt2-l pr3 right-0 top-0"> <a class="github-button needs-js link primary-color-dark" href="https://github.com/jenkins-zh/jenkins-zh/" data-size="large" data-show-count="false" aria-label="Star Jenkins WeChat GitHub">Star</a> </span> </div> </nav> <main role="main" class="content-with-sidebar min-vh-100 pb7 pb0-ns"> <main> <article class="w-100 ph4 pb5 pb6-ns pt1 pt5-ns"> <div class="flex-l"> <div class="order-2 w-100 w-20-l ph5-m ph0-l mb4 sticky"> <aside class="mw5 br3 mv3 nested-links"> <h3 class="f4 dib author"> Zhao Xiaojie </h3> <p class="lh-copy measure center mt0 f6 black-60 bio"> Contributor of @jenkinsci . Jenkins press contact in China. </p> <a href="https://github.com/LinuxSuRen" target="_blank" class="link dim v-mid dib"> <svg version="1.1" fill="gray" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="18" viewBox="0 0 27 32"> <path d="M9.28 21.44q0.064-0.128-0.064-0.256-0.16-0.128-0.256-0.032-0.064 0.128 0.064 0.224 0.16 0.128 0.256 0.064zM8.768 20.704q-0.096-0.128-0.224-0.096-0.096 0.096 0 0.224 0.128 0.16 0.224 0.096t0-0.224zM8.032 19.968q0.032-0.064-0.096-0.128-0.128-0.032-0.128 0.032-0.064 0.096 0.064 0.16 0.16 0.032 0.16-0.064zM8.416 20.384q0.032 0 0.032-0.064t-0.064-0.096q-0.128-0.128-0.192-0.064t0.032 0.192q0.096 0.096 0.192 0.032zM9.952 21.728q0.032-0.128-0.16-0.192-0.16-0.064-0.224 0.064t0.16 0.192q0.16 0.064 0.224-0.064zM10.688 21.792q0-0.16-0.192-0.16t-0.192 0.16 0.192 0.128 0.192-0.128zM11.392 21.664q-0.032-0.128-0.224-0.096t-0.16 0.16q0.032 0.16 0.192 0.096t0.192-0.16zM22.848 16q0-3.776-2.656-6.464t-6.464-2.688-6.464 2.688-2.688 6.464q0 2.976 1.76 5.376t4.48 3.296q0.32 0.064 0.48-0.096t0.16-0.352q0-0.928-0.032-1.696-0.096 0.032-0.256 0.064t-0.64 0.032-0.864-0.096-0.768-0.352-0.544-0.736q-0.416-1.056-1.024-1.312-0.032-0.032-0.064-0.064l-0.16-0.16t-0.096-0.16 0.064-0.128 0.352-0.064q0.096 0 0.256 0.032t0.544 0.288 0.576 0.64q0.288 0.48 0.672 0.736t0.768 0.256 0.704-0.064 0.512-0.16q0.128-0.864 0.608-1.248-0.896-0.096-1.536-0.32t-1.312-0.704-0.992-1.344-0.352-2.144q0-1.408 0.96-2.464-0.448-1.088 0.096-2.4 0.32-0.128 0.96 0.128t1.088 0.512l0.448 0.288q1.056-0.288 2.304-0.288t2.272 0.288q0.192-0.128 0.512-0.32t0.992-0.448 1.024-0.16q0.512 1.312 0.096 2.4 0.928 1.056 0.928 2.464 0 1.024-0.256 1.792t-0.64 1.248-0.928 0.8-1.12 0.448-1.216 0.224q0.608 0.544 0.608 1.696 0 0.704 0 1.6t-0.032 0.896q0 0.224 0.16 0.352t0.48 0.096q2.752-0.928 4.512-3.296t1.728-5.376zM27.424 7.424v17.152q0 2.112-1.504 3.616t-3.648 1.536h-17.12q-2.144 0-3.648-1.536t-1.504-3.616v-17.152q0-2.112 1.504-3.616t3.648-1.536h17.12q2.144 0 3.648 1.536t1.504 3.616z"></path> </svg> </a> <div> 作者:<span class="originalAuthor">michaelneale</span> <div> <a class="originalLink" href="" target="_blank">原文链接</a> </div> </div> </aside> <aside class="fixed-lTK mw5-l right-0 f6 bl-l b--moon-gray pv4 pv0-ns ph4-l nested-list-reset nested-links nested-copy-line-height"> <p class="b">此页面上的内容</p> <nav id="TableOfContents"> <ul> <li><a href="#什么是-webhook">什么是 WebHook</a></li> <li><a href="#内网环境">内网环境</a></li> <li><a href="#问题可能也是机会">问题可能也是机会</a></li> <li><a href="#一个-webhook-转发服务">一个 WebHook 转发服务</a></li> <li><a href="#设置">设置</a></li> </ul> </nav> <div date-pref> <a href=".." class="dib f6 pl1 hover-bg-light-gray br-100"> <svg class="fill-current" height="30px" viewBox="0 0 24 24" width="30px" xmlns="http://www.w3.org/2000/svg"> <path transform="rotate(90 11.704999923706055,12.000000000000002) " d="m15.41,7.41l-1.41,-1.41l-6,6l6,6l1.41,-1.41l-4.58,-4.59l4.58,-4.59z" id="svg_1"/> <path d="M0 0h24v24H0z" fill="none"/> </svg> </a> <a href="https://jenkins-zh.cn/wechat/articles/2018/11/2018-11-21-validate-jenkinsfile/" class="dib f6 pl1 hover-bg-light-gray br-100" title="在 VS Code 中校验 Jenkinsfile "> <svg class="fill-current" height="30px" viewBox="0 0 24 24" width="30px" xmlns="http://www.w3.org/2000/svg"> <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/> <path d="M0 0h24v24H0z" fill="none"/> </svg> </a> <a href="https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-24-becoming-contributor-newbie-tickets/" class="dib f6 pr1 hover-bg-light-gray br-100" title="成为一名 Jenkins 贡献者:对新手友好的工单"> <svg class="fill-current" height="30px" viewBox="0 0 24 24" width="30px" xmlns="http://www.w3.org/2000/svg"> <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/> <path d="M0 0h24v24H0z" fill="none"/> </svg> </a> </div> </aside> </div> <div class="order-1 w-80-l mw8 ph0 ph5-ns mid-gray nested-copy-line-height no-underline nested-links nested-img nested-copy-seperator nested-blockquote mt0-ns" style="flex-grow:1;"> <button id="copyMe" onclick="copyMe()" style="display: none">Copy Me</button> <div class="documentation-copy center mw8"> <div id="readout" class="fixed right-0 bottom-0"> </div> <header class="flex-none w-100"> <h1 class="lh-title mb3 mv0 pt3 primary-color-dark">在安全防火墙内通过 WebHook 触发构建</h1> </header> <aside class="bt bw1 pt3 mt2 mid-gray b--mid-gray fn w-100"> <div class="f4 fw4 lh-copy"> 谁说局域网里就不能带 GitHub 的 WebHook 玩? </div> </aside> <div class="prose" id="prose"> <p>在这篇文章中,我将向大家展示,如何让运行在防火墙内的 Jenkins 依然可以实时地收到 GitHub 的 WebHook。当然,你也可以把这个方法应用到如 BitBucket、 DockerHub 或任何可以推送 WebHook 的其他服务中。但是,下面的步骤仅适用于托管在 GitHub 上的项目。</p> <h1 id="什么是-webhook">什么是 WebHook</h1> <p>简单地描述下什么是 WebHook:事件消息(通常是 JSON,也可以是其他的)由服务端以 HTTP(S) 协议发送到监听的客户端。</p> <img src="/images/2019-01-07-webhook-firewalls/webhooks.png" height="" style="width: auto;"/> <p>事件流自左到右,Jenkins 会监听类似 <code>/github-webhook/</code> 或 <code>/dockerhub-webhook/</code> 等路径上的 HTTP 请求,唤醒并执行一些任务。</p> <p>GitHub 或 BitBucket 可能会报告一个新的提交或 PR,DockerHub 报告一个上游的镜像发生了变更。这些事情的共同之处在于,它们会推送给 Jenkins,并期待可以推送成功(例如:可以访问到 Jenkins)。在网络是开放的情况下时,例如 GitHub 企业版 或 Jenkins 在监听公网时,这是可以正常工作的。</p> <h1 id="内网环境">内网环境</h1> <p>当有东西挡在中间时,也就是防火墙:</p> <img src="/images/2019-01-07-webhook-firewalls/firewalls.png" height="" style="width: auto;"/> <p>(_按照行业标准,所有防火墙都必须能起到屏障的作用。因此,无论如何,请不要在你的组织内搞破坏_)</p> <p>当你在笔记本电脑上运行 Jenkins 并希望从 GitHub 接收 WebHook 时,这也是一样的。可能是为了测试你的设置,也可能是为了在 Mac 上运行 iOS 版本构建,又或者是部分网络没有暴露在互联网中,这都是合理的。 除非你的笔记本电脑可以让整个互联网访问到(这当然不太可能),或者你的网络配置得恰到好处,否则网络连接将无法流动,此时 WebHook是不可用的。</p> <p>没关系,我们可以退而求其次,使用轮询变更的方式。只是这样很糟糕。你会用尽 API 配额,还无法实时地获取变更,这真的不是一个好方法。</p> <h1 id="问题可能也是机会">问题可能也是机会</h1> <p>我们可以解决这个问题,但也可以把这个视为一个机会。有的东西在互联网中不可访问,或者以某些默认的方法锁定是一个特色,不是一个 Bug。你可以很大程度上减少你的攻击面,同时可以进行深度防护:</p> <img src="/images/2019-01-07-webhook-firewalls/exposed.png" height="" style="width: auto;"/> <h1 id="一个-webhook-转发服务">一个 WebHook 转发服务</h1> <p>输入 link:<a href="https://smee.io/[Smee">https://smee.io/[Smee</a>] 这个很容易记住的名字。这是一个由 GitHub 提供的 link:<a href="https://github.com/probot/smee[开源软件项目],还能以服务的方式托管在">https://github.com/probot/smee[开源软件项目],还能以服务的方式托管在</a> GitHub 上。这可以为你捕获并转发 WebHook。我会用一个图来给你解释它。</p> <img src="/images/2019-01-07-webhook-firewalls/forwarding.png" height="" style="width: auto;"/> <p>GitHub 把一个事件(该场景下是通过 HTTPS/json)推送给 Smee.io(也就是圆圈标记的部分,暴露在互联网上并能被 GitHub 访问到),而 Jenkins 通过一个客户端使用一个向外的连接订阅 Smee 。注意箭头的方向:Jenkins 只有一个向外的连接。</p> <p>这一点很重要,只要防火墙允许向外访问就可以工作(像 NAT 以及其他网络通常就是这样的)。如果 Jenkins 无法访问外部的任何服务,那么,本文也就当然不会有什么帮助了(但是这通常不会出现的)。</p> <h1 id="设置">设置</h1> <p>步骤1:首先,访问 <a href="https://smee.io/">https://smee.io/</a> 并点击 “Start a new channel”:</p> <img src="/images/2019-01-07-webhook-firewalls/smee.png" height="" style="width: auto;"/> <p>你会得到一个唯一的 URL(你应该拷贝出来以便后续使用):</p> <img src="/images/2019-01-07-webhook-firewalls/config1.png" height="" style="width: auto;"/> <p>然后,在你运行 Jenkins 的地方安装 smee 客户端:</p> <p><code>npm install --global smee-client</code></p> <p>(这让 smee 命令行客户端可以接收并转发 WebHook)。</p> <p>现在,启动 smee 客户端并指向你的 Jenkins。在该案例中,我的 Jenkins 运行在 8080 端口(这是默认的,如果在你的笔记本上运行的话,根据需要修改端口和 smee 地址):</p> <p><code>smee --url https://smee.io/GSm1B40sRfBvSjYS --path /github-webhook/ --port 8080</code></p> <p>这样的话,会连接 smee 服务并转发 WebHook 到 /github-webhook/(最后的斜线很重要,不要丢了)。当运行起来,你将会从日志里看到,它已经连接并转发 WebHook。只要你希望能收到 WebHook 就需要保持该命令的运行。</p> <p>下一步,你需要配置一个使用 GitHub 的流水线。这里我从头开始配置。如果你已经有了一个的话,可以跳过:</p> <img src="/images/2019-01-07-webhook-firewalls/newpipeline.png" height="" style="width: auto;"/> <p>我选择 GitHub 作为代码仓库:</p> <img src="/images/2019-01-07-webhook-firewalls/choice.png" height="" style="width: auto;"/> <p>然后,选择你的仓库。这将会设置好来准备接收来自 GitHub 的 WebHook(如果你已经有了流水线,并使用 GitHub 作为 SCM 源,那么也是可以的)。</p> <p>最后一步,是告诉 GitHub 为那个仓库(或组织也可以)发送 WebHook 事件给 Smee(最终会由 Jenkins 接收到)。</p> <p>选择你的 GitHub 仓库设置选项卡,并点击 “add webhook”:</p> <img src="/images/2019-01-07-webhook-firewalls/addwebhook.png" height="" style="width: auto;"/> <p>然后,配置 WebHook:</p> <ul> <li>粘贴从上面步骤中拷贝的 smee 的 URL</li> <li>选择 <code>application/json</code> 作为内容类型</li> <li>选择 <code>send everything</code>(你可以选择你想要的事件,但我只是处于简单这么做)。</li> <li>点击 Add Webhook(或 update)</li> </ul> <p>它看起来应该像这样:</p> <img src="/images/2019-01-07-webhook-firewalls/config2.png" height="" style="width: auto;"/> <p>好,现在 WebHook 应该可以了。你可以在你的仓库中添加一个变更,并稍后检查构建状态:</p> <img src="/images/2019-01-07-webhook-firewalls/running.png" height="" style="width: auto;"/> <p>祝你好运!</p> </div> <aside class="bt bw1 pt3 mt2 mid-gray b--mid-gray fn w-100"> </aside> <script src="https://utteranc.es/client.js" repo="jenkins-zh/jenkins-zh.github.io" issue-term="pathname" theme="github-light" crossorigin="linuxsuren" async> </script> </div> </div> </div> </article> <div class="w-100 bg-light-gray"> <div class="mw7 pa4 center nested-lh-copy lh-copy"> <h6 class="f4 dark-gray mb2"> <a href="https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-16-webhook-firewalls/" class="hide-child link primary-color"> <span class="nl3 child"><svg class="grow" fill="" height="14px" viewBox="0 0 24 24" width="14px" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg> </span> “在安全防火墙内通过 WebHook 触发构建” </a> 更新于:January 1, 0001 </h6> <a href="https://github.com/jenkins-zh/jenkins-zh/edit/master/content/wechat/articles/2019/01/2019-01-16-webhook-firewalls.md" class=" f6 ph3 pv1 br2 dib tc ttu mv3 bg-primary-color white hover-bg-green link " target="_blank">改善此页</a> <div class="nested-lh-copy"> <ul class="list dib nested-links ml0 pl0"> <li class="db mb2 b"> Tags: </li> <li class="db dib-l mr3"> <a class="tag" href="/tags/jenkins"> jenkins </a> </li> <li class="db dib-l mr3"> <a class="tag" href="/tags/webhooks"> webhooks </a> </li> <li class="db dib-l mr3"> <a class="tag" href="/tags/security"> security </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/08/2019-08-05-jenkins-multi-branch-pipeline/" class="link"> 在大型企业里维护多分支流水线 </a> </li> <li class="db b mt4 mb2 mr2"> Related entries: </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/07/2019-07-31-pipeline-config-history-plugin/" class="link"> Jenkins 流水线配置历史插件介绍 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/07/2019-07-14-jenkins-pipeline-workshop/" class="link"> 持续交付落地实践工作坊 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/07/2019-07-18-jenkins-weekly-release/" class="link"> Jenkins 每周版更新 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/07/2019-07-09-jenkins-release/" class="link"> Jenkins 长期支持版更新 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/06/2019-06-26-using-active-choices-plugin-merge-jobs/" class="link"> 使用Active-Choices-Plugin插件将十个Job合成一个 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/06/2019-06-14-setup-jenkins-ci-in-30-minutes/" class="link"> 30分钟搞定 Jenkins CI </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/06/2019-06-10-jenkins-pipeline-workshop/" class="link"> 还在苦恼不会写 Jenkins 流水线?来场工作坊! </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-29-jenkins-release/" class="link"> Jenkins 2.176~2.178版本更新 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-28-jenkins-pipeline-shared-lib-unit-test/" class="link"> 如何对 Jenkins 共享库进行单元测试 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-22-jacoco-coverage-for-functional-test/" class="link"> 基于 Jenkins + JaCoCo 实现功能测试代码覆盖率统计 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-20-jenkins-ansible-springboot/" class="link"> 使用 Jenkins + Ansible 实现 Spring Boot 自动化部署101 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-17-from-jenkins-to-jenkins-x/" class="link"> 从 Jenkins 到 Jenkins X </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-15-gsoc-annoncement/" class="link"> 19年 GSoC 中 Jenkins 的七个项目 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-14-devops-jenkins-credential-manage/" class="link"> 基于 Jenkins 的 DevOps 平台应该如何设计凭证管理 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-13-jenkins-book-gift/" class="link"> Jenkins 公众号送书福利 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-09-jenkins-release/" class="link"> Jenkins 版本发布 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-08-jenkins-plugin-develop-within-two-days-part02/" class="link"> Jenkins 插件开发之旅:两天内从 idea 到发布(下篇) </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-07-jenkins-install-plugins-shell/" class="link"> Jenkins 自动化安装插件 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/05/2019-05-06-jenkins-plugin-develop-within-two-days-part01/" class="link"> Jenkins 插件开发之旅:两天内从 idea 到发布(上篇) </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-29-progressive-delivery-with-jenkins-x-automatic-cana/" class="link"> 使用 Jenkins X 渐进式交付:自动化金丝雀部署 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-26-progressive-delivery-with-jenkins-x/" class="link"> 使用 Jenkins X 渐进式交付 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-25-jenkins-ansible-nginx/" class="link"> 使用 Jenkins + Ansible 实现自动化部署 Nginx </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-23-jenkins-master-shared-home/" class="link"> 关于 Jenkins master 共享 JENKINS_HOME 目录的实验 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-19-the-business-value-of-cd/" class="link"> 持续交付的商业价值 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-15-zabbix-monitor-jenkins/" class="link"> 使用 Zabbix 监控 Jenkins </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-12-brief-analysis-the-encryption-algorithm-of-the-built-in-jenkins-user-database/" class="link"> 简析 Jenkins 专有用户数据库加密算法 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-10-getting-started-with-docker-for-java-applications/" class="link"> Java 应用使用 Docker 的入门指南:建立一个 CI/CD 流水线 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/04/2019-04-08-becoming-contributor-intro/" class="link"> 介绍:成为一名 Jenkins 贡献者的旅程 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/03/2019-03-13-electron-pipeline-demo/" class="link"> Electron 应用的流水线设计 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/03/2019-03-13-ready-for-cdf/" class="link"> 为 Continuous Delivery Foundation 的成立感到兴奋 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/03/2019-01-08-mpl-modular-pipeline-library/" class="link"> MPL - 模块化的流水线库 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/02/2019-02-27-jenkins-script-console-in-practice/" class="link"> 批量修改 Jenkins 任务的技巧 </a> </li> <li class="db dib-l mb2 mr3"> <a href="/wechat/articles/2019/06/2019-06-24-becoming-contributor-newbie-tickets/" class="link"> 成为一名 Jenkins 贡献者:对新手友好的工单 </a> </li> </ul> </div> </div> </div> </main> <script type="text/javascript"> if(window.location.search == "?copy=true") { showCopyBut(); } function copyMe(){ var tempElements = []; var logoZone = document.createElement("div"); logoZone.innerHTML = "<a href=\"https://jenkins-zh.cn\"><img width=\"520\" src=\"https://jenkins-zh.cn/wechat/images/grey-backgroud-jenkins-slogan.jpg\"/></a>"; document.getElementById('prose').append(logoZone); tempElements.push(logoZone); var doc = document.getElementsByClassName('documentation-copy')[0]; var articleHeader = document.createElement("div"); tempElements.push(articleHeader); articleHeader.innerHTML = "本文首发于:<a href=\"https:\/\/jenkins-zh.cn\/wechat\/articles\/2019\/01\/2019-01-16-webhook-firewalls\/\">Jenkins 中文社区</a>"; var rangeToSelect = document.createRange(); rangeToSelect.selectNodeContents(doc); var data = window.getSelection(); data.addRange(rangeToSelect); tempElements.push(appendArticleFooter(data.getRangeAt(0))); data.getRangeAt(0).insertNode(articleHeader); document.execCommand("copy", true, null); for(var i in tempElements) { tempElements[i].remove(); } clearSelection(); hideCopyBut(); } function clearSelection(){ window.getSelection().empty(); } function showCopyBut() { document.getElementById('copyMe').style=""; } function hideCopyBut() { document.getElementById('copyMe').style="display:none"; } function appendArticleFooter(range) { var articleFooter = createArticleFooter(); range.insertNode(articleFooter); return articleFooter; } function createArticleFooter() { var articleFooter = document.createElement("div"); var authors = document.getElementsByClassName("author"); var originalAuthors = document.getElementsByClassName("originalAuthor"); var originalLinks = document.getElementsByClassName("originalLink"); var articleFooterHtml = ""; var isTranslated = false; if(originalAuthors.length > 0){ articleFooterHtml += "<div>"; if(originalLinks.length > 0){ articleFooterHtml += "<a href=" + originalLinks[0].innerText + ">原文链接</a> "; } articleFooterHtml += "作者:" + originalAuthors[0].innerText; articleFooterHtml += "</div>"; isTranslated = true; } if(authors.length > 0){ articleFooterHtml += "<div>"; if(isTranslated) { articleFooterHtml += "译者:" + authors[0].innerText; } else { articleFooterHtml += "作者:" + authors[0].innerText; } articleFooterHtml += "</div>"; } articleFooter.innerHTML = articleFooterHtml; return articleFooter; } </script> </main> <footer class="bg-primary-color-dark ph4-ns pt4 relative w-100" role="contentinfo"> <div class="center flex-ns flex-wrap justify-between mw9 w-90"> <div class="pb3 pt4 w-100 w-50-ns"> <div class="b f3 light-gray mb3 nested-links tc"> 由 <a href="https://github.com/jenkins-zh/jenkins-zh/graphs/contributors" target="_blank" class="link">Jenkins 社区贡献者</a> 维护<br/> </div> <ul class="center f6 list ma0 mv3 pa0 tc" style="display:none"><li class="dib mr3"><a href="https://github.com/jenkins-zh/jenkins-zh/issues/new" class="dim link light-gray pv2">File an Issue</a></li></ul> <ul class="center f6 list ma0 mv4 pa0 tc"> <li class="dib mr3"> <a href="https://twitter.com/jenkinsci" target="_blank" class="dim link light-gray pv2">Twitter</a> </li> <li class="dib mr3"> <a href="https://www.youtube.com/channel/UC63xz3pq26BBgwB3cnwCoqQ" target="_blank" class="dim link light-gray pv2">YouTube</a> </li> <li class="dib mr3"> <a href="https://space.bilibili.com/433584098" target="_blank" class="dim link light-gray pv2">哔哩哔哩</a> </li> </ul> </div> <div> <div style="color: #ffffff; display: inline-block; text-align: center; margin-right: 5px; margin-left: 5px;">优酷视频 <div> <a href="https://i.youku.com/jenkinszh" target="_blank"> <img src="/images/youku-qrcode.png" with="100" height="100"> </a> </div> </div> <div style="color: #ffffff; display: inline-block; text-align: center; margin-right: 5px; margin-left: 5px;">微信公众号 <div> <a href="https://mp.weixin.qq.com/s/vifdduC3kRGSIMpyL03yVA" target="_blank"> <img src="https://jenkins.io/images/jenkins-wechat.png" with="100" height="100"> </a> </div> </div> </div> </div> <div class="f7 gray mb5 mb0-ns ph3 w-100" style="display:none"> <p class="dib mr4">Jenkins® is a registered trademark of <a href="https://www.spi-inc.org/" class="link">Software in the Public Interest, Inc.</a></p> <p class="dib">Copyright 2018–2019 the original authors.</p> </div> <div class="bg-primary-color-dark bottom-0 left-0 right-0 dn-l fixed pb3 ph3 w-100"><div class="globalmenu mobilemenu pb3 dn"> <ul class="list hidden dib ph0 ma0 scrolling-touch tc"> <li class="tl dib ma0 hover-bg-black w-100"> <a href="/wechat/" class="ttu f6 link primary-color-light overflow hover-white db brand-font ma0 w-100 pv3 ph4"> 博客 </a> </li> <li class="tl dib ma0 hover-bg-black w-100"> <a href="/tutorial/" class="ttu f6 link primary-color-light overflow hover-white db brand-font ma0 w-100 pv3 ph4"> 教程 </a> </li> <li class="tl dib ma0 hover-bg-black w-100"> <a href="/event/" class="ttu f6 link primary-color-light overflow hover-white db brand-font ma0 w-100 pv3 ph4"> 活动 </a> </li> <li class="tl dib ma0 hover-bg-black w-100"> <a href="/partner/" class="ttu f6 link primary-color-light overflow hover-white db brand-font ma0 w-100 pv3 ph4"> 合作伙伴 </a> </li> <li class="tl dib ma0 hover-bg-black w-100"> <a href="/about/" class="ttu f6 link primary-color-light overflow hover-white db brand-font ma0 w-100 pv3 ph4"> 关于我们 </a> </li> <li class="tl dib ma0 hover-bg-black w-100"> <a href="http://jenkins.io/zh" class="ttu f6 link primary-color-light overflow hover-white db brand-font ma0 w-100 pv3 ph4"> Jenkins 官网 </a> </li> </ul> </div> <div class="docsmenu mobilemenu pb3 dn"> <ul class="list dib ph0 ma0 scrolling-touch tc"> </ul> </div> <div class="flex dn-l justify-between"> <button class="js-toggle flex-auto dib dn-l f6 tc db mt4-ns ph3 pv2 link mr2 white bg-primary-color-dark hover-bg-primary-color ba b--white-40 w-auto" data-target=".globalmenu">Menu</button> <button class="js-toggle flex-auto dib dn-l f6 tc db mt4-ns ph3 pv2 link white bg-primary-color-dark hover-bg-primary-color ba b--white-40 w-auto" data-target=".docsmenu">Docs Menu</button> </div> </div> </footer> <link href="/dist/auto-complete.css" rel="stylesheet"> <script type="text/javascript"> var baseurl = "https:\/\/jenkins-zh.cn\/"; </script> <script src="/dist/lunr.js"></script> <script src="/dist/autocomplete.js"></script> <script src="/dist/jquery-3.2.1.min.js"></script> <script src="/dist/search.js"></script> <script async defer src="https://buttons.github.io/buttons.js"></script> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?6db234f713318730f0e5f6a95bdd8d47"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> <script> (function(){ var src = (document.location.protocol == "http:") ? "http://js.passport.qihucdn.com/11.0.1.js?6276dcef5c15f276644151772390c1f9":"https://jspassport.ssl.qhimg.com/11.0.1.js?6276dcef5c15f276644151772390c1f9"; document.write('<script src="' + src + '" id="sozz"><\/script>'); })(); </script> </body> </html>