CI下composer install装不上私有包,90%因Composer未读取认证、未识别仓库类型或未禁用默认源,导致静默回退至packagist.org而报“Could not find package”。

CI 环境下 composer install 装不上私有包,90% 不是网络或 Token 问题,而是 Composer 根本没读到你的认证配置、没识别到仓库类型、或没禁用默认源——它安静地 fallback 到 packagist.org,然后报 Could not find package。
CI 中 auth.json 必须放对位置且权限正确
CI 容器或 runner 默认不读项目根目录下的 auth.json,除非你显式告诉 Composer;全局路径又因用户环境不同而不可靠。最稳做法是:在 CI 脚本里动态生成并写入 ~/.composer/auth.json,然后设权限。
- Linux/macOS runner:运行
mkdir -p ~/.composer && echo '{"http-basic": {"gitlab.example.com": {"username": "oauth2", "password": "glpat-xxx"}}}' > ~/.composer/auth.json && chmod 600 ~/.composer/auth.json - Windows runner(GitHub Actions):用
shell: pwsh写入$env:APPDATAComposeruth.json,同样需chmod等效操作(PowerShell 的Set-ACL) - 别把
auth.json提交进 Git,也别用composer config --global—— CI 环境通常无状态,每次都要重置 - 验证是否生效:加
-v运行composer install -v,日志中应出现Reading composer.json of acme/utils和GET https://gitlab.example.com/api/v4/projects/...
repositories 必须顶层数组 + packagist.org: false
CI 下的 composer.json 若只写了仓库 URL 却没关默认源,Composer 会优先查 packagist.org,私有包永远不被匹配——这不是 bug,是设计行为。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
repositories必须是composer.json最外层字段,不能嵌在config、extra或scripts里 - 必须显式添加
"packagist.org": false(注意:冒号后是布尔值false,不是字符串"false") - 若用 Satis 或 Artifactory,
type必须为"composer",URL 末尾斜杠/不可省略,否则返回 404,Composer 静默跳过 - GitLab 私有仓库场景下,
url必须带.git后缀(如https://gitlab.example.com/acme/utils.git),否则composer install报No valid composer.json was found
require 包名和分支必须与私有库 composer.json 逐字符一致
Composer 不解析 Git 路径,只比对私有包自身 composer.json 里的 name 字段。差一个字母、大小写、分隔符,就彻底失败。
- 假设私有库根目录
composer.json写的是{"name": "acme/utils"},主项目require就必须写"acme/utils": "dev-main" - 不能写成
"Acme/utils"、"acme-utils"、"acme/utils-dev",也不能漏掉 vendor 段 - 分支必须加
dev-前缀:"dev-main"可行,"main"或"*"会被当模糊约束,去 packagist.org 查 - 如果私有库没打任何 tag,唯一可用版本就是
dev-main(或dev-master,取决于默认分支名)
autoload 不生效?dump-autoload 不是自动触发的
私有包下载进 vendor ≠ 类能自动加载。Composer 的 autoload 映射只在安装时或手动执行 composer dump-autoload 时生成,且完全依赖私有包自己声明的 autoload 段。
- 私有包的
composer.json必须含有效autoload,例如{"autoload": {"psr-4": {"Acme\Utils\": "src/"}} - CI 脚本中,
composer install后建议补一句composer dump-autoload --optimize,避免因缓存或增量更新导致映射缺失 - 如果私有包用了自定义命名空间但没声明 autoload,
new AcmeUtilsHelper()一定报Class not found,跟安装成功与否无关
最易被忽略的一点:Satis 构建后,客户端必须能直接 curl -I https://satis.example.com/packages.json 返回 200;Nginx 返回 403 或 404,Composer 就静默 fallback,不会报错也不会提示——你得自己去 CI 日志里翻 HTTP 请求行确认。

















