默认 actions/cache 对 Composer 缓存易失效,因 Composer 缓存键隐式依赖 PHP 版本、platform 配置等,而 actions/cache 仅按指定 key 判断;正确做法是固定 PHP minor 版本、用 hashFiles('**/composer.lock') 作 key、缓存 ~/.composer/cache 并加 --no-interaction --prefer-dist --optimize-autoloader。

为什么默认的 actions/cache 对 Composer 缓存容易失效?
直接用 composer install 前缓存 ~/.composer/cache 目录看似合理,但实际 CI 中常命中失败。根本原因是:Composer 的缓存键不仅依赖 composer.lock 内容,还隐式受 PHP 版本、平台配置(如 platform-check)、插件行为影响。GitHub Actions 的 actions/cache 默认只按你提供的 key 判断,一旦 PHP minor 版本升级(如 8.2.10 → 8.2.12)或 composer.json 中 config.platform.php 变更,缓存就不可复用,却仍被“成功恢复”——导致后续 install 重装全部包,白费时间。
正确做法:用 composer install --no-interaction --prefer-dist --optimize-autoloader + 锁文件哈希作缓存 key
必须把缓存 key 绑定到真正决定依赖树的内容上:即 composer.lock 的内容哈希,且确保 PHP 环境稳定。推荐组合:
- 固定 PHP minor 版本(如
php-version: '8.2'),避免 patch 升级触发缓存失效 - 用
hashFiles('**/composer.lock')生成 key,比单纯用composer.lock时间戳更可靠 - 缓存目录设为
~/.composer/cache,这是 Composer 默认查找路径 - 务必加
--no-interaction --prefer-dist --optimize-autoloader,否则缓存可能被跳过或降级为源码安装
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: composer
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: ${{ runner.os }}-php-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
- name: Install dependencies
run: composer install --no-interaction --prefer-dist --optimize-autoloader遇到 Cache not found for input keys 还是慢?检查三个硬性条件
这个提示不等于失败,但若每次都是“not found”,说明缓存从未写入或 key 不一致。常见原因:
-
composer.lock文件未提交到仓库——CI 拉取的是空锁文件,哈希永远是空字符串 - workflow 中用了
strategy.matrix但 key 里漏了matrix.php-version,导致不同 PHP 版本共用一个缓存路径,互相污染 - 本地开发时执行了
composer update但没提交新composer.lock,CI 用旧 lock 哈希查缓存,而上次缓存是用新 lock 写的,自然找不到
进阶:多项目共享缓存(如 monorepo)需额外处理 vendor/
如果项目结构含多个子目录各自有 composer.json(如 packages/foo/composer.json),不能只靠全局 ~/.composer/cache。此时应:
- 为每个子目录单独设置 cache step,key 包含子路径和对应 lock 文件哈希
- 避免在 root 执行
composer install,改用cd packages/foo && composer install - 慎用
composer install --global,它会绕过项目级缓存逻辑,且权限易出错
最麻烦的其实是 lock 文件变更频率——只要它一动,整个缓存就失效。所以别为了“省几秒”频繁 update,稳住 lock 才是提速核心。










