Contributing to Layup
Thanks for your interest in contributing! Here's how to get started.
Development Setup
# Clone the repo
git clone https://github.com/Crumbls/layup.git
cd layup
# Install dependencies
composer install
# Run tests
vendor/bin/pest
# Run code style fixer
vendor/bin/pint
# Run static analysis / refactoring
vendor/bin/rector --dry-run
Code Style
Layup uses Laravel Pint with the Laravel preset. Run it before committing:
vendor/bin/pint
The pre-push hook runs Pint in --test mode and Pest automatically. If either fails, the push is blocked.
Running Tests
# All tests
vendor/bin/pest
# Specific file
vendor/bin/pest tests/Unit/WidgetTest.php
# Filter by name
vendor/bin/pest --filter="renders heading widget"
# Parallel (faster)
vendor/bin/pest --parallel
Writing Tests
Tests live in tests/Unit/ and tests/Feature/. We use Pest.
Widget tests should cover:
- Default data structure
- Form schema returns valid Filament components
- Preview renders something useful
- Frontend rendering produces correct HTML
- Edge cases (empty data, missing fields, long content)
Feature tests should cover:
- Artisan commands
- HTTP routes (frontend rendering)
- Full page builder lifecycle
Example widget test:
it('renders with default data', function () {
$widget = new MyWidget(['data' => MyWidget::getDefaultData()]);
$html = $widget->render()->render();
expect($html)->toBeString()->not->toBeEmpty();
});
it('has valid form schema', function () {
$schema = MyWidget::getContentFormSchema();
expect($schema)->toBeArray()->not->toBeEmpty();
expect($schema[0])->toBeInstanceOf(\Filament\Forms\Components\Component::class);
});
Building Custom Widgets
See the Custom Widgets section in the README. The short version:
- Extend
Crumbls\Layup\View\BaseWidget - Implement
getType(),getLabel(),getContentFormSchema(),getDefaultData(),render() - Drop it in
App\Layup\Widgets(auto-discovered) or register via config/plugin
If you're building a widget package for others to use, publish it as a Composer package with a service provider that registers the widgets.
Pull Requests
- Fork the repo and create a feature branch
- Write tests for your changes
- Run
vendor/bin/pintandvendor/bin/pest - Open a PR with a clear description of what and why
Keep PRs focused — one feature or fix per PR. Large refactors should be discussed in an issue first.
Releasing documentation
Package documentation is versioned with the package. Documentation changes in this repository become public after a release; pushing a documentation-only branch does not update the documentation site.
Before merging a documentation change, run:
bin/docs-lint
When release-please publishes a Layup release, the release workflow sends the package name and tag to the documentation site's webhook. The site then fetches the Markdown from that release's GitHub reference and serves it with the matching documentation version.
Maintainers must configure these Layup repository secrets for the notification step:
DOCS_SYNC_WEBHOOK_URL-- the documentation site's/webhooks/docsendpointDOCS_SYNC_WEBHOOK_SECRET-- the shared secret matching the site'sDOCS_WEBHOOK_SECRETsetting
The workflow safely skips notification when either secret is missing. For an unpublished local preview, run the documentation site's local sync command with this package as its source path; see the crumbls-docs repository README.
Reporting Issues
Open an issue with:
- What you expected to happen
- What actually happened
- Steps to reproduce (minimal example)
- PHP, Laravel, and Filament versions