composer install –dry-run 会报错说明 lock 文件过期:它校验 composer.json 与 composer.lock 是否一致,若缺失依赖、版本不匹配或 hash 错误则失败,且需在根目录执行、vendor 清空。

composer install –dry-run 会报错说明 lock 文件过期
CI 中最直接的检测方式,就是用 composer install --dry-run。它不写文件、不下载包,只校验 composer.json 和 composer.lock 是否一致:如果 lock 文件缺失依赖、版本不匹配或 hash 不对,命令会立即失败并输出类似 Your lock file does not contain the required package "monolog/monolog" 或 The lock file is not up to date with the latest changes in composer.json 的错误。
这个命令本质是复现 install 流程但跳过写入,所以快、准、无副作用。
- 必须在项目根目录执行,且确保
vendor/不存在或已清空(否则可能绕过校验) - CI 中建议加
--no-interaction --no-ansi --no-progress避免干扰输出 - 某些旧版 Composer(–dry-run 支持不稳定,推荐升级到 2.x
diff -q composer.json composer.lock 不可靠
单纯比对两个文件内容差异(比如用 diff -q)完全无效——composer.lock 是生成的二进制友好 JSON,含哈希、平台信息、依赖树结构,和 composer.json 的语义完全不对应。改一行 PHP 版本要求,lock 文件可能重排整个 packages 数组,diff 必然报不同,但实际没破同步关系。
-
composer.json变更后必须运行composer update或composer install才能生成新 lock - 手动编辑
composer.lock属于高危操作,CI 应该拒绝这种“伪同步” - 真正要检测的是“锁是否反映当前 json 声明”,不是“文本是否相似”
CI 脚本里怎么写才稳?
一个健壮的检查脚本核心就三步:清理环境 → 干跑安装 → 捕获退出码。不需要解析 JSON、不依赖外部 diff 工具。
rm -rf vendor composer.lock composer install --dry-run --no-interaction --no-ansi --no-progress
如果上一步返回非 0,说明 lock 缺失或过期;如果返回 0,说明当前 composer.json 理论上可被现有 lock 完全满足(注意:这不代表 lock 本身合法,只是和 json 同步)。
- 务必先删
vendor/和composer.lock,否则--dry-run可能误判(例如 lock 存在但 vendor 已删,它会尝试重建 lock) - 若项目允许 dev 依赖参与校验,加
--with-all-dependencies;否则默认只校验 require - Git CI 中常把
composer.lock提交进仓库,所以检查前别用git checkout -- composer.lock这类操作覆盖本地 lock
为什么不用 composer validate?
composer validate 只检查 JSON 格式、schema 合法性、字段拼写等,完全不涉及 composer.json 和 composer.lock 的同步关系。它可能对一个严重过期的 lock 文件返回 OK,因为 lock 本身格式没问题。
-
composer validate --strict会检查 license 字段、homepage 等,仍不碰同步逻辑 - 真正要问的是“我改了 json,lock 跟上了吗”,只有
--dry-run能回答这个问题 - 有些团队用
composer show --outdated辅助判断,但它查的是远程包版本,不是本地 lock 同步状态
实际跑起来,最易忽略的是 vendor 目录残留和 Composer 版本差异——CI 镜像里装的 Composer 小版本不一致,可能导致 --dry-run 在本地通、CI 上挂,尤其跨 1.x / 2.x 时。