Skip to content

Development Workflow

mab056 edited this page Feb 15, 2026 · 3 revisions

Development Workflow

Branching and Commits

Recommended branch model:

  • Base branch: dev
  • Feature branch examples:
    • feature/<name>
    • fix/<name>

Conventional commit prefixes:

  • feat, fix, docs, refactor, test, chore

Reference:

  • CONTRIBUTING.md

Mandatory Engineering Rules

Architecture constraints:

  • No singleton pattern
  • No static methods/properties
  • No final classes/methods
  • Constructor dependency injection
  • Interface-first contracts

Coding standards:

  • WordPress Coding Standards (WPCS)
  • Tab indentation
  • Allman braces

Pattern Enforcement Tests

Every new class MUST have the following tests in its corresponding test class:

public function test_class_is_not_final() {
    $reflection = new \ReflectionClass( MyClass::class );
    $this->assertFalse( $reflection->isFinal(), 'Class should NOT be final' );
}

public function test_no_static_methods() {
    $reflection = new \ReflectionClass( MyClass::class );
    $methods    = $reflection->getMethods( \ReflectionMethod::IS_STATIC );

    $static_methods = array_filter( $methods, function( $method ) {
        return strpos( $method->getName(), '__' ) !== 0;
    } );

    $this->assertEmpty( $static_methods, 'Class should have NO static methods' );
}

This is a non-negotiable requirement, verified in code review. See Testing and Quality for details.

TDD Cycle

Required cycle for any change:

  1. RED: write failing tests first
  2. GREEN: implement minimal code to pass
  3. REFACTOR: improve code while keeping tests green

Test placement:

  • Unit: tests/Unit/
  • Integration: tests/Integration/
  • E2E (when UI/user behavior changes): tests/e2e/

Security Checklist for Changes

When touching admin forms or endpoints:

  • Add/verify capability checks
  • Add/verify nonce checks
  • Sanitize all input
  • Escape all output

When touching outbound HTTP:

  • Route calls through HttpClientInterface
  • Preserve anti-SSRF guarantees

When touching diagnostics:

  • Ensure sensitive data passes through RedactionInterface

Daily Commands

Install dependencies:

  • composer install

Run quality gate:

  • composer test
  • composer phpcs
  • composer analyse

Run matrix (CI-like local):

  • composer test:matrix

Run multisite tests (after changes to Uninstaller or multisite components):

  • composer test:integration:multisite

Run E2E manually:

  • npm ci
  • npm run env:start
  • bash bin/e2e-setup.sh
  • npm run test:e2e
  • npm run env:stop

Adding a New Health Check

High-level flow:

  1. Create a class in src/Checks/ implementing CheckInterface
  2. Inject dependencies via constructor (no globals in business logic)
  3. Add unit tests and integration tests (including pattern enforcement tests)
  4. Register the check in config/bootstrap.php inside CheckRunner setup
  5. Verify rendering in HealthScreen and DashboardWidget

Updating Alert Channels

High-level flow:

  1. Implement/modify channel class in src/Channels/
  2. Keep settings contract in sync with AlertSettings
  3. Ensure channel output is safe and escaped
  4. Add/update tests (unit + integration)
  5. Validate via E2E when UI flow changes

Definition of Done

Before merge/release, all should pass:

  • composer test
  • composer phpcs
  • composer analyse
  • Relevant E2E scenarios (if UI flow changed)
  • Pattern enforcement tests present for every new class
  • bin/build-zip.sh generates a valid ZIP

And documentation should be updated:

  • CHANGELOG.md
  • Wiki pages impacted by the change

Clone this wiki locally