Любой PHP-разработчик ежедневно дергает пакеты через composer require. Но когда дело доходит до того, чтобы вынести собственное решение (утилиту, бандл для Symfony или пакет для Laravel) в открытый доступ, многие спотыкаются на базовых вещах: ломается автозагрузка классов, релизы на GitHub не долетают до Packagist, а пользователи жалуются на конфликты зависимостей.
Packagist — это не хостинг кода (сам код живет в вашем Git-репозитории), а центральный реестр метаданных. Он сообщает Composer, откуда скачать архив и какие требования предъявляет библиотека к окружению.
Разберем по шагам, как подготовить репозиторий, опубликовать пакет и настроить нормальный CI/CD релизный цикл.
Шаг 1. Готовим composer.json без детских ошибок
Главный файл пакета должен быть оформлен строго по стандартам, иначе Packagist либо выдаст предупреждения, либо Composer откажется корректно резолвить зависимости у конечных пользователей.
Рабочий минимальный шаблон для библиотеки:
{
"name": "vendor-name/package-name",
"description": "Краткое и четкое описание того, что делает пакет",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Your Name",
"email": "you@example.com"
}
],
"require": {
"php": ">=8.2",
"illuminate/support": "^10.0|^11.0"
},
"require-dev": {
"pestphp/pest": "^2.0",
"mockery/mockery": "^1.6"
},
"autoload": {
"psr-4": {
"VendorName\PackageName\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"VendorName\PackageName\Tests\": "tests/"
}
},
"minimum-stability": "stable",
"prefer-stable": true
}
На что обратить внимание:
- PSR-4 автозагрузка: Слэши в пространстве имен должны быть экранированы (
\), а путь заканчиваться слэшем (src/). Тестовые неймспейсы выносите строго вautoload-dev, чтобы они не попадали в вендор конечных проектов. - Гибкие диапазоны версий (
require): Не зашивайте жесткие зависимости (вроде"illuminate/support": "11.2.0"). Используйте операторы^или комбинации (^10.0|^11.0), иначе ваш пакет будет конфликтовать с другими библиотеками в проекте пользователя. - Лицензия: Без поля
"license"(например,MITилиBSD-3-Clause) многие компании просто юридически не смогут использовать ваш код в коммерческих проектах.
Перед коммитом всегда валидируйте конфиг локально:
composer validate --strict
Шаг 2. Первая публикация на Packagist
- Регистрируемся на packagist.org (проще всего авторизоваться напрямую через аккаунт GitHub).
- Жмем кнопку Submit в верхнем меню.
- Вставляем публичный URL вашего репозитория на GitHub (например,
https://github.com/vendor-name/package-name). - Packagist проверит репозиторий, прочитает
composer.jsonи создаст карточку пакета.
Пакет появится в каталоге моментально, но пока в нем не создано ни одного релиза, пользователи смогут ставить только ветки разработки (например, dev-main).
Шаг 3. Автоматизация обновлений через GitHub Webhook
Обновлять пакет вручную кнопкой «Update» в личном кабинете — путь к забытым релизам. Packagist синхронизируется с GitHub автоматически по вебхуку:
- В профиле Packagist перейдите в Profile → Your API Token и скопируйте токен.
- В вашем репозитории на GitHub перейдите в Settings → Webhooks → Add webhook.
- Заполните поля:
- Payload URL:
https://packagist.org/api/github?username=ВАШ_ЮЗЕРНЕЙМ - Content type:
application/json - Secret: ваш API Token из Packagist
- Which events: выберите Just the push event.
- Сохраните вебхук. Теперь любой пуш тега или коммита в основную ветку моментально обновит данные в каталоге.
Шаг 4. Версионирование: забудьте про поле "version" в файле
Частая ошибка новичков — вручную указывать "version": "1.0.0" внутри файла composer.json. Делать этого не нужно.
Packagist определяет версии исключительно по Git-тегам. Composer опирается на Семантическое версионирование (SemVer): MAJOR.MINOR.PATCH.
Как выпускать релизы правильно:
# Выкатили исправление бага (patch)
git tag v1.0.1
git push origin v1.0.1
# Добавили новую обратно совместимую фичу (minor)
git tag v1.1.0
git push origin v1.1.0
# Сломали обратную совместимость или переписали API (major)
git tag v2.0.0
git push origin v2.0.0
Как только тег улетает на GitHub, вебхук триггерит Packagist, и свежая версия становится доступна для composer update по всему миру в течение пары минут.
А если пакет приватный?
Если вы пишете код для внутренних сервисов компании или коммерческого заказчика, выкладывать его на публичный Packagist нельзя. Для таких случаев есть два нормальных пути:
- GitHub VCS репозиторий напрямую в
composer.jsonпроекта:"repositories": [ { "type": "vcs", "url": "git@github.com:your-company/private-package.git" } ]
Composer склонирует репозиторий по SSH-ключам разработчика или deploy-ключу сервера.
2. **Собственный self-hosted реестр (Satis):**
Бесплатный генератор статического репозитория от создателей Composer. Подходит, когда приватных пакетов становится больше десятка и их нужно централизованно версионировать во внутренней сети компании.