From 290df7d72d41317d8806206adbd36e6f535e2e32 Mon Sep 17 00:00:00 2001 From: Richard McDaniel <1130888+rmcdaniel@users.noreply.github.com> Date: Fri, 13 Nov 2026 17:08:57 +0000 Subject: [PATCH] Prepare the PHP 8.2 embedded transition on owned container data --- .github/workflows/ci.yml | 26 ++++++---- .../ci/laravel-service-transition-smoke.sh | 48 +++++++++++-------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aee86a1f..8f02f532 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -998,6 +998,7 @@ jobs: name: Laravel ${{ matrix.source }} to service mode runs-on: ubuntu-24.04 timeout-minutes: 20 + needs: action-policy strategy: fail-fast: false matrix: @@ -1009,22 +1010,29 @@ jobs: workflow: '^1.0' steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: - python-version: '3.12' + persist-credentials: false + - name: Check out the fixed APT prerequisite + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + repository: durable-workflow/.github + ref: 18783be6bef737cc778e4c7282a8797e39daa61a + path: .central-apt-source + persist-credentials: false + - name: Select Ubuntu's Python 3.12 + run: | + /usr/bin/python3 -I -S -c 'import sys; assert sys.version_info[:2] == (3, 12)' + echo /usr/bin >> "$GITHUB_PATH" - name: Select authenticated dependency trust - uses: durable-workflow/.github/.github/actions/bootstrap-patched-pip@75587fc33ff40c34f32ef777293dad56bb6f48c7 # clean-trust + uses: durable-workflow/.github/.github/actions/bootstrap-patched-pip@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 # clean-trust with: clients: pip,python,composer,curl,git - name: Disable APT download retries (CVE-2026-109518) run: echo 'Acquire::Retries "0";' | sudo tee /etc/apt/apt.conf.d/99-no-retries >/dev/null - - uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 - with: - php-version: ${{ matrix.php }} - tools: composer:2.10.3 - coverage: none + - name: Prepare the reviewed PHP container runtime + run: bash "$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh" "8.2" - name: Verify Composer trust before requests - uses: durable-workflow/.github/.github/actions/verify-composer-trust@75587fc33ff40c34f32ef777293dad56bb6f48c7 # clean-trust + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 # clean-trust - name: Exercise the established Laravel application transition env: LARAVEL_REQUIREMENT: ${{ matrix.laravel }} diff --git a/scripts/ci/laravel-service-transition-smoke.sh b/scripts/ci/laravel-service-transition-smoke.sh index 529b3ddf..4174a3c7 100755 --- a/scripts/ci/laravel-service-transition-smoke.sh +++ b/scripts/ci/laravel-service-transition-smoke.sh @@ -12,11 +12,17 @@ if [[ "$source_mode" != embedded_v1 && "$source_mode" != embedded_v2 ]]; then exit 1 fi -temporary_root="${RUNNER_TEMP:-${TMPDIR:-/tmp}}" -if [ -d /dev/shm ] && [ -w /dev/shm ]; then - database_root=/dev/shm -else +if [[ -n "${SDK_PHP_CI_STATE:-}" ]]; then + # All PHP invocations share this owned data mount; host controls stay RO. + temporary_root="$SDK_PHP_CI_STATE/data" database_root="$temporary_root" +else + temporary_root="${RUNNER_TEMP:-${TMPDIR:-/tmp}}" + if [ -d /dev/shm ] && [ -w /dev/shm ]; then + database_root=/dev/shm + else + database_root="$temporary_root" + fi fi fixture_root=$(mktemp -d "${temporary_root%/}/laravel-service-transition.XXXXXX") @@ -288,12 +294,12 @@ fi composer dump-autoload --no-interaction --no-scripts --quiet queue_depth() { - QUEUE_NAME="$1" DATABASE_PATH="$database_path" php -r ' - $database = new PDO("sqlite:".getenv("DATABASE_PATH")); + php -r ' + $database = new PDO("sqlite:".$argv[1]); $statement = $database->prepare("SELECT COUNT(*) FROM jobs WHERE queue = :queue"); - $statement->execute(["queue" => getenv("QUEUE_NAME")]); + $statement->execute(["queue" => $argv[2]]); echo (int) $statement->fetchColumn(); - ' + ' "$database_path" "$1" } drain_queue() { @@ -312,10 +318,10 @@ drain_queue() { } hash_source_tables() { - TABLES="$source_tables" DATABASE_PATH="$database_path" php -r ' - $database = new PDO("sqlite:".getenv("DATABASE_PATH")); + php -r ' + $database = new PDO("sqlite:".$argv[1]); $snapshot = []; - foreach (explode(",", getenv("TABLES")) as $table) { + foreach (explode(",", $argv[2]) as $table) { $statement = $database->query(sprintf("SELECT * FROM \"%s\" ORDER BY rowid", $table)); if ($statement === false) { throw new RuntimeException("Missing embedded history table {$table}."); @@ -323,7 +329,7 @@ hash_source_tables() { $snapshot[$table] = $statement->fetchAll(PDO::FETCH_ASSOC); } echo hash("sha256", json_encode($snapshot, JSON_THROW_ON_ERROR)); - ' + ' "$database_path" "$source_tables" } php artisan transition:embedded-start embedded-completed >/dev/null @@ -333,12 +339,12 @@ if [ "$source_mode" = embedded_v2 ]; then drain_queue "$source_queue" fi embedded_result=$(php artisan transition:embedded-inspect embedded-completed) -EMBEDDED_RESULT="$embedded_result" php -r ' - $result = json_decode(getenv("EMBEDDED_RESULT"), true, 512, JSON_THROW_ON_ERROR); +php -r ' + $result = json_decode($argv[1], true, 512, JSON_THROW_ON_ERROR); if ($result["completed"] !== true || $result["output"] !== "hello from Laravel, Ada") { throw new RuntimeException("The established embedded workflow did not preserve its injected dependency and result."); } -' +' "$embedded_result" if [ "$source_mode" = embedded_v1 ]; then php artisan transition:embedded-start embedded-open --open >/dev/null @@ -347,12 +353,12 @@ else fi drain_queue "$source_queue" embedded_open=$(php artisan transition:embedded-inspect embedded-open) -EMBEDDED_RESULT="$embedded_open" php -r ' - $result = json_decode(getenv("EMBEDDED_RESULT"), true, 512, JSON_THROW_ON_ERROR); +php -r ' + $result = json_decode($argv[1], true, 512, JSON_THROW_ON_ERROR); if ($result["completed"] !== false) { throw new RuntimeException("The coexistence rehearsal did not retain an open embedded-owned run."); } -' +' "$embedded_open" source_state_before=$(hash_source_tables) sdk_path=$(cd "$sdk_path" && pwd) @@ -553,12 +559,12 @@ if [ "$source_state_after_service" != "$source_state_before" ]; then fi embedded_open_after=$(php artisan transition:embedded-inspect embedded-open) -EMBEDDED_RESULT="$embedded_open_after" php -r ' - $result = json_decode(getenv("EMBEDDED_RESULT"), true, 512, JSON_THROW_ON_ERROR); +php -r ' + $result = json_decode($argv[1], true, 512, JSON_THROW_ON_ERROR); if ($result["completed"] !== false) { throw new RuntimeException("The embedded-owned open run did not remain routed to its original engine."); } -' +' "$embedded_open_after" printf 'source_mode=%s laravel=%s workflow=%s sdk=2.0.x-dev result=%s history_owner=embedded status=passed\n' \ "$source_mode" "$laravel_requirement" "$source_version_after" 'hello from Laravel, Ada'