GitHub Actions中直接运行composer install必然失败,因ubuntu-latest镜像默认无PHP和Composer二进制;必须组合shivammathur/setup-php@v2(装指定PHP及mbstring、xml、zip等扩展)与php-actions/composer@v6(下载校验版Composer并注入PATH),禁用apt/curl安装,严格缓存含composer.lock哈希、PHP/Composer版本及镜像URL的key,并删vendor与lock后重装以确保镜像生效。

GitHub Actions里直接写composer install必然失败
因为ubuntu-latest镜像默认不带PHP,更没有composer二进制。这不是配置问题,是根本不存在。你看到的command not found: composer或PHP is not installed错误,源头就在这里。
必须组合两个动作:先用shivammathur/setup-php@v2装好指定PHP版本及必需扩展(如mbstring、xml、zip),再用php-actions/composer@v6按当前PHP版本下载校验过的composer二进制并注入PATH。别用sudo apt install composer——Ubuntu仓库里的版本老旧,且不保证启用ext-zip;也别用curl -sS https://getcomposer.org/installer——容易因TLS中断、镜像源不稳定或跳过校验出问题。
php-actions/composer@v6为什么比手动装更稳
它不走全局安装,而是把二进制放./bin/composer并自动加到PATH,避免和系统路径冲突。它还会自动校验composer.json格式,并支持精确指定版本,比如:
uses: php-actions/composer@v6 with: composer-version: '2.5.8'
更重要的是,它只读项目根目录下的composer.json,完全忽略全局配置(如~/.composer/config.json)。这意味着你在CI里配镜像源,不能靠composer config -g,必须确保项目级repositories已写入并提交Git。
项目级镜像配置必须进根目录再执行composer config
在GitHub Actions中,composer config repo.packagist composer https://mirrors.aliyun.com/composer/这条命令必须在含composer.json的目录下运行,否则会写错位置甚至创建空文件。它会自动在composer.json顶层添加或更新"repositories": {"packagist": {...}},不覆盖已有私有源(如"type": "vcs")。
- 如果
composer.json里"repositories"是数组[],命令会失败——需先手动改成空对象{} - URL末尾必须带
/,少一个斜杠会导致请求拼成/composerpackages.json,返回404 - type值必须显式写
"composer",写成"https"或"packagist"都无效
配完不是立刻生效:必须删掉vendor/和composer.lock,再跑composer install --no-cache。否则composer.lock里仍存着官方源的dist.url,Composer会绕过镜像直连api.github.com,你看到的“卡在Downloading”就是这个原因。
缓存vendor/和~/.composer/cache要带多维key
GitHub Actions默认缓存不可靠,必须手动用actions/cache@v4,且key要包含:composer.lock哈希 + PHP版本 + Composer版本 + 镜像URL。例如:
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}-${{ steps.php-version.outputs.php-version }}-${{ steps.composer-version.outputs.composer-version }}-aliyun
不这么做,换PHP小版本(如8.2→8.3)或改镜像后,缓存会命中原先的vendor/,导致包路径错乱或hash does not match报错。另外,php-actions/composer@v6本身不处理缓存,它只负责提供二进制;缓存逻辑必须由你显式声明。
最常被忽略的一点:镜像源只影响元数据拉取和ZIP包下载,不影响依赖解析过程。“Resolving dependencies”卡住,90%不是镜像问题,而是composer.json里版本约束太宽(如"^2.0")引发回溯爆炸——这时该优先用composer install恢复旧lock,而不是反复折腾镜像配置。


















