# 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. Same-repository branches receive an automatic `dist/` commit; fork PRs must include the generated changes themselves. 7. Fork PRs run all public checks automatically. The private Hyvä Playwright suite is prepared against the exact PR revision and waits for a maintainer to approve the `trusted-fork-tests` environment before it runs. ### 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).