必须缓存 ~/.composer/cache 而非 vendor/,因前者存储下载的 zip/tar 包和 VCS 克隆副本,后者仅为软链接结果;只缓其一将导致重复下载或构建缓慢,正确配置需匹配 OS、PHP 版本及 composer.lock 哈希。

缓存路径必须是 ~/.composer/cache,不是 vendor/
GitHub Actions 里缓存 Composer 依赖,真正该缓存的是 ~/.composer/cache,不是 vendor/。前者存下载好的 zip/tar 包和 VCS 克隆副本,后者只是软链接或复制结果。只缓 vendor/ 会导致每次 composer install 都重下所有包;只缓全局 cache 而不配对恢复,则 vendor/ 构建仍慢。
常见错误现象包括:
-
Cloning into '/tmp/composer-cache/vcs/xxx'报错用户名为空(Git 凭据缺失) - 日志里反复出现
Downloading xxx.zip,但缓存动作显示 “Cache restored” - CI 时间稳定在 2–5 分钟,没降到 20–40 秒
正确做法:
- 缓存路径写死为
~/.composer/cache(Linux/macOS)或%USERPROFILE%\AppData\Roaming\Composer\Cache(Windows),不要用相对路径或./cache - 确保
setup-php动作已执行,否则~/.composer/cache目录可能不存在或权限异常 - 缓存动作必须放在
composer install之前,且不能被跳过(比如条件判断误关)
缓存 key 必须包含 OS、PHP 版本、composer.lock 哈希
光用 ${{ hashFiles('**/composer.lock') }} 不够。Composer 缓存实际受 PHP minor 版本(如 8.2.x)、操作系统、甚至 platform 配置隐式影响。key 缺任何一项,都可能命中“看似成功、实则失效”的缓存。
推荐 key 写法:
key: ${{ runner.os }}-php-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
注意:
- 如果用了
matrix矩阵测试多个 PHP 版本,matrix.php-version必须和setup-php的php-version一致 -
composer.json也建议加入哈希:${{ hashFiles('**/composer.json') }},防止 lock 文件未更新但配置变更(如config.platform.php)导致兼容问题 - 不要用
runner.version或时间戳——它们会让缓存永远不命中
镜像源要在 composer install 前设置,不能只改全局配置
国内用户常配阿里云或腾讯云镜像,但在 GitHub Actions 中,仅运行 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 是无效的。因为 actions/cache 恢复的是二进制包缓存,不是配置;且 CI runner 是干净环境,每次启动后配置会被重置。
安全可靠的做法是:
- 用
COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/composer/环境变量覆盖(推荐) - 或在
composer install命令中加--repository=https://mirrors.aliyun.com/composer/参数(注意:该参数仅限 Composer 2.5+) - 避免修改
auth.json或全局 config,容易因权限或路径引发Could not fetch错误
如果项目有私有包,镜像必须配合 token 使用:
COMPOSER_AUTH: '{"http-basic":{"packagist.example.com":{"username":"${{ secrets.PACKAGIST_USER }}","password":"${{ secrets.PACKAGIST_TOKEN }}"}}}'
缓存没生效?先查这三件事
看到 Cache not found for input keys 不代表失败,但若每次都这样,说明缓存根本没写入或 key 总不匹配。
立刻检查:
-
composer.lock是否真的提交到了仓库?空文件或 .gitignore 误删会导致哈希恒为空字符串 -
setup-php步骤是否成功?失败则~/.composer/cache目录不会创建,后续缓存动作静默跳过 - 有没有在
composer install前漏设COMPOSER_CACHE_DIR=~/.composer/cache?虽然 Composer 默认会读这个路径,但显式声明能避免某些 runner 权限异常
最隐蔽的坑是:PHP patch 版本升级(如从 8.2.10 升到 8.2.12)导致缓存 key 不一致——所以固定 matrix.php-version: '8.2' 比写 '8.2.x' 更稳。


















