Jekyll 稳定分支发布指南:从 3.9-stable 等旧版本分支回溯安全补丁与关键修复
【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyll
本文面向 Jekyll 核心维护者,讲解如何从[x].[y]-stable命名的旧版本稳定分支(如3.9-stable)切出包含安全补丁和关键 Bug 修复的发布版本,并同步更新master默认分支上的版本元文件。读完后你将掌握完整的双分支发布流程:稳定分支上如何触发发布、master上如何回填 History 与站点元文件,以及如何手动发布机器人不覆盖的非默认分支 GitHub Release。
背景:为什么要从稳定分支切发布
Jekyll Core 的常规发布都从默认master分支切出。但当仍在维护期内的旧版本系列出现需要修复的安全漏洞或关键 Bug 时,核心团队会从专门命名的稳定分支切出回溯发布。分支命名遵循[x].[y]-stable模式:
[x]为 semver 主版本号,[y]为次版本号;- 例如
3.9-stable分支上的提交,最终都会以jekyll-3.9.x系列 gem 的形式发布。
这一点可以从 History.markdown 中得到印证:3.9.x系列至今持续有安全补丁发布,如## 3.9.5 / 2024-02-12、## 3.9.4 / 2023-12-28、## 3.9.3 / 2023-01-29、## 3.9.2 / 2022-03-27等小节,它们与4.x主线版本并存于同一份历史文档中。
流程之所以比常规发布复杂,根源在于:稳定分支上的发布,最终也必须在master分支上留下记录——版本历史、文档站点的 changelog 和站点配置文件都只能由master上的生成任务统一维护。
前置条件
开始操作前,维护者必须满足以下条件(摘自 releasing-off-stable-branches.md):
- 对目标
*-stable分支和master分支均拥有写权限; - 全程使用本地 CLI 程序(git/rake)完成任务,而不是通过 GitHub Web UI 操作;
- 熟悉从
master切发布的标准流程(见 releasing-a-new-version.md),本文流程是其在稳定分支上的缩减改编版; - 发布博文(release post)已经起草完毕,并且已通过一个处于可合并状态的 pull request等待合并到
master; - 稳定的网络连接。
阶段一:在稳定分支上触发发布
确认本地已检出目标*-stable分支,且与远端jekyll/jekyll上的同名分支保持同步后,按以下步骤操作:
更新版本号:修改 lib/jekyll/version.rb 中的
VERSION字符串。该文件是仓库中唯一需要手动改版本号的地方:module Jekyll VERSION = "4.4.1" endRakefile 顶部的
version辅助函数直接读取Jekyll::VERSION,gem 构建、任务名等均由此派生,因此改这一处即可联动全局。更新 History 文档:按 更新 History 文档的标准做法操作——把 History.markdown 的第一个标题
## HEAD替换为## X.Y.Z / YYYY-MM-DD形式的版本里程碑标题(版本号与发布日期都要调整),并按优先级从高到低重排小节(Major Enhancements→Minor Enhancements→Bug Fixes→Security Fixes等)。重要:在稳定分支上切勿运行
rake site:generate。该任务会把 History.markdown 转换后写入文档站的 docs/_docs/history.md 等元文件,而这些文件只能在master上生成——这正是后文"更新默认分支"阶段才执行该命令的原因。暂存 History 片段:把与本次发布相关的完整 History 小节(标题行连同其下所有条目)复制并粘贴到文本编辑器的一个新标签页/窗口中备用,后续在
master回填和撰写 GitHub Release 正文时都会用到。提交并推送:以规范的提交信息提交版本号文件与 History 文档的改动,然后推送到上游远端:
git commit -am "Release :gem: v[CURRENT_VERSION]" git push upstream 3.9-stable其中
upstream指向git@github.com:jekyll/jekyll.git,[CURRENT_VERSION]替换为本次发布的实际版本号。
为什么稳定分支的流程与 master 不同:自动化边界
常规master发布中,推送后会自动触发 GitHub Actions 工作流完成 gem 构建、打 tag、推 gem,并由 JekyllBot 发布 GitHub Release。但从 release-please.yml 可以看到,该工作流的触发条件被严格限定为:
on: push: branches: - master其release-pleasejob 运行 release-please-action,其中version-file指向lib/jekyll/version.rb、changelog-path指向History.markdown、include-v-in-tag为true),随后的publish-gemjob 仅在release_created == 'true'时构建并发布 gem。也就是说,整套自动化只对master生效——从3.9-stable等非默认分支推送后,机器人不会创建 tag、不会发布 gem、更不会创建 GitHub Release,这些步骤都必须由维护者手动完成。当前发布基线可参考 .github/release-please-manifest.json(记录".": "4.4.1")。
阶段二:发布博文到 master
- 确认稳定分支上触发的工作流(gem 构建与发布流水线)已成功完成。
- 将此前起草的 release post pull request合并到
master。
阶段三:让默认分支反映稳定分支的发布
本地检出master并确认其与远端同步后:
回填 History 文档:将之前暂存的 History 片段手动注入 History.markdown 的正确位置。History 文档中的各版本小节首要按时间倒序排列,次要按 semver 主版本归类。例如
v3.9.2的发布小节会排在v3.9.1之上、但位于所有4.x版本小节之下。这一点在 History.markdown 中可以直接验证:4.4.1 / 2025-01-29、4.4.0 / 2025-01-27等4.x小节在前,其后才是## 3.9.5 / 2024-02-12起的3.9.x序列。可选:更新
VERSION字符串:若 lib/jekyll/version.rb 中的现有版本号小于本次稳定分支发布的最新版本号,则一并更新。运行
rake site:generate更新文档站点的元文件。该任务是 rake/site.rake 中定义的聚合任务:generated_pages,包含:history、:latest_version、:conduct、:contributing、:security、:support六个子任务,其中与版本号直接相关的产物有:docs/_config.yml—— 站点配置中的version字段;docs/_docs/history.md—— 由History.markdown转换生成的 changelog 页面;docs/latest_version.txt—— 记录最新版本号的纯文本文件。
从 site.rake 的
latest_version任务 可以看到其具体逻辑:task :latest_version do next if version =~ %r!(beta|rc|alpha)!i # 预发布版本不写入 ... config["version"] = version # 写入 docs/_config.yml File.write(config_file, YAML.dump(config)) File.open("#{docs_folder}/latest_version.txt", "wb") { |f| f.puts(version) } end注意其中有一处关键约束:版本号匹配
beta|rc|alpha时任务直接跳过,即预发布版本不会同步到站点元文件。当前仓库中这三个文件的状态也印证了这一点:docs/_config.yml中为version: 4.4.1,docs/latest_version.txt 内容为4.4.1,与lib/jekyll/version.rb完全一致。History 页面的生成则由
:history任务调用siteify_file("History.markdown")完成:Rakefile 中的siteify_file会为文件补上 front matter(含permalink: /docs/history/与"本文件自动生成,请编辑源文件"的提示),content_for 再经converted_history管道处理——去掉## HEAD段、为每个版本标题和子小节生成锚点、把裸的#1234PR 编号转为链接、并对含 Liquid 语法的片段包上{% raw %}转义。提交并推送:将各元文件改动以提交信息
Release :gem: v[CURRENT_VERSION]提交,推送到上游远端。
阶段四:手动发布 GitHub Release
这是稳定分支发布与master发布最显著的区别:由于 JekyllBot 只为默认分支创建的 tag 自动创建并发布 GitHub Release,维护者必须手动为稳定分支新推的 tag 创建发布:
- 选择刚推送的新 tag;
- 标题与所选 tag 名保持一致(因
include-v-in-tag为true,tag 形如v3.9.5); - 之前暂存的 History 片段作为 Release 正文;
- 从正文中删除片段标题行(即
## x.y.z / YYYY-MM-DD这一行); - 点击发布。
技巧:可以在更新默认分支之前就先把 GitHub Release 置为draft(草稿)状态,待推送完master的更新提交后立即正式发布,从而让整体流程更平滑。
版本号的确定与发布博文脚手架
稳定分支上更新版本号前,需要先确定正确的目标版本。可参考 releasing-a-new-version.md 给出的判读规则:先查看 History.markdown 中## HEAD小节的内容——
- 若含
Major Enhancements子节:递增主版本,次版本与补丁版本归零(如"3.9.1" => "4.0.0"),预发布可加后缀; - 若含
Minor Enhancements子节:仅递增次版本,补丁版本归零(如"4.0.2" => "4.1.0"); - 其余情况(
Bug Fixes、Security Fixes等):仅递增补丁版本(如"4.0.2" => "4.0.3")。
稳定分支上的安全补丁发布通常落在第三种情况,例如在3.9-stable上把3.9.4递增为3.9.5。
若发布博文尚未起草,可用仓库内置的 rake 任务生成脚手架:
bundle exec rake site:releases:new[3.9.5]site.rake 中的site:releases:new任务 会在docs/_posts/下按YYYY-MM-DD-jekyll-3-9-5-released.markdown命名创建博文,并预填title、date、version、category: release等 front matter。随后撰写正文时,感谢名单可用提交日志命令生成(v3.9.4为上一个发布 tag):
git shortlog -sn master...v3.9.4完成后为该博文开启 pull request,等待前述阶段二的合并步骤。
流程小结
| 阶段 | 所在分支 | 关键动作 | 自动化程度 |
|---|---|---|---|
| 触发发布 | *-stable | 改version.rb、更新History.markdown、暂存片段、提交推送 | 推送后由 CI 构建 gem |
| 发布博文 | master | 合并 release post 的 pull request | — |
| 更新默认分支 | master | 回填 History、可选改版本号、rake site:generate、提交推送 | 元文件由 rake 生成 |
| 发布 GitHub Release | Web | 手动为稳定分支 tag 创建 Release,正文用暂存片段 | 机器人不覆盖非默认分支 |
整个流程的核心风险点有两个:一是在稳定分支上误跑rake site:generate(会把不该出现在该分支的元文件改动混入提交),二是 History 片段回填时放错位置(必须遵守"时间倒序 + 按主版本归类"的双层排序规则)。只要牢记"稳定分支只改版本与历史、master负责一切站点元文件与记录回填"的分工,回溯发布就能安全完成。
【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyll
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考