To make our package available to others, we just need to initialize the Git repository inside our folder of /packages/laraveldaily/laravel-permission-editor
and push the code to GitHub, then register that repository on Packagist.
So, step by step.
1. Push to GitHub
First, we create a new repository on GitHub. You can actually use a different system like Gitlab or Bitbucket, just the repository should be public.
Important: to avoid conflicts, the repository name should be exactly the same as you specified in the composer.json
of the package, in the "name" field.
Then we follow the GitHub instructions to push our code to the repository, just replacing the suggested "readme.md" commit with pushing all files.
cd packages/laraveldaily/laravel-permission-editorgit initgit add .git commit -m "First commit"git branch -M maingit remote add origin https://github.com/LaravelDaily/laravel-permission-editor.gitgit push -u origin main
This is the result, in Terminal:
So, our package code is on Github now, great!
2. Readme file
As you can see in the screenshot above, there are no installation instructions, and even GitHub itself is telling us to create a README file.
Let's be polite to our users and create this file, with installation instructions, in Markdown language, and push it to GitHub. This is the result:
3. Version Release on GitHub
We have the package on GitHub, but this is not where composer
takes the packages from. The central database of the packages is called Packagist. You need to create the account there, and then Submit your package.
But, before we do that, let's tell Packagist that we're launching our first version, let's assign it a version number of v0.0.1
.
In general, if you follow the so-called semantic versioning, those three parts mean this:
- The first number is the major version: it means big releases with potential breaking changes, like Laravel 9 or Laravel 10, which happens every 6 months
- The second number is the minor version: it means new features without breaking the full package behavior, like Laravel 9.xx that happens every week
- The third number is the patch version: it means any bugfixes or small typo fixes which may happen multiple times per day if needed
It's totally your personal preference which version to start from: some creators choose to start with v1.0.0
, while others release v0.0.1
and stay on v0.x
for months after that.
To release a version, we need to do two things.
First, in the composer.json
of our package, we need to specify the version and push that change to GitHub:
packages/laraveldaily/laravel-permission-editor/composer.json:
{ "name": "laraveldaily/laravel-permission-editor", "description": "Visual UI for managing Roles/Permissions for Spatie Laravel Permission package", // ... "version": "0.0.1"}
Next, we need to go to GitHub and look at the "Releases" on the right side, and click "Create a new release":
Inside that form, we need to create a new tag corresponding to our version number:
Finally, we can put the name and the description of the new version, which would be easily visible to the package users.
Feel free to put any text you want in there, and click "Publish release".
4. Release on Packagist
As I mentioned before, we need to publish the package on Packagist.
The direct URL to submit the package is this: packagist.org/packages/submit
As you can see, all we need to do is provide the repository URL from Github. Packagist will "scan" the contents of that repository and check if everything needed is present for the release.
So I put this: https://github.com/LaravelDaily/laravel-permission-editor
Then I get this text as a result:
The package name found for your repository is: laraveldaily/laravel-permission-editor, press Submit to confirm.
And I click "Submit"...
First, the package will be crawled, and then the information update will happen, and in a minute or so, I see THIS:
That's it! We released our package to the public!
Hard to believe? Let's test it! Let's create a new fresh Laravel project, install the Spatie Permission package, and install our package.
laravel new project5cd project5composer require spatie/laravel-permissionphp artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"php artisan migratecomposer require laraveldaily/laravel-permission-editorphp artisan vendor:publish --provider="Laraveldaily\LaravelPermissionEditor\PermissionEditorServiceProvider"
Launching the browser...
Ta-daaaa!
So, that's it for this long tutorial, this is how to create and publish a Laravel package. As always, if you have any questions or see some information missing, shoot in the comments below.
The package repository is available on GitHub: LaravelDaily/laravel-permission-editor
See you guys in other tutorials!
Image is missing in the following line:
Thanks for the notice, fixed!
Struggled a bit following the tutorial in places, but with some determination and lots of faff I actually released my first ever Laravel package! It won't set the world alight, but it will let you generate website thumbnails using the url2png API :) Feel free to have & any offer any recommendations :) https://github.com/gkimpson/url2png-laravel https://packagist.org/packages/gkimpson/url2png-laravel
Looks like a great start! Happy to inspire your journey to create packages. Could you speciffy the places where you struggled, maybe I could change something in the course material to be clearer?
It was probably more to do with me doing new concepts than anything you did wrong - although one part of chapter 5 - the
PermissionEditorServiceProvider.php
boot() method changes somewhat (the->as('permission-editor');
is removed for instance - after a while I realised this is needed. It was still a very good tutorial and the final chapter with the information regarding the releasing the packages was super useful as this was a first for me :)I think a good way would be to do a very basic package initially & then have this permissions-editor package as a more advanced package (as its involves other dependencies, routes, views etc..), similar to how you have done the Laravel Testing in two courses (one for beginners and one advanced).
Either way, I did a thing and made a package for the first time so i'm happy with that :) Keep up the good work Povilas!
Thanks again for the feedback, will keep in mind!
Thank you so much That's very helpful
I was trying to find a package development tutorial that will explain about dependencies and how to inlude them into my own package. Finally I found it here.
Thanks a lot Povilas.
Looking forward for new article based tutorials Like these as these save a lot of time.
Of several that I have tried, this is the first course through which I have been able to completely create a package to be able to reuse my code.
Very good material, thanks for the effort.
so should we install our package dependencies like spati-permissions, before install our package ?
can we just dirctly install our package with it dependencies ?
thank you mr Povilas
You can set dependancies in your packages
composer.json
file. This will install the dependancies with your package at the same time. No need to install it separateHey Mr.Modestas, so what if i publish new package depends on another packages with spesfic versions maybe......
can i let the end user when install my package download all dependencies of my package with right versions dirctly without write them on composer.json by him and without install them by him ?
because maybe the end user install wrong version, or maybe even don't relize that my package depends on another packages
All the packages and versions you define in your composer.json as dependancies - will be installed. These will be exact versions you need and it will not allow users to have the same package with higher/lower versions (will trigger composer incompatibility error)
Great!
Thank you so much Mr.Modestas
Hi Povilas, congratulations to you and your team for this great tutorial.
I was wondering if the github repository has to be public in order to publish it in packagist. What if I have a modular application that works with multiple packages thatn can be optionally installed and those packages work only for that particular app? For example the main application has its core module that could be cloned from github, but then you could install other modules by requiring packages.
Since this packages only work with the core module, can they be a sort of private packages?
In case you need private packages (which it sounds that you do) - you need to use private packagist:
https://packagist.com/