ci/cd中应避免修改全局config.json,而用composer_repo_packagist环境变量或项目级repositories配置(含mirrors机制)实现镜像源切换,并每次构建前执行composer clear-cache。

CI/CD里改镜像源,别碰全局config.json
CI/CD 构建通常以非 root 用户(如 runner、www-data 或自定义 service user)运行,而 composer config -g 默认写入当前用户的 ~/.composer/config.json。但很多流水线用 sudo 执行命令,结果把配置落到了 root 家目录下,构建时根本读不到——这不是配置失败,是压根没被加载。
更麻烦的是:不同 runner 实例、不同 Docker 镜像、不同 CI 平台(GitHub Actions / GitLab CI / Jenkins)的用户环境完全隔离,靠改全局配置无法统一生效。
- 不要在 CI 脚本里执行
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ - 不要依赖
~/.composer/config.json的存在或内容 - 优先走项目级注入或环境变量覆盖,确保每次构建都“干净启动”
用 COMPOSER_REPO_PACKAGIST 环境变量临时覆盖
这是最轻量、最可控的方式:不修改任何文件,只靠环境变量告诉 Composer 当前会话该连哪个源。它优先级高于全局配置,且不会污染工作区。
示例(GitLab CI):
script: - export COMPOSER_REPO_PACKAGIST=https://mirrors.aliyun.com/composer/ - composer install --no-interaction
注意三点:
- 值必须是完整 URL,结尾带
/,否则静默 fallback 到 packagist.org - 协议必须匹配镜像支持方式:阿里云内网用
http://mirrors.cloud.aliyuncs.com/composer/,公网用https - 该变量只影响当前 shell 会话;若分多个 job 或 stage,每个都要重新
export
项目级 repositories 注入要防空数组和顺序错
如果项目已有 composer.json 且含 "repositories" 字段,直接用 composer config repo.packagist ... 会失败——因为该命令只接受对象格式({}),不支持数组([])。而多数团队私有包配置已用数组,强行注入会导致 JSON 格式损坏。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
安全做法是用 jq 做结构化更新(Linux/macOS):
jq '(.repositories |= (if type == "array" then . |= (index({"packagist.org": false}) as $i | if $i == null then [{"packagist.org": false}] + [{"type":"composer","url":"https://mirrors.aliyun.com/composer/"}] + . else . end) else {"packagist.org": false, "packagist": {"type":"composer","url":"https://mirrors.aliyun.com/composer/"}} end))' composer.json > tmp.json && mv tmp.json composer.json
关键点:
- 必须保证
{"packagist.org": false}是repositories数组第一项,否则仍会回源请求元数据 - 不能让
"repositories": []空数组残留,Composer 2.x 会直接报错 - Windows 上可用 PowerShell +
ConvertFrom-Json+ConvertTo-Json替代,但要注意缩进和 UTF-8 BOM
多镜像+故障转移才是 CI 稳定的关键
单镜像扛不住并发构建:清华源限流 60 req/min/IP,阿里云在高密度 CI 下也常返回 429 Too Many Requests。靠换一个源解决不了问题,得用 Composer 原生的 mirrors 机制。
正确写法(写入 composer.json):
"repositories": [
{
"packagist.org": false
},
{
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/",
"canonical": false,
"mirrors": [
{
"type": "composer",
"url": "https://repo.huaweicloud.com/repository/php/",
"only": ["*"]
}
]
}
]
要点:
-
"canonical": false必须显式声明,否则 Composer 不启用 mirror fallback -
"only": ["*"]表示所有包都走该镜像,避免部分包漏掉 - 实际部署前务必跑
composer update -vvv并 grep 日志里的GET请求,确认失败时真切换到了备选镜像
真正容易被忽略的是缓存:CI 每次构建都应加 composer clear-cache,否则旧 packages.json 元数据还在,即使配置全对,也会卡在“Loading composer repositories”阶段。










