ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

FreshRSS 开发者贡献指南:从 Pull Request 到高质量合并的全流程实战

FreshRSS 开发者贡献指南:从 Pull Request 到高质量合并的全流程实战 FreshRSS 开发者贡献指南从 Pull Request 到高质量合并的全流程实战【免费下载链接】FreshRSSA free, self-hostable news aggregator…项目地址: https://gitcode.com/gh_mirrors/fr/FreshRSS本篇指南聚焦 FreshRSS 开源仓库中面向开发者的 Pull RequestPR工作流涵盖分支同步rebase/merge、提交信息规范、测试要求与文档义务四大核心环节。无论你是首次向该项目提交补丁的新手还是希望深入理解其协作规范的贡献者读完本文后都能掌握一套可直接执行的分支操作命令、符合项目惯例的提交信息写法以及被维护者接受 PR 所需的全部验收要点。一、开 PR 前的准备模板与检查清单在 FreshRSS 中当你打开一个新的 Pull Request 时提交信息会根据 docs/pull_request_template.md 中的模板自动预填。这个模板不仅是一个格式框架更是一份别漏掉任何事的验收清单其核心内容如下关联 Issue模板首行是Closes #用于声明本 PR 关闭的 Issue 编号变更说明以Changes proposed in this pull request列出本次改动要点手动测试步骤以 How to test the feature manually给出可复现的验证路径PR 检查清单Pull request checklistclear commit messages提交信息清晰code manually tested代码经过手动测试unit tests written (optional if too hard)单元测试若过于困难则为可选documentation updated文档已同步更新维护者非常看重这份清单因为它确保了文档保持最新、提交历史保持清晰、代码始终稳定。即使某项测试确实难以编写也应在 PR 描述中如实说明。分支规范为什么目标是edgeFreshRSS 的开发主线分支是edge。所有新功能、修复与重构都应基于最新的edge分支进行目的是让你的代码建立在项目最新状态之上避免合并时产生冲突。若你对 Git 操作有任何疑问维护者明确表示欢迎在 PR 中提问求助——我们都曾是从 Git 新手开始的。二、同步edge分支的两种方式在提交 PR 之前确保你的分支基于最新的edge可以避免大量合并冲突。文档提供了两种方法Rebasing变基与Merging合并。方式一Rebasing推荐历史更线性变基是最干净的方式Git 历史完全线性因此更易于阅读与导航。代价是对 Git 不熟练的开发者而言冲突解决可能更困难。其命令序列为git checkout edge # 切换到 edge 分支 git pull upstream edge # 拉取 edge 分支的最新版本 git checkout - # 回到你的开发分支 git rebase edge # 将你的分支变基到 edge 之上如果你有把握还可以使用交互式变基来重写历史、让提交更清晰git rebase -i edge注意文档明确警告——永远不要对一个别人正在协作的分支执行 rebase因为变基会重写历史一旦有人基于旧历史工作会引发极难理清的混乱局面。方式二Merging冲突更易解决如果你更倾向于合并而非变基可以直接把edge合并进自己的分支git checkout edge # 切换到 edge 分支 git pull upstream edge # 拉取 edge 分支的最新版本 git checkout - # 回到你的开发分支 git merge edge # 将 edge 合并进你的分支这种方式下冲突通常更容易解决但你的提交历史可读性会稍差。不过文档也提到别担心在把你的 PR 合并回edge之前我们会处理好的。——即维护者会在最终合并时负责梳理历史。关于 rebase 的一个 TODO 说明值得留意的是原文在该章节开头留有一条TODO 标注随着 GitHub 的squash and merge机制的普及rebase以及其他形式的改写历史操作相比其收益而言更加危险和麻烦例如会破坏已有的 review 机制。因此维护者正在考虑更新本节内容——这提示贡献者在向项目提问或参考本文时可以留意该章节的后续更新。三、如何撰写规范的 Commit MessageFreshRSS 要求提交信息必须规范理由是提交信息应当解释过去的选择为什么以方便日后调试。一段好的提交信息由主题行与正文组成。主题行第一行以动词开头例如 Add用几个词说明提交的目标通常少于 50 个字符保持简洁可以把它视为一句以 This commit will 开头的句子的后半部分。例如This commit will *add feature X*即第一行写作Add feature X。正文空行之后空一行后开始写正文通常每行折行在 72 个字符语气可以相对自由正文是澄清补丁上下文的地方例如你是在什么场景下发现这个 bug 的或者补丁之前遇到的问题是什么提供这些信息能帮助其他开发者理解某个选择背后的原因尤其是在几个月后发现该补丁引入了 bug 时你还可以在正文中添加引用比如 bug 跟踪器中的原始 ticket URL或某个论坛的讨论链接。这一约定与 docs/en/developers/02_GitHub.md 中分支与推送章节的要求保持一致提交信息应在第一行简要描述变更例如 Fix broken icon必要时以空行分隔并附加更长的解释。文档建议的参考来源是 chris.beams.io 的 git commit 最佳实践文章原文中给出该链接。四、如何编写测试PHPUnit 与 CI 门槛FreshRSS 目前测试数量尚不算多但项目正在持续补充维护者非常感激贡献者为补丁编写测试。检查清单中的测试项就是为了鼓励大家多写测试而设立的。测试框架与工具链项目使用 PHPUnit 的require-dev部分phpunit/phpunit: ^10。此外docs/en/developers/03_Running_tests.md 进一步说明FreshRSS 还使用PHPStan静态分析、PHP_CodeSniffer代码风格检查等工具并且任何测试未通过的代码都不会被合并进edge。以仓库中的真实测试为例tests/app/Models/BooleanSearchTest.php 展示了单元测试的典型写法通过#[DataProvider]提供多组输入如空搜索串、intitle:sale、intitle:a OR intitle:b断言FreshRSS_EntryDAO::sqlBooleanSearch()生成的 SQL 与绑定参数完全符合预期从而验证布尔搜索的prepend()逻辑限制搜索而非扩大搜索。本地运行测试在开发机上用make命令即可运行整套测试cd ./FreshRSS/ make test-alltest-all目标实际依次执行 composer 相关测试PHP 语法检查、PHPUnit、PHPCS、PHPStan、npm 测试ESLint与 typos 拼写检查详见 Makefile 中的test-all: composer-test npm-test typos-test定义。一些语法、格式、空白与 i18n 约定问题可以自动修复make fix-all该命令会执行composer-fix翻译文件格式化与phpcbf自动修复以及npm-fix前端代码自动修复。在 Docker 中测试多版本 PHP某些测试需要在 Docker 镜像中运行特别是用来验证 PHP 的最低与最高版本兼容性# 准备镜像 make composer-test docker build --pull --tag freshrss/freshrss:oldest -f Docker/Dockerfile-Oldest . docker build --pull --tag freshrss/freshrss:newest -f Docker/Dockerfile-Newest . # 运行测试 docker run --rm -e FRESHRSS_ENVdevelopment -e TZUTC -v $(pwd):/var/www/FreshRSS freshrss/freshrss:oldest bin/composer test docker run --rm -e FRESHRSS_ENVdevelopment -e TZUTC -v $(pwd):/var/www/FreshRSS freshrss/freshrss:newest bin/composer test对应的两个镜像定义分别位于 Docker/Dockerfile-Oldest 与 Docker/Dockerfile-Newest。CI 自动测试在 GitHub 上打开 Pull Request 时测试会自动通过GitHub Actions运行其配置位于仓库.github/workflows/tests.yml原文给出链接。CI 的存在是为了确保你的代码不会引入回归——如果测试失败维护者不会合并 PR而是要求你先修复 bug 再进入代码评审。用快照调试 feed 问题由于 feed 数据具有易变性调试相关问题时建议使用**快照snapshot**配合 mock 服务器。具体步骤在 docs/en/developers/03_Running_tests.md 中有详细说明核心流程为创建或进入mock 服务器主目录并创建__files与mappings两个文件夹将 feed 快照复制/移动到__files文件夹在mappings文件夹创建feed.json内容如下{ request: { method: GET, urlPathPattern: /.* }, response: { status: 200, bodyFileName: {{request.pathSegments.[0]}}, transformers: [response-template], headers: { Content-Type: application/rssxml } } }启动容器化的 WireMock 服务器PORT为主机通信端口NETWORK为 Docker 网络名默认freshrss-networkdocker run -it --rm -p PORT:8080 --name wiremock --network NETWORK -v $PWD:/home/wiremock wiremock/wiremock:latest-alpine --local-response-templating之后即可直接访问 mock 文件从主机访问http://localhost:PORT/RSS从同一网络内的容器访问http://wiremock:8080/RSS。feed 快照的获取方式见 docs/en/developers/06_Reporting_Bugs.md使用wget feed url -O output.rss.txt将 feed 内容保存为文本文件后拖入 Issue 即可。写测试的合理边界文档同时提醒并非所有东西都容易测试不要在这些事情上花太多时间。遇到困难时尽管向维护者求助——这正体现了单元测试若过于困难则为可选这一检查清单项的用意。五、为什么你应该同步编写文档文档规范是 FreshRSS 协作文化的核心之一原文档给出的理由非常直白一个友好的项目应该有正确而完整的文档这样新人不至于问太多问题用户也能为自己的问题找到答案。文档不应该以后再写——因为大概率永远不会写。当前仓库的文档仍有许多可改进之处因此维护者非常欢迎贡献者参与文档建设。具体来说一个完整的 PR 应当同步考虑用户文档docs/en/users 下的使用指南、docs/en/admins 下的部署管理指南开发者文档docs/en/developers 下覆盖从环境搭建02_First_steps.md、分支与推送02_GitHub.md、运行测试03_Running_tests.md、发布新版本05_Release_new_version.md到报告 bug06_Reporting_Bugs.md的完整手册其入口为 docs/en/developers/01_Index.md多语言文档仓库还通过 docs/po4a.conf 维护法文等多语言文档版本见 docs/fr 目录。如果你修改了用户可见的行为如新增配置项、API 变化、界面改动请在 PR 中同步更新对应文档并勾选检查清单中的 documentation updated。六、一次完整贡献的流程回顾综合 docs/en/developers/02_GitHub.md 与本文档一次完整的 FreshRSS 贡献流程可以归纳为Fork 并配置远程仓库将官方仓库添加为upstream从edge拉取最新代码git checkout edge git pull upstream edge新建开发分支git checkout -b my-development-branch提交变更git add相关文件后git commit撰写符合规范动词开头、50字符主题行 72 字符正文的提交信息本地自检git show复查改动运行make test-all必要时make fix-all确保测试通过同步主线在 PR 之前用 rebase 或 merge 将edge的最新内容合入自己的分支推送并开 PRgit push推送后基于分支创建 PR按 docs/pull_request_template.md 模板填写变更说明与手动测试步骤勾选全部检查项等待 CI 与评审GitHub Actions 会自动跑测试若有失败修复后重新推送必要时为难以自动化的部分补充文档说明。整个过程的核心原则可以概括为提交信息讲清楚为什么代码必须经过验证文档永远不要留到以后——这三条守则共同保证了 FreshRSS 长期维护的稳定性也是任何想被顺利合并的 PR 必须满足的底线。【免费下载链接】FreshRSSA free, self-hostable news aggregator…项目地址: https://gitcode.com/gh_mirrors/fr/FreshRSS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表