为 RomM 贡献代码:从 AI 披露规范到 PR 合并的完整开源协作指南
2026/9/15 17:05:02 网站建设 项目流程

为 RomM 贡献代码:从 AI 披露规范到 PR 合并的完整开源协作指南

【免费下载链接】rommA beautiful, powerful, self-hosted ROM manager and player.项目地址: https://gitcode.com/GitHub_Trending/rom/romm

RomM 是一个美观、强大、可自托管的 ROM 管理与游玩平台,采用 AGPL-3.0 许可,由 FastAPI(后端)与 Vue 3(前端)构成。本文以仓库根目录的 CONTRIBUTING.md 为骨架,结合 DEVELOPER_SETUP.md、.trunk/trunk.yaml、pyproject.toml 与.github/workflows/下的真实 CI 工作流,为你完整梳理一条从"提 Issue"到"PR 被合并"的贡献路径:包括颇具特色的 AI 辅助披露政策、本地化翻译的工程化检查、开发环境搭建、编码规范与测试要求,让你在提交第一个 PR 前就对项目期望了然于胸。

一、贡献前必读:行为准则与 AI 辅助披露

1.1 行为准则(Code of Conduct)

RomM 遵循 Contributor Covenant 行为准则,完整条款见 CODE_OF_CONDUCT.md。凡是参与项目(包括 Issue、PR、讨论区)即视为同意遵守该准则。准则明确将"分享受版权保护的 ROM 文件、讨论如何盗版 ROM、发布下载链接"列为不可接受行为——这一点对 ROM 管理项目尤为重要。违规行为可通过<community@romm.app>向社区负责人举报,社区负责人依据 Correction(私下书面警告)、Warning(限时隔离)、Temporary Ban(临时封禁)、Permanent Ban(永久封禁)四级阶梯处理。

1.2 AI 辅助披露:必须写进 PR 的硬性要求

这是 RomM 贡献规范中最具特色的一条,值得所有依赖 AI 编码的开发者特别注意:

使用任何形式的 AI 辅助参与 RomM 贡献,都必须在 Pull Request 中披露,并说明 AI 的使用程度(例如仅用于文档,还是用于代码生成)。如果 PR 的回复也由 AI 生成,同样需要披露。唯一的例外是微不足道的自动补全(tab-completion)无需披露。

官方给出的披露示例:

> This PR was written primarily by Claude Code.

或更详细的版本:

> I consulted ChatGPT to understand the codebase but the solution > was fully authored manually by myself.

披露不是走形式——文档明确指出,隐瞒 AI 使用对 PR 另一端的人工维护者是不礼貌的,也会让维护者难以判断该对该贡献投入多少审查力度。项目方的态度是:在理想世界里 AI 辅助能产出与人类同等或更高质量的工作,但现实并非如此,多数情况下 AI 产出质量堪忧,因此请对维护者保持尊重并如实披露。

1.3 大改动先沟通

如果你打算实现大型功能或对项目做显著改动,规范要求:先开一个 Issue,并加入 Discord 与维护者讨论想法,避免做无用功。

二、贡献文档与本地化翻译

2.1 文档贡献

项目官方文档托管在独立仓库(docs.rommapp.dev 对应 rommapp/docs),想改进文档的贡献者应直接向该文档仓库提交 PR,欢迎新页面、更新与勘误。仓库根目录的 AGENTS.md、CLAUDE.md 等文件则面向代码仓库内的协作场景。

2.2 新增语言翻译

如果想把项目翻译成新语言,规范给出的路径是:在frontend/src/locales下创建新语言文件夹,以现有语言文件为模板,完成后开 PR 合入。

从仓库源码看,这一过程已被工程化,不只是"复制粘贴":

  • 目录结构frontend/src/locales下已有en_USzh_CNja_JPde_DEfr_FR等 20 个语言目录(含en_GBen_US两个英语变体),每个语言目录内按功能命名空间拆分为多个 JSON 文件,如common.jsonlogin.jsonsettings.json等,与英文基准一一对应。
  • 加载机制:frontend/src/locales/index.ts 使用import.meta.glob按命名空间懒加载语言包,en_US是回退语言(FALLBACK_LOCALE),并内置了如cs_CZ的复数规则处理。
  • CI 自动校验:工作流 .github/workflows/i18n.yml 在 PR 涉及frontend/src/locales/**/*.json时自动运行两个 stdlib-only 检查脚本:
    • check_i18n_locales.py:对照en_US检查每个语言目录是否缺文件、缺 key,缺项会打印出来并让检查失败;
    • check_i18n_sorted.py:确保所有 locale JSON 的 key 按字母序排列(嵌套对象同样递归检查),与 Prettier 格式对齐(2 空格缩进、保留 Unicode、结尾换行);传入--fix可自动重写乱序文件。

因此,提交翻译 PR 前请先本地运行这两个脚本自检,避免 CI 红叉。

三、代码贡献完整工作流

CONTRIBUTING.md 给出了 8 步标准流程:

  1. Fork仓库到自己的账号。
  2. Clone你的 fork。
  3. Checkoutmaster分支(主线分支)。
  4. 按照 DEVELOPER_SETUP.md 完成开发环境搭建(下文第四节详述)。
  5. 为功能/修复创建新分支git checkout -b feature-or-fix-name
  6. 修改并用描述性提交信息提交:git commit -am 'Add feature XYZ'
  7. 推送到你的 fork:git push origin feature-or-fix-name
  8. 向原仓库的master分支开 Pull Request

注意第 5 步的分支命名习惯(feature-or-fix-name)与第 6 步的提交信息要求,这是后续 review 与 CI 顺畅通过的基础。

四、开发环境搭建(DEVELOPER_SETUP.md 详解)

贡献代码前必须先跑通环境。仓库提供了Docker 一键手动两种方式,二者共用同一套 mock 目录与.env

4.1 通用环境准备

两种方式都从准备 mock 目录开始:

mkdir -p romm_mock/library/roms/switch touch romm_mock/library/roms/switch/metroid.xci mkdir -p romm_mock/resources mkdir -p romm_mock/assets mkdir -p romm_mock/config touch romm_mock/config/config.yml

然后复制环境变量模板并填写:

cp env.template .env

开发模式的最小配置:

ROMM_BASE_PATH=/app/romm DEV_MODE=true

4.2 Option 1:Docker 方式

docker compose build # 或 --no-cache 从零重建 docker compose up -d

启动后访问http://localhost:3000,得益于卷挂载,代码改动会自动热更新到应用。另外两个可选堆栈各自独立成文件,均加入开发网络的网络,需先启动主栈:

docker compose -f docker-compose.oidc.yml up -d # Authentik,用于 OIDC 开发 docker compose -f docker-compose.streaming.yml up -d # webstation,用于串流开发

Authentik 监听http://localhost:9001,通过.env中的OIDC_*变量指向;webstation 镜像仅 amd64 且体积达数 GB,从romm_mock/webstation读取模拟器配置与 BIOS,其BROKER_SECRET跟随.envSTREAMING_BROKER_SECRET

4.3 Option 2:手动方式

先装系统依赖(RAHasher 用于计算 RetroAchievements 哈希,macOS 用户可跳过):

sudo apt install libmariadb3 libmariadb-dev libpq-dev git clone --recursive https://github.com/RetroAchievements/RALibretro.git cd ./RALibretro git checkout 1.8.3 git submodule update --init --recursive make HAVE_CHD=1 -f ./Makefile.RAHasher cp ./bin64/RAHasher /usr/bin/RAHasher

Python 侧使用uv管理(pyproject.toml 要求requires-python = ">=3.14"):

curl -LsSf https://astral.sh/uv/install.sh | sh uv venv source .venv/bin/activate uv sync --all-extras --dev

启动数据库与中间件后运行后端(迁移会在启动时自动执行):

docker compose up -d cd backend uv run python3 main.py

前端(需要 npm >= 9,详见 frontend/package.json 中的dev/build等脚本):

cd frontend npm install mkdir assets/romm ln -s ../romm_mock/resources assets/romm/resources ln -s ../romm_mock/assets assets/romm/assets npm run dev

4.4 Linter:Trunk

项目统一用 Trunk 做 lint,一份配置管理多种 linter:

curl https://get.trunk.io -fsSL | bash trunk fmt trunk check

注意:不安装并运行 linter 会导致 CI 检查失败,PR 将无法合并。

从 .trunk/trunk.yaml 可见,Trunk 已启用并编排了ruffblackisortmypybanditeslintprettiermarkdownlinthadolintshellcheckyamllinttrufflehogcheckovtrivygrype等一整套工具,运行时的 Python 版本同样固定为 3.14.4。同时配置了合理的豁免:自动生成的frontend/src/__generated__/**、被 vendor 的backend/utils/rom_patcher/patcher.js、故意格式错误的测试 fixture 等路径跳过全部 linter;冻结的 v1 UI(frontend/src/views|components|console|layouts/**/*.vue)跳过 ESLint;backend/alembic/**跳过 mypy。Trunk 在 pre-commit 自动执行trunk fmt,并配置了trunk-announcetrunk-upgrade-available

前端侧独立的 frontend/eslint.config.js 还启用了eslint-plugin-vuevuejs-accessibility,关注 Vue 模板的可访问性。

五、测试:本地必过、CI 双数据库矩阵

5.1 本地测试

先用 root 用户初始化测试库(沿用 backend/romm_test/setup.sql):

docker exec -i romm-db-dev mariadb -uroot -p<root password> < backend/romm_test/setup.sql

运行测试(迁移同样会自动执行;可传路径或文件只跑子集):

cd backend uv run pytest [path/file] uv run pytest -vv # 全量,-vv 提高输出详细度

测试所需的全部环境变量由 backend/pytest.ini 注入,包括 MariaDB 连接、各刮削服务 API Key 占位、DEV_MODE=false等;asyncio_mode = auto意味着异步测试无需手动标记。后端测试依赖(pytest、pytest-asyncio、pytest-cov、pytest-mock、pytest-recording、pytest-xdist、hypothesis、fakeredis)定义在 pyproject.toml 的testextra 中。仓库的backend/tests/下覆盖了从适配器、处理器到端点、任务、迁移的完整测试体系。

5.2 CI 中的测试矩阵

工作流 .github/workflows/pytest.yml 展示了项目对测试的认真程度:

  • 在 PR(涉及backend/**pyproject.tomluv.lock等)与 master push 时触发;
  • 双数据库矩阵:同时针对mariadb:12.3.3postgres:18跑全量测试,另起valkey:9.0.6作为 Redis 兼容服务,保证两个后端驱动都健康;
  • 实际命令使用 pytest-xdist 并行(-n 4)、--maxfail=10、输出 JUnit XML 与覆盖率报告,并针对 MariaDB 为每个 worker 数据库授权。

此外 .github/workflows/trunk-check.yml 在每次 PR 上跑 Trunk Check 并回贴注解;.github/workflows/i18n.yml 在 locale 文件变更时校验翻译完整性;还有frontend.ymle2e.yml(Playwright)、typecheck.ymlvue-tsc)、migrations.yml等构成完整 CI 网。发布构建(.github/workflows/build.yml)要求 tag 符合严格 SemVer 格式x.y.z(可带-alpha.N/-beta.N/-rc.N后缀),并在 amd64 与 arm64 两个原生 runner 上分别构建后合并为多架构镜像。

六、Pull Request 指南与编码风格

提交 PR 前请对照以下要求自查:

  • 代码符合项目编码标准;
  • 本地已测试(含新功能的测试用例,并保证既有测试全部通过);
  • 必要处更新文档;
  • PR 标题与描述清晰、有描述性;
  • 若使用了 AI 辅助,按第一节要求如实披露。

编码风格方面,跟随项目既有风格即可。使用 VSCode 等编辑器时,建议安装官方推荐的扩展:Prettier、Python、Pylance、Ruff、Vue - Official(Volar)。这些工具与上文 Trunk 中的 prettier/ruff/eslint 配置一一对应,能让你在本地就把 CI 要求提前满足。

七、Issue 报告

遇到 bug 或有改进建议,在 GitHub 上创建 Issue,并尽可能提供详细信息,包括可复现步骤。描述充分、能稳定复现的 Issue 是维护者定位问题的第一手材料,也是你贡献的起点。

八、许可协议

向 RomM 贡献即表示你同意贡献以项目 LICENSE(GNU Affero General Public License v3,AGPL-3.0)授权,参见 pyproject.toml 中license = "AGPL-3.0-only"的声明。这意味着你的代码将与项目以同样的开源条款向社区开放。

结语

RomM 的贡献流程并不复杂,但"门槛"设置得很清晰:AI 辅助必须披露、Trunk lint 不过不合并、pytest 双数据库矩阵全绿、翻译必须过 i18n 检查。对贡献者而言,这恰恰是最友好的保障——只要按 DEVELOPER_SETUP.md 搭好环境、在本地把 .trunk/trunk.yaml 与 pytest 跑通,再如实填写 PR 描述,你的代码就有很大概率顺利进入这个 AGPL-3.0 的开源项目。祝贡献愉快!

【免费下载链接】rommA beautiful, powerful, self-hosted ROM manager and player.项目地址: https://gitcode.com/GitHub_Trending/rom/romm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询