CI中缓存~/.composer/cache常失效,根本原因非未配置,而是COMPOSER_CACHE_DIR未显式设置、路径不一致、权限不足或PHP/lock/镜像源三者不匹配。

CI里缓存 ~/.composer/cache 为什么经常失效
根本原因不是缓存没配,而是路径没对上或权限没到位。GitLab CI 默认不设 COMPOSER_CACHE_DIR,即使你在 cache: 块里声明了 ~/.composer/cache,Composer 仍会写进默认位置(比如 /root/.composer/cache),导致缓存未命中。
常见失效点:
-
cache:声明的路径和COMPOSER_CACHE_DIR不一致 - PHP 进程用户(如
www-data或gitlab-runner)对缓存目录无写权限 - CI 作业没挂载持久卷,每次都是全新容器,
~/.composer/cache每次清空 - 全局配置里残留了
cache-dir,和cache-files-dir冲突
解决办法:在 before_script 或 job 级 variables 中显式设 COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.composer-cache",再让 cache: 块指向同一路径。
GitHub Actions 缓存 key 怎么写才不翻车
key 写错一个字符,缓存就完全不复用。关键不是“看起来像”,而是三要素必须同时满足:
- 必须包含
composer.lock的哈希值——不能只用**/composer.json - 要带上 PHP 版本,不同版本可能触发不同 dist 包解析逻辑
- 避免用
github.sha,它每 commit 都变,缓存形同虚设
推荐写法:
key: ${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
验证是否生效:看日志里有没有 Cache hit;如果一直 Cache miss,先检查 hashFiles('**/composer.lock') 是否真能读到文件(路径是否被 actions/checkout 拉下来了)。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
要不要缓存 vendor 目录本身
缓存 vendor/ 看起来快,但实际风险高、适用场景窄:
- 分支频繁变动时,
composer.lock一改,缓存直接失效,还可能混入旧包 - 不同 PHP 版本下生成的
autoload_classmap.php不兼容,缓存跨版本复用会报错 - CI 脚本里漏了
--no-dev或--optimize-autoloader,缓存的vendor/就不是你想要的状态
更稳妥的做法是只缓存 ~/.composer/cache,然后每次跑 composer install --no-dev --prefer-dist --optimize-autoloader。这样既复用 zip 包,又保证 autoload 和 classmap 是当前环境生成的。
离线 CI 构建必须配 cache-files-dir
CI 服务器断网时,只有 files/ 子目录下的 zip 包能被 --prefer-dist 直接读取。其他路径(如 repo/、vcs/)里的元数据全失效。
正确做法分三步:
- 先清掉旧配置:
composer config --global --unset cache-dir - 设专用路径:
composer config --global cache-files-dir /path/to/offline-cache - 触发下载:
composer install --no-autoloader --no-scripts --prefer-dist
验证是否成功:检查目标路径下是否存在类似 monolog/monolog/2.10.0.0/monolog-monolog-6a8c4b5.zip 的结构。漏掉这一步,所谓“离线构建”只是幻想。

















