ci中composer.lock冲突不能自动修复,必须先用git checkout --theirs composer.json确保composer.json无冲突,再运行composer update --lock重建合法锁文件,输出应为“0 installs, 0 updates, 0 removals”,否则说明json未对齐需中断构建。

不能自动修复,也不该让它尝试修复。 CI 构建阶段出现 composer.lock 冲突,说明 Git 合并没完成、composer.json 还没对齐,此时任何 composer install 都会失败或跳过关键校验——它不是修复工具,是执行器。
为什么 CI 里跑 composer install 无法解决 lock 冲突
Git 合并冲突残留的 标记会让 <code>composer.lock 变成非法 JSON,composer install 直接报 JSON decode error: Syntax error 并退出。即使你用脚本删了标记,顺序错乱、缩进变动、字段缺失也会导致后续哈希校验失败,出现 Package xyz has a mismatched hash 或静默装错子依赖。
-
composer install不读composer.json做决策,只按 lock 文件还原 vendor —— 它不关心冲突,只关心 lock 能不能解析、内容是否匹配 - CI 环境通常 clean(无旧
vendor/),一旦 lock 文件损坏,composer install既不能 fallback,也无法“猜”出正确版本 - 加
--no-interaction或--ignore-platform-reqs只是掩盖问题,不是修复;线上可能因扩展缺失或 PHP 版本不匹配直接报Class not found
CI 构建前必须确保 composer.json 已 clean
所有修复动作必须在 Git 层完成,不能甩给 Composer。CI 脚本本身不该承担合并逻辑。
- 用
git status --porcelain | grep "composer\.json"检查composer.json是否还有未解决冲突;若有,构建应立即失败 - 推荐统一策略:
git checkout --theirs composer.json(取远端版本)或git checkout --ours composer.json(取当前分支),再人工核对变更是否合理 - 禁止在 CI 脚本里写
git merge origin/main || true这类忽略错误的命令——它会让冲突进入构建流程,后果不可控
CI 中唯一合法的 lock 修复动作:composer update --lock
只有当 composer.json 已 clean、composer.lock 仍报冲突(比如 rebase 后 lock 被删或损坏),才在 CI 中运行该命令。但它不是“自动修复”,而是重建契约。
- 必须前置条件:
composer.json已无冲突,且composer validate --strict通过 - 运行
composer update --lock后,检查输出是否为Lock file operations: 0 installs, 0 updates, 0 removals;若出现大量Updating xxx,说明composer.json实际还没对齐,CI 应中断 - 生成新
composer.lock后,**不要直接继续 install**;先git add composer.lock && git commit -m "ci: fix lock after rebase",再触发下一轮构建——否则下次拉代码又会冲突
真正该在 CI 里做的预防动作
靠修复不如靠防。CI 是检验协作规范的最后一道闸,不是补漏的垃圾桶。
- 加
composer validate --strict:检测composer.json格式、字段合法性,以及 lock 文件是否存在但未提交 - 加
composer install --dry-run:验证 lock 是否能被完整解析、所有包 dist URL 是否可达、哈希是否可校验——失败即阻断 - 启用
"config": {"lock": true}(Composer 2.2+):强制所有composer install行为都校验 lock 完整性,提前暴露篡改或损坏 - 禁止
composer update出现在 CI 脚本中;所有依赖升级必须走 PR +composer.json+composer.lock一起提交
最常被忽略的一点:CI 构建失败时,错误日志里出现 content-hash mismatch 或 require-dev section changed,往往不是 lock 文件坏了,而是有人在本地改了 composer.json 却忘了 composer update --lock,然后直接推了——这时候修 lock 不解决问题,得回溯谁绕过了流程。











