ci/cd 中 composer install 失败主因是环境未配置:需先 checkout 代码并指定工作目录,安装 php 扩展,确保 composer.json/lock 存在,且必须使用 --no-dev --optimize-autoloader --classmap-authoritative --no-interaction 参数组合。

CI/CD 里直接写 composer install 会失败,不是网络问题
根本原因是 GitHub Actions、GitLab CI 等 runner 默认不切换工作目录,也不预装 PHP 扩展。你看到的 Could not open input file: composer.json 或 ext-zip missing,90% 都是环境没配对,不是包源挂了。
- 必须先用
actions/checkout@v4(或等效步骤)拉取代码,再显式cd ${{ github.workspace }}或统一加working-directory: ${{ github.workspace }} - Ubuntu runner 不自带
ext-zip、ext-xml、ext-mbstring,得用shivammathur/setup-php@v2显式启用,否则composer install启动就退出 -
composer.json和composer.lock必须存在且可读——CI 日志开头加ls -la是最快验证方式
composer install 必须带的三个参数缺一不可
漏掉任何一个,线上类加载大概率出错,缓存命中率暴跌,甚至出现 Class not found 且查不到原因。
-
--no-dev:跳过require-dev里的包(如 phpunit、infection),避免把测试工具打进生产包 -
--optimize-autoloader:生成vendor/composer/autoload_classmap.php,类加载不再扫描文件,提速 50%+ -
--classmap-authoritative:强制 Composer 完全信任 classmap,不 fallback 到文件系统查找——这是防止线上Class not found的最后一道防线
正确写法:composer install --no-dev --optimize-autoloader --classmap-authoritative --no-interaction。别省 --no-interaction,CI 环境卡在交互提示上等于构建失败。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
钩子脚本(如 post-install-cmd)在 CI 里默认不执行
不是配置错了,是 Composer v2+ 的安全策略:CI 环境默认设 COMPOSER_DEV_MODE=0,所有钩子被静默禁用。指望它自动清缓存、生成配置,基本等于没写。
- 不要依赖
post-install-cmd自动触发——它在 CI 中不可靠 - 把关键操作(如
php artisan config:cache)抽成独立脚本名,比如"scripts": { "deploy:cache": "php artisan config:cache" } - 在 CI 步骤中显式调用:
composer run-script deploy:cache --no-dev,这样不受钩子开关影响,逻辑更可控 - 如果脚本依赖开发工具(如
phpunit),但又不想装进生产环境,就拆开:用--no-dev装依赖,再单独composer require --dev phpunit --no-install临时装测试工具
缓存 vendor/ 是个常见误区
缓存整个 vendor/ 目录看着快,实际问题一堆:跨 OS 权限异常、Git 污染、缓存键失效频繁。真正该缓存的是 Composer 自身下载层。
- 用
actions/cache@v3缓存~/.composer/cache,key 用${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - 别缓存
vendor/,它体积大、易冲突,且每次composer install都会校验 lock 文件并重装,缓存意义不大 - 构建产物打包时,用
tar -czf release.tar.gz --exclude=.git --exclude=tests --exclude=.env* .,确保不带敏感文件和开发残留
复杂点在于权限和上下文:CI 构建机的用户、目标服务器的 Web 用户、PHP 进程用户三者常不一致,storage/ 目录权限、.env 文件所有权、OPcache 是否启用,都得在脚本里显式检查,不能靠“本地能跑”来推断线上可用。










