Packagist 要求 GitHub 仓库公开且含合法 composer.json:name 格式为 vendor/package-name,type 推荐 library,需配置 autoload;必须配置 GitHub webhook 实现自动更新;版本依赖以 Git tag 为准(如 v1.0.0),非 composer.json 的 version 字段;发布前须运行 composer validate 和 --dry-run 验证。

packagist.org 要求 GitHub 仓库必须公开且含 composer.json
Packagist 不托管代码,只索引公开 Git 仓库(GitHub/GitLab/Bitbucket),所以第一步不是点“提交”,而是确保你的项目已推送到公开仓库,并根目录存在合法的 composer.json。常见错误是本地开发完直接去 Packagist 提交私有仓库链接,结果提示 “Repository not found” 或 “Invalid repository URL”。
检查重点:
-
composer.json必须有"name"字段,格式为"vendor/package-name"(如"myorg/my-utils"),且vendor需与你在 Packagist 的用户名一致 -
"type"推荐设为"library"(非"project"),否则 Packagist 可能拒绝索引 - 建议加上
"autoload"(哪怕只是{"psr-4": {"MyOrg\": "src/"}}),否则安装后无法自动加载类
在 Packagist 上手动 submit 后,需用 GitHub webhook 自动更新
首次提交后,Packagist 会抓取一次 tag 或 branch(默认是 main 或 master)。但之后你 push 新 tag(比如 v1.0.1)时,Packagist 不会自动感知——除非你配置了 GitHub webhook。
实操步骤:
- 进 GitHub 仓库 →
Settings→Webhooks→Add webhook -
Payload URL填https://packagist.org/api/github -
Which events would you like to trigger this webhook?选Just the push event或勾选Releases(如果你用 GitHub Releases 发版) - 保存后,下次
git push origin v2.0.0就会自动触发 Packagist 更新,不用再手动 resync
没配 webhook 的典型现象:Packagist 页面显示 “Last updated: 3 days ago”,但你刚打了新 tag,composer require vendor/package:dev-main 能装,:v2.0.0 却报 Could not find package ... in a version matching...。
版本号必须用标准语义化格式,且 tag 名和 version 字段要一致
Composer 解析版本依赖靠的是 Git tag 名(如 v1.2.3),不是 composer.json 里的 "version" 字段——该字段会被忽略。所以你写 "version": "9.9.9" 没用,反而可能误导自己。
正确做法:
- tag 名严格用
vX.Y.Z(如v1.0.0)、X.Y.Z(无v前缀也行,但建议统一)或dev-*分支名(如dev-feature/login) - 打 tag 前确认当前 commit 已包含你要发布的全部改动,且
composer.json中的"name"和 autoload 配置已就绪 - 执行:
git tag v1.0.0 && git push origin v1.0.0(注意不是git push --tags,后者可能推错历史 tag)
容易踩的坑:tag 名写成 1.0、v1.0 或 release-1.0.0,Composer 会识别为 dev- 开头的不稳定分支,导致 require 时必须加 @dev 后缀,且不会进入稳定版本列表。
本地测试安装前,先用 composer validate 和 composer install --dry-run
很多人跳过验证直接发版,结果用户 composer require 失败,错误信息五花八门,其实问题出在自己本地就能发现。
两个命令必须跑:
-
composer validate:检查composer.json格式、必填字段、name是否合规、autoload路径是否存在等。报错就别提交 -
composer install --dry-run:模拟安装流程,看是否能正常解析依赖、下载、生成 autoloader。如果这里卡住,线上用户一定失败
特别注意 autoload 路径:比如你写了 "psr-4": {"MyLib\": "src/"},但实际目录是 ./Src/(大小写不一致)或 ./lib/,--dry-run 不会报错,但运行时 class not found——得靠你手动 php -r "require 'vendor/autoload.php'; new MyLibFoo();" 验证。
发布不是终点,而是让别人能复现你本地环境的起点。路径大小写、Git 忽略规则(比如误把 src/ 加进 .gitignore)、Windows/macOS 行尾符差异,都会让 packagist 抓到一个“缺文件”的包。










