Plugin API
This reference lists plugin capabilities and lifecycle callback contracts.
These signatures are the public API.
AfterTestSubscriber
Namespace: Greenlight\Plugin
Lets a plugin act after each test attempt in a worker.
Greenlight runs higher priorities first. It uses reverse registration order for equal priorities. Plugins that implement both subscriber capabilities run their after callbacks in the exact reverse order. Greenlight runs all after subscribers even when a before subscriber stops the attempt.
The method receives and returns the result. A plugin can return the same
result or a replacement. Use TestResult::withOutcome() for outcome changes
so that the result records their source.
interface AfterTestSubscriber extends Plugin
afterTest()
public function afterTest(TestContext $context, TestResult $result): TestResult;
AttachmentRetentionDecider
Namespace: Greenlight\Plugin
Changes the publication decision for one completed test attachment.
interface AttachmentRetentionDecider extends Plugin
retainAttachment()
public function retainAttachment(
TestResult $result,
Attachment $attachment,
bool $retain,
): bool;
BeforeTestSubscriber
Namespace: Greenlight\Plugin
Lets a plugin act before each test attempt in a worker.
Greenlight runs lower priorities first. It uses registration order for equal priorities. A skip or failure stops the remaining before subscribers.
interface BeforeTestSubscriber extends Plugin
beforeTest()
Greenlight calls this method after it constructs the test instance and
before the before hooks. $context->skip() or SkipTest reports a
skipped test. Other throwables cause errors that name the plugin.
public function beforeTest(TestContext $context): void;
PHPDoc:
@throws SkipTest
CommandDefinition
Namespace: Greenlight\Plugin
Defines one named command-line command.
final readonly class CommandDefinition
$name
public string $name;
PHPDoc:
@var non-empty-string
$description
public string $description;
PHPDoc:
@var non-empty-string
__construct()
public function __construct(
string $name,
string $description,
private \Closure $handler,
)
PHPDoc:
@param \Closure(CommandInvocation): CommandResult $handler@throws \InvalidArgumentException
CommandInvocation
Namespace: Greenlight\Plugin
Contains the input and output channels for one plugin command invocation.
final readonly class CommandInvocation
$command
public string $command
$arguments
public array $arguments
$workingDirectory
public string $workingDirectory
$binaryPath
public ?string $binaryPath
write()
Write exact text to standard output.
public function write(string $text): void
writeError()
Write exact text to standard error.
public function writeError(string $text): void
CommandProvider
Namespace: Greenlight\Plugin
Supplies named command-line commands.
interface CommandProvider extends Plugin
commands()
public function commands(): array;
PHPDoc:
@return list<CommandDefinition>
CommandResult
Namespace: Greenlight\Plugin
Contains the result that a Greenlight command returns. An interrupted result contains a signal number from 1 through 127.
final readonly class CommandResult
success()
public static function success(): self
failure()
public static function failure(): self
usage()
public static function usage(): self
interrupted()
public static function interrupted(int $signal): self
PHPDoc:
@throws \InvalidArgumentException if the signal is outside 1 through 127
CoverageMapTransformer
Namespace: Greenlight\Plugin
Changes the merged coverage map before Greenlight exports it.
interface CoverageMapTransformer extends Plugin
transformCoverageMap()
public function transformCoverageMap(CoverageMap $coverage): CoverageMap;
HarnessProvider
Namespace: Greenlight\Plugin
Adds harness services to the worker registry.
Greenlight adds built-in services before services() results. A duplicate
type in the same source causes a configuration error. Unnamed definitions
share one source. Different named sources can define the same type.
interface HarnessProvider extends Plugin
services()
public function services(): array;
PHPDoc:
@return list<ServiceDefinition>
IntegrationFixtureProvider
Namespace: Greenlight\Plugin
Supplies orchestrator-owned infrastructure for one test run.
interface IntegrationFixtureProvider extends Plugin
integrationFixtures()
public function integrationFixtures(): array;
PHPDoc:
@return list<IntegrationFixtureDefinition>
Plugin
Namespace: Greenlight\Plugin
Identifies an object as a Greenlight plugin.
Plugins implement one or more capability interfaces. The plugin guide lists each command, orchestrator, and worker capability.
interface Plugin
This type does not declare public members.
Prioritized
Namespace: Greenlight\Plugin
Controls order within each plugin capability. Capability interfaces define whether callbacks use or reverse this order. The default value is zero. The base order puts lower values first and keeps registration order for equal values. Greenlight reads the value one time for each owner-local plugin instance.
interface Prioritized
priority()
public function priority(): int;
ReporterProvider
Namespace: Greenlight\Plugin
Supplies named reporter factories to the command-line reporter registry.
Greenlight calls reporters() one time for a command. It calls a selected
factory for each run, including each repeat or watch run.
interface ReporterProvider extends Plugin
reporters()
Return a new reporter for each factory call. Do not close the supplied output because Greenlight owns it.
public function reporters(): array;
PHPDoc:
@return list<ReporterDefinition>
RetryDecider
Namespace: Greenlight\Plugin
A worker checks retry deciders after each failed or errored attempt. Greenlight runs lower priorities first and uses registration order for equal priorities. It stops at the first decider that returns true.
A true result starts a new attempt with a new test instance and a new
service scope.
A false result permits the next decider to check the attempt. It does not
prevent another decider, including the built-in retry policy, from retrying.
shouldRetry() receives the retry policy, result, attempt number, and
optional cause. It does not receive TestContext because the attempt is
complete.
interface RetryDecider extends Plugin
shouldRetry()
public function shouldRetry(RetryPolicy $policy, TestResult $result, int $attempt, ?\Throwable $cause): bool;
RunAcceptancePolicy
Namespace: Greenlight\Plugin
Evaluates an otherwise successful run without changing test outcomes.
Greenlight calls each policy one time after reporters finish. It runs lower priorities first and uses registration order for equal priorities. Return null to accept the run. Return a non-empty failure message to reject it. Greenlight runs all policies and reports all rejection messages.
interface RunAcceptancePolicy extends Plugin
failureMessage()
public function failureMessage(ResultSummary $summary, int $retriedPasses): ?string;
PHPDoc:
@param non-negative-int $retriedPasses
RunLifecycleSubscriber
Namespace: Greenlight\Plugin
Observes the orchestrator event stream.
onRunEvent() receives run, worker, class, and test events in arrival order.
The subscriber only observes events and cannot change results.
interface RunLifecycleSubscriber extends Plugin
onRunEvent()
public function onRunEvent(Event $event): void;
TerminalResultTransformer
Namespace: Greenlight\Plugin
Transforms a test result after retries and test-scope teardown complete.
Greenlight runs lower priorities first. It uses registration order for equal priorities. Greenlight calls each transformer one time for each executed test, before the worker finalizes the class scope and publishes the result.
A plugin can return the same result or a replacement. Preserve the test
identity. Use TestResult::withOutcome() for outcome changes so that the
result records their source. Greenlight contains transformer failures and
continues with the remaining transformers.
interface TerminalResultTransformer extends Plugin
transformTerminalResult()
public function transformTerminalResult(TestDefinition $definition, TestResult $result): TestResult;
TestAttemptRunner
Namespace: Greenlight\Plugin
Runs each complete test attempt in a plugin-defined runtime boundary.
interface TestAttemptRunner extends Plugin
runTestAttempt()
public function runTestAttempt(\Closure $attempt): mixed;
PHPDoc:
@template T@param \Closure(): T $attempt@return T
TestContext
Namespace: Greenlight\Plugin
Supplies the test instance, identity, attachments, and service access to plugins.
The per-test service scope closes before afterTest(). A service() call
for a per-test service then throws. Other service scopes remain available.
final readonly class TestContext
$attachments
public Attachments $attachments;
$instance
public object $instance
$id
public TestId $id
$definition
public TestDefinition $definition
service()
public function service(string $type): object
PHPDoc:
@template T of object@param class-string<T> $type@return T@throws ServiceResolutionFailed when a service resolver cannot supply a valid service
skip()
Stops the current attempt during beforeTest(). Code after the call does
not run.
public function skip(string $reason): never
PHPDoc:
@param non-empty-string $reason@throws SkipTest
TestPlan
Namespace: Greenlight\Plugin
Contains the selected tests for one run in execution order. Each test ID occurs once. Tests from each class form one consecutive block.
final readonly class TestPlan
$tests
public array $tests
withTests()
Returns a plan with replacement test selection and order. Keep each test ID unique and each class in one consecutive block.
public function withTests(array $tests): self
PHPDoc:
@param list<TestId> $tests@throws \InvalidArgumentException if a test ID repeats or a class occurs in separate blocks
TestPlanTransformer
Namespace: Greenlight\Plugin
Removes or reorders selected tests before a run starts. Each replacement can contain only tests from the plan the plugin receives. A later transformer cannot restore a test that an earlier transformer removed.
interface TestPlanTransformer extends Plugin
transformTestPlan()
public function transformTestPlan(TestPlan $plan): TestPlan;
WatchSource
Namespace: Greenlight\Plugin
Reports changes that cause a watch-mode rerun.
interface WatchSource extends Plugin
poll()
public function poll(): array;
PHPDoc:
@return list<non-empty-string> changed paths or trigger labels since the previous poll
WorkerBootstrapContext
Namespace: Greenlight\Plugin
Worker-local view of orchestrator-provisioned integration resources.
final readonly class WorkerBootstrapContext
$workerId
public string $workerId
$channel
public TestChannel $channel
$resources
public IntegrationResources $resources
__construct()
public function __construct(
public string $workerId,
public TestChannel $channel,
public IntegrationResources $resources,
)
PHPDoc:
@param non-empty-string $workerId
WorkerBootstrapSubscriber
Namespace: Greenlight\Plugin
Initializes one worker after fixture data arrives and before Greenlight uses harness providers or service resolvers.
interface WorkerBootstrapSubscriber extends Plugin
onWorkerBootstrap()
public function onWorkerBootstrap(WorkerBootstrapContext $context): void;
WorkerRuntimeRunner
Namespace: Greenlight\Plugin
Runs one physical worker in a plugin-defined runtime boundary.
interface WorkerRuntimeRunner extends Plugin
runWorker()
public function runWorker(\Closure $worker): mixed;
PHPDoc:
@template T@param \Closure(): T $worker@return T