@colinodell
Releasing High-Quality
Packages
@colinodell
@colinodell@colinodell
PHP League Leadership Team
Maintainer of popular packages:
league/commonmark
league/html-to-markdown
colinodell/json5
Colin O'Dell
Lead Developer &
DevOps Engineer
Director of Technology
at Unleashed Technologies
@colinodell
What Are Packages?
Reusable libraries;
installed via Composer
@colinodell
PEAR / PHPClasses.org
@colinodell
PHP-FIG, PSR-0, & Composer
2009: Framework Interoperability Group adopts PSR-0 autoloading
standard
2011: Composer development begins
2012: Composer released with PSR-0 support
Today: 213,660
Packages on Packagist
1.6 million
Unique Releases
@colinodell
Package Benefits
• Pre-written
• Reusable
• Community-maintained
• Framework-agnostic
• Easily installed
• Robust dependency resolution
@colinodell
Releasing Your Own Packages
@colinodell
Overview
Definition of Quality
Project Structure
Testing
Packaging
Releasing
Ongoing Maintenance
Development Best Practices
@colinodell
@colinodell
Definition of Quality
Semantically
Versioned
Actively
Maintained
User Friendly Composer
Installable
Extensively
Documented
S A U C E
@colinodell
Project Structure
@colinodell
Project
Structure
@colinodell
Project & Vendor Name
There are only two hard things in Computer
Science: cache invalidation and naming things.
-- Phil Karlton
@colinodell
Project & Vendor Name
PHP namespace = VendorNameProjectName
Packagist repo = vendor-name/project-name
• Choosing a name:
• Available
• Unique/memorable
• Easy to search
• Make names consistent
@colinodell
@colinodell
composer.json
• Project dependencies
• Include PHP version &
extensions
• Development dependencies
• Autoloading configuration
• PSR-4 not PSR-0
• Separate namespace
for tests
@colinodell
Source
Code
@colinodell
Source Code
• Minimal dependencies; wide
constraint ranges
• Make framework agnostic
• Service providers for specific
frameworks okay
• Provide interfaces
• Use community standards (PSRs)
• Follow best practices and design
principles
• Consistent coding style (PSR-2?)
@colinodell
Project Hosting
Features:
• Project downloads
• Issue reporting
• Pull requests / code reviews
• Collaboration
• CI integrations
@colinodell
Testing
Automating the testing process
@colinodell
Automated
Tests
@colinodell
Unit Tests
• Test individual
components
• PHPUnit – defacto
standard
• Aim for 80% code
coverage
@colinodell
@colinodell
Automated Tests
• Not just unit tests:
• Functional tests
• Integration tests
• Acceptance tests
• Other good test frameworks:
• Phpspec
• Behat
• Codeception
• Use continuous integration!
@colinodell
Continuous Integration
@colinodell
Continuous Integration
@colinodell
Continuous Integration
• Run tests across all supported
versions
• Track code quality
• Scrutinizer CI
• Check code style
• StyleCI
• PHPCS
@colinodell
.travis.yml
@colinodell
.styleci.yml
@colinodell
@colinodell
Project
Structure
@colinodell
Packaging
Getting the code ready for distribution
@colinodell
Licensing
• Distribution
• Attribution
•Modifications
•Commercial Use
Permissive: MIT; BSD; ISC
Prevent Closed Source: GPLv3; Mozilla Public License
Documentation: Creative Commons
@colinodell
Licensing
• choosealicense.com
• creativecommons.org/choose
@colinodell
Licensing
@colinodell
Licensing
@colinodell
Project
Structure
@colinodell
Documentation:
README.md
• Badges
• What problem your package solves
• Installation steps
• Sample Usage
• Configuration
@colinodell
Documentation:
docblocks
Benefits:
• Read docs while coding
• IDE auto-completion
• Short description
• Parameter types, names, and
purposes
• Return types
• Any thrown exceptions
@colinodell
Documentation:
RTFM
• Advanced usage or configuration
• Additional code samples
• Other functionality
Where to host?
• GitHub Pages
• Jekyll
• MkDocs
• Other static site generator
• readthedocs.org
• Your own hosting
@colinodell
Archive Settings
Package consumers (probably) don’t want:
• Tests
• Dev dependencies
• Issue / PR templates
• Travis CI configuration
• Your .gitignore development settings
@colinodell
Archive Settings - .gitattributes
@colinodell
Archive Settings:
composer.json
{
{
@colinodell
Project
Structure
@colinodell
Packagist.org
@colinodell
Releasing
Launching your package
@colinodell
Semantic Versioning – semver.org
1.0.0 (stable)
or
0.1.0 (unstable)
@colinodell
Semantic Versioning – semver.org
x . y . zMajor . Minor . Patch
@colinodell
Semantic Versioning – semver.org
2 . 4 . 5Major . Minor . Patch
Incompatible
Changes
Backwards-
Compatible;
New Features
Bug Fixes
@colinodell
2 . 4 . 6
2 . 4 . 5Major . Minor . Patch
Incompatible
Changes
Backwards-
Compatible;
New Features
Bug Fixes
@colinodell
2 . 5 . 0
2 . 4 . 5Major . Minor . Patch
Incompatible
Changes
Backwards-
Compatible;
New Features
Bug Fixes
@colinodell
3 . 0 . 0
2 . 4 . 5Major . Minor . Patch
Incompatible
Changes
Backwards-
Compatible;
New Features
Bug Fixes
@colinodell
Semantic Versioning – semver.org
0 . x . yMajor . Minor . Patch
Any 0.x.y release may break backwards compatibility!
My recommendation: treat X.Y as major.minor
@colinodell
CHANGELOG.md
• Follow https://keepachangelog.com
@colinodell
@colinodell
UPGRADE.md
• Documentation on upgrading between major versions
• Describe BC breaks
• Provide instructions for users to update their code
@colinodell
@colinodell
Tagging a
Release
@colinodell
Released!
@colinodell
Project
Structure
@colinodell
Ongoing Maintenance
Addressing issues, handling PRs, and maintaining your community
@colinodell
Maintainer Responsibilities
• Be responsive
• Triage issues; keep queue clean
• Review PRs & provide feedback
• Share responsibility with core contributors
@colinodell
CONTRIBUTING.md
• Requirements
• Considerations
• Process
• Tips
@colinodell
Issue / PR Templates
@colinodell
Issue / PR Templates
@colinodell
Issue / PR Templates
@colinodell
CODE_OF_CONDUCT.md
• Expresses values and rules that contributors should adhere to
• Promotes inclusion and contributions
• Defines unacceptable behavior and enforcement
• https://www.contributor-covenant.org/
@colinodell
.editorconfig
• Defines preferred indentation style and line breaks
• Automatically configures contributor IDEs
• Most major IDEs supported
@colinodell
.gitignore
Ensures certain files are never committed to Git
@colinodell
Project
Structure
@colinodell
Further Reading
Additional information and resources on creating high-quality PHP packages
@colinodell
Further Reading
• https://github.com/thephpleague/skeleton
• http://phppackagechecklist.com
• https://getcomposer.org/doc/04-schema.md
• https://leanpub.com/principles-of-package-design
@colinodell
Questions?
@colinodell
@colinodell
Thanks!

Releasing High Quality PHP Packages - ConFoo Montreal 2019

Editor's Notes

  • #3 I’m a member of the PHP League - We’re a group of developers dedicated to building high-quality packages for the PHP community Share our experience and best practice
  • #4 --- Community-created bundle of code Provides useful functionality … It wasn’t always this easy
  • #5 Virtually no interoperability
  • #6 Framework Interoperability Group Autoloading eliminated need to manually require_once
  • #7 Several benefits to having code available as a package … So you’ve got some code you want to release… (Maybe you want to pay it forward?) How would you do that?
  • #8 More than just throwing code online
  • #9 Packages and what makes them high-quality Look at structure of a quality package And the steps to prepare, release, and maintain your package
  • #10 Everyone has their own definition Great staring point but not exhaustive
  • #12 Look at quality through the lens of good project structure
  • #13 This will serve as our checklist
  • #15 Two parts: Vendor = person, group, company, or organization Project = individual package
  • #17 (click once) 1. Meta info (click again) …
  • #19 Logging: PSR-3 HTTP: PSR-7, 13, 15, 17 Caching: PSR-6, 16 Containers: PSR-11
  • #23 “test bench”
  • #26 Automatically runs tasks when: Code is pushed PR is created Code is merged New version is released Perfect for tests!
  • #28 Run tests: Across all supported PHP versions Against future PHP versions Using minimal/older Composer constraints
  • #37 Copyright Mention license
  • #39 First impression
  • #46 … At this point, Package is registered but not “released” – no versions available
  • #50 Safe upgrading
  • #51 Safe upgrading
  • #52 Safe upgrading
  • #53 Safe upgrading
  • #54 Great for new libraries where architecture isn’t finalized
  • #56 Added Changed Fixed Deprecated Removed