Compare commits

..
Author SHA1 Message Date
Jeppe B 8e528f3eae Fix null path confirmation rows 2026-06-01 19:53:40 +02:00
Jeppe B bb98df9e73 Merge pull request #164 from copenhagentruckwash/fix-truckwash-edge-gateway-stack.service-errors
Fix edge gateway PHP Docker extension setup
2026-06-01 19:30:15 +02:00
Jeppe B fe3719530a Fix edge gateway PHP image extensions 2026-06-01 19:19:01 +02:00
Jeppe B 603f497bef Merge pull request #163 from copenhagentruckwash/investigate-test-failure-issues
ci: retry Release Manager gate on transient 504s
2026-06-01 17:09:13 +02:00
6 changed files with 46 additions and 7 deletions
@@ -4319,8 +4319,10 @@ class selfserve_studio_graph
int $terminalPathCount,
array $questionIds,
array $progress = [],
array $confirmationRows = []
?array $confirmationRows = null
): array {
$confirmationRows = $confirmationRows ?? [];
usort($outcomes, static fn(array $left, array $right): int => ((int)($right['path_count'] ?? 0) <=> (int)($left['path_count'] ?? 0))
?: strcmp((string)($left['summary'] ?? ''), (string)($right['summary'] ?? '')));
foreach ($outcomes as $index => &$outcome) {
@@ -3,9 +3,10 @@ FROM ${BASE_IMAGE}
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends bash ca-certificates curl docker.io docker-compose; \
rm -rf /var/lib/apt/lists/*; \
php -r 'foreach (["curl", "sqlite3"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, "Missing PHP extension: {$extension}\n"); exit(1); } }'
apt-get install -y --no-install-recommends bash ca-certificates curl docker.io docker-compose libcurl4-openssl-dev libsqlite3-dev; \
docker-php-ext-install -j"$(nproc)" curl sqlite3 pdo_sqlite; \
php -r 'foreach (["curl", "sqlite3"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, "Missing PHP extension: {$extension}\n"); exit(1); } }'; \
rm -rf /var/lib/apt/lists/*
COPY auto-updater.php /usr/local/bin/auto-updater.php
@@ -2,7 +2,11 @@ ARG BASE_IMAGE=php:8.2-cli-bookworm
FROM ${BASE_IMAGE}
RUN set -eux; \
php -r 'foreach (["curl", "sqlite3"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, "Missing PHP extension: {$extension}\n"); exit(1); } }'
apt-get update; \
apt-get install -y --no-install-recommends libcurl4-openssl-dev libsqlite3-dev; \
docker-php-ext-install -j"$(nproc)" curl sqlite3 pdo_sqlite; \
php -r 'foreach (["curl", "sqlite3"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, "Missing PHP extension: {$extension}\n"); exit(1); } }'; \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/truckwash-edge-agent
@@ -2,7 +2,11 @@ ARG BASE_IMAGE=php:8.2-cli-bookworm
FROM ${BASE_IMAGE}
RUN set -eux; \
php -r 'foreach (["curl", "sqlite3"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, "Missing PHP extension: {$extension}\n"); exit(1); } }'
apt-get update; \
apt-get install -y --no-install-recommends libcurl4-openssl-dev libsqlite3-dev; \
docker-php-ext-install -j"$(nproc)" curl sqlite3 pdo_sqlite; \
php -r 'foreach (["curl", "sqlite3"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, "Missing PHP extension: {$extension}\n"); exit(1); } }'; \
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/truckwash-edge-agent
@@ -97,16 +97,21 @@ it('builds the installer around the compose stack artifacts and management polli
expect($agentSource)->toContain("'last_transport_error'");
expect($agentSource)->toContain('private function recordTransportFailure(string $context, Throwable $throwable): void');
expect($edgeDockerfileSource)->toContain('FROM ${BASE_IMAGE}');
expect($edgeDockerfileSource)->toContain('apt-get install -y --no-install-recommends libcurl4-openssl-dev libsqlite3-dev;');
expect($edgeDockerfileSource)->toContain('docker-php-ext-install -j"$(nproc)" curl sqlite3 pdo_sqlite;');
expect($edgeDockerfileSource)->toContain('extension_loaded($extension)');
expect($edgeDockerfileSource)->toContain('Missing PHP extension: {$extension}');
expect($edgeDockerfileSource)->toContain('COPY agent.php /opt/truckwash-edge-agent/agent.php');
expect($workerDockerfileSource)->toContain('FROM ${BASE_IMAGE}');
expect($workerDockerfileSource)->toContain('apt-get install -y --no-install-recommends libcurl4-openssl-dev libsqlite3-dev;');
expect($workerDockerfileSource)->toContain('docker-php-ext-install -j"$(nproc)" curl sqlite3 pdo_sqlite;');
expect($workerDockerfileSource)->toContain('extension_loaded($extension)');
expect($workerDockerfileSource)->toContain('Missing PHP extension: {$extension}');
expect($workerDockerfileSource)->toContain('COPY lan-worker.php /opt/truckwash-edge-agent/lan-worker.php');
expect($autoUpdaterSource)->toContain("'/bin/bash ' . escapeshellarg(\$launcherPath) . ' reconcile 2>&1'");
expect($autoUpdaterDockerfileSource)->toContain('COPY auto-updater.php /usr/local/bin/auto-updater.php');
expect($autoUpdaterDockerfileSource)->toContain('apt-get install -y --no-install-recommends bash ca-certificates curl docker.io docker-compose;');
expect($autoUpdaterDockerfileSource)->toContain('apt-get install -y --no-install-recommends bash ca-certificates curl docker.io docker-compose libcurl4-openssl-dev libsqlite3-dev;');
expect($autoUpdaterDockerfileSource)->toContain('docker-php-ext-install -j"$(nproc)" curl sqlite3 pdo_sqlite;');
expect($autoUpdaterDockerfileSource)->toContain('extension_loaded($extension)');
expect($serviceSource)->not->toContain('node /opt/truckwash-edge-agent/agent.mjs');
});
@@ -1265,6 +1265,29 @@ it('marks projected path confirmations confirmed or stale by stable signatures',
->and($changed['summary']['confirmations']['stale'])->toBe(1);
});
it('treats null path confirmation rows as an empty confirmation set', function (): void {
$service = selfserve_studio_graph_without_constructor();
$method = new ReflectionMethod(selfserve_studio_graph::class, 'pathOutcomesPayload');
$payload = $method->invoke(
$service,
['department_id' => 6, 'lane_id' => 7],
[],
[],
[],
false,
null,
0,
0,
[],
[],
null
);
expect($payload['summary']['confirmations']['total'])->toBe(0)
->and($payload['confirmations']['removed'])->toBe([]);
});
it('truncates path outcome projection when the state cap is reached', function (): void {
$service = selfserve_studio_graph_without_constructor();
$simulate = function (array $overrides): array {