Composer包版本由Git轻量标签(如v1.2.3)驱动,而非composer.json中的version字段;必须带v前缀、符合语义化格式、用git tag v1.2.3命令创建并推送至远程,且私有包需删除version字段、配置vcs仓库类型。

Composer包的版本号不是靠改composer.json里的version字段来发布的,而是由Git轻量标签(tag)驱动的——你打什么tag,Packagist就认什么版本,composer.json里硬写version反而容易导致同步失败或安装报错。
Git tag必须用v1.2.3格式,否则Composer直接跳过
Composer只识别严格符合语义化版本的轻量tag,且必须带v前缀。比如v2.1.0有效,2.1.0、v2.1、v2.1.0-beta、release-2.1.0全都不行。
- 打tag命令必须是
git tag v2.1.0,漏掉v就白打了 - 不能用
git tag -a(带注释的annotated tag),旧版Packagist可能解析失败;统一用轻量tag - tag名里不能有空格、下划线、多余横线(如
v2.1.0_final会被忽略) - 打完必须推送到远程:
git push origin v2.1.0,只本地打没用 - 已有非法tag(如
1.2.0)要删干净:git tag -d 1.2.0 && git push origin :refs/tags/1.2.0
composer.json里别写version字段,尤其私有包
私有包或准备提交到Packagist的包,composer.json中应删除version字段。一旦写了,就必须和tag完全一致,否则Packagist会拒绝同步,本地composer require也会报Package has a version constraint which does not match the version in its composer.json。
- 开发态建议留空,让Composer自动从tag推断
- 如果CI需要注入构建号(如
2.1.0+git.abc123),应在打包前用脚本动态写入,且必须配套打对应tag - 私有包通过
repositories引入时,version字段被完全忽略,实际版本由require约束决定 - 确认是否生效:运行
composer show vendor/package,输出的version应来自tag,不是composer.json
Packagist同步失败?先查这三件事
推了v2.1.0却拉不到,90%不是Composer问题,而是Packagist没同步成功。别急着重装Composer,先看这几处:
- 仓库是否在Packagist上启用了自动更新:Settings → 勾选“Automatically update the package on new commits?”
-
git ls-remote --tags origin能看到v2.1.0,但composer show没列出该版本 → 大概率是webhook没触发或Payload URL配置错误 - tag名和
composer.json中version冲突(比如tag是v2.1.0,但json里写了"version": "2.1.1")→ Packagist直接跳过该tag - 私有GitLab/GitHub仓库需手动配webhook,Packagist不会主动轮询;公共GitHub仓库则依赖GitHub事件推送
镜像源不解决Git tag同步问题
换阿里云镜像、清缓存、改config,对Git tag能否被识别毫无影响。镜像只缓存Packagist元数据和dist包,不参与tag发现或版本映射。
- 你推了
v2.1.0,Packagist没同步 → 镜像里自然也没有这个版本 -
composer clear-cache只能清本地缓存,不能强制Packagist重新抓取tag - 验证是否同步成功,唯一可靠方式是访问
https://packagist.org/packages/vendor/package页面,看Versions列表里有没有v2.1.0 - 手动触发同步:登录Packagist,进入包页点“Update”按钮(需已绑定仓库且有权限)
最易被忽略的点:很多人以为打完tag就万事大吉,其实Packagist同步有延迟(默认15分钟轮询),而手动点“Update”又常因权限或绑定失效失败;真正稳的做法是在CI里用curl调Packagist API触发更新,并校验返回状态码。


















