CI中必须用composer install而非update,因其严格按已提交的composer.lock还原精确版本、顺序与依赖树,确保构建可重现;update会重算依赖、生成新lock,绕过代码审查引发BC break或Fatal error。

CI/CD 里为什么 composer install 会装错版本
根本原因就一个:命令没用对,或者锁文件没到位。CI 流水线里跑 composer update,等于主动放弃锁定——它会重新解析整个依赖图,哪怕你 composer.json 里写的是 "monolog/monolog": "2.9.1",update 也可能把它升到 2.9.2 或降级连带影响其他包。composer install 才是唯一读 composer.lock 的命令,但它有个硬前提:composer.lock 必须存在、已提交、且没被 .gitignore 掉。
流水线脚本必须写的三件事
不是“加上 lock 文件”就行,得确保它在正确时间、以正确方式参与构建:
- 第一步检查:
ls -la composer.lock,确认文件存在且不是空的;CI 报content-hash mismatch就说明composer.json和composer.lock对不上,别跳过警告 - 安装命令固定为:
composer install --no-dev --no-interaction --no-progress --optimize-autoloader;--no-lock绝对禁止出现,它会让install退化成update - 上线前加保险:
composer install --locked,它会校验composer.lock中每个包的版本是否仍满足composer.json的约束,不满足直接报错退出,不让你带着漂移版本上线
为什么不能在 CI 里跑 composer update
composer update 不是“更新安全补丁”的快捷键,它是全量重算依赖树的高风险操作。哪怕只改一行 composer.json,它也可能把 symfony/http-foundation 从 6.4.10 升到 7.0.0-RC1,或把 phpunit/phpunit 从 9.6.15 拉到 10.0.0-alpha。CI 流水线的目标是可重现,不是尝鲜。
真正该做的只有两件事:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 安全审计走
composer audit --fail-on-warnings,发现 CVE 就让构建失败,逼人去手动修复composer.json+update vendor/package - 紧急修复时,本地执行
composer update monolog/monolog(只更新单个包),立刻提交composer.json和composer.lock,CI 自然跟着走新版本
最容易被忽略的 platform 兼容性陷阱
composer.lock 里存着 "platform": {"php": "8.2.15"},但你的 CI 节点跑的是 PHP 8.1 —— 这时候 composer install 会直接失败,报错不是“找不到包”,而是“platform requirement mismatch”。很多人以为是 lock 文件坏了,其实是环境 PHP 版本和锁文件声明不一致。
解决方法不是升级 PHP,而是提前在 composer.json 的 config.platform 字段声明目标环境:
"config": {
"platform": {
"php": "8.1.0"
}
}
这样生成的 composer.lock 就会按 8.1 做兼容性判断,CI 跑起来才不会突然中断。

















