Skip to content

Commit b7b7d63

Browse files
authored
Merge branch '1.x' into nw-1258-implement-deployment-tagging-system-for-nightwatch-graphs
2 parents 87720e0 + 1be43d6 commit b7b7d63

10 files changed

Lines changed: 122 additions & 18 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
# Release Notes
22

3-
## [Unreleased](https://github.com/laravel/nightwatch/compare/v1.22.0...1.x)
3+
## [Unreleased](https://github.com/laravel/nightwatch/compare/v1.24.0...1.x)
4+
5+
### Added
6+
7+
- Laravel 13 support
8+
9+
## [v1.24.0](https://github.com/laravel/nightwatch/compare/v1.23.0...v1.24.0) - 2026-02-27
10+
11+
### What's Changed
12+
13+
* Laravel 13 support by [@jessarcher](https://github.com/jessarcher) in https://github.com/laravel/nightwatch/pull/335
14+
15+
**Full Changelog**: https://github.com/laravel/nightwatch/compare/v1.23.0...v1.24.0
16+
17+
## [v1.23.0](https://github.com/laravel/nightwatch/compare/v1.22.0...v1.23.0) - 2026-02-27
18+
19+
### What's Changed
20+
21+
* Ignore Livewire checksum failure cache keys by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/nightwatch/pull/331
22+
* Add `Nightwatch::digest` to proactively transmit events to the agent by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/nightwatch/pull/330
23+
24+
**Full Changelog**: https://github.com/laravel/nightwatch/compare/v1.22.3...v1.23.0
425

526
## [v1.22.0](https://github.com/laravel/nightwatch/compare/v1.21.1...v1.22.0) - 2026-01-15
627

‎agent/build/agent.phar‎

475 Bytes
Binary file not shown.

‎agent/build/signature.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0389423268858E42BBF5CE5338A2515B812A14A30FE5E79C4B19A7C3D3C45426C1061A5C34CA67300409BA190E583F1D5BFC39B7965E255675DBEA180A75A5C2
1+
EEFAD35214A42F62A817D01F5805400DCA2E15A50631BEE1AFF51DED19103C51460A44D5D4F496521EA85EA3D1893CEF0311CEE55B13229DEFC770936B5783A5

‎agent/composer.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
"@php vendor/bin/phpunit"
6363
],
6464
"build": [
65-
"bash ./build.sh"
65+
"bash ./build.sh",
66+
"([ ! \"${CI}\" ] && composer install) || true"
6667
],
6768
"watch": [
6869
"npm ci",

‎agent/src/Ingest.php‎

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class Ingest
3030
*/
3131
private array $concurrentRequests = [];
3232

33-
private ?TimerInterface $sendBufferAfterDelayTimer = null;
33+
private ?TimerInterface $digestDelayTimer = null;
3434

3535
private StreamBuffer|NullBuffer $buffer;
3636

@@ -58,19 +58,21 @@ public function __construct(
5858

5959
public function write(string $payload): void
6060
{
61+
if ($this->buffer->isNotEmpty() && $this->buffer->willExceedThresholdWith($payload)) {
62+
$this->cancelDigestDelay();
63+
64+
$this->digest();
65+
}
66+
6167
$this->buffer->write($payload);
6268

6369
if ($this->buffer->reachedThreshold()) {
64-
if ($this->sendBufferAfterDelayTimer !== null) {
65-
$this->loop->cancelTimer($this->sendBufferAfterDelayTimer);
66-
67-
$this->sendBufferAfterDelayTimer = null;
68-
}
70+
$this->cancelDigestDelay();
6971

7072
$this->digest();
7173
} elseif ($this->buffer->isNotEmpty()) {
72-
$this->sendBufferAfterDelayTimer ??= $this->loop->addTimer($this->maxBufferDurationInSeconds, function () {
73-
$this->sendBufferAfterDelayTimer = null;
74+
$this->digestDelayTimer ??= $this->loop->addTimer($this->maxBufferDurationInSeconds, function () {
75+
$this->digestDelayTimer = null;
7476

7577
$this->digest();
7678
});
@@ -82,9 +84,7 @@ public function write(string $payload): void
8284
*/
8385
public function forceDigest(): PromiseInterface
8486
{
85-
if ($this->sendBufferAfterDelayTimer !== null) {
86-
$this->loop->cancelTimer($this->sendBufferAfterDelayTimer);
87-
}
87+
$this->cancelDigestDelay();
8888

8989
if ($this->buffer->isNotEmpty()) {
9090
$this->digest();
@@ -223,4 +223,12 @@ private function parseResponse(ResponseInterface $response): array
223223
$refreshIn,
224224
];
225225
}
226+
227+
private function cancelDigestDelay(): void
228+
{
229+
if ($this->digestDelayTimer !== null) {
230+
$this->loop->cancelTimer($this->digestDelayTimer);
231+
$this->digestDelayTimer = null;
232+
}
233+
}
226234
}

‎agent/src/NullBuffer.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ public function reachedThreshold(): bool
1414
return false;
1515
}
1616

17+
public function willExceedThresholdWith(string $payload): bool
18+
{
19+
return false;
20+
}
21+
1722
/**
1823
* @return non-empty-string
1924
*/

‎agent/src/StreamBuffer.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ public function reachedThreshold(): bool
3131
return strlen($this->buffer) >= $this->threshold;
3232
}
3333

34+
public function willExceedThresholdWith(string $payload): bool
35+
{
36+
// -2 to account for the removal of the `[` and `]` characters when
37+
// appending to the stream.
38+
return (strlen($this->buffer) + (strlen($payload) - 2)) > $this->threshold;
39+
}
40+
3441
/**
3542
* @return non-empty-string
3643
*/

‎agent/tests/Feature/IngestTest.php‎

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ public function test_it_ingests_payloads_under_the_threshold_after_10_seconds():
703703
$ingestDetailsBrowser->assertPending([]);
704704
}
705705
706-
public function test_it_ingests_payloads_before_10_seconds_if_the_buffer_exceeds_the_threshold(): void
706+
public function test_it_ingests_payloads_before_10_seconds_if_the_buffer_reaches_the_threshold(): void
707707
{
708708
$loop = new LoopFake(runForSeconds: 11);
709709
$server = new TcpServerFake;
@@ -724,7 +724,7 @@ public function test_it_ingests_payloads_before_10_seconds_if_the_buffer_exceeds
724724
ingestBrowser: $ingestBrowser,
725725
loop: $loop,
726726
server: $server,
727-
maxBufferLength: 63,
727+
maxBufferLength: 62,
728728
);
729729
730730
$this->assertNull($e, $e?->getMessage() ?? '');
@@ -803,6 +803,68 @@ public function test_it_ingests_immediately_when_buffer_is_empty_and_a_payload_o
803803
$ingestDetailsBrowser->assertPending([]);
804804
}
805805
806+
public function test_it_ingests_immediately_when_incoming_payload_will_put_buffer_over_the_threshold(): void
807+
{
808+
$loop = new LoopFake(runForSeconds: 14);
809+
$server = new TcpServerFake;
810+
$ingestDetailsBrowser = new BrowserFake([
811+
Response::jwt(),
812+
]);
813+
$ingestBrowser = new BrowserFake([
814+
Response::ingested(),
815+
Response::ingested(),
816+
]);
817+
$loop->addTimer(0, $server->pendingConnection([['t' => 'request']]));
818+
$loop->addTimer(1, $server->pendingConnection([['t' => 'request']]));
819+
$loop->addTimer(2, $server->pendingConnection([['t' => 'request']]));
820+
$loop->addTimer(3, $server->pendingConnection([['t' => 'request']]));
821+
822+
[$output, $e] = $this->runAgent(
823+
via: 'source',
824+
ingestDetailsBrowser: $ingestDetailsBrowser,
825+
ingestBrowser: $ingestBrowser,
826+
loop: $loop,
827+
server: $server,
828+
maxBufferLength: 61,
829+
);
830+
831+
$this->assertNull($e, $e?->getMessage() ?? '');
832+
$this->assertLogMatches(<<<'OUTPUT'
833+
{date} {info} Authentication successful {duration}
834+
{date} {info} Ingest successful {duration}
835+
{date} {info} Ingest successful {duration}
836+
OUTPUT, $output);
837+
$ingestBrowser->assertSent([
838+
Request::ingest([
839+
['t' => 'request'],
840+
['t' => 'request'],
841+
['t' => 'request'],
842+
]),
843+
Request::ingest([
844+
['t' => 'request'],
845+
]),
846+
]);
847+
$ingestBrowser->assertProcessing([]);
848+
$ingestBrowser->assertPending([]);
849+
$loop->assertRun([
850+
new Timer(interval: 0, runAt: 0, scheduledAt: 0, scheduledBy: $this->functionName()),
851+
new Timer(interval: 1, runAt: 1, scheduledAt: 0, scheduledBy: $this->functionName()),
852+
new Timer(interval: 2, runAt: 2, scheduledAt: 0, scheduledBy: $this->functionName()),
853+
new Timer(interval: 3, runAt: 3, scheduledAt: 0, scheduledBy: $this->functionName()),
854+
new Timer(interval: 10, runAt: 13, scheduledAt: 3, scheduledBy: 'Laravel\NightwatchAgent\Ingest::write'),
855+
]);
856+
$loop->assertCanceled([
857+
new Timer(interval: 10, canceledAt: 3, scheduledAt: 0, scheduledBy: 'Laravel\NightwatchAgent\Ingest::write'),
858+
]);
859+
$loop->assertPending([
860+
new Timer(interval: 3_600, runAt: 3_600, scheduledAt: 0, scheduledBy: 'Laravel\NightwatchAgent\IngestDetailsRepository::scheduleRefreshIn'),
861+
]);
862+
$ingestDetailsBrowser->assertSent([
863+
Request::json('/api/agent-auth'),
864+
]);
865+
$ingestDetailsBrowser->assertPending([]);
866+
}
867+
806868
public function test_it_stops_ingesting_data_when_exceeding_quota_during_request(): void
807869
{
808870
$loop = new LoopFake(runForSeconds: 60);

‎composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"php": "^8.2",
2424
"ext-zlib": "*",
2525
"guzzlehttp/promises": "^2.0",
26-
"laravel/framework": "^10.0|^11.0|^12.0",
26+
"laravel/framework": "^10.0|^11.0|^12.0|^13.0",
2727
"monolog/monolog": "^3.6",
2828
"nesbot/carbon": "^2.0|^3.0",
2929
"psr/http-message": "^1.0|^2.0",

‎version.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.22.0
1+
1.24.0

0 commit comments

Comments
 (0)