Free-Programming-Books 中文贡献指南:从第一个 Pull Request 到通过 CI 自动检查
本篇指南面向希望向 Free-Programming-Books 免费编程书籍清单贡献内容的开发者,尤其是第一次在 GitHub 上提交 Pull Request(PR)的新人。指南以 docs/HOWTO-zh.md 为主线,先讲清“在哪里提交、如何打开 PR”,再结合本仓库真实的 CI 配置(.github/workflows/fpb-lint.yml、.github/workflows/check-urls.yml、.github/workflows/rtl-ltr-linter.yml)与规范文档(docs/CONTRIBUTING-zh.md),带你掌握“新增一条免费资源链接到正确清单”的全流程,以及如何读懂、修复自动检查报出的错误。
欢迎来到 Free-Programming-Books
Free-Programming-Books 是一份用 Markdown 维护的免费编程学习资源清单,仓库按资源类型划分了多个目录:书籍位于 books(如 free-programming-books-zh.md),课程位于 courses,交互式教程、在线 Playground、播客/录屏与竞赛题库分别位于 more 与 casts。项目欢迎各类贡献者,即使是第一次在 GitHub 上提交 PR 的新人也同样受欢迎。
如果你尚未提交过 PR,建议先熟悉基础操作。GitHub 官方文档与教程(如"关于拉取请求""创建拉取请求"及 GitHub Hello World)可以帮助你掌握 fork 仓库、创建分支、提交改动并发起 PR 的完整流程;入门后还可通过 GitHub 初学者教程、如何 fork 仓库并提交 PR 等视频加深理解。仓库本身也提供了 PR 模板,发起 PR 时会自动填充一份包含自查项的表单(如"已搜索是否重复""已按字母顺序排列"等),按模板逐项确认即可降低被驳回的概率。
贡献的起点:问题(Issue)与 Pull Request
贡献者并不强制要求熟悉 Git。规则很简单:如果发现了有趣但尚未收录在此仓库中的资源,可以先打开一个 Issue 来讨论该主题;如果你已经会用 Git,则直接 fork 本仓库并提交 PR。即使是有经验的开源贡献者,也常会在细节上碰壁——这正是本指南希望帮你绕开的坑。
提交 PR 后,仓库的持续集成(CI)会自动接管。当前仓库实际配置了多套 GitHub Actions 工作流:主要格式检查 .github/workflows/fpb-lint.yml 会在每个 PR 上安装 free-programming-books-lint 并运行 fpb-lint books casts courses more;.github/workflows/rtl-ltr-linter.yml 专门扫描阿拉伯语、希伯来语、波斯语、乌尔都语等 RTL(从右到左)语言文件的混排问题;.github/workflows/check-urls.yml 则用 awesome_bot 校验被改动文件中每条链接是否仍然有效。如果你的 PR 看到绿色的通过标识,说明一切就绪;如果某个检查失败,请点击失败的 "Details" 链接查看 linter 的具体输出,根据报错修正后向 PR 所在分支新增一个 commit 即可,无需重新发起 PR。
选择正确的清单类型
仓库同时维护多种资源清单,提交前务必判断资源应归属哪一类。这里列出的分类规则来自 docs/CONTRIBUTING-zh.md,帮助新手准确分类:
- Books(书籍):PDF、HTML、ePub、基于 gitbook.io 的站点、一个 Git 仓库等。
- Courses(课程):课程是一种学习材料而非一本书(例如 MIT OpenCourseWare 上的算法导论)。
- Interactive Tutorials(交互式教程):允许用户输入代码或命令并实时评估结果的交互式网站,例如 Try Haskell、Try GitHub。
- Playgrounds(在线游乐场):可在网页上编写、编译、运行或分享代码片段的在线站点、游戏或桌面软件,通常支持 fork 后改写。
- Podcasts and Screencasts(播客和录屏):播客与视频类内容,存放在 casts 目录。
- Problem Sets & Competitive Programming(题库与竞赛编程):通过解决简单或复杂问题来评估编程技能的网站或软件。
另外,仓库明确不收录博客、博客文章、单纯网站、非课程/录屏的视频、书籍章节、书籍预览样章、IRC 或 Telegram 频道、Slack 或邮件列表等内容。若你认为范围本身需要调整,请通过 Issue 提出讨论,而不要直接改动列表。
基本准则:什么样的链接可以收录
即使通过了机器检查,人工审阅仍会基于内容准则把关。以下准则是贡献前必须核对的关键项:
- 请确保所提交的书籍确实免费;若存疑请仔细核实,并在 PR 中说明你认为其免费的原因,这对管理员很有帮助。
- 不接受存储在 Google Drive、Dropbox、Mega、Scribd、Issuu 及其他类似文件上传平台上的文件。
- 使用最权威来源的链接:原作者的网站优于编辑的网站,编辑的网站优于第三方网站。
- 优先使用
https链接而非http(前提是同一域名且提供相同内容);在根域上去掉末尾斜杠。 - 总是选择最短的链接:
http://example.com/dir/优于http://example.com/dir/index.html;不要提供短链接。 - 优先提供指向 "current"(当前版)的链接而非 "version"(具体版本号)链接。
- 若链接存在过期证书/自签名证书/SSL 问题:能替换就先替换为对应的
http版本;无 http 版本则可在浏览器添加例外;否则删除该链接。 - 若一个链接存在多种格式,添加单独一条链接并注明每种格式;若同一资源在不同位置存在差异较大的版本,可各加一条并附说明。
- 相较一个较大的提交,更倾向于原子提交(一次提交对应一次添加/删除/修改);提交 PR 前无需压缩(squash)提交。
- 若书籍较旧,请在书名中注明出版年份;尽量包含作者或合适的署名,中文列表可用“等”缩短作者列表。
- 未完成且仍在编写的书籍需添加
:construction:编写中/翻译中标记;使用 Internet Archive 的 Wayback Machine 等恢复的链接需添加:card_file_box: archived标记。 - 若在开始下载前需要电子邮件地址或账户设置,请在括号中做相应说明。
规定格式:让每条记录都“长一个样”
所有列表都是 .md 文件,遵循统一格式。每个文件以索引开始,列出并链接全部 section 与 subsection;section 使用三级标题 ###,subsection 使用四级标题 ####。整体空行规则可概括为 2-1-0-1:
2:新添加的 section 与上一节末尾链接之间保留2个空行;1:标题与第一个链接之间保留1个空行;0:任意两个相邻链接之间不留空行;1:每个.md文件末尾保留1个空行。
示意如下:
[...]
* [一本很有用的书](http://example.com/example.html)
(空行)
(空行)
### 电子书种类标题
(空行)
* [Another 很有用的书](http://example.com/book.html)
* [Other 有用的书](http://example.com/other.html)
具体写法上有许多易错细节,linter 往往正是卡在这些地方:
- 在
]与(之间不要留空格:
错误:* [一本很有用的书] (http://example.com/book.html)
正确:* [一本很有用的书](http://example.com/book.html)
- 若包含作者,使用由英文半角空格包围的破折号
-分隔:
错误:* [一本很有用的书](http://example.com/book.html)- 张显宗
正确:* [一本很有用的书](http://example.com/book.html) - 张显宗
- 链接与格式说明之间留一个空格,格式说明一律使用英文半角括号:
错误:* [一本很有用的书](https://example.org/book.pdf)(PDF)
正确:* [一本很有用的书](https://example.org/book.pdf) (PDF)
错误:* [一本很有用的书](https://example.org/book.pdf) (繁体中文)
正确:* [一本很有用的书](https://example.org/book.pdf) (繁体中文)
- 作者的书写顺序固定为“作者在电子书格式之前”;多作者、多译者使用中文顿号
、分隔,译者名后加英文半角括号括起的(翻译),可用“等”缩写长列表:
错误:* [一本很有用的书](https://example.org/book.pdf) - 张显宗,岳绮罗
正确:* [一本很有用的书](https://example.org/book.pdf) - 张显宗、岳绮罗(翻译)
正确:* [一本很有用的书](https://example.org/book.pdf) - 张显宗、岳绮罗、顾玄武、出尘子 等
- 单资源多格式时,用主链接配 HTML 说明、再用方括号集中列出其余格式:
正确:* [一本很有用的书](http://example.com/) - 张显宗 (HTML) [(PDF, EPUB)](https://downloads.example.org/book.html)
- 旧书把出版年份写进标题而非作为尾部字段:
错误:* [一本很有用的书](https://example.org/book.html) - 张显宗 - 1970
正确:* [一本很有用的书 (1970)](https://example.org/book.html) - 张显宗
- 编写(翻译)中的书籍与归档链接的固定写法:
* [马上出版的一本书](http://example.com/book2.html) - 张显宗 (HTML) *( :construction: 编写中)*
* [马上出版的一本书](http://example.com/book2.html) - 张显宗 (HTML) *( :construction: 翻译中)*
* [A Way-backed Interesting Book](https://web.archive.org/web/20211016123456/http://example.com/) - John Doe (HTML) *( :card_file_box: archived)*
可以在 books/free-programming-books-zh.md 中看到这些规则的实际落地:例如“版本控制”一节中 * [Git Magic](http://...)... - Ben Lynn, trl.: 俊杰, 萌和江薇, et al. (HTML) 就同时示范了多作者缩写、trl.: 译者标记与格式括号的用法。翻译类书籍建议使用 MARC relators 代码表彰作者之外的创作者,例如 trl.: 表示“翻译器”;同一作者的多个条目需按字母顺序二次排序,出现顺序错误时请留意 linter 报错中提示应交换的行。
标题、URL 与元数据规范
除纯格式外,CONTRIBUTING 还对清单中的元数据(标题、URL、创作者、平台与存取注释)提出了要求:
- 标题:尽量沿用资源自身的原始标题,不要自行创作或改动;不要使用全大写,常规标题大小写即可;不要在标题中使用表情符号。
- URL:不接受短链;必须删除追踪代码;URL 应进行转义(可从浏览器地址栏复制已转义的地址);支持 HTTPS 时一律使用
https;避免给出不直接托管所列资源、而只是跳转到别处的网页。 - 创作者:在合适情况下为免费资源的创建者署名,也包括译者;使用中文顿号或逗号分隔多个条目;允许使用“等 / et al.”缩写作者列表;不允许为创作者提供链接;对编译或混音类作品(如“Compiled from StackOverflow Documentation”)需在“创作者”位置作描述性说明。
- 平台与存取注释:课程列表尤其需要标注平台(如 Coursera、EdX、Udacity、Udemy),因为不同平台的功能与访问模型差异很大;Youtube 播放清单不把 YouTube 列为平台,而是尽量列出创作者;Leanpub 混合存取模式的书允许使用“(Leanpub 账户或请求的有效电子邮件)”之类的注释。
自动检查是如何运作的
理解 CI 的具体运作方式,有助于更快地定位问题。三个核心工作流的实现如下:
- 格式与排序检查:工作流
.github/workflows/fpb-lint.yml在 PR 上安装free-programming-books-lint(fpb-lint),对books casts courses more四个目录执行fpb-lint,校验列表是否按字母顺序排列并符合格式化规则;linter 输出被清理后作为 artifact 上传,方便开发者下载error.log查看全部问题。 - URL 有效性检查:工作流
.github/workflows/check-urls.yml使用 awesome_bot 对本次 PR 改动的每个.md/.yml文件执行链接检查,参数--allow-redirect --allow-dupe --allow-ssl允许跳转、重复与带 SSL 的地址;结果 JSON 经本地 action(见.github/actions)汇总为报告。 - RTL/LTR 混排检查:针对阿拉伯语、希伯来语、波斯语等从右到左书写的语言文件,工作流
.github/workflows/rtl-ltr-linter.yml会安装python-bidi与PyYAML,并执行本仓库自带的 scripts/rtl_ltr_linter.py。从脚本源码看,其通过正则识别 RTL 字符与纯 LTR(ASCII)片段,对 HTMLdir属性与<span>嵌套方向上下文做解析,并用get_display做双向文本视觉序分析,检测 RTL 上下文中紧跟 LTR 元数据等混排问题;各项检测的严重级别与ltr_keywords/ltr_symbols等参数由同目录的 scripts/rtl_ltr_linter_config.yml 配置,默认对 bidi 不匹配报 error、对 RTL 语境中的 LTR 关键词/符号报 warning,只有本次改动涉及 RTL 语言文件或 PR 带有 RTL 标签时才执行。
因此,即便你只新增一行中文书籍链接,改动也会触发格式 linter 与 URL 校验;而对 books/free-programming-books-ar.md 等 RTL 文件的改动,则还会触发上述混排检查。一个值得注意的细节是:在 check-urls 工作流中,CI 的结论以被检查的最后一个文件为准。当一条 PR 同时改动多个文件时,即便个别文件存在问题也可能显示绿色构建,因此请在 PR 收尾时主动展开 "Show all checks" → "Details" 查看各文件独立的构建日志,而不要只依赖汇总的绿灯。
其他语言的维护与翻译流程
内容从英文版翻译到其他语言时,仓库遵循一套“审查与改编”流程:始终以 docs/CONTRIBUTING.md 等英文文件为信息来源与准则;译者仔细翻译并兼顾语言与文化差异;翻译稿经过母语人士审阅;必要时允许译者对术语、措辞做本土化改编而保留核心信息;最后进行质量保证检查,并鼓励读者持续反馈以改进翻译质量。需要说明的是,以上流程描述来自 docs/CONTRIBUTING-zh.md 的“审查和适应过程”一节,它确立了各语言列表(books、courses、docs 中大量 -xx.md 文件)与英文主文件保持同步的协作基调。
常见问题与快速排查清单
- PR 状态是红色:点击失败项的 "Details",查看
fpb-lint的error.log或工作流注解;绝大多数问题集中在“字母顺序”与“空行/空格”上,按报错行号修正后向 PR 分支新增 commit。 - 不确定添加的资源是否合适:先通读 docs/CONTRIBUTING-zh.md 的分类与准则;仍拿不准就到 Issue 中发起讨论。
- 链接在不同格式间选择:默认选最短、最权威、https、去尾部斜杠的链接;多种格式并存时用一条记录集中标注。
- 改动涉及多个文件但构建全绿:CI 结果以最后检查的文件为准,务必逐文件核对 Details 日志。
对照仓库内真实样本(例如 books/free-programming-books-zh.md 中“版本控制”到“Git”等小节),逐一比对空行、破折号、括号、字母顺序,再借助上述自动化检查兜底,你的第一个贡献就能顺利通过全部检查。不要犹豫提出问题——每位贡献者都是从第一个 PR 开始的,维护高质量清单的关键不在于一次写对,而在于根据 linter 的反馈快速迭代。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00