Skip to content

Latest commit

 

History

History
195 lines (144 loc) · 6.57 KB

File metadata and controls

195 lines (144 loc) · 6.57 KB

Contributing to nr_llm

Thank you for your interest in contributing to the TYPO3 LLM extension!

Development Setup

Prerequisites

  • PHP 8.2+
  • DDEV for local development
  • Composer
  • Node.js 20+ (for E2E tests)

Getting Started

# Clone the repository
git clone https://github.com/netresearch/t3x-nr-llm.git
cd t3x-nr-llm

# Start DDEV
ddev start

# Install dependencies
ddev composer install

# Run tests
ddev exec ".Build/bin/phpunit -c Build/phpunit.xml"

Code Quality

Before submitting a PR, ensure all checks pass:

# Code style, PHPStan, unit, integration and fuzzy tests.
# Rector and the functional tests are not part of this script — CI runs those
# too, so run them individually before pushing.
ddev exec "composer ci"

# Or run individually:
ddev exec ".Build/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --dry-run"
ddev exec ".Build/bin/phpstan analyse -c Build/phpstan/phpstan.neon"
ddev exec ".Build/bin/phpunit -c Build/phpunit.xml"
ddev exec ".Build/bin/rector process --config=Build/rector/rector.php --dry-run"

API Stability Markers

Every class-level docblock carries @api, @api Extension point: … or @internal (ADR-127, Documentation/Api/Stability.rst). New classes pick a marker at creation time. @api means the semver promise covers it — every type in its method signatures must be @api too. Extension-point interfaces must not gain a new abstract member within a major version. Everything else is @internal.

The rendered @api surface — constructors included — is frozen in Tests/Unit/Api/api-surface.txt. The snapshot test classifies its own failure: additive (a new class, method, property, constant or enum case) means regenerate the file and note it under ### Added; breaking (anything removed or changed, a widened constructor included) means stop and decide.

Removing or narrowing something @api follows Documentation/Api/Deprecation.rst: deprecate in a minor, keep it working through one further minor line, remove in the next major, and add the migration row the inventory test requires. Which TYPO3 and PHP versions the promise is made on is Documentation/Api/SupportMatrix.rst, and it is asserted against composer.json, ext_emconf.php and the CI matrix.

Testing Requirements

All contributions MUST include appropriate tests.

Change Type Required Tests
New feature Unit tests + Integration tests
Bug fix Regression test (proves the fix)
Refactoring Existing tests must pass
New provider Unit tests + Integration tests
API changes Update affected tests

Test Types

# Unit tests
composer ci:test:php:unit

# Integration tests
composer ci:test:php:integration

# Functional tests (requires DDEV)
ddev exec "composer ci:test:php:functional"

# Fuzzy/Property-based tests
composer ci:test:php:fuzzy

# Mutation tests (code quality)
composer ci:test:php:mutation

# E2E tests (requires DDEV + Playwright)
npm run test:e2e

Coverage Requirements

  • New code should have reasonable test coverage
  • Critical paths (security, API calls) require high coverage
  • Run composer test -- --coverage-html=coverage to view coverage report

Security Guidelines

  • Never commit secrets (API keys, passwords, tokens)
  • Escape all output - use htmlspecialchars() for HTML, Fluid auto-escaping
  • Validate all input - use DTOs with type-safe extraction
  • Use parameterized queries - Extbase Query or QueryBuilder
  • Report vulnerabilities privately via GitHub Security Advisories

See SECURITY.md for vulnerability reporting.

Pull Request Process

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Write/update tests (required)
  5. Ensure all tests pass
  6. Commit using conventional commits
  7. Push and open a Pull Request

PR Checklist

  • Tests added/updated
  • All CI checks pass
  • Documentation updated (if applicable)
  • CHANGELOG.md entry added under ## [Unreleased]
  • ADR added under Documentation/Adr/ if the public surface changed
  • No secrets committed
  • Follows existing code style

Changelog and ADRs

Every change that a consumer or an integrator can notice gets a CHANGELOG.md entry under ## [Unreleased], in the Keep a Changelog section that fits (Added / Changed / Deprecated / Removed / Fixed / Security). Version bumps belong to the release commit, never to a feature PR.

A change to the public surface also gets an Architecture Decision Record under Documentation/Adr/, named Adr<N><Description>.rst — take the next free number and follow the format of an existing one. Add the file name to the toctree at the bottom of Documentation/Adr/Index.rst as well; that toctree is explicit, so an unregistered ADR renders as an orphan page nothing links to. Public surface means anything a consumer builds against: an interface, a DI-tagged extension point, a database table, a TCA field, an Extension Configuration key, a console command, or the behaviour of any of them. Recording why matters more than recording what; the diff already shows what.

Commit Messages

We use conventional commits:

  • feat: New features
  • fix: Bug fixes
  • docs: Documentation changes
  • refactor: Code refactoring
  • test: Test changes
  • chore: Maintenance tasks
  • security: Security fixes

Adding a New Provider

  1. Create a new class extending AbstractProvider
  2. Implement required methods
  3. Add unit tests in Tests/Unit/Provider/
  4. Add integration tests in Tests/Integration/Provider/
  5. Update documentation in Documentation/
  6. Add to TCA adapter type options

Code Review

All PRs require review by a code owner before merging. Reviews focus on:

  • Code quality and maintainability
  • Test coverage and quality
  • Security considerations
  • Documentation completeness

Questions?

Open an issue or start a discussion!

Commit Signing

All commits must be cryptographically signed and carry a DCO sign-off: git commit -S --signoff. The require-signed-commits ruleset on the default branch enforces the signature (the "Verified" badge on GitHub); the DCO check enforces the Signed-off-by trailer — these are two different things and both are required. Quickest setup is SSH signing: register your SSH key as a signing key on your GitHub account, then git config --global gpg.format ssh && git config --global user.signingkey ~/.ssh/<key>.pub.