-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathrss.xml
More file actions
2 lines (2 loc) · 126 KB
/
rss.xml
File metadata and controls
2 lines (2 loc) · 126 KB
1
2
<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:a="http://www.w3.org/2005/Atom" xmlns:c="http://purl.org/rss/1.0/modules/content/"><channel><title>CC的部落格</title><link>https://blog.ccknbc.cc/</link><description>CC康纳百川</description><language>zh-CN</language><copyright>All rights reserved 2026, CC康纳百川</copyright><lastBuildDate>Wed, 06 May 2026 18:02:26 GMT</lastBuildDate><generator>Hexo</generator><image><url>https://cdn.jsdmirror.com/gh/ccknbc-backup/cdn/logo/CC.png</url><title>CC的部落格</title><link>https://blog.ccknbc.cc/</link></image><a:link href="https://blog.ccknbc.cc/rss.xml" rel="self" type="application/rss+xml"/><item><title>Hexo浏览器定向推送文章更新</title><link>https://blog.ccknbc.cc/posts/hexo-webpushr-notification/</link><description><![CDATA[<font style="color:rgb(38, 38, 38);">这一次,CC的部落格可以根据读者订阅主题定向推送了,并且实现了NPM插件化</font>]]></description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%8D%9A%E5%AE%A2/">博客</category><category domain="https://blog.ccknbc.cc/tags/%E5%8D%9A%E5%AE%A2/">博客</category><category domain="https://blog.ccknbc.cc/tags/%E5%B7%A5%E5%85%B7/">工具</category><pubDate>Sun, 10 May 2026 00:54:10 GMT</pubDate><c:encoded><![CDATA[<p>查看本文<a href="https://www.yuque.com/ccknbc/blog/37/"><strong>语雀</strong></a>版本【首发】,自动同步更新至<a href="https://blog.ccknbc.cc/posts/hexo-webpushr-notification/"><strong>CC的部落格</strong></a>!</p><p>两年前,我刚开始使用<code>Hexo</code>的时候,写了一篇文章<a href="https://blog.ccknbc.cc/posts/implementation-of-simple-browser-update-push/">简单浏览器更新推送的实现</a>,最近登录<a href="https://www.webpushr.com/">webpushr</a>控制台,发现其支持按话题<code>topic</code>指定推送了,而原来的插件一直没有更新,且对个人的写作习惯不是很友好,所以对原插件进行了修改,并发布到了<code>NPM</code></p><p>欢迎大家前往<a href="/sub">订阅页面</a>选择合适的订阅方式,关于邮件订阅,现已支持分类订阅</p><h2 id="安装">安装<a class="fa-solid fa-hashtag" href="#安装"></a></h2><p>推荐使用 <code>npm</code> 以插件形式安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i hexo-webpushr-notification</span><br></pre></td></tr></table></figure><h3 id="自定义修改">自定义修改<a class="fa-solid fa-hashtag" href="#自定义修改"></a></h3><p>当然你也可以自定义修改<a href="https://github.com/Rock-Candy-Tea/hexo-webpushr-notification/blob/main/webpushr.js">webpushr.js</a>文件后,再安装相关需要依赖,然后将文件放到<code>Hexo/scripts/</code>目录下即可正常运行,CC本人亦是如此</p><p>对于 0.2.0 以上版本,您只需要在 Hexo 所在目录安装 axios 即可,这样测试相较于安装 GitHub 更方便(以及欢迎 PR )</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i axios</span><br></pre></td></tr></table></figure><h2 id="使用">使用<a class="fa-solid fa-hashtag" href="#使用"></a></h2><p>在你的 Hexo 根目录配置文件 <code>_config.yml</code>中添加如下内容,可按需配置,建议前往 <a href="https://github.com/Rock-Candy-Tea/hexo-webpushr-notification#readme">README</a> 查看最新配置</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">webpushr:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">webpushrKey:</span> <span class="string">"webpushrKey"</span></span><br><span class="line"> <span class="attr">webpushrAuthToken:</span> <span class="string">"webpushrAuthToken"</span></span><br><span class="line"> <span class="comment"># 出于安全考虑,建议将上述两个重要参数添加至系统全局环境变量,并删除或注释掉此处配置</span></span><br><span class="line"> <span class="comment"># 否则可在网页端向访问者或订阅用户发送推送 https://www.webpushr.com/api-playground</span></span><br><span class="line"> <span class="comment"># 例如GitHub Actions环境变量配置,参数名不变,密钥名自定义,可参考如下</span></span><br><span class="line"> <span class="comment"># env:</span></span><br><span class="line"> <span class="comment"># webpushrKey: ${{ secrets.WEBPUSHR_KEY }}</span></span><br><span class="line"> <span class="comment"># webpushrAuthToken: ${{ secrets.WEBPUSHR_AUTH_TOKEN }}</span></span><br><span class="line"> <span class="comment"># 如果您的仓库私有,则无需担心此问题</span></span><br><span class="line"></span><br><span class="line"> <span class="attr">trackingCode:</span> <span class="string">"trackingCode"</span></span><br><span class="line"> <span class="attr">icon:</span> <span class="string">"https://.../192.png"</span> <span class="comment"># 必须为 HTTPS 以及 192*192 png图片</span></span><br><span class="line"> <span class="comment"># auto_hide: false # 默认为 1,代表true,即自动隐藏</span></span><br><span class="line"> <span class="comment"># sort: "date" # 默认为updated,即只要最新文章更改了更新时间即推送新文章,改为date即文章第一次发布时间</span></span><br><span class="line"> <span class="comment"># delay: "0" # 延时推送,考虑到CDN缓存更新,默认定时为在 hexo d 10分钟后推送,单位为分钟(最短延时为5分钟,设置 0 则会立即推送)</span></span><br><span class="line"> <span class="comment"># expire: "15d" # 推送过期时长,默认值为7天,格式如下:'5m'代表5分钟,'5h'代表5小时, '5d'代表5天.</span></span><br><span class="line"> <span class="comment"># image: # 默认为文章封面,Front-matter 属性为'cover'(butterfly主题友好选项),如果您没有定义默认封面或此属性,请在这里设置默认image</span></span><br><span class="line"> <span class="attr">action_buttons:</span> <span class="comment"># 如果你需要额外自定义按钮 可按照如下格式:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">title:</span> <span class="string">阅读全文</span> <span class="comment"># 当 title 未配置时 默认值为 “前往查看”</span></span><br><span class="line"> <span class="comment"># url: # 当 url 未配置时 默认值为 最新文章链接</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">title:</span> <span class="string">订阅页面</span></span><br><span class="line"> <span class="attr">url:</span> <span class="string">https://blog.ccknbc.cc/sub/</span></span><br><span class="line"> <span class="comment"># 当 action_buttons 未定义时也默认保留了一个“前往查看”按钮,除非设置为 false</span></span><br><span class="line"> <span class="comment"># action_buttons: false # 当设为 false 则不显示额外的按钮,因为隐藏按钮即为当前文章链接</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 以下配置为按订阅主题推送给不同订阅用户,请按照数组形式,一一对应,具体位置请看使用文档</span></span><br><span class="line"> <span class="attr">categories:</span> [<span class="string">工作</span>, <span class="string">博客</span>, <span class="string">工具</span>, <span class="string">生活</span>, <span class="string">音乐</span>, <span class="string">学习</span>]</span><br><span class="line"> <span class="attr">segment:</span> [<span class="string">"484223"</span>, <span class="string">"484224"</span>, <span class="string">"484225"</span>, <span class="string">"484226"</span>, <span class="string">"484227"</span>, <span class="string">"484229"</span>]</span><br><span class="line"> <span class="attr">endpoint:</span> <span class="string">segment</span> <span class="comment"># 可选配置 all / segment / sid</span></span><br><span class="line"> <span class="comment"># 默认为 segment,即根据不同主题推送细分,同时配置上述选项</span></span><br><span class="line"> <span class="comment"># 例如 all,即推送至所有用户;针对本地测试,建议只推送给单个用户即自己,同时设置下方的 sid 值</span></span><br><span class="line"> <span class="comment"># 您也可以将segment 设置为 all-users 对应的ID,同样也可以实现推送至所有用户</span></span><br><span class="line"> <span class="attr">sid:</span> <span class="string">"119810055"</span> <span class="comment"># 单个用户ID 可在控制台查看 https://app.webpushr.com/subscribers</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># 此外,在文章 Front-Matter 处</span></span><br><span class="line"> <span class="comment"># 可覆盖 auto_hide 和 expire 配置,针对需要特别提醒文章可以设置不自动隐藏及过期时间延长等操作</span></span><br><span class="line"> <span class="comment"># 以及可指定schedule参数(例如:schedule: 2022-10-01 00:00:00),定时推送</span></span><br><span class="line"> <span class="comment"># 当文章头设置 webpushr: false 时,可关闭本篇文章推送,此参数主要防止久远文章更改更新时间后自动推送</span></span><br></pre></td></tr></table></figure><ol><li>前往 webpushr 控制台获取如下参数,注册的时候可能会遇到一点困难,中国大陆用户需要科学上网来加载验证服务)</li><li>关于注册及一些具体内容,可以看之前的文章 <a href="https://blog.ccknbc.cc/posts/implementation-of-simple-browser-update-push/">简单浏览器更新推送的实现</a></li><li>依次点击 <code>Integration</code> > <code>REST API Keys</code>,即可看到你的<code>webpushrKey</code> 及 <code>webpushrAuthToken</code></li><li>依次点击 <code>Setup</code> > <code>TrackingCode</code>,可以看到如下代码</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><!-- start webpushr tracking code --></span><br><span class="line"> <span class="language-xml"><span class="tag"><<span class="name">script</span>></span><span class="language-javascript">(<span class="keyword">function</span>(<span class="params">w,d, s, id</span>) {<span class="keyword">if</span>(<span class="title function_">typeof</span>(w.<span class="property">webpushr</span>)!==<span class="string">'undefined'</span>) <span class="keyword">return</span>;w.<span class="property">webpushr</span>=w.<span class="property">webpushr</span>||<span class="keyword">function</span>(<span class="params"></span>){(w.<span class="property">webpushr</span>.<span class="property">q</span>=w.<span class="property">webpushr</span>.<span class="property">q</span>||[]).<span class="title function_">push</span>(<span class="variable language_">arguments</span>)};<span class="keyword">var</span> js, fjs = d.<span class="title function_">getElementsByTagName</span>(s)[<span class="number">0</span>];js = d.<span class="title function_">createElement</span>(s); js.<span class="property">id</span> = id;js.<span class="property">async</span>=<span class="number">1</span>;js.<span class="property">src</span> = <span class="string">"https://cdn.webpushr.com/app.min.js"</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"> fjs.<span class="property">parentNode</span>.<span class="title function_">appendChild</span>(js);}(<span class="variable language_">window</span>,<span class="variable language_">document</span>, <span class="string">'script'</span>, <span class="string">'webpushr-jssdk'</span>));</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="title function_">webpushr</span>(<span class="string">'setup'</span>,{<span class="string">'key'</span>:<span class="string">'BKOlpbdgvBCWXqXI6PtsUzobY7TLV9gwJU8bzMktrwfrSERg_xnLvbjpdw8x2GmFmi1ZcLTz0ni6OnX5MAwoM58'</span> });</span><span class="tag"></<span class="name">script</span>></span></span></span><br><span class="line"> <!-- end webpushr tracking code --></span><br></pre></td></tr></table></figure><p>最后一行<code>BKOlpbdgvBCWXqXI6PtsUzobY7TLV9gwJU8bzMktrwfrSERg_xnLvbjpdw8x2GmFmi1ZcLTz0ni6OnX5MAwoM58</code> 就是你的 <code>trackingCode</code></p><p><strong>注意</strong>:因权限问题,本地测试时(<code>hexo s</code>)可能不会显示弹窗,但如果你配置了小铃铛,小铃铛会显示</p><h2 id="额外配置">额外配置<a class="fa-solid fa-hashtag" href="#额外配置"></a></h2><p>因官方sw脚本注册后,我们无法注册自己的sw脚本,但官方提供了配置,方便我们使用sw的缓存,拦截请求等功能</p><p>首先在配置项中添加 <code>sw_self: true </code>配置,开启自行注册sw(默认用户不用添加或者设为 <code>false</code>)</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">webpushr:</span></span><br><span class="line"> <span class="attr">sw_self:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>另外,你还需要在你的脚本文件(例如<code>sw.js</code>)中引入</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title function_">importScripts</span>(<span class="string">'https://cdn.webpushr.com/sw-server.min.js'</span>);</span><br></pre></td></tr></table></figure><p>完成这些你就可以自行注册你的<code>sw</code>脚本了,如果你需要了解如何编写或注册<code>service worker</code>脚本,可以参考以下文章或项目</p><p><a href="https://kmar.top/posts/73014407/">hexo-swpp</a></p><p><a href="https://blog.cyfan.top/p/c0af86bb.html">Service Worker</a></p><p><a href="https://clientworker.js.org/">clientworker</a></p><p><a href="https://github.com/GoogleChrome/workbox">Workbox</a></p><h2 id="自定义">自定义<a class="fa-solid fa-hashtag" href="#自定义"></a></h2><p>个人建议将控制台右上角小铃铛🔔里全部配置一遍以获得更好的效果</p><p>你需要自定义一些参数才可以使用根据不同主题,按照订阅者订阅话题推送功能(目前根据个人需求是这个设置,默认行为为当未匹配到对应分类时不推送文章,而不是向所有用户推送文章,当然你也可以配置目标为所有用户)</p><p>在控制台,点击<code>Setup</code>><code>Opt-In Prompt</code> ,向下滑动打开<code>Enable Topics</code>(小铃铛样式无此选项,因此推荐您使用前两种样式),并新增几个主题,对应你想推送的文章分类即可</p><p>然后点击<code>Users</code>><code>Segments</code> ,即可获取对应的<code>segment</code>关系,依次填入配置项即可</p><h2 id="工作原理">工作原理<a class="fa-solid fa-hashtag" href="#工作原理"></a></h2><p>当你运行<code>hexo generate</code>插件会在<code>public</code> 目录生成 <code>newPost.json</code> 这样一个文件. <code>newPost.json</code> 包含了一些你想推送的新文章相关信息,示例格式如下</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"> <span class="attr">"title"</span><span class="punctuation">:</span> <span class="string">"Hexo浏览器定向推送文章更新"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"updated"</span><span class="punctuation">:</span> <span class="string">"2023-04-22T20:25:00+08:00"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"message"</span><span class="punctuation">:</span> <span class="string">"这一次,CC的部落格可以根据读者订阅主题定向推送了,并且实现了NPM插件化"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"target_url"</span><span class="punctuation">:</span> <span class="string">"https://blog.ccknbc.cc/posts/hexo-webpushr-notification/"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"image"</span><span class="punctuation">:</span> <span class="string">"https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/d2a947d48815ed24936a919873b97841_w1366_h768_s31.png"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"categories"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"> <span class="string">"博客"</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"schedule"</span><span class="punctuation">:</span> <span class="string">"2023-06-13T15:16:41.187Z"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"expire"</span><span class="punctuation">:</span> <span class="string">"7d"</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">"auto_hide"</span><span class="punctuation">:</span> <span class="string">"1"</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>而他的来源就是我们在文章开头<code>Front-Matter</code>自定义的那些属性,而本插件针对<code>Butterfly</code>主题做了针对性修改,您也可以在您的模板文件目录下修改文章模板文件(<code>Hexo/scaffolds/post.md</code>),主要针对性参数如下</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">date:</span> </span><br><span class="line"><span class="attr">updated:</span> </span><br><span class="line"><span class="attr">schedule:</span> <span class="string">对应配置项中定时推送时间</span></span><br><span class="line"><span class="attr">auto_hide:</span> <span class="string">对应配置项中是否自动隐藏</span></span><br><span class="line"><span class="attr">expire:</span> <span class="string">对应配置项中过期时间</span></span><br><span class="line"><span class="attr">categories:</span> <span class="string">文章分类</span></span><br><span class="line"><span class="attr">description:</span> <span class="string">对应配置项中message,即文章描述</span></span><br><span class="line"><span class="attr">cover:</span> <span class="string">对应配置项中image,默认选取文章封面</span></span><br></pre></td></tr></table></figure><p>如果你的主题不是采用默认的<code>date</code> <code>updated</code> 参数,记得补充,因为这是判断最新文章的依据</p><p>如果你习惯了使用截断的方式,也无需配置<code>description</code>继续使用,示例如下,注意<code><!-- more --></code></p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">title: Hexo使用Web Push Notification 浏览器通知推送</span><br><span class="line">tags:</span><br><span class="line"><span class="bullet"> -</span> hexo</span><br><span class="line"><span class="bullet"> -</span> 服务器推送技术</span><br><span class="line"><span class="bullet"> -</span> push notifications</span><br><span class="line">categories:</span><br><span class="line"><span class="bullet"> -</span> 开发</span><br><span class="line">comments: true</span><br><span class="line">abbrlink: 98ae9e55</span><br><span class="line"><span class="section">date: 2020-02-26 10:00:00</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line">Web Push Notification 是怎么工作的?个人博客为什么要使用它?如何使用它?</span><br><span class="line"></span><br><span class="line"><!-- more --></span><br></pre></td></tr></table></figure><p>当执行 <code>hexo deploy</code>命令时,插件会比较在线版本和本地版本<code>newPost.json</code>中最新文章更新时间是否一致,如果不同,则插件将推送最新文章更新通知(默认为十分钟后推送)</p><p><strong>注意</strong>:如果您是第一次使用本地测试应该看到</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">INFO 无文章更新 或 为首次推送更新</span><br></pre></td></tr></table></figure><p>这是正常现象,因为此时你的网站还没有<code>newPost.json</code>这个文件,后续有更新时将正常推送,你可以先推送一次,再修改更新时间测试一次,当然建议测试目标选择自己,即sid选项配置</p><p>当然如果您在使用过程中有什么问题或遇到了Bug也欢迎随时在评论区或<a href="https://github.com/Rock-Candy-Tea/hexo-webpushr-notification/issues">issues</a>反馈,当然因为本人是菜鸡,所以有大佬PR最好了</p><h2 id="推送效果">推送效果<a class="fa-solid fa-hashtag" href="#推送效果"></a></h2><p>因为我是通知自动隐藏后才截图,所以大致效果如下所示</p><p><img src="https://cdn.nlark.com/yuque/0/2022/png/8391407/1664951686275-f37cb76d-34f6-40ed-94c6-9bed130d0605.png" alt="" loading="lazy"></p><h2 id="后续计划">后续计划<a class="fa-solid fa-hashtag" href="#后续计划"></a></h2><ul class="contains-task-list"><li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"> 兼容自定义<code>Service Work</code>的功能,因为<code>webpushr-sw.js</code>优先注册的原因,只能有一个 <code>sw</code>注册,无法注册自己编写脚本。</li><li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"> 支持参数更多的可自定义,启用或关闭。例如不延时,立即发送;不显示按钮(因为默认就是跳转到文章)等</li><li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"> 目前的判断逻辑,虽然可以根据更新时间来判断,但如果很久之前的文章翻新,只要更新时间最新,也会触发推送,主要针对 updated 方式,还没想到好的解决办法,目前就是确认需要推送才更改更新时间咯</li><li class="task-list-item"><input class="task-list-item-checkbox" disabled="" type="checkbox"> 优化代码,减少代码量</li></ul>]]></c:encoded></item><item><title>基于小波变换的图像去噪技术研究</title><link>https://blog.ccknbc.cc/posts/research-on-image-denoising-technology-based-on-wavelet-transform/</link><description>基于小波变换的图像去噪技术研究</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%AD%A6%E4%B9%A0/">学习</category><category domain="https://blog.ccknbc.cc/tags/%E5%AD%A6%E4%B9%A0/">学习</category><pubDate>Sun, 10 May 2026 00:54:10 GMT</pubDate><c:encoded><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/18"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/research-on-image-denoising-technology-based-on-wavelet-transform"><strong>CC的部落格</strong></a></p><p><font style="color:#333333;"><div class="note warning simple"><p>这篇文章占个坑,目前不会公开,因为成为了毕业论文</p></div></font></p>]]></c:encoded></item><item><title>GitHub 自动合并 PR 笔记</title><link>https://blog.ccknbc.cc/posts/github-automatically-merges-pull-requests-notes/</link><description>GitHub 自动合并 PR 笔记</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%B7%A5%E5%85%B7/">工具</category><category domain="https://blog.ccknbc.cc/tags/%E5%B7%A5%E5%85%B7/">工具</category><pubDate>Sun, 10 May 2026 00:54:10 GMT</pubDate><c:encoded><</code> (create a merge commit),<br><code>[rebase](https://help.github.com/en/articles/about-pull-request-merges#rebase-and-merge-your-pull-request-commits)</code><br>(rebase all commits of the branch onto the base branch)<br>or <code>[squash](https://help.github.com/en/articles/about-pull-request-merges#squash-and-merge-your-pull-request-commits)</code><br>(squash all commits into a single commit). The default option is <code>merge</code>.</li><li><code>MERGE_METHOD_LABELS</code>: Set to allow labels to determine the merge method<br>(see <code>MERGE_METHOD</code> for possible values).<br>For example, <code>automerge=merge,autosquash=squash</code>. If no such label is present,<br>the method set by <code>MERGE_METHOD</code> will be used. The default value is <code>""</code>.</li><li><code>MERGE_METHOD_LABEL_REQUIRED</code>: Set to <code>true</code> to require one of the<br><code>MERGE_METHOD_LABELS</code> to be set. The default value is <code>false</code>.</li><li><code>MERGE_COMMIT_MESSAGE</code>: The commit message to use when merging the pull<br>request into the base branch. Possible values are <code>automatic</code> (use GitHub’s<br>default message), <code>pull-request-title</code> (use the pull request’s title),<br><code>pull-request-description</code> (use the pull request’s description),<br><code>pull-request-title-and-description</code> or a literal<br>value with optional placeholders (for example <code>Auto merge {pullRequest.number}</code>).<br>The default value is <code>automatic</code>.</li><li><code>MERGE_COMMIT_MESSAGE_REGEX</code>: When using a commit message containing the<br>PR’s body, use the first capturing subgroup from this regex as the commit<br>message. Can be used to separate content that should go with the commit into<br>the code base’s history from boilerplate associated with the PR (licensing<br>notices, check lists, etc). For example, <code>(.*)^---</code> would keep everything up<br>until the first 3-dash line (horizontal rule in MarkDown) from the commit<br>message. The default value is empty, which disables this feature.</li><li><code>MERGE_FILTER_AUTHOR</code>: When set, only pull requests raised by this author<br>will be merged automatically.</li><li><code>MERGE_FORKS</code>: Whether merging from external repositories is enabled<br>or not. By default, pull requests with branches from forked repositories will<br>be merged the same way as pull requests with branches from the main<br>repository. Set this option to <code>false</code> to disable merging of pull requests<br>from forked repositories. The default value is <code>true</code>.</li><li><code>MERGE_RETRIES</code> and <code>MERGE_RETRY_SLEEP</code>: Sometimes, the pull request check<br>runs haven’t finished yet, so the action will retry the merge after some time.<br>The number of retries can be set with <code>MERGE_RETRIES</code>.<br>The default number of retries is <code>6</code> and setting it to <code>0</code> disables the retry logic.<br><code>MERGE_RETRY_SLEEP</code> sets the time to sleep between retries, in milliseconds.<br>The default is <code>5000</code> (5 seconds) and setting it to <code>0</code> disables sleeping<br>between retries.</li><li><code>MERGE_DELETE_BRANCH</code>: Automatic deletion of branches does not work for all<br>repositories. Set this option to <code>true</code> to automatically delete branches<br>after they have been merged. The default value is <code>false</code>.</li></ul><p>The following update options are supported:</p><ul><li><code>UPDATE_LABELS</code>: The labels that need to be present for a pull request to be<br>updated (using <code>UPDATE_METHOD</code>). The default value is <code>automerge</code>.<br>Note that updating will only happen when the option “Require branches to be<br>up to date before merging” is enabled in the branch protection rules.<br>This option can be a comma-separated list of labels, see the <code>MERGE_LABELS</code><br>option for more information.</li><li><code>UPDATE_METHOD</code>: Which method to use when updating the pull request<br>to the base branch. Possible values are <code>merge</code> (create a merge commit) or<br><code>rebase</code> (rebase the branch onto the head of the base branch). The default<br>option is <code>merge</code>.<br>When the option is <code>rebase</code> and the <a href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing">rebasing</a><br>failed, the action will exit with error code 1. This will also be visible<br>in the pull request page, with a message like “this branch has conflicts<br>that must be resolved” and a list of conflicting files.</li><li><code>UPDATE_RETRIES</code> and <code>UPDATE_RETRY_SLEEP</code>: Sometimes, the pull request check<br>runs haven’t finished yet and the action doesn’t know if an update is<br>necessary. To query the pull request state multiple times, the number of<br>retries can be set with <code>UPDATE_RETRIES</code>. The default number of retries is <code>1</code><br>and setting it to <code>0</code> disables the retry logic.<br><code>UPDATE_RETRY_SLEEP</code> sets the time to sleep between retries, in milliseconds.<br>The default is <code>5000</code> (5 seconds) and setting it to <code>0</code> disables sleeping<br>between retries.</li></ul><p>Also, the following general options are supported:</p><ul><li><code>GITHUB_TOKEN</code>: This should always be <code>"${{ secrets.GITHUB_TOKEN }}"</code>.<br>However, in some cases it can be useful to run this action as a certain user<br>(by default, it will run as <code>github-actions</code>). This can be useful if you want<br>to use the “Restrict who can push to matching branches” option in the branch<br>protection rules, for example.<br>To use this setting for manually providing a token, you need to create a<br><a href="https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line">personal access token</a><br>for the user (make sure to check <code>public_repo</code> when it’s a public repository<br>or <code>repo</code> when it’s a private repository). All API requests (merge/rebase)<br>will then be executed as the specified user. The token should be kept secret,<br>so make sure to add it as secret, not as environment variable, in the GitHub<br>workflow file!</li></ul><p>You can configure the environment variables in the workflow file like this:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">env:</span></span><br><span class="line"> <span class="attr">GITHUB_TOKEN:</span> <span class="string">"$<span class="template-variable">{{ secrets.GITHUB_TOKEN }}</span>"</span></span><br><span class="line"> <span class="attr">MERGE_LABELS:</span> <span class="string">"automerge,!work in progress"</span></span><br><span class="line"> <span class="attr">MERGE_REMOVE_LABELS:</span> <span class="string">"automerge"</span></span><br><span class="line"> <span class="attr">MERGE_METHOD:</span> <span class="string">"squash"</span></span><br><span class="line"> <span class="attr">MERGE_COMMIT_MESSAGE:</span> <span class="string">"pull-request-description"</span></span><br><span class="line"> <span class="attr">MERGE_FORKS:</span> <span class="string">"false"</span></span><br><span class="line"> <span class="attr">MERGE_RETRIES:</span> <span class="string">"6"</span></span><br><span class="line"> <span class="attr">MERGE_RETRY_SLEEP:</span> <span class="string">"10000"</span></span><br><span class="line"> <span class="attr">UPDATE_LABELS:</span> <span class="string">""</span></span><br><span class="line"> <span class="attr">UPDATE_METHOD:</span> <span class="string">"rebase"</span></span><br></pre></td></tr></table></figure><h2 id="Supported-Events">Supported Events<a class="fa-solid fa-hashtag" href="#Supported-Events"></a></h2><p>Automerge can be configured to run for these events:</p><ul><li><code>check_run</code></li><li><code>check_suite</code></li><li><code>issue_comment</code></li><li><code>pull_request_review</code></li><li><code>pull_request_target</code></li><li><code>pull_request</code></li><li><code>push</code></li><li><code>repository_dispatch</code></li><li><code>schedule</code></li><li><code>status</code></li><li><code>workflow_dispatch</code></li></ul><p>For more information on when these occur, see the Github documentation on <a href="https://docs.github.com/en/actions/reference/events-that-trigger-workflows">events that trigger workflows</a> and <a href="https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads">their payloads</a>.</p><h2 id="Limitations">Limitations<a class="fa-solid fa-hashtag" href="#Limitations"></a></h2><ul><li>When a pull request is merged by this action, the merge will not trigger other GitHub workflows.<br>Similarly, when another GitHub workflow creates a pull request, this action will not be triggered.<br>This is because <a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows">an action in a workflow run can’t trigger a new workflow run</a>. However, the <code>[workflow_run](https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#workflow_run)</code> event is triggered as expected.</li><li>When <a href="https://help.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token">using a personal access token (PAT) to work around the above limitation</a>, note that when the user issuing the PAT is an administrator and <a href="https://help.github.com/en/github/administering-a-repository/enabling-branch-restrictions">branch restrictions do not include administrators</a>, pull requests may be merged even if they are not mergeable for non-administrators (see <a href="https://github.com/pascalgn/automerge-action/issues/65">#65</a>).</li><li>Currently, there is no way to trigger workflows when the pull request branch<br>becomes out of date with the base branch. There is a request in the<br><a href="https://github.community/t5/GitHub-Actions/New-Trigger-is-mergable-state/m-p/36908">GitHub community forum</a>.</li></ul><h2 id="Debugging">Debugging<a class="fa-solid fa-hashtag" href="#Debugging"></a></h2><p>To run the action with full debug logging, update your workflow file as follows:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">- name: automerge</span><br><span class="line"> uses: pascalgn/automerge-action@...</span><br><span class="line"> with:</span><br><span class="line"> args: "--trace"</span><br></pre></td></tr></table></figure><p>If you need to further debug the action, you can run it locally.</p><p>You will need a <a href="https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line">personal access token</a>.</p><p>Then clone this repository, create a file <code>.env</code> in the repository, such as:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">GITHUB_TOKEN="123abc..."</span><br><span class="line">URL="https://github.com/pascalgn/repository-name/pull/123"</span><br></pre></td></tr></table></figure><p>Install dependencies with <code>yarn</code>, and finally run <code>yarn it</code> (or <code>npm run it</code>).</p><h2 id="License">License<a class="fa-solid fa-hashtag" href="#License"></a></h2><p><a href="LICENSE">MIT</a></p><h1>bulldozer</h1><p><img src="https://cdn.nlark.com/yuque/0/2021/svg/8391407/1610874951039-f74d3099-f28f-4856-ade7-6c677ce4869d.svg" alt="" loading="lazy"> <img src="https://img.shields.io/docker/pulls/palantirtechnologies/bulldozer.svg" alt="" loading="lazy"></p><p><code>bulldozer</code> is a <a href="https://developer.github.com/apps/">GitHub App</a> that</p><p>automatically merges pull requests (PRs) when (and only when) all required</p><p>status checks are successful and required reviews are provided.</p><p>Additionally, <code>bulldozer</code> can:</p><ul><li>Only merge pull requests that match certain conditions, like having a<br>specific label or comment</li><li>Ignore pull requests that match certain conditions, like having a specific<br>label or comment</li><li>Automatically keep pull request branches up-to-date by merging in the target<br>branch</li><li>Wait for additional status checks that are not required by GitHub</li></ul><p>Bulldozer might be useful if you:</p><ul><li>Have CI builds that take longer than the normal review process. It will merge<br>reviewed PRs as soon as the tests pass so you don’t have to watch the pull<br>request or remember to merge it later.</li><li>Combine it with <a href="https://github.com/palantir/policy-bot">policy-bot</a> to<br>automatically merge certain types of pre-approved or automated changes.</li><li>Want to give contributors more control over when they can merge PRs without<br>granting them write access to the repository.</li><li>Have a lot of active development that makes it difficult to merge a pull<br>request while it is up-to-date with the target branch.</li></ul><h2 id="Contents">Contents<a class="fa-solid fa-hashtag" href="#Contents"></a></h2><ul><li><a href="#behavior">Behavior</a></li><li><a href="#configuration">Configuration</a><ul><li><a href="#bulldozeryml-specification">bulldozer.yml Specification</a></li></ul></li><li><a href="#faq">FAQ</a></li><li><a href="#deployment">Deployment</a></li><li><a href="#development">Development</a></li><li><a href="#contributing">Contributing</a></li><li><a href="#license">License</a></li></ul><h2 id="Behavior">Behavior<a class="fa-solid fa-hashtag" href="#Behavior"></a></h2><p><code>bulldozer</code> will only merge pull requests that GitHub allows non-admin</p><p>collaborators to merge. This means that all branch protection settings,</p><p>including required status checks and required reviews, are respected. It also</p><p>means that you <em>must</em> enable branch protection to prevent <code>bulldozer</code> from</p><p>immediately merging every pull request.</p><p>Only pull requests matching the trigger conditions (or <em>not</em> matching</p><p>ignore conditions) are considered for merging. <code>bulldozer</code> is event-driven,</p><p>which means it will usually merge a pull request within a few seconds of the</p><p>pull request satisfying all preconditions.</p><h2 id="Configuration-2">Configuration<a class="fa-solid fa-hashtag" href="#Configuration-2"></a></h2><p>The behavior of the bot is configured by a <code>.bulldozer.yml</code> file at the root of</p><p>the repository. The file name and location are configurable when running your</p><p>own instance of the server.</p><p>The <code>.bulldozer.yml</code> file is read from the most recent commit on the target</p><p>branch of each pull request. If <code>bulldozer</code> cannot find a configuration file,</p><p>it will take no action. This means it is safe to enable the <code>bulldozer</code> on all</p><p>repositories in an organization.</p><h3 id="bulldozer-yml-Specification">bulldozer.yml Specification<a class="fa-solid fa-hashtag" href="#bulldozer-yml-Specification"></a></h3><p>The <code>.bulldozer.yml</code> file supports the following keys.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># "version" is the configuration version, currently "1".</span></span><br><span class="line"><span class="attr">version:</span> <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># "merge" defines how and when pull requests are merged. If the section is</span></span><br><span class="line"><span class="comment"># missing, bulldozer will consider all pull requests and use default settings.</span></span><br><span class="line"><span class="attr">merge:</span></span><br><span class="line"> <span class="comment"># "trigger" defines the set of pull requests considered by bulldozer. If</span></span><br><span class="line"> <span class="comment"># the section is missing, bulldozer considers all pull requests not excluded</span></span><br><span class="line"> <span class="comment"># by the ignore conditions.</span></span><br><span class="line"> <span class="attr">trigger:</span></span><br><span class="line"> <span class="comment"># Pull requests with any of these labels (case-insensitive) are added to</span></span><br><span class="line"> <span class="comment"># the trigger.</span></span><br><span class="line"> <span class="attr">labels:</span> [<span class="string">"merge when ready"</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Pull requests where the body or any comment contains any of these</span></span><br><span class="line"> <span class="comment"># substrings are added to the trigger.</span></span><br><span class="line"> <span class="attr">comment_substrings:</span> [<span class="string">"==MERGE_WHEN_READY=="</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Pull requests where any comment matches one of these exact strings are</span></span><br><span class="line"> <span class="comment"># added to the trigger.</span></span><br><span class="line"> <span class="attr">comments:</span> [<span class="string">"Please merge this pull request!"</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Pull requests where the body contains any of these substrings are added</span></span><br><span class="line"> <span class="comment"># to the trigger.</span></span><br><span class="line"> <span class="attr">pr_body_substrings:</span> [<span class="string">"==MERGE_WHEN_READY=="</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Pull requests targeting any of these branches are added to the trigger.</span></span><br><span class="line"> <span class="attr">branches:</span> [<span class="string">"develop"</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Pull requests targeting branches matching any of these regular expressions are added to the trigger.</span></span><br><span class="line"> <span class="attr">branch_patterns:</span> [<span class="string">"feature/.*"</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># "ignore" defines the set of pull request ignored by bulldozer. If the</span></span><br><span class="line"> <span class="comment"># section is missing, bulldozer considers all pull requests. It takes the</span></span><br><span class="line"> <span class="comment"># same keys as the "trigger" section.</span></span><br><span class="line"> <span class="attr">ignore:</span></span><br><span class="line"> <span class="attr">labels:</span> [<span class="string">"do not merge"</span>]</span><br><span class="line"> <span class="attr">comment_substrings:</span> [<span class="string">"==DO_NOT_MERGE=="</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># "method" defines the merge method. The available options are "merge",</span></span><br><span class="line"> <span class="comment"># "rebase", "squash", and "ff-only".</span></span><br><span class="line"> <span class="attr">method:</span> <span class="string">squash</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># Allows the merge method that is used when auto-merging a PR to be different based on the</span></span><br><span class="line"> <span class="comment"># target branch. The keys of the hash are the target branch name, and the values are the merge method that</span></span><br><span class="line"> <span class="comment"># will be used for PRs targeting that branch. The valid values are the same as for the "method" key.</span></span><br><span class="line"> <span class="comment"># <span class="doctag">Note:</span> If the target branch does not match any of the specified keys, the "method" key is used instead.</span></span><br><span class="line"> <span class="attr">branch_method:</span></span><br><span class="line"> <span class="attr">develop:</span> <span class="string">squash</span></span><br><span class="line"> <span class="attr">master:</span> <span class="string">merge</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># "options" defines additional options for the individual merge methods.</span></span><br><span class="line"> <span class="attr">options:</span></span><br><span class="line"> <span class="comment"># "squash" options are only used when the merge method is "squash"</span></span><br><span class="line"> <span class="attr">squash:</span></span><br><span class="line"> <span class="comment"># "title" defines how the title of the commit message is created when</span></span><br><span class="line"> <span class="comment"># generating a squash commit. The options are "pull_request_title",</span></span><br><span class="line"> <span class="comment"># "first_commit_title", and "github_default_title". The default is</span></span><br><span class="line"> <span class="comment"># "pull_request_title".</span></span><br><span class="line"> <span class="attr">title:</span> <span class="string">"pull_request_title"</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># "body" defines how the body of the commit message is created when</span></span><br><span class="line"> <span class="comment"># generating a squash commit. The options are "pull_request_body",</span></span><br><span class="line"> <span class="comment"># "summarize_commits", and "empty_body". The default is "empty_body".</span></span><br><span class="line"> <span class="attr">body:</span> <span class="string">"empty_body"</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># If "body" is "pull_request_body", then the commit message will be the</span></span><br><span class="line"> <span class="comment"># part of the pull request body surrounded by "message_delimiter"</span></span><br><span class="line"> <span class="comment"># strings. This is disabled (empty string) by default.</span></span><br><span class="line"> <span class="attr">message_delimiter:</span> <span class="string">==COMMIT_MSG==</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># "required_statuses" is a list of additional status contexts that must pass</span></span><br><span class="line"> <span class="comment"># before bulldozer can merge a pull request. This is useful if you want to</span></span><br><span class="line"> <span class="comment"># require extra testing for automated merges, but not for manual merges.</span></span><br><span class="line"> <span class="attr">required_statuses:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"ci/circleci: ete-tests"</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># If true, bulldozer will delete branches after their pull requests merge.</span></span><br><span class="line"> <span class="attr">delete_after_merge:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># "update" defines how and when to update pull request branches. Unlike with</span></span><br><span class="line"><span class="comment"># merges, if this section is missing, bulldozer will not update any pull requests.</span></span><br><span class="line"><span class="attr">update:</span></span><br><span class="line"> <span class="comment"># "trigger" defines the set of pull requests that should be updated by</span></span><br><span class="line"> <span class="comment"># bulldozer. It accepts the same keys as the trigger in the "merge" block.</span></span><br><span class="line"> <span class="attr">trigger:</span></span><br><span class="line"> <span class="attr">labels:</span> [<span class="string">"WIP"</span>, <span class="string">"Update Me"</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># "ignore" defines the set of pull requests that should not be updated by</span></span><br><span class="line"> <span class="comment"># bulldozer. It accepts the same keys as the ignore in the "merge" block.</span></span><br><span class="line"> <span class="attr">ignore:</span></span><br><span class="line"> <span class="attr">labels:</span> [<span class="string">"Do Not Update"</span>]</span><br></pre></td></tr></table></figure><h2 id="FAQ">FAQ<a class="fa-solid fa-hashtag" href="#FAQ"></a></h2><h4 id="Can-I-specify-both-ignore-and-trigger">Can I specify both <code>ignore</code> and <code>trigger</code>?<a class="fa-solid fa-hashtag" href="#Can-I-specify-both-ignore-and-trigger"></a></h4><p>Yes. If both <code>ignore</code> and <code>trigger</code> are specified, bulldozer will attempt to match</p><p>on both. In cases where both match, <code>ignore</code> will take precedence.</p><h4 id="Can-I-specify-the-body-of-the-commit-when-using-the-squash-strategy">Can I specify the body of the commit when using the <code>squash</code> strategy?<a class="fa-solid fa-hashtag" href="#Can-I-specify-the-body-of-the-commit-when-using-the-squash-strategy"></a></h4><p>Yes. When the merge strategy is <code>squash</code>, you can set additional options under the</p><p><code>options.squash</code> property, including how to render the commit body.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">merge:</span></span><br><span class="line"> <span class="attr">method:</span> <span class="string">squash</span></span><br><span class="line"> <span class="attr">options:</span></span><br><span class="line"> <span class="attr">squash:</span></span><br><span class="line"> <span class="attr">body:</span> <span class="string">summarize_commits</span> <span class="comment"># or `pull_request_body`, `empty_body`</span></span><br></pre></td></tr></table></figure><p>You can also define part of pull request body to pick as a commit message when</p><p><code>body</code> is <code>pull_request_body</code>.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">merge:</span></span><br><span class="line"> <span class="attr">method:</span> <span class="string">squash</span></span><br><span class="line"> <span class="attr">options:</span></span><br><span class="line"> <span class="attr">squash:</span></span><br><span class="line"> <span class="attr">body:</span> <span class="string">pull_request_body</span></span><br><span class="line"> <span class="attr">message_delimiter:</span> <span class="string">==COMMIT_MSG==</span></span><br></pre></td></tr></table></figure><p>Anything that’s contained between two <code>==COMMIT_MSG==</code> strings will become the</p><p>commit message instead of whole pull request body.</p><h4 id="What-if-I-don’t-want-to-put-config-files-into-each-repo">What if I don’t want to put config files into each repo?<a class="fa-solid fa-hashtag" href="#What-if-I-don’t-want-to-put-config-files-into-each-repo"></a></h4><p>You can add default repository configuration in your bulldozer config file.</p><p>It will be used only when your repo config file does not exist.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">options:</span></span><br><span class="line"> <span class="attr">default_repository_config:</span></span><br><span class="line"> <span class="attr">ignore:</span></span><br><span class="line"> <span class="attr">labels:</span> [<span class="string">"do not merge"</span>] <span class="comment"># or any other available config.</span></span><br></pre></td></tr></table></figure><h4 id="Bulldozer-isn’t-merging-my-commit-when-it-should-what-could-be-happening">Bulldozer isn’t merging my commit when it should, what could be happening?<a class="fa-solid fa-hashtag" href="#Bulldozer-isn’t-merging-my-commit-when-it-should-what-could-be-happening"></a></h4><p>Bulldozer will attempt to merge a branch whenever it passes the trigger/ignore</p><p>criteria. GitHub may prevent it from merging a branch in certain conditions, some of</p><p>which are to be expected, and others that may be caused by mis-configuring Bulldozer.</p><ul><li>Required status checks have not passed</li><li>Review requirements are not satisfied</li><li>The merge strategy configured in <code>.bulldozer.yml</code> is not allowed by your<br>repository settings</li><li>Branch protection rules are preventing <code>bulldozer[bot]</code> from <a href="https://help.github.com/articles/about-branch-restrictions/">pushing to the<br>branch</a>. Github apps can be added to the list of restricted<br>push users, so you can allow Bulldozer specifically for your repo.</li></ul><h4 id="Bulldozer-isn’t-updating-my-branch-when-it-should-what-could-be-happening">Bulldozer isn’t updating my branch when it should, what could be happening?<a class="fa-solid fa-hashtag" href="#Bulldozer-isn’t-updating-my-branch-when-it-should-what-could-be-happening"></a></h4><p>When using the branch update functionality, Bulldozer only acts when the target</p><p>branch is updated <em>after</em> updates are enabled for the pull request. For</p><p>example:</p><ol><li>User A opens a pull request targetting <code>develop</code></li><li>User B pushes a commit to <code>develop</code></li><li>User A adds the <code>update me</code> label to the first pull request</li><li>User C pushes a commit to <code>develop</code></li><li>Bulldozer updates the pull request with the commits from Users B and C</li></ol><p>Note that the update does <em>not</em> happen when the <code>update me</code> label is added,</p><p>even though there is a new commit on <code>develop</code> that is not part of the pull</p><p>request.</p><h4 id="Can-Bulldozer-work-with-push-restrictions-on-branches">Can Bulldozer work with push restrictions on branches?<a class="fa-solid fa-hashtag" href="#Can-Bulldozer-work-with-push-restrictions-on-branches"></a></h4><p>As mentioned above, as of Github ~2.19.x, GitHub Apps <em>can</em> be added to the list of users associated</p><p>with <a href="https://help.github.com/articles/about-branch-restrictions/">push restrictions</a>. If you don’t want to do this, or if you’re running</p><p>an older version of Github that doesn’t support this behaviour, you may work</p><p>around this:</p><ol><li>Use another app like <a href="https://github.com/palantir/policy-bot">policy-bot</a> to<br>implement <em>approval</em> restrictions as required status checks instead of using<br>push restrictions. This effectively limits who can push to a branch by<br>requiring changes to go through the pull request process and be approved.</li><li>Configure Bulldozer to use a personal access token for a regular user to<br>perform merges in this case. The token must have the <code>repo</code> scope and the<br>user must be allowed to push to the branch. In the server configuration<br>file, set:</li></ol><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">options:</span></span><br><span class="line"> <span class="attr">push_restriction_user_token:</span> <span class="string"><token-value></span></span><br></pre></td></tr></table></figure><ol start="2"><li>The token is <em>only</em> used if the target branch has push restrictions enabled.<br>All other merges are performed as the normal GitHub App user.</li></ol><h2 id="Deployment">Deployment<a class="fa-solid fa-hashtag" href="#Deployment"></a></h2><p>bulldozer is easy to deploy in your own environment as it has no dependencies</p><p>other than GitHub. It is also safe to run multiple instances of the server,</p><p>making it a good fit for container schedulers like Nomad or Kubernetes.</p><p>We provide both a Docker container and a binary distribution of the server:</p><ul><li>Binaries: <a href="https://bintray.com/palantir/releases/bulldozer">https://bintray.com/palantir/releases/bulldozer</a></li><li>Docker Images: <a href="https://hub.docker.com/r/palantirtechnologies/bulldozer/">https://hub.docker.com/r/palantirtechnologies/bulldozer/</a></li></ul><p>A sample configuration file is provided at <code>config/bulldozer.example.yml</code>.</p><p>Certain values may also be set by environment variables; these are noted in the</p><p>comments in the sample configuration file.</p><h3 id="GitHub-App-Configuration">GitHub App Configuration<a class="fa-solid fa-hashtag" href="#GitHub-App-Configuration"></a></h3><p>To configure Bulldozer as a GitHub App, these general options are required:</p><ul><li><strong>Webhook URL</strong>: <code>http(s)://<your-bulldozer-domain>/api/github/hook</code></li><li><strong>Webhook secret</strong>: A random string that matches the value of the<br><code>github.app.webhook_secret</code> property in the server configuration</li></ul><p>The app requires these permissions:</p><table><thead><tr><th>Permission</th><th>Access</th><th>Reason</th></tr></thead><tbody><tr><td>Repository administration</td><td>Read-only</td><td>Determine required status checks</td></tr><tr><td>Checks</td><td>Read-only</td><td>Read checks for ref</td></tr><tr><td>Repository contents</td><td>Read & write</td><td>Read configuration, perform merges</td></tr><tr><td>Issues</td><td>Read & write</td><td>Read comments, close linked issues</td></tr><tr><td>Repository metadata</td><td>Read-only</td><td>Basic repository data</td></tr><tr><td>Pull requests</td><td>Read & write</td><td>Merge and close pull requests</td></tr><tr><td>Commit status</td><td>Read-only</td><td>Evaluate pull request status</td></tr></tbody></table><p>The app should be subscribed to these events:</p><ul><li>Check run</li><li>Commit comment</li><li>Pull request</li><li>Status</li><li>Push</li><li>Issue comment</li><li>Pull request review</li><li>Pull request review comment</li></ul><h3 id="Operations">Operations<a class="fa-solid fa-hashtag" href="#Operations"></a></h3><p>bulldozer uses <a href="https://github.com/palantir/go-baseapp">go-baseapp</a> and</p><p><a href="https://github.com/palantir/go-githubapp">go-githubapp</a>, both of which emit</p><p>standard metrics and structured log keys. Please see those projects for</p><p>details.</p><h3 id="Example-Files">Example Files<a class="fa-solid fa-hashtag" href="#Example-Files"></a></h3><p>Example <code>.bulldozer.yml</code> files can be found in <code>[config/examples](https://github.com/palantir/bulldozer/tree/develop/config/examples)</code></p><h3 id="Migrating-Version-0-4-X-to-1-X">Migrating: Version 0.4.X to 1.X<a class="fa-solid fa-hashtag" href="#Migrating-Version-0-4-X-to-1-X"></a></h3><p>The server configuration for bulldozer allows you to specify <code>configuration_v0_path</code>, which is a list of paths</p><p>to check for <code>0.4.X</code> style bulldozer configuration. When a <code>1.X</code> style configuration file does not appear</p><p>at the configured path, bulldozer will attempt to read from the paths configured by <code>configuration_v0_path</code>,</p><p>converting the legacy configuration into an equivalent <code>v1</code> configuration internally.</p><p>The upgrade process is therefore to deploy the latest version of bulldozer with both <code>configuration_path</code> and</p><p><code>configuration_v0_path</code> configured, and to enable the bulldozer GitHub App on all organizations where it was</p><p>previously installed.</p><h2 id="Development">Development<a class="fa-solid fa-hashtag" href="#Development"></a></h2><p>To develop <code>bulldozer</code>, you will need a <a href="https://golang.org/doc/install">Go installation</a>.</p><p><strong>Run style checks and tests</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./godelw verify</span><br></pre></td></tr></table></figure><p><strong>Running the server locally</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># copy and edit the server config</span><br><span class="line">cp config/bulldozer.example.yml config/bulldozer.yml</span><br><span class="line"></span><br><span class="line">./godelw run bulldozer server</span><br></pre></td></tr></table></figure><ul><li><code>config/bulldozer.yml</code> is used as the default configuration file</li><li>The server is available at <code>http://localhost:8080/</code></li></ul><p><strong>Running the server via Docker</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># copy and edit the server config</span><br><span class="line">cp config/bulldozer.example.yml config/bulldozer.yml</span><br><span class="line"></span><br><span class="line"># build the docker image</span><br><span class="line">./godelw docker build --verbose</span><br><span class="line"></span><br><span class="line">docker run --rm -v "$(pwd)/config:/secrets/" -p 8080:8080 palantirtechnologies/bulldozer:latest</span><br></pre></td></tr></table></figure><ul><li>This mounts the <code>config</code> directory (which should contain the <code>bulldozer.yml</code> configuration file) at the expected location</li><li>The server is available at <code>http://localhost:8080/</code></li></ul><h2 id="Contributing">Contributing<a class="fa-solid fa-hashtag" href="#Contributing"></a></h2><p>Contributions and issues are welcome. For new features or large contributions,</p><p>we prefer discussing the proposed change on a GitHub issue prior to a PR.</p><h2 id="License-2">License<a class="fa-solid fa-hashtag" href="#License-2"></a></h2><p>This application is made available under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>.</p><h1>probot-auto-merge</h1><p><img src="https://travis-ci.org/bobvanderlinden/probot-auto-merge.svg?branch=master" alt="" loading="lazy"></p><p><img src="https://img.shields.io/coveralls/github/bobvanderlinden/probot-auto-merge.svg" alt="" loading="lazy"></p><p>A GitHub App built with <a href="https://github.com/probot/probot">Probot</a> that automatically merges PRs</p><blockquote><p><img src="/" alt="" loading="lazy"></p></blockquote><h2 id="Usage-2">Usage<a class="fa-solid fa-hashtag" href="#Usage-2"></a></h2><ol><li><a href="https://github.com/apps/probot-auto-merge">Configure the GitHub App</a></li><li>Create <code>.github/auto-merge.yml</code> in your repository.</li><li>Customize configuration to your needs. See below.</li></ol><h2 id="Configuration-3">Configuration<a class="fa-solid fa-hashtag" href="#Configuration-3"></a></h2><p>Configuration of <code>probot-auto-merge</code> is done through <code>.github/auto-merge.yml</code> in</p><p>your repository. An example of this file can be found <a href="auto-merge.example.yml">here</a>.</p><p>You can also see the configuration for this repository <a href=".github/auto-merge.yml">here</a>.</p><p>The configuration has values that serve as conditions on whether or not a pull request</p><p>should be automatically merged and also configuration about the merge itself. Values</p><p>that serve as conditions are annotated as such below.</p><p>All conditions must be met before a PR will be automatically merged. You can get more</p><p>flexibility by defining multiple rules. Rules can have multiple conditions and if any</p><p>of the conditions inside a rule are met, the PR is also merged. See <a href="#rules-default-none">rules</a>.</p><p>If the target branch is a protected branch, you must add <code>probot-auto-merge</code> bot to</p><p>the list of <code>People, teams or apps with push access</code> in your branch protection rules.</p><p>Note that the default configuration options are to do nothing. This is to prevent</p><p>implicit and possibly unintended behavior.</p><p>The configuration fields are as follows:</p><h3 id="minApprovals-required-condition"><code>minApprovals</code> (required, condition)<a class="fa-solid fa-hashtag" href="#minApprovals-required-condition"></a></h3><p>The minimum number of reviews from each association that approve the pull request before</p><p>doing an automatic merge. For more information about associations see:</p><p><a href="https://developer.github.com/v4/enum/commentauthorassociation/">https://developer.github.com/v4/enum/commentauthorassociation/</a></p><p>Possible associations: <code>OWNER</code>, <code>MEMBER</code>, <code>COLLABORATOR</code>, <code>CONTRIBUTOR</code>, <code>FIRST_TIMER</code>, <code>FIRST_TIME_CONTRIBUTOR</code>, <code>NONE</code></p><p>In the example below when a pull request gets 2 approvals from owners, members or collaborators,</p><p>the automatic merge will continue.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">minApprovals:</span></span><br><span class="line"> <span class="attr">COLLABORATOR:</span> <span class="number">2</span></span><br></pre></td></tr></table></figure><p>In the example below when a pull request gets 1 approval from an owner OR 2 approvals from members, the automatic merge will continue.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">minApprovals:</span></span><br><span class="line"> <span class="attr">OWNER:</span> <span class="number">1</span></span><br><span class="line"> <span class="attr">MEMBER:</span> <span class="number">2</span></span><br></pre></td></tr></table></figure><h3 id="requiredReviewers-condition-default-none"><code>requiredReviewers</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#requiredReviewers-condition-default-none"></a></h3><p>Whenever required reviewers are configured, pull requests will only be automatically</p><p>merged whenever all of these reviewers have approved the pull request.</p><p>In the example below, pull requests need to have been approved by the user ‘rogerluan’</p><p>before they will be automatically merged.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">requiredReviewers:</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">rogerluan</span></span><br></pre></td></tr></table></figure><h3 id="maxRequestedChanges-condition-default-none"><code>maxRequestedChanges</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#maxRequestedChanges-condition-default-none"></a></h3><p>Similar to <code>minApprovals</code>, maxRequestedChanges determines the maximum number of</p><p>requested changes before a pull request will be blocked from being automatically</p><p>merged.</p><p>It yet again allows you to configure this per association.</p><p>Note that <code>maxRequestedChanges</code> takes precedence over <code>minApprovals</code>.</p><p>In the example below, automatic merges will be blocked when one of the owners, members</p><p>or collaborators has requested changes.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">maxRequestedChanges:</span></span><br><span class="line"> <span class="attr">COLLABORATOR:</span> <span class="number">0</span></span><br></pre></td></tr></table></figure><p>In the example below, automatic merges will be blocked when the owner has</p><p>requested changes or two members, collaborators or other users have requested</p><p>changes.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">maxRequestedChanges:</span></span><br><span class="line"> <span class="attr">OWNER:</span> <span class="number">0</span></span><br><span class="line"> <span class="attr">NONE:</span> <span class="number">1</span></span><br></pre></td></tr></table></figure><p>The default for this value is:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">maxRequestedChanges:</span></span><br><span class="line"> <span class="attr">NONE:</span> <span class="number">0</span></span><br></pre></td></tr></table></figure><h3 id="blockingBaseBranches-condition-default-none"><code>blockingBaseBranches</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#blockingBaseBranches-condition-default-none"></a></h3><p>Whenever blocking base branches are configured, pull requests will only be automatically</p><p>merged whenever their base branch (into which the PR would be merged) is not matching</p><p>the patterns listed.</p><p>In the example below, pull requests that have the base branch <code>develop</code> or one that starts</p><p>with <code>feature-</code> will not be merged automatically.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">blockingBaseBranches:</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">develop</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">regex:</span> <span class="string">^feature-</span></span><br></pre></td></tr></table></figure><p>Note: remove the whole section when you’re not using blocking base branches.</p><h3 id="requiredBaseBranches-condition-default-none"><code>requiredBaseBranches</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#requiredBaseBranches-condition-default-none"></a></h3><p>Whenever required base branches are configured, pull requests will only be automatically</p><p>merged whenever their base branch (into which the PR would be merged) is matching</p><p>any of the patterns listed.</p><p>In the example below, pull requests need to have the base branch <code>master</code> or one that</p><p>starts with <code>v{number}</code> before they will be automatically merged.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">requiredBaseBranches:</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">master</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">regex:</span> <span class="string">^v\d</span></span><br></pre></td></tr></table></figure><h3 id="blockingLabels-condition-default-none"><code>blockingLabels</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#blockingLabels-condition-default-none"></a></h3><p>Blocking labels are the labels that can be attached to a pull request to make</p><p>sure the pull request is not being merged automatically.</p><p>In the example below, pull requests that have the <code>blocked</code> label will not be</p><p>merged automatically.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">blockingLabels:</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">blocked</span></span><br></pre></td></tr></table></figure><p>The above example denotes literal label names. Regular expressions can be used to</p><p>partially match labels. This can be specified by the <code>regex:</code> property in the</p><p>configuration. The following example will block merging when a label is added that</p><p>starts with the text <code>blocked</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">blockingLabels:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">regex:</span> <span class="string">^blocked</span></span><br></pre></td></tr></table></figure><p>Note: remove the whole section when you’re not using blocking labels.</p><h3 id="requiredLabels-condition-default-none"><code>requiredLabels</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#requiredLabels-condition-default-none"></a></h3><p>Whenever required labels are configured, pull requests will only be automatically</p><p>merged whenever all of these labels are attached to a pull request.</p><p>In the example below, pull requests need to have the label <code>merge</code> before they</p><p>will be automatically merged.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">requiredLabels:</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">merge</span></span><br></pre></td></tr></table></figure><p>The above example denotes literal label names. Regular expressions can be used to</p><p>partially match labels. This requires <code>regex:</code> property in the configuration. The</p><p>following example will requires at least one label that starts with <code>merge</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">requiredLabels:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">regex:</span> <span class="string">^merge</span></span><br></pre></td></tr></table></figure><p>Note: remove the whole section when you’re not using required labels.</p><h3 id="blockingTitleRegex-condition-default-none"><code>blockingTitleRegex</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#blockingTitleRegex-condition-default-none"></a></h3><p>Whenever a blocking title regular expression is configured, pull requests that have a title</p><p>matching the configured expression will not be automatically merged.</p><p>This is useful whenever pull requests with <code>WIP</code> in their title need to be skipped.</p><p>In the example below, pull requests with the word <code>wip</code> in the title will not be</p><p>automatically merged. This also includes <code>[wip]</code>, <code>WIP</code> or <code>[WIP]</code>, but not <code>swiping</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">blockingTitleRegex:</span> <span class="string">'\bWIP\b'</span></span><br></pre></td></tr></table></figure><h3 id="requiredTitleRegex-condition-default-none"><code>requiredTitleRegex</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#requiredTitleRegex-condition-default-none"></a></h3><p>Whenever a required title regular expression is configured, only pull requests that have a title</p><p>matching the configured expression will automatically be merged.</p><p>This is useful for forks, that can only create pull request text, no labels.</p><p>In the example below, pull requests with the title containing <code>MERGE</code> will be</p><p>automatically merged. This also includes This also includes <code>[merge]</code>, <code>MERGE</code> or <code>[MERGE]</code>, but not <code>submerge</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">requiredTitleRegex:</span> <span class="string">'\bMERGE\b'</span></span><br></pre></td></tr></table></figure><h3 id="blockingBodyRegex-condition-default-none"><code>blockingBodyRegex</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#blockingBodyRegex-condition-default-none"></a></h3><p>Whenever a blocking body regular expression is configured, pull requests that have a body</p><p>matching the configured expression will not be automatically merged.</p><p>This is useful whenever pull requests with a certain string in their body need to be skipped.</p><p>In the example below, pull requests with the body containing <code>do-not-merge</code> will not be</p><p>automatically merged. This also includes <code>labels: do-not-merge</code>, <code>LABELS: DO-NOT-MERGE</code> or <code>some more text, but do-not-merge</code>,</p><p>but not <code>do-not-merge-just-kidding</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">blockingBodyRegex:</span> <span class="string">'(^|\\s)do-not-merge($|\\s)'</span></span><br></pre></td></tr></table></figure><h3 id="requiredBodyRegex-condition-default-none"><code>requiredBodyRegex</code> (condition, default: none)<a class="fa-solid fa-hashtag" href="#requiredBodyRegex-condition-default-none"></a></h3><p>Whenever a required body regular expression is configured, only pull requests that have a body</p><p>matching the configured expression will automatically be merged.</p><p>This is useful for forks, that can only create pull request text, no labels.</p><p>In the example below, pull requests with the body containing <code>ok-to-merge</code> will be</p><p>automatically merged. This also includes <code>labels: ok-to-merge</code>, <code>LABELS: OK-TO-MERGE</code> or <code>some more text, but ok-to-merge</code>, but not <code>not-ok-to-merge</code>:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">requiredBodyRegex:</span> <span class="string">'(^|\\s)ok-to-merge($|\\s)'</span></span><br></pre></td></tr></table></figure><h3 id="reportStatus-default-false"><code>reportStatus</code> (default: <code>false</code>)<a class="fa-solid fa-hashtag" href="#reportStatus-default-false"></a></h3><p>The status of the auto-merge process will be shown in each PR as a <a href="https://help.github.com/articles/about-status-checks/">check</a>. This can be especially useful to find out why a PR is not being merged automatically.</p><p>To enable status reporting, add the following to your configuration:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">reportStatus:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h3 id="updateBranch-default-false"><code>updateBranch</code> (default: <code>false</code>)<a class="fa-solid fa-hashtag" href="#updateBranch-default-false"></a></h3><p>Whether an out-of-date pull request is automatically updated.</p><p>It does so by merging its base on top of the head of the pull request.</p><p>This is similar to the behavior of the ‘Update branch’ button.</p><p><code>updateBranch</code> is useful for repositories where protected branches are used</p><p>and the option <em>Require branches to be up to date before merging</em> is enabled.</p><p>Note that this only works when the branch of the pull request resides in the same</p><p>repository as the pull request itself.</p><p>In the example below automatic updating of branches is enabled:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">updateBranch:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h3 id="deleteBranchAfterMerge-default-false"><code>deleteBranchAfterMerge</code> (default: <code>false</code>)<a class="fa-solid fa-hashtag" href="#deleteBranchAfterMerge-default-false"></a></h3><p>Whether the pull request branch is automatically deleted.</p><p>This is the equivalent of clicking the ‘Delete branch’ button shown on merged</p><p>pull requests.</p><p>Note that this only works when the branch of the pull request resides in the same</p><p>repository as the pull request itself.</p><p>In the example below automatic deletion of pull request branches is enabled:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deleteBranchAfterMerge:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h3 id="mergeMethod-default-merge"><code>mergeMethod</code> (default: <code>merge</code>)<a class="fa-solid fa-hashtag" href="#mergeMethod-default-merge"></a></h3><p>In what way a pull request is merged. This can be:</p><ul><li><code>merge</code>: creates a merge commit, combining the commits from the pull request on top of<br>the base of the pull request (default)</li><li><code>rebase</code>: places the commits from the pull request individually on top of the base of the pull request</li><li><code>squash</code>: combines all changes from the pull request into a single commit and places the commit on top<br>of the base of the pull request</li></ul><p>For more information see <a href="https://help.github.com/articles/about-pull-request-merges/">https://help.github.com/articles/about-pull-request-merges/</a></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">mergeMethod:</span> <span class="string">merge</span></span><br></pre></td></tr></table></figure><h3 id="mergeCommitMessage-default-none"><code>mergeCommitMessage</code> (default: none)<a class="fa-solid fa-hashtag" href="#mergeCommitMessage-default-none"></a></h3><p>Optionally specify the merge commit message format. The following template tags</p><p>are supported:</p><ul><li><code>{title}</code>: The pull request title at the moment it is merged</li><li><code>{body}</code>: The pull request body at the moment it is merged</li><li><code>{number}</code>: The pull request number</li><li><code>{branch}</code>: The name of the source branch</li><li><code>{commits}</code>: A list of merged commits</li></ul><p>When this option is not set, the merge commit message is controlled by</p><p>GitHub and uses a combination of the title of the pull request when it was</p><p>opened (note that later changes to the title are ignored) and a list of</p><p>commits.</p><p>This settings is ignored when <code>mergeMethod</code> is set to <code>rebase</code>.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">mergeCommitMessage:</span> <span class="string">|</span></span><br><span class="line"><span class="string"> {title} (#{number})</span></span><br><span class="line"><span class="string"> {body}</span></span><br></pre></td></tr></table></figure><h3 id="rules-default-none"><code>rules</code> (default: none)<a class="fa-solid fa-hashtag" href="#rules-default-none"></a></h3><p>Rules allow more flexibility configuring conditions for automatically merging. Each rule is defined by</p><p>multiple conditions. All conditions inside a rule must be met before a rule triggers a merge. Any of the</p><p>defined rules can trigger a merge individually.</p><p>An example of a configuration with 2 rules that will trigger a merge upon 1 approval from an owner <em>or</em> a <code>merge</code> label:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rules:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">minApprovals:</span></span><br><span class="line"> <span class="attr">OWNER:</span> <span class="number">1</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">requiredLabels:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">merge</span></span><br></pre></td></tr></table></figure><p>This can be combined with conditions on global level, as the global conditions will take precedence. The following example will not trigger a merge when a PR has the <code>blocking</code> label, regardless what the rules say:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">blockingLabels:</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">blocking</span></span><br><span class="line"><span class="attr">rules:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">minApprovals:</span></span><br><span class="line"> <span class="attr">OWNER:</span> <span class="number">1</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">requiredLabels:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">merge</span></span><br></pre></td></tr></table></figure><p>Note: remove the whole rules section when you’re not using any rules.</p><h3 id="requiredAuthorRole-default-none"><code>requiredAuthorRole</code> (default: none)<a class="fa-solid fa-hashtag" href="#requiredAuthorRole-default-none"></a></h3><p>Using the <code>requiredAuthorRole</code> condition you can specify conditions based on the role of the pull request author.</p><p>For instance, using <code>rules</code>, one can be more loose when the author is an owner, and more restrictive otherwise.</p><p>Here’s an example of a configuration that requires acceptance of 2 owners or 1 owner if the other owner made the PR:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rules:</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">requiredAuthorRole:</span> <span class="string">OWNER</span></span><br><span class="line"> <span class="attr">minApprovals:</span></span><br><span class="line"> <span class="attr">OWNER:</span> <span class="number">1</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">minApprovals:</span></span><br><span class="line"> <span class="attr">OWNER:</span> <span class="number">2</span></span><br></pre></td></tr></table></figure><h2 id="Development-2">Development<a class="fa-solid fa-hashtag" href="#Development-2"></a></h2><h3 id="Setup">Setup<a class="fa-solid fa-hashtag" href="#Setup"></a></h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Install dependencies</span></span><br><span class="line">npm install</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Run typescript</span></span><br><span class="line">npm run build</span><br></pre></td></tr></table></figure><h3 id="Testing">Testing<a class="fa-solid fa-hashtag" href="#Testing"></a></h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run test</span><br></pre></td></tr></table></figure><p>or during development:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run test:watch</span><br></pre></td></tr></table></figure><h3 id="Running">Running<a class="fa-solid fa-hashtag" href="#Running"></a></h3><p>See <a href="https://probot.github.io/docs/development/#configuring-a-github-app">https://probot.github.io/docs/development/#configuring-a-github-app</a></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run build && npm run dev</span><br></pre></td></tr></table></figure><h3 id="Running-on-Docker">Running on Docker<a class="fa-solid fa-hashtag" href="#Running-on-Docker"></a></h3><p>This will build and run the app on a container called <code>probot-auto-merge</code>:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run docker</span><br></pre></td></tr></table></figure><p>To just build the container image:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run docker:build</span><br></pre></td></tr></table></figure><p>To run the built image:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run docker:run</span><br></pre></td></tr></table></figure><h3 id="Running-the-linter">Running the linter<a class="fa-solid fa-hashtag" href="#Running-the-linter"></a></h3><p>This will run the linter, pointing out the infractions, but it won’t fix them automatically.</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run lint</span><br></pre></td></tr></table></figure><h2 id="Deployment-2">Deployment<a class="fa-solid fa-hashtag" href="#Deployment-2"></a></h2><p>To deploy <code>probot-auto-merge</code> yourself, please follow <a href="https://probot.github.io/docs/deployment/">the guidelines defined by Probot on deploying GitHub applications</a>.</p><p>The permissions and events needed for the app to function can be found below.</p><h3 id="Permissions">Permissions<a class="fa-solid fa-hashtag" href="#Permissions"></a></h3><ul><li>Administration: Read-only</li><li>Checks: Read & write</li><li>Contents: Read & write</li><li>Issues: Read & write</li><li>Metadata: Read-only</li><li>Pull requests: Read & write</li><li>Commit statuses: Read-only</li><li>Members: Read-only</li></ul><h3 id="Events">Events<a class="fa-solid fa-hashtag" href="#Events"></a></h3><ul><li>Check run</li><li>Check suite</li><li>Label</li><li>Pull request</li><li>Pull request review</li><li>Pull request review comment</li><li>Status</li></ul><h2 id="Contributing-2">Contributing<a class="fa-solid fa-hashtag" href="#Contributing-2"></a></h2><p>If you have suggestions for how <code>probot-auto-merge</code> could be improved, or want to report a bug, open an issue! We’d love all and any contributions.</p><p>For more, check out the <a href="CONTRIBUTING.md">Contributing Guide</a>.</p><h2 id="License-3">License<a class="fa-solid fa-hashtag" href="#License-3"></a></h2><p><a href="LICENSE">ISC</a> © 2018 Bob van der Linden <a href="mailto:bobvanderlinden@gmail.com">bobvanderlinden@gmail.com</a> (<a href="https://github.com/bobvanderlinden/probot-auto-merge">https://github.com/bobvanderlinden/probot-auto-merge</a>)</p><h1>auto-label-merge-conflicts</h1><blockquote><p>A Github action to auto-label PRs with merge conflicts</p></blockquote><h2 id="Purpose">Purpose<a class="fa-solid fa-hashtag" href="#Purpose"></a></h2><p>This action checks all open Pull Requests for merge conflicts and marks them with a Github label.</p><p><img src="/./demo.png" alt="" loading="lazy"></p><p>Once a conflict is resolved the label is automatically removed.</p><p>The typical use case is to run this action post merge (e.g. push to <code>master</code>) to quickly see which other PRs are now in conflict.</p><p>We use this setup e.g. on our monorepo at <a href="https://github.com/comtravo">Comtravo</a>. Instead of a grumpy CTO pinging developers to fix their merge conflicts there’s now a shiny bot.</p><h2 id="Set-up">Set up<a class="fa-solid fa-hashtag" href="#Set-up"></a></h2><p>To configure the action on your repo you have to do 2 things:</p><ol><li>pick a Github label that should be used to mark PRs with conflicts</li></ol><p>This label will then be managed by this action. It will be added to PRs with merge conflicts and removed from PRs without conflicts.</p><ol start="2"><li>configure the new workflow by creating a YML config file in your <code>.github/workflows</code> folder:</li></ol><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">on:</span></span><br><span class="line"> <span class="attr">push:</span></span><br><span class="line"> <span class="attr">branches:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">master</span></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line"> <span class="attr">triage:</span></span><br><span class="line"> <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line"> <span class="attr">steps:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">mschilde/auto-label-merge-conflicts@master</span></span><br><span class="line"> <span class="attr">with:</span></span><br><span class="line"> <span class="attr">CONFLICT_LABEL_NAME:</span> <span class="string">"has conflicts"</span></span><br><span class="line"> <span class="attr">GITHUB_TOKEN:</span> <span class="string">${{</span> <span class="string">secrets.GITHUB_TOKEN</span> <span class="string">}}</span></span><br><span class="line"> <span class="attr">MAX_RETRIES:</span> <span class="number">5</span></span><br><span class="line"> <span class="attr">WAIT_MS:</span> <span class="number">5000</span></span><br></pre></td></tr></table></figure><p>The label from step 1 should be referenced in the parameter <code>CONFLICT_LABEL_NAME</code></p><p>Take a look at <a href="https://github.com/mschilde/auto-label-merge-conflicts/blob/master/%2Egithub/workflows/label_merge_conflicts.yml">this repo</a> for an example setup.</p><h3 id="Arguments">Arguments:<a class="fa-solid fa-hashtag" href="#Arguments"></a></h3><ul><li>MAX_RETRIES: optional (default 5)</li><li>WAIT_MS: optional (default 5000)</li></ul><h2 id="Limitations-2">Limitations<a class="fa-solid fa-hashtag" href="#Limitations-2"></a></h2><p>Github does not reliably compute the <code>mergeable</code> status which is used by this action to detect merge conflicts.</p><p>If <code>master</code> changes the mergeable status is unknown until someone (most likely this action) requests it. <a href="https://stackoverflow.com/a/30620973">Github then tries to compute the status with an async job.</a></p><p>This is usually quick and simple, but there are no guarantees and Github might have issues.</p><p>You can tweak <code>MAX_RETRIES</code> and <code>WAIT_MS</code> to increase the timeout before giving up on a Pull Request.</p><h2 id="Local-dev-setup">Local dev setup<a class="fa-solid fa-hashtag" href="#Local-dev-setup"></a></h2><p>To play around with the code base, you need <code>Docker</code> and <code>make</code> set up locally.</p><p>Run <code>make build</code>, <code>make develop</code>, then <code>yarn install</code>.</p><h1>How to use PR Valet</h1><p>Step 1: Install <a href="https://github.com/marketplace/pr-valet">PR Valet</a>.</p><p>Step 2: Add the <code>valet:merge</code> label to your pull request.</p><p>Step 3: Work on your other tasks while PR Valet takes care of merging your pull request.</p><h1><a href="https://docs.mergify.io/">https://docs.mergify.io/</a></h1><h1><a href="https://snyk.io/">https://snyk.io/</a></h1>]]></c:encoded></item><item><title>一款简洁却不简单的 m3u8 下载工具</title><link>https://blog.ccknbc.cc/posts/a-simple-but-not-simple-m3u8-download-tool/</link><description>一款简洁却不简单的 m3u8 下载工具</description><author>CC康纳百川</author><category domain="https://blog.ccknbc.cc/categories/%E5%B7%A5%E5%85%B7/">工具</category><category domain="https://blog.ccknbc.cc/tags/%E5%B7%A5%E5%85%B7/">工具</category><pubDate>Sun, 10 May 2026 00:54:10 GMT</pubDate><c:encoded><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/19/"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/a-simple-but-not-simple-m3u8-download-tool/"><strong>CC的部落格</strong></a></p><p><a href="https://github.com/nilaoda/N_m3u8DL-CLI">官方仓库</a></p><p><img src="https://cdn.nlark.com/yuque/0/2021/gif/8391407/1610273643341-942cd95d-6f1e-4356-afc9-d5961c7d078a.gif" alt="" loading="lazy"></p><p>批量下载优酷m3u8</p><p><img src="https://cdn.nlark.com/yuque/0/2021/gif/8391407/1610273775655-7e8c3956-6d5a-4760-a59b-d02e6c21126e.gif" alt="" loading="lazy"></p><p>LINETV(台湾站解析)<br><img src="https://cdn.nlark.com/yuque/0/2021/gif/8391407/1610273823214-764f768e-4b64-4073-8793-498c61a30285.gif" alt="" loading="lazy"></p><p>其实 SimpleG 提供了 CLI 更直观简单的调用方式,因此更加方便快捷,解密,录直播必备。</p>]]></c:encoded></item><item><title>很棒的状态页面</title><link>https://blog.ccknbc.cc/posts/undefined/</link><description><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/23/"><strong>语雀</strong></a></p>
<p>自动同步更新至<a]]></description><author>CC康纳百川</author><pubDate>Sun, 10 May 2026 00:54:10 GMT</pubDate><c:encoded><![CDATA[<p>本文首发在<a href="https://www.yuque.com/ccknbc/blog/23/"><strong>语雀</strong></a></p><p>自动同步更新至<a href="https://blog.ccknbc.cc/posts/awesome-status-pages/"><strong>CC的部落格</strong></a></p><h2 id="Awesome-status-pages">Awesome status pages<a class="fa-solid fa-hashtag" href="#Awesome-status-pages"></a></h2><p>Awesome list of status pages open source software, online services and public status pages of major internet companies</p><h2 id="Opensource">Opensource<a class="fa-solid fa-hashtag" href="#Opensource"></a></h2><ul><li><a href="https://cachethq.io/">Cachet</a> - Laravel based status page system for everyone.</li><li><a href="https://github.com/weeblrpress/clearstatus/">ClearStatus</a> - Hugo-based status page, supports Netlify. Supports events from Github, Gitlab or any git repo with markdown.</li><li><a href="https://github.com/jayfk/statuspage">Corestats</a> - turn GitHub issues into a status page</li><li><a href="https://github.com/cstate/cstate">cState</a> - Simple, dev friendly, and free to host (Netlify & GitHub Pages)</li><li><a href="https://github.com/TwinProduction/gatus">Gatus</a> - Automated service health dashboard</li><li><a href="https://github.com/tadhglewis/issue-status">Issue Status</a> - Simple, modern and flexible status page</li><li><a href="https://github.com/tmobile/kardio">Kardio</a> - Simple Health Status Tool with Rich UI for Services deployed on Kubernetes and other platforms.</li><li><a href="https://lambstatus.github.io">LambStatus</a> (<em>Deprecated</em>)</li><li><a href="https://monitoror.com/">Monitoror</a> - monitoring wallboard</li><li><a href="https://github.com/Pryx/server-status">Server-Status</a></li><li><a href="http://www.stashboard.org/">StashBoard</a> - Python, for Google App Engine (<em>Deprecated</em>)</li><li><a href="https://github.com/Cyclenerd/static_status">Static status</a> - Bash script to generate a static status page</li><li><a href="https://github.com/hunterlong/statping">Statping</a></li><li><a href="https://marquez.co/statusfy">Statusfy</a></li><li><a href="https://github.com/sanathp/statusok">StatusOK</a></li><li><a href="https://github.com/darkpixel/statuspage">statuspage</a> - Simple self-hosted open source status page site written in Django (inspired by <a href="https://cachethq.io/">Cachet</a>)</li><li><a href="https://staytus.co/">Staytus</a> (<em>Deprecated</em>)</li><li><a href="https://github.com/ianheggie/health_check">health_check</a> - Simple health check of Rails app for use with uptime checking sites like newrelic and pingdom</li><li><a href="https://github.com/rails-engine/status-page">status-page</a> - Mountable status page for your Rails application, to check Cache, Redis, Sidekiq</li><li><a href="https://github.com/lbeder/health-monitor-rails">health-monitor-rails</a> - A Rails plugin which provides a health checking and monitoring API of various services and application aspects</li><li><a href="https://github.com/valeriansaliou/vigil">Vigil</a> - Microservices Status Page. Monitors a distributed infrastructure and sends alerts (Slack, SMS, etc.).</li><li><a href="https://github.com/EvotecIT/Statusimo">Statusimo</a> - A PowerShell module that is able to generate a status page entirely from PowerShell.</li><li><a href="https://github.com/eidam/cf-workers-status-page">Workers Status Page</a> - Cloudflare Workers (completely on the edge) powered monitoring & status page.</li><li><a href="https://github.com/upptime/upptime">Upptime</a> - monitor and status page powered by GitHub</li><li><a href="https://github.com/RatherLogical/Uptimon">Uptimon</a> - A PHP powered status page/monitoring solution.</li><li><a href="https://github.com/bderenzo/tinystatus">Tinystatus</a> - A tiny static status page generator (written in pure shell)</li></ul><h2 id="Services">Services<a class="fa-solid fa-hashtag" href="#Services"></a></h2><ul><li><a href="https://www.adminlabs.com/status-page/">AdminLabs Statuspage</a></li><li><a href="https://www.appbeat.io/">AppBeat Monitoring</a> - uptime monitoring with integrated status page</li><li><a href="https://asserted.io"><s>Asserted.io</s></a>~~ - uptime tests written in Mocha ~~<s><em>(Discontinued)</em></s></li><li><a href="https://www.freshworks.com/statuspage/">FreshStatus</a></li><li><a href="https://hetrixtools.com">HetrixTools</a> - uptime monitoring for ips and websites with an integrated status page</li><li><a href="https://tryhexadecimal.com">Hexadecimal</a> - uptime & certificate monitoring and hosted status pages</li><li><a href="https://hund.io/">Hund</a></li><li><a href="https://instatus.com">Instatus</a> - Free online service with a static & customizable page.</li><li><a href="https://lambstatus.github.io/">LambStatus</a></li><li><a href="https://nixstats.com/">NixStats</a> - service for servers, web, log and blacklists monitoring</li><li><a href="https://pagefate.com">PageFate.com</a> - free online service with customisable design</li><li><a href="https://www.ping2me.io/">ping2me</a> - monitor endpoints to make sure that they are online.</li><li><a href="https://pingpong.one">PingPong</a> - incident management, uptime & certificate monitoring and hosted status pages</li><li><a href="https://www.sorryapp.com">Sorry™</a></li><li><a href="https://www.squadcast.com">Squadcast</a> - On-Call & SRE platform with StatusPages built-in</li><li><a href="https://status.io">Status.io</a></li><li><a href="https://statuskeeper.com/">StatusKeeper</a></li><li><a href="https://statuskit.com/">StatusKit</a></li><li><a href="https://www.statuspage.io">Statuspage.io</a> - online service from Atlassian</li><li><a href="https://statuspal.io">Statuspal</a> - Hosted status pages & monitoring.</li><li><a href="https://statusy.co"><s>Statusy</s></a>~~ ~~<s><em>(Discontinued)</em></s></li><li><a href="https://updown.io/">UpDown.io</a> - uptime monitoring with flexible status with rest api</li><li><a href="https://uptimerobot.com/">Uptime Robot</a></li><li><a href="https://www.uptimetoolbox.com/">UptimeToolbox</a> - Website/Server monitors with status pages.</li></ul><h2 id="Public-status-pages">Public status pages<a class="fa-solid fa-hashtag" href="#Public-status-pages"></a></h2><ul><li><a href="https://status.adobe.com/">Adobe System Status</a> - Adobe services status</li><li><a href="https://cloudharmony.com/status-for-akamai">Akamai Status</a> - Akamai Service Status</li><li><a href="https://status.aws.amazon.com/">Amazon AWS Service health dashboard</a></li><li><a href="https://www.apple.com/support/systemstatus/">Apple Support System Status</a> - Apple support status</li><li><a href="https://status.box.com/">Box Status</a> - <a href="http://Box.net">Box.net</a> status</li><li><a href="https://www.cloudflarestatus.com/">Cloudflare Status</a> - Cloudflare System Status</li><li><a href="https://cloudharmony.com/status-of-cdn-for-aws">CloudFront Status</a> - Amazon CloudFront Service Status</li><li><a href="https://status.datadoghq.com/">Datadog Status</a> - the status of Datadog.</li><li><a href="https://status.digitalocean.com/">DigitalOcean Status</a> - DigitalOcean Status page</li><li><a href="https://status.discordapp.com/">Discord App Status</a> - Discord App (videoconferencing, audioconferencing) status page</li><li><a href="https://developers.facebook.com/status/dashboard/">Facebook Platform Status</a> - Facebook platform status page</li><li><a href="https://status.fastly.com/">Fastly Status Page</a> - Fastly Status</li><li><a href="https://status.github.com/api">GitHub Status API</a> - GitHub status using REST API</li><li><a href="https://status.github.com/">GitHub Status</a> - GitHub status page</li><li><a href="https://status.gitlab.com">GitLab System Status</a> - GitLab status page</li><li><a href="https://status.cloud.google.com/">Google Cloud Status</a> - Status of Google Cloud</li><li><a href="https://www.google.com/appsstatus">Google GSuite Appstatus</a> - Google Applications (G Suite) online status page</li><li><a href="https://status.heroku.com/">Heroku Status</a> - Heroku status page</li><li><a href="https://status.ads.microsoft.com/">Microsoft Advertizement Status</a> - Microsoft Advertizement status page</li><li><a href="https://status.azure.com/ru-ru/status">Microsoft Azure Status</a> - Microsoft Azure status page</li><li><a href="https://status.office365.com/">Microsoft Office365 Status</a> - Microsoft Office365 status page</li><li><a href="https://www.paypal-status.com/product/production">Paypal Status Page</a></li><li><a href="https://www.pintereststatus.com/">Pinterest Status Page</a></li><li><a href="https://status.rackspace.com/">Rackspace System Status</a> - Rackspace hosting and services status page</li><li><a href="https://www.redditstatus.com/">reddit Status</a> - reddit Social Media status page</li><li><a href="https://support.skype.com/en/status/">Skype Status</a> - Microsoft Skype Status page</li><li><a href="https://status.slack.com/">Slack Status</a> - Slack, chat platform, status page</li><li><a href="https://api.twitterstat.us/">Twitter API Status</a> - Twitter API status page</li><li><a href="https://grafana.wikimedia.org/d/000000479/frontend-traffic?orgId=1">Wikipedia Frontend Monitoring</a> - Graphana based status page replacement for Wikipedia</li><li><a href="https://status.zoom.us/">Zoom Cloud Status</a> - Zoom (videoconferencing) status page</li></ul><h2 id="目前使用">目前使用<a class="fa-solid fa-hashtag" href="#目前使用"></a></h2><p><a href="https://cc.instatus.com/"><strong>Instatus</strong></a>(中文)| <a href="https://ccknbc.statuspage.io/"><strong>Statuspage</strong></a>(English)</p><p>因为 Instatus 我贡献了翻译,而且相较于其他免费产品,可自定义的地方实在太多了(好评,白嫖党的胜利)</p><p>而 Statuspage 主要是他可链接的第三方实在太多了,免费帐户的话能添加 25 个组件,反正也没有外国人看我,就当自用吧</p><p>配合 Freshping, Uptimerobot 等监控联动,这两个均可自动化向推特发送通知,当然 Uptimerobot 自身推送的方式也很多,RSS, Telegram, Webhook 等满足日常需要了。此外良心的他们对于订阅更新支持也很完善,虽然根本没人会去订阅,但还是要有这些功能对吧,高大上点(不是)</p><p>不过对于使用中文为主的我们来说,Instatus 是您的不二选择,时区,时间格式,语言什么的自定义太友好了,免费账号是完全够个人站长使用的,但是他的 embed 目前来说我希望能自适应大小,深色模式等,反正还很期待啦。而说到 embed, Statuspage 的 embed 个人觉得好看点吧,可以选择弹窗模式,悬浮模式,基础模式,徽标模式,自适应也不错,不过因为不支持中文(就是懒得自己在再整,官方那个代码都两年没动了)。此外 <a href="https://instatus.com/out"><strong>Instatus OUT</strong></a> 提供了网页端或者客户端(状态栏)快捷监控第三方的服务,而未来 Instatus 还会带来哪些服务呢,让我们共同期待吧!</p><hr><p>但自从 <a href="https://www.vercel-status.com/incidents/r758bhbklgfd"><strong>Vercel 事件</strong></a> 后,我们自己的状态页不受影响,IP换到了中国专用IP,但是 Instatus 官方还是原来的 A记录 IP,导致中国大陆用户无法访问其状态页和官网,这对用户体验来说是没什么,但对于站长就麻烦点了,得使用代理才能更新事件。不过 API, 邮件, WebHook 等方式应该可以解决,但官网控制面板更加方便,然后和开发者沟通更换了 IP, 目前一切正常,并且提前拥有了多语言和深色模式的支持,未来也会有其他功能,静态网页访问就是快!!!</p>]]></c:encoded></item></channel></rss>