Skip to main content

开发协作与跨仓库构建

聚合仓库 SDUOJ/sduoj 只记录子仓库版本。应用代码在对应子仓库修改,通用文档放在 OnlineJudge。下文按维护分支的现有链路组织;具体技术版本以该仓库的声明和锁文件为准。

仓库与边界​

聚合目录维护分支职责
OnlineJudgemain产品说明、文档与 Issue Tracker
sduoj-servermaster后端服务与 common/interface Maven 包;实际仓库为 sduoj-server-private
sduoj-web2master用户、管理、考试 SPA
sduoj-judgermasterMQ 消费、编译、评测与结果回报
sduoj-sandboxmasterC 沙箱、seccomp 与输出协议
judging-containersmaster语言运行时和 sandbox 工具链镜像
sduoj-deploymiddlewaresCompose、环境模板与迁移资源

AutoLab 是独立 Python 扩展,尚未列入聚合仓库的子模块。涉及题单上下文或首页入口时,应同时记录它的源码版本、接口与制品,不能认为一个聚合 SHA 已锁定全部运行进程。

开始工作​

git clone [email protected]:SDUOJ/sduoj.git
cd sduoj
git submodule update --init --recursive
git submodule status

先检查目标仓库的工作区和分支。子模块初始化可能处于 detached HEAD,开发前应从明确基线建立需求分支。保留他人的未提交内容。不要通过全量 remote update 顺带升级无关模块。

API 与 UI 功能沿 server 的 interface/service 和 web2 的 API 封装实现。评测行为沿 judger 的 handler、manager、command 实现。filesys 保持 Kotlin/WebFlux;服务间复用已有 Feign、MQ、会话和角色模型。

产品功能不应改写构建链。禁止 composite/includeBuild、消费者 CI 额外 checkout 后端源码、复制 sandbox 补丁到 judger、临时更换镜像标签或 --scan 行为。SQL、sandbox/JSON 协议、认证、Gateway filter 和真实凭据的修改,按根目录 AGENTS 先提出具体方案并取得同意。基础设施问题单独处理。

本地依赖:server → MavenLocal → judger​

使用 Java 17 和各仓库自带 Gradle wrapper。确认 server、judger 的 Versions.sduoj 相同。先在 server 执行:

./gradlew test buildJar --scan
./gradlew \
:sduoj-common:sduoj-common-entity:publishToMavenLocal \
:sduoj-common:sduoj-common-util:publishToMavenLocal \
:sduoj-common:sduoj-common-rpc:publishToMavenLocal \
:sduoj-common:sduoj-common-mq:publishToMavenLocal \
:sduoj-user:sduoj-user-interface:publishToMavenLocal \
:sduoj-problem:sduoj-problem-interface:publishToMavenLocal \
:sduoj-filesys:sduoj-filesys-interface:publishToMavenLocal

随后在 judger 执行 ./gradlew build --scan。新增第一方传递依赖时,使用其已有发布任务补齐。记录本地包的源码 SHA、坐标和校验值,避免误用同名旧 SNAPSHOT。需要隔离本地 Maven 仓库时,两边使用相同的 -Dmaven.repo.local=绝对路径。

CI 由 server 原有 Publish package 工作流发布到 GitHub Packages,judger 从包仓库消费。先发布接口包,再验证消费者能在没有本地开发包的环境中解析它。源码读写权限与 Packages 权限分别检查;不要通过新增源码读取 token 替代包发布。

工具链:sandbox → judging-containers → judger​

judger Dockerfile 从既有 GHCR 工具链镜像复制 /opt,不编译 sandbox。工具链通过 judging-containers 对应的手动工作流构建,传入原有版本参数,验收 amd64/arm64 后再构建 judger。

sandbox 安装脚本下载 GitHub master,不读取聚合仓库的 sandbox pin。更新 pin 不代表生产二进制更新。记录实际源码与镜像 digest,并在最终 judger 镜像内验证 CLI、JSON 和所需系统调用。发现旧工具链缺能力时,保持功能关闭,沿生产者流程处理;不要在消费者内再维护一份补丁。

提交与推送​

一个提交聚焦一个可说明、可审查的目的。合同、实现、迁移、兼容修复、指标和清理可按依赖拆开;不要给一个包含多项业务功能的提交统一贴 IDE 标签。已经共享的历史使用后续修正,不为重排而强推。

先在相关子仓库提交,提交信息用英文;再按一个需求一次对齐整组 gitlink,不逐个随意 bump。关联的 SQL、配置开关与独立扩展版本同时写入发布清单。

获准实际 push 后,每个仓库 push 前执行 git pull --rebase,解决冲突并复核受影响验证。先推子仓库,确认远端存在引用 SHA,再更新和推聚合仓库。rebase 改变 SHA 时必须重新对齐父引用。没有明确授权不 push,不强推。

构建失败先走上述原链诊断。仍缺包、权限或工具链时,报告具体失败与所缺制品,停止依赖它的步骤;不要扩大产品改动范围。

本地启动见本地开发,交付与回退见发布和运维。