# Contributing to Magewire Thanks for your interest in contributing. This guide covers how to set up a development environment, the rules around generated code, how to write commits, and how to get a pull request merged. ## Code of Conduct By participating in this project you agree to abide by the [Code of Conduct](CODE_OF_CONDUCT.md). ## Ways to Contribute - Report bugs or request features via [GitHub Discussions](https://github.com/magewirephp/magewire/discussions). - Report security vulnerabilities privately — see [SECURITY.md](SECURITY.md). **Do not** open public issues or PRs for security reports. - Submit code changes via pull request (this document). - Improve documentation at [magewirephp/magewire-docs](https://github.com/magewirephp/magewire-docs). ## Requirements - PHP **8.2+** - Composer 2 - Node.js 20+ (for Tailwind compilation) - Git - A working Magento 2 installation for integration testing ## Getting Started ```bash git clone https://github.com/magewirephp/magewire.git cd magewire composer install npm install ``` Composer install wires up CaptainHook automatically. The hooks enforce: - **`pre-commit`** — runs `vendor/bin/portman build` so `dist/` stays in sync. - **`commit-msg`** — validates [Conventional Commits](https://www.conventionalcommits.org/) format. ## Repository Layout | Directory | Description | Edit? | |-----------|-------------|-------| | `src/` | Magento module (controllers, blocks, DI, templates, layout XML) | ✅ | | `lib/Magewire/` | Hand-written Magewire core (Mechanisms, Features, Containers) | ✅ | | `lib/MagewireBc/` | Backwards compatibility layer (v1 → v3 migration) | ✅ | | `lib/Magento/` | Magento framework extensions (`Magewirephp\Magento\` namespace) | ✅ | | `lib/Symfony/` | Symfony utility imports (`Magewirephp\Symfony\` namespace) | ✅ | | `lib/Livewire/` | Downloaded Livewire source cache | ❌ | | `dist/` | Portman-generated output (ported + merged Livewire code) | ❌ | | `portman/Livewire/` | Augmentation files merged into ported Livewire source | ✅ | | `themes/` | Theme compatibility modules (Hyvä, Luma, Breeze, Backend) | ✅ | ### Golden rule — never edit `dist/` directly `dist/` is generated by Portman from `lib/Livewire/` (upstream cache) plus `portman/Livewire/` (our augmentations). To modify code that lives in `dist/`: 1. Create or edit the matching file in `portman/Livewire/` (mirror the Livewire source structure). 2. Run `vendor/bin/portman build`. 3. The result lands in `dist/` under the `Magewirephp\Magewire\` namespace. `vendor/bin/portman watch` rebuilds on save while you work. To bump Livewire version, change `version-lock` in `portman.config.php` and rebuild. ## Code Style Two toolchains, two scopes: | Tool | Scope | Command | |------|-------|---------| | `mago` | `lib/`, `src/`, `themes/` (hand-written code) | `mago lint`, `mago format` | | `php-cs-fixer` | `dist/` only (generated code) | `vendor/bin/php-cs-fixer fix dist/` | | `rector` | `dist/` only | `vendor/bin/rector process dist/` | Mago formatter preset: PSR-12, single quotes, 200 char print width, `sort-uses` enabled. See `mago.toml` for the full rule set. Run before opening a PR: ```bash mago lint mago format vendor/bin/portman build vendor/bin/php-cs-fixer fix dist/ ``` ## Commit Messages [Conventional Commits](https://www.conventionalcommits.org/) — enforced by the `commit-msg` hook. Format: `(): ` Common types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `ci`. Examples: ``` feat(compiler): add @render.parent directive fix(snapshot): handle null property reassignment chore(portman): bump Livewire to 3.7.12 ``` Breaking changes — append `!` after the type/scope and add a `BREAKING CHANGE:` footer: ``` feat(component)!: drop deprecated mount() signature BREAKING CHANGE: Components must now implement boot() instead of mount(). ``` Release-please uses these to cut version bumps and generate `CHANGELOG.md`. ## Pull Requests 1. Fork and branch from `main`. Name the branch after the change (e.g. `fix/snapshot-null-guard`). 2. Keep PRs focused — one concern per PR. 3. Update or add a skill under `.claude/skills/` if your change alters a documented API or pattern. 4. Include a description explaining **why**, not just **what** — the diff shows the what. 5. Link relevant discussions or issues. 6. CI will re-run `portman build` on your PR and auto-commit `dist/` changes, so you don't need to include `dist/` diffs if you don't want to. But committing them locally first avoids conflicts. ### What gets rejected - Edits to `dist/`, `lib/Livewire/`, or `node_modules/`. - Commits with non-Conventional-Commit messages. - Runtime behavior changes without a matching update to the relevant skill doc under `.claude/skills/`. - Changes that skip `mago format` / `php-cs-fixer`. ## Testing ### Playwright E2E ```bash cd tests/Playwright cp .env.example .env # configure BASE_URL + credentials npm install && npx playwright install npx playwright test # headless npx playwright test --ui # interactive npx playwright test tests/example.spec.ts # single file ``` Requires Magento with Sample Data installed. Fixtures provide guest, customer, admin, and API browser contexts. ### Manual Install the module into a real Magento 2 project via Composer path repository during development: ```json { "repositories": [ { "type": "path", "url": "/path/to/magewire" } ], "require": { "magewirephp/magewire": "*" } } ``` ## Skills (Claude / AI Context) The `.claude/skills/` tree contains deep-context reference files that agents and contributors can load on demand. If you add, remove, or significantly change a public API — component lifecycle, directive, Feature registration, snapshot shape — update the matching skill. Keep skills and code in lockstep. Core skills (theme-agnostic): - `magewire` — component API, lifecycle hooks, `wire:*` directives - `magewire-architecture` — Mechanisms, Features, snapshot flow, DI patterns - `magewire-javascript` — CSP-compatible JS, Alpine.js integration - `magewire-portman` — Portman workflow, augmentation files - `magewire-best-practices` — component/template/DI/events/security rules - `magewire-theming` — building theme compatibility modules - `magewire-backwards-compatibility` — v1 → v3 BC layer ## Releases Automated via [release-please](https://github.com/googleapis/release-please). On merge to `main` with Conventional Commits, release-please opens a release PR that bumps the version and updates `CHANGELOG.md`. Merging the release PR tags and publishes to Packagist. Manual release steps should never be needed. If release-please misbehaves, open a discussion. ## License By contributing, you agree your contributions will be licensed under the [MIT License](LICENSE.md).