diff --git a/qualification/composer-container-trust.json b/qualification/composer-container-trust.json index 2705305..ebb76c7 100644 --- a/qualification/composer-container-trust.json +++ b/qualification/composer-container-trust.json @@ -268,7 +268,7 @@ "mode": 493 }, "scripts/ci/run-php-container.sh": { - "sha256": "3381acfe8ef0eddd2b88b6acce0ae1143357ff3a61884d2c7ae274ba3ee81bd9", + "sha256": "025b2def722eed3a3e534698333478bd82d6c735dca14cf8c2dbb8c3bb0392e3", "mode": 493 }, "tests/ci/test_php_container_tls.py": { @@ -346,7 +346,241 @@ "mode": 493 }, "scripts/ci/run-php-container.sh": { - "sha256": "3381acfe8ef0eddd2b88b6acce0ae1143357ff3a61884d2c7ae274ba3ee81bd9", + "sha256": "025b2def722eed3a3e534698333478bd82d6c735dca14cf8c2dbb8c3bb0392e3", + "mode": 493 + }, + "tests/ci/test_php_container_tls.py": { + "sha256": "d73a2a3c494bd31bd4f8b5215070aa7ff4807c3e4cb75e8b3eb51d2fe057c0ae", + "mode": 420 + }, + "docker/brotli/install-vendor.sh": { + "sha256": "d7eb8b2a3e0af1c3072a56bcb81632b22f061f211d8fe5e57ee901c8bf94c92f", + "mode": 420 + }, + "docker/brotli/verify-runtime.php": { + "sha256": "580cc465e349f3872eca592355294e7320fe7f1a4560ff5d4c83d5900921c00e", + "mode": 420 + }, + "docker/brotli/verify-system-brotli.c": { + "sha256": "3353927d206aaf5e63157e46be715c6cbee46bac777e29f8f9e25c4c1f656667", + "mode": 420 + }, + "docker/brotli/version": { + "sha256": "e064953e075ddb99fb7b48ad29e215f2dfa075812c127eb1d6ab680e9920fba2", + "mode": 420 + }, + "tests/ci/test_php_container_isolation.py": { + "sha256": "209b1382e473f674dad3f6a1fbc447557dba647df2d23b70c8af1db2dab97697", + "mode": 420 + } + } + }, + "sdk-php-framework-81-ci": { + "target": "sdk-php", + "workflows": { + "ci.yml": [ + "framework-compat81" + ] + }, + "commands": [ + "bash \"$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh\" \"8.1\"" + ], + "environment": [ + "SDK_PHP_CI_IMAGE", + "SDK_PHP_CI_ROOT", + "SDK_PHP_CI_STATE" + ], + "absent_files": [ + "docker/php-ci/Dockerfile.dockerignore", + "docker/php-ci/Dockerfile.81.dockerignore" + ], + "files": { + ".dockerignore": { + "sha256": "77afbcb7937677f268f626472f8cf3fef5c8a7384e743df09e081d38279383e1", + "mode": 420 + }, + "docker/php-ci/Dockerfile": { + "sha256": "81d23fbbee7e4ee97ca14df9d17982aa664335b94499c5019662259fe0387eaa", + "mode": 420 + }, + "docker/php-ci/Dockerfile.81": { + "sha256": "c16c2c06252b1b179ccab41876ce76a30febf8a6fd5d92234a2bbed54d7be222", + "mode": 420 + }, + "docker/php-ci/ci-defaults.ini": { + "sha256": "656a644d0a5392488dd843614c40c763a950294e4af6eee124c919930a21a72f", + "mode": 420 + }, + "docker/php-ci/verify-php-trust.php": { + "sha256": "529c282e7422202bf25565431a6391de388f86dfe5bfd6c75cf21daa56ffa75e", + "mode": 420 + }, + "scripts/ci/php-container-images.json": { + "sha256": "389247efc6e551b553314bfe64f66aaef3a96c0bf659e6f78322b84b0dc9860b", + "mode": 420 + }, + "scripts/ci/setup-php-container.sh": { + "sha256": "ae216b71a15ab40098e4341e6ab2ebe4f2a3cecc497cbb9eb412bfd19c446cf9", + "mode": 493 + }, + "scripts/ci/run-php-container.sh": { + "sha256": "025b2def722eed3a3e534698333478bd82d6c735dca14cf8c2dbb8c3bb0392e3", + "mode": 493 + }, + "tests/ci/test_php_container_tls.py": { + "sha256": "d73a2a3c494bd31bd4f8b5215070aa7ff4807c3e4cb75e8b3eb51d2fe057c0ae", + "mode": 420 + }, + "docker/brotli/install-vendor.sh": { + "sha256": "d7eb8b2a3e0af1c3072a56bcb81632b22f061f211d8fe5e57ee901c8bf94c92f", + "mode": 420 + }, + "docker/brotli/verify-runtime.php": { + "sha256": "580cc465e349f3872eca592355294e7320fe7f1a4560ff5d4c83d5900921c00e", + "mode": 420 + }, + "docker/brotli/verify-system-brotli.c": { + "sha256": "3353927d206aaf5e63157e46be715c6cbee46bac777e29f8f9e25c4c1f656667", + "mode": 420 + }, + "docker/brotli/version": { + "sha256": "e064953e075ddb99fb7b48ad29e215f2dfa075812c127eb1d6ab680e9920fba2", + "mode": 420 + }, + "tests/ci/test_php_container_isolation.py": { + "sha256": "209b1382e473f674dad3f6a1fbc447557dba647df2d23b70c8af1db2dab97697", + "mode": 420 + } + } + }, + "sdk-php-framework-82-ci": { + "target": "sdk-php", + "workflows": { + "ci.yml": [ + "framework-compat" + ] + }, + "commands": [ + "bash \"$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh\" \"8.2\"" + ], + "environment": [ + "SDK_PHP_CI_IMAGE", + "SDK_PHP_CI_ROOT", + "SDK_PHP_CI_STATE" + ], + "absent_files": [ + "docker/php-ci/Dockerfile.dockerignore", + "docker/php-ci/Dockerfile.81.dockerignore" + ], + "files": { + ".dockerignore": { + "sha256": "77afbcb7937677f268f626472f8cf3fef5c8a7384e743df09e081d38279383e1", + "mode": 420 + }, + "docker/php-ci/Dockerfile": { + "sha256": "81d23fbbee7e4ee97ca14df9d17982aa664335b94499c5019662259fe0387eaa", + "mode": 420 + }, + "docker/php-ci/Dockerfile.81": { + "sha256": "c16c2c06252b1b179ccab41876ce76a30febf8a6fd5d92234a2bbed54d7be222", + "mode": 420 + }, + "docker/php-ci/ci-defaults.ini": { + "sha256": "656a644d0a5392488dd843614c40c763a950294e4af6eee124c919930a21a72f", + "mode": 420 + }, + "docker/php-ci/verify-php-trust.php": { + "sha256": "529c282e7422202bf25565431a6391de388f86dfe5bfd6c75cf21daa56ffa75e", + "mode": 420 + }, + "scripts/ci/php-container-images.json": { + "sha256": "389247efc6e551b553314bfe64f66aaef3a96c0bf659e6f78322b84b0dc9860b", + "mode": 420 + }, + "scripts/ci/setup-php-container.sh": { + "sha256": "ae216b71a15ab40098e4341e6ab2ebe4f2a3cecc497cbb9eb412bfd19c446cf9", + "mode": 493 + }, + "scripts/ci/run-php-container.sh": { + "sha256": "025b2def722eed3a3e534698333478bd82d6c735dca14cf8c2dbb8c3bb0392e3", + "mode": 493 + }, + "tests/ci/test_php_container_tls.py": { + "sha256": "d73a2a3c494bd31bd4f8b5215070aa7ff4807c3e4cb75e8b3eb51d2fe057c0ae", + "mode": 420 + }, + "docker/brotli/install-vendor.sh": { + "sha256": "d7eb8b2a3e0af1c3072a56bcb81632b22f061f211d8fe5e57ee901c8bf94c92f", + "mode": 420 + }, + "docker/brotli/verify-runtime.php": { + "sha256": "580cc465e349f3872eca592355294e7320fe7f1a4560ff5d4c83d5900921c00e", + "mode": 420 + }, + "docker/brotli/verify-system-brotli.c": { + "sha256": "3353927d206aaf5e63157e46be715c6cbee46bac777e29f8f9e25c4c1f656667", + "mode": 420 + }, + "docker/brotli/version": { + "sha256": "e064953e075ddb99fb7b48ad29e215f2dfa075812c127eb1d6ab680e9920fba2", + "mode": 420 + }, + "tests/ci/test_php_container_isolation.py": { + "sha256": "209b1382e473f674dad3f6a1fbc447557dba647df2d23b70c8af1db2dab97697", + "mode": 420 + } + } + }, + "sdk-php-framework-84-ci": { + "target": "sdk-php", + "workflows": { + "ci.yml": [ + "framework-compat84" + ] + }, + "commands": [ + "bash \"$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh\" \"8.4\"" + ], + "environment": [ + "SDK_PHP_CI_IMAGE", + "SDK_PHP_CI_ROOT", + "SDK_PHP_CI_STATE" + ], + "absent_files": [ + "docker/php-ci/Dockerfile.dockerignore", + "docker/php-ci/Dockerfile.81.dockerignore" + ], + "files": { + ".dockerignore": { + "sha256": "77afbcb7937677f268f626472f8cf3fef5c8a7384e743df09e081d38279383e1", + "mode": 420 + }, + "docker/php-ci/Dockerfile": { + "sha256": "81d23fbbee7e4ee97ca14df9d17982aa664335b94499c5019662259fe0387eaa", + "mode": 420 + }, + "docker/php-ci/Dockerfile.81": { + "sha256": "c16c2c06252b1b179ccab41876ce76a30febf8a6fd5d92234a2bbed54d7be222", + "mode": 420 + }, + "docker/php-ci/ci-defaults.ini": { + "sha256": "656a644d0a5392488dd843614c40c763a950294e4af6eee124c919930a21a72f", + "mode": 420 + }, + "docker/php-ci/verify-php-trust.php": { + "sha256": "529c282e7422202bf25565431a6391de388f86dfe5bfd6c75cf21daa56ffa75e", + "mode": 420 + }, + "scripts/ci/php-container-images.json": { + "sha256": "389247efc6e551b553314bfe64f66aaef3a96c0bf659e6f78322b84b0dc9860b", + "mode": 420 + }, + "scripts/ci/setup-php-container.sh": { + "sha256": "ae216b71a15ab40098e4341e6ab2ebe4f2a3cecc497cbb9eb412bfd19c446cf9", + "mode": 493 + }, + "scripts/ci/run-php-container.sh": { + "sha256": "025b2def722eed3a3e534698333478bd82d6c735dca14cf8c2dbb8c3bb0392e3", "mode": 493 }, "tests/ci/test_php_container_tls.py": { diff --git a/tests/fixtures/sdk-php-framework-runtime.yml b/tests/fixtures/sdk-php-framework-runtime.yml new file mode 100644 index 0000000..799c872 --- /dev/null +++ b/tests/fixtures/sdk-php-framework-runtime.yml @@ -0,0 +1,570 @@ +# Actual proposed SDK jobs at 2713469e40ba16766e462cf4f80d1dcdaf704fda; runtime-source byte identity is checked separately. +jobs: + test: + name: PHP ${{ matrix.php }} + runs-on: ubuntu-24.04 + needs: action-policy + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + php: + - '8.1' + - '8.2' + - '8.4' + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + with: + persist-credentials: false + - name: Check out the fixed APT prerequisite + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + 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@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + 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 + - name: Prepare the reviewed PHP container runtime + run: bash "$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh" "${{ matrix.php + }}" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - run: composer validate --strict + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - run: composer install --no-interaction --prefer-dist + - name: Lint PHP + run: php scripts/ci/lint-php.php + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - run: 'mkdir -p build + + php scripts/ci/reference-replay-clock-numbers.php > build/replay-clock-numbers.json + + composer test -- --log-junit build/phpunit.xml + + ' + - name: Retain source numeric observations + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: replay-clock-numbers-php-${{ matrix.php }} + path: build/replay-clock-numbers.json + if-no-files-found: error + retention-days: 90 + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - run: composer check-boundary + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Preserve the HTTP-only PHP 8.1 platform + if: matrix.php == '8.1' + run: composer check-http-only-platform + carbon-2: + name: PHP 8.1 with Carbon 2 + runs-on: ubuntu-24.04 + needs: action-policy + timeout-minutes: 15 + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + with: + persist-credentials: false + - name: Check out the fixed APT prerequisite + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + 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@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + 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 + - name: Prepare the reviewed PHP container runtime + run: bash "$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh" "8.1" carbon2 + - name: Constrain the manifest to the oldest supported Carbon major + run: "php -r '$path = \"composer.json\";\n $manifest = json_decode((string)\ + \ file_get_contents($path), flags: JSON_THROW_ON_ERROR);\n $manifest->require->{\"\ + nesbot/carbon\"} = \"^2.72.6\";\n file_put_contents($path, json_encode($manifest,\ + \ JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR).\"\\n\"\ + );'\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - run: composer install --no-interaction --prefer-dist --no-progress + - name: Require Carbon 2 + run: "php -r 'require \"vendor/autoload.php\";\n $version = ltrim((string)\ + \ Composer\\InstalledVersions::getPrettyVersion(\"nesbot/carbon\"), \"v\"\ + );\n fwrite(STDOUT, \"nesbot/carbon {$version}\\n\");\n exit(str_starts_with($version,\ + \ \"2.\") ? 0 : 1);'\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - run: 'mkdir -p build + + php scripts/ci/reference-replay-clock-numbers.php > build/replay-clock-numbers.json + + composer test + + ' + - name: Retain Carbon 2 source numeric observations + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a + with: + name: replay-clock-numbers-php-8.1-carbon-2 + path: build/replay-clock-numbers.json + if-no-files-found: error + retention-days: 90 + framework-compat81: + name: ${{ matrix.framework }} ${{ matrix.version }} + runs-on: ubuntu-24.04 + timeout-minutes: 15 + needs: action-policy + strategy: + fail-fast: false + matrix: + include: + - framework: Symfony + version: '6.4' + php: '8.1' + package: symfony/framework-bundle:^6.4 + console_package: symfony/console:^6.4 + script: symfony.php + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + with: + persist-credentials: false + - name: Check out the fixed APT prerequisite + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + 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@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + 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 + - name: Prepare the reviewed PHP container runtime + run: bash "$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh" "8.1" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Install SDK into a clean framework consumer + env: + FRAMEWORK_BOOTSTRAP: ${{ matrix.bootstrap }} + FRAMEWORK_PACKAGE: ${{ matrix.package }} + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + FRAMEWORK_CONSOLE_PACKAGE: ${{ matrix.console_package }} + COMPAT_SCRIPT: ${{ matrix.script }} + run: "consumer=\"$(mktemp -d)\"\nprintf '%s\\n' \"$consumer\" > \"$RUNNER_TEMP/framework-consumer\"\ + \ncd \"$consumer\"\ncomposer init --name=durable-workflow/framework-compat\ + \ --no-interaction\ncomposer config repositories.sdk path \"$GITHUB_WORKSPACE\"\ + \nif [ \"$COMPAT_SCRIPT\" = laravel.php ]; then\n bootstrap_arguments=()\n\ + \ if [ \"$FRAMEWORK_BOOTSTRAP\" = existing_supported_lock ]; then\n #\ + \ Model the established application named by the adoption contract.\n #\ + \ Composer may refuse a new installation of an end-of-life Laravel\n #\ + \ line, but SDK installation still runs with normal policy against\n #\ + \ the resulting existing lock file.\n bootstrap_arguments+=(--no-blocking)\n\ + \ fi\n # matrix.package is the published caret support range. Install\n\ + \ # exactly its minimum release, and prove the SDK does not move it.\n exercised_version=\"\ + ${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\n composer require \"\ + $FRAMEWORK_EXERCISED_PACKAGE\" \\\n --no-interaction --prefer-dist --no-progress\ + \ \"${bootstrap_arguments[@]}\"\n php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\"\ + \ \"$consumer\" laravel/framework \"$exercised_version\"\n composer require\ + \ durable-workflow/sdk:@dev \\\n --no-interaction --prefer-dist --no-progress\n\ + \ php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\" \"$consumer\"\ + \ laravel/framework \"$exercised_version\"\nelse\n framework_packages=(\"\ + $FRAMEWORK_PACKAGE\")\n if [ -n \"$FRAMEWORK_CONSOLE_PACKAGE\" ]; then\n\ + \ framework_packages+=(\"$FRAMEWORK_CONSOLE_PACKAGE\")\n fi\n composer\ + \ require durable-workflow/sdk:@dev \"${framework_packages[@]}\" \\\n --no-interaction\ + \ --prefer-dist --with-all-dependencies\nfi\ncomposer require --dev phpstan/phpstan:^2.0\ + \ 'monolog/monolog:^2.9|^3.0' --no-interaction --prefer-dist\nif [ \"$COMPAT_SCRIPT\"\ + \ = laravel.php ]; then\n php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\"\ + \ \"$consumer\" laravel/framework \"$exercised_version\"\nfi\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Install SDK into a fresh Laravel application for cached role isolation + if: matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php == + '8.4' + env: + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + run: "application=\"$SDK_PHP_CI_STATE/data/laravel-fresh-config-cache\"\nexercised_version=\"\ + ${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\ncomposer create-project\ + \ laravel/laravel:^13.0 \"$application\" \\\n --no-interaction --prefer-dist\ + \ --no-progress\ncomposer --working-dir=\"$application\" require \"$FRAMEWORK_EXERCISED_PACKAGE\"\ + \ \\\n --with-all-dependencies --no-interaction --prefer-dist --no-progress\n\ + php scripts/ci/assert-installed-version.php \"$application\" laravel/framework\ + \ \"$exercised_version\"\ncomposer --working-dir=\"$application\" config repositories.sdk\ + \ path \"$GITHUB_WORKSPACE\"\ncomposer --working-dir=\"$application\" require\ + \ durable-workflow/sdk:@dev \\\n --no-interaction --prefer-dist --no-progress\n\ + php scripts/ci/assert-installed-version.php \"$application\" laravel/framework\ + \ \"$exercised_version\"\n" + - name: Exercise fresh Laravel cached role isolation + if: matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php == + '8.4' + run: 'bash tests/compat/laravel-fresh-config-cache.sh "$SDK_PHP_CI_STATE/data/laravel-fresh-config-cache" + + ' + - name: Exercise native container, diagnostics, and testing integration + env: + COMPAT_SCRIPT: ${{ matrix.script }} + run: "consumer=\"$(cat \"$RUNNER_TEMP/framework-consumer\")\"\nif [ \"$COMPAT_SCRIPT\"\ + \ = laravel.php ]; then\n DURABLE_WORKFLOW_CLIENT_TOKEN=client-secret \\\n\ + \ DURABLE_WORKFLOW_WORKER_TOKEN=worker-secret \\\n php \"tests/compat/${COMPAT_SCRIPT}\"\ + \ \"$consumer/vendor/autoload.php\"\n php tests/compat/laravel-config-cache.php\ + \ \"$consumer/vendor/autoload.php\"\n bridge_path=src/Bridge/Laravel\n compatibility_scripts=(\n\ + \ \"tests/compat/${COMPAT_SCRIPT}\"\n tests/compat/laravel-config-cache.php\n\ + \ tests/compat/laravel-fresh-config-cache.php\n tests/compat/laravel-fresh-role-launch.php\n\ + \ )\nelse\n php \"tests/compat/${COMPAT_SCRIPT}\" \"$consumer/vendor/autoload.php\"\ + \n bridge_path=src/Bridge/Symfony\n compatibility_scripts=(\"tests/compat/${COMPAT_SCRIPT}\"\ + )\nfi\ncompatibility_scripts+=(tests/compat/history-cache.php tests/compat/execution-telemetry.php)\n\ + php tests/compat/static-credentials.php \"$consumer/vendor/autoload.php\"\ + \ \"$COMPAT_SCRIPT\"\nphp \"$consumer/vendor/bin/phpstan\" analyse -c phpstan-framework.neon\ + \ \\\n --autoload-file=\"$consumer/vendor/autoload.php\" \\\n src/Bridge/FrameworkRuntimeException.php\ + \ \\\n src/Bridge/ServiceConfiguration.php src/Bridge/Event \\\n \"$bridge_path\"\ + \ \"${compatibility_scripts[@]}\"\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Exercise optional tracing in framework workers + if: (matrix.framework == 'Laravel' && matrix.version == '12' && matrix.php == + '8.2') || (matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php + == '8.4') || (matrix.framework == 'Symfony' && matrix.version == '6.4') + env: + COMPAT_SCRIPT: ${{ matrix.script }} + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + DURABLE_WORKFLOW_TEST_TRACING: '1' + run: "php -r 'if (getenv(\"DURABLE_WORKFLOW_TEST_TRACING\") !== \"1\") { throw\ + \ new RuntimeException(\"Tracing control flag was not forwarded\"); }'\nconsumer=\"\ + $(cat \"$RUNNER_TEMP/framework-consumer\")\"\ncomposer --working-dir=\"$consumer\"\ + \ require --dev open-telemetry/api:1.10.1 'monolog/monolog:^3.0' \\\n --no-interaction\ + \ --prefer-dist --no-progress\nif [ \"$COMPAT_SCRIPT\" = laravel.php ]; then\n\ + \ php scripts/ci/assert-installed-version.php \"$consumer\" laravel/framework\ + \ \\\n \"${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\nfi\nDURABLE_WORKFLOW_CLIENT_TOKEN=client-secret\ + \ \\\n DURABLE_WORKFLOW_WORKER_TOKEN=worker-secret \\\n php \"tests/compat/${COMPAT_SCRIPT}\"\ + \ \"$consumer/vendor/autoload.php\"\n" + framework-compat: + name: ${{ matrix.framework }} ${{ matrix.version }} + runs-on: ubuntu-24.04 + timeout-minutes: 15 + needs: action-policy + strategy: + fail-fast: false + matrix: + include: + - framework: Laravel + version: '12' + php: '8.2' + package: laravel/framework:^12.69.0 + exercised_package: laravel/framework:12.69.0 + bootstrap: fresh_supported_install + script: laravel.php + - framework: Symfony + version: '7' + php: '8.2' + package: symfony/framework-bundle:^7.0 + console_package: symfony/console:^7.0 + script: symfony.php + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + with: + persist-credentials: false + - name: Check out the fixed APT prerequisite + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + 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@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + 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 + - 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@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Install SDK into a clean framework consumer + env: + FRAMEWORK_BOOTSTRAP: ${{ matrix.bootstrap }} + FRAMEWORK_PACKAGE: ${{ matrix.package }} + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + FRAMEWORK_CONSOLE_PACKAGE: ${{ matrix.console_package }} + COMPAT_SCRIPT: ${{ matrix.script }} + run: "consumer=\"$(mktemp -d)\"\nprintf '%s\\n' \"$consumer\" > \"$RUNNER_TEMP/framework-consumer\"\ + \ncd \"$consumer\"\ncomposer init --name=durable-workflow/framework-compat\ + \ --no-interaction\ncomposer config repositories.sdk path \"$GITHUB_WORKSPACE\"\ + \nif [ \"$COMPAT_SCRIPT\" = laravel.php ]; then\n bootstrap_arguments=()\n\ + \ if [ \"$FRAMEWORK_BOOTSTRAP\" = existing_supported_lock ]; then\n #\ + \ Model the established application named by the adoption contract.\n #\ + \ Composer may refuse a new installation of an end-of-life Laravel\n #\ + \ line, but SDK installation still runs with normal policy against\n #\ + \ the resulting existing lock file.\n bootstrap_arguments+=(--no-blocking)\n\ + \ fi\n # matrix.package is the published caret support range. Install\n\ + \ # exactly its minimum release, and prove the SDK does not move it.\n exercised_version=\"\ + ${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\n composer require \"\ + $FRAMEWORK_EXERCISED_PACKAGE\" \\\n --no-interaction --prefer-dist --no-progress\ + \ \"${bootstrap_arguments[@]}\"\n php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\"\ + \ \"$consumer\" laravel/framework \"$exercised_version\"\n composer require\ + \ durable-workflow/sdk:@dev \\\n --no-interaction --prefer-dist --no-progress\n\ + \ php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\" \"$consumer\"\ + \ laravel/framework \"$exercised_version\"\nelse\n framework_packages=(\"\ + $FRAMEWORK_PACKAGE\")\n if [ -n \"$FRAMEWORK_CONSOLE_PACKAGE\" ]; then\n\ + \ framework_packages+=(\"$FRAMEWORK_CONSOLE_PACKAGE\")\n fi\n composer\ + \ require durable-workflow/sdk:@dev \"${framework_packages[@]}\" \\\n --no-interaction\ + \ --prefer-dist --with-all-dependencies\nfi\ncomposer require --dev phpstan/phpstan:^2.0\ + \ 'monolog/monolog:^2.9|^3.0' --no-interaction --prefer-dist\nif [ \"$COMPAT_SCRIPT\"\ + \ = laravel.php ]; then\n php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\"\ + \ \"$consumer\" laravel/framework \"$exercised_version\"\nfi\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Install SDK into a fresh Laravel application for cached role isolation + if: matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php == + '8.4' + env: + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + run: "application=\"$SDK_PHP_CI_STATE/data/laravel-fresh-config-cache\"\nexercised_version=\"\ + ${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\ncomposer create-project\ + \ laravel/laravel:^13.0 \"$application\" \\\n --no-interaction --prefer-dist\ + \ --no-progress\ncomposer --working-dir=\"$application\" require \"$FRAMEWORK_EXERCISED_PACKAGE\"\ + \ \\\n --with-all-dependencies --no-interaction --prefer-dist --no-progress\n\ + php scripts/ci/assert-installed-version.php \"$application\" laravel/framework\ + \ \"$exercised_version\"\ncomposer --working-dir=\"$application\" config repositories.sdk\ + \ path \"$GITHUB_WORKSPACE\"\ncomposer --working-dir=\"$application\" require\ + \ durable-workflow/sdk:@dev \\\n --no-interaction --prefer-dist --no-progress\n\ + php scripts/ci/assert-installed-version.php \"$application\" laravel/framework\ + \ \"$exercised_version\"\n" + - name: Exercise fresh Laravel cached role isolation + if: matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php == + '8.4' + run: 'bash tests/compat/laravel-fresh-config-cache.sh "$SDK_PHP_CI_STATE/data/laravel-fresh-config-cache" + + ' + - name: Exercise native container, diagnostics, and testing integration + env: + COMPAT_SCRIPT: ${{ matrix.script }} + run: "consumer=\"$(cat \"$RUNNER_TEMP/framework-consumer\")\"\nif [ \"$COMPAT_SCRIPT\"\ + \ = laravel.php ]; then\n DURABLE_WORKFLOW_CLIENT_TOKEN=client-secret \\\n\ + \ DURABLE_WORKFLOW_WORKER_TOKEN=worker-secret \\\n php \"tests/compat/${COMPAT_SCRIPT}\"\ + \ \"$consumer/vendor/autoload.php\"\n php tests/compat/laravel-config-cache.php\ + \ \"$consumer/vendor/autoload.php\"\n bridge_path=src/Bridge/Laravel\n compatibility_scripts=(\n\ + \ \"tests/compat/${COMPAT_SCRIPT}\"\n tests/compat/laravel-config-cache.php\n\ + \ tests/compat/laravel-fresh-config-cache.php\n tests/compat/laravel-fresh-role-launch.php\n\ + \ )\nelse\n php \"tests/compat/${COMPAT_SCRIPT}\" \"$consumer/vendor/autoload.php\"\ + \n bridge_path=src/Bridge/Symfony\n compatibility_scripts=(\"tests/compat/${COMPAT_SCRIPT}\"\ + )\nfi\ncompatibility_scripts+=(tests/compat/history-cache.php tests/compat/execution-telemetry.php)\n\ + php tests/compat/static-credentials.php \"$consumer/vendor/autoload.php\"\ + \ \"$COMPAT_SCRIPT\"\nphp \"$consumer/vendor/bin/phpstan\" analyse -c phpstan-framework.neon\ + \ \\\n --autoload-file=\"$consumer/vendor/autoload.php\" \\\n src/Bridge/FrameworkRuntimeException.php\ + \ \\\n src/Bridge/ServiceConfiguration.php src/Bridge/Event \\\n \"$bridge_path\"\ + \ \"${compatibility_scripts[@]}\"\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Exercise optional tracing in framework workers + if: (matrix.framework == 'Laravel' && matrix.version == '12' && matrix.php == + '8.2') || (matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php + == '8.4') || (matrix.framework == 'Symfony' && matrix.version == '6.4') + env: + COMPAT_SCRIPT: ${{ matrix.script }} + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + DURABLE_WORKFLOW_TEST_TRACING: '1' + run: "php -r 'if (getenv(\"DURABLE_WORKFLOW_TEST_TRACING\") !== \"1\") { throw\ + \ new RuntimeException(\"Tracing control flag was not forwarded\"); }'\nconsumer=\"\ + $(cat \"$RUNNER_TEMP/framework-consumer\")\"\ncomposer --working-dir=\"$consumer\"\ + \ require --dev open-telemetry/api:1.10.1 'monolog/monolog:^3.0' \\\n --no-interaction\ + \ --prefer-dist --no-progress\nif [ \"$COMPAT_SCRIPT\" = laravel.php ]; then\n\ + \ php scripts/ci/assert-installed-version.php \"$consumer\" laravel/framework\ + \ \\\n \"${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\nfi\nDURABLE_WORKFLOW_CLIENT_TOKEN=client-secret\ + \ \\\n DURABLE_WORKFLOW_WORKER_TOKEN=worker-secret \\\n php \"tests/compat/${COMPAT_SCRIPT}\"\ + \ \"$consumer/vendor/autoload.php\"\n" + framework-compat84: + name: ${{ matrix.framework }} ${{ matrix.version }} + runs-on: ubuntu-24.04 + timeout-minutes: 15 + needs: action-policy + strategy: + fail-fast: false + matrix: + include: + - framework: Laravel + version: '12' + php: '8.4' + package: laravel/framework:^12.69.0 + exercised_package: laravel/framework:12.69.0 + bootstrap: fresh_supported_install + script: laravel.php + - framework: Laravel + version: '13' + php: '8.4' + package: laravel/framework:^13.30.0 + exercised_package: laravel/framework:13.30.0 + bootstrap: fresh_supported_install + script: laravel.php + - framework: Symfony + version: '8' + php: '8.4' + package: symfony/framework-bundle:^8.0 + console_package: symfony/console:^8.0 + script: symfony.php + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + with: + persist-credentials: false + - name: Check out the fixed APT prerequisite + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 + 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@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + 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 + - name: Prepare the reviewed PHP container runtime + run: bash "$GITHUB_WORKSPACE/scripts/ci/setup-php-container.sh" "8.4" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Install SDK into a clean framework consumer + env: + FRAMEWORK_BOOTSTRAP: ${{ matrix.bootstrap }} + FRAMEWORK_PACKAGE: ${{ matrix.package }} + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + FRAMEWORK_CONSOLE_PACKAGE: ${{ matrix.console_package }} + COMPAT_SCRIPT: ${{ matrix.script }} + run: "consumer=\"$(mktemp -d)\"\nprintf '%s\\n' \"$consumer\" > \"$RUNNER_TEMP/framework-consumer\"\ + \ncd \"$consumer\"\ncomposer init --name=durable-workflow/framework-compat\ + \ --no-interaction\ncomposer config repositories.sdk path \"$GITHUB_WORKSPACE\"\ + \nif [ \"$COMPAT_SCRIPT\" = laravel.php ]; then\n bootstrap_arguments=()\n\ + \ if [ \"$FRAMEWORK_BOOTSTRAP\" = existing_supported_lock ]; then\n #\ + \ Model the established application named by the adoption contract.\n #\ + \ Composer may refuse a new installation of an end-of-life Laravel\n #\ + \ line, but SDK installation still runs with normal policy against\n #\ + \ the resulting existing lock file.\n bootstrap_arguments+=(--no-blocking)\n\ + \ fi\n # matrix.package is the published caret support range. Install\n\ + \ # exactly its minimum release, and prove the SDK does not move it.\n exercised_version=\"\ + ${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\n composer require \"\ + $FRAMEWORK_EXERCISED_PACKAGE\" \\\n --no-interaction --prefer-dist --no-progress\ + \ \"${bootstrap_arguments[@]}\"\n php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\"\ + \ \"$consumer\" laravel/framework \"$exercised_version\"\n composer require\ + \ durable-workflow/sdk:@dev \\\n --no-interaction --prefer-dist --no-progress\n\ + \ php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\" \"$consumer\"\ + \ laravel/framework \"$exercised_version\"\nelse\n framework_packages=(\"\ + $FRAMEWORK_PACKAGE\")\n if [ -n \"$FRAMEWORK_CONSOLE_PACKAGE\" ]; then\n\ + \ framework_packages+=(\"$FRAMEWORK_CONSOLE_PACKAGE\")\n fi\n composer\ + \ require durable-workflow/sdk:@dev \"${framework_packages[@]}\" \\\n --no-interaction\ + \ --prefer-dist --with-all-dependencies\nfi\ncomposer require --dev phpstan/phpstan:^2.0\ + \ 'monolog/monolog:^2.9|^3.0' --no-interaction --prefer-dist\nif [ \"$COMPAT_SCRIPT\"\ + \ = laravel.php ]; then\n php \"$GITHUB_WORKSPACE/scripts/ci/assert-installed-version.php\"\ + \ \"$consumer\" laravel/framework \"$exercised_version\"\nfi\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Install SDK into a fresh Laravel application for cached role isolation + if: matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php == + '8.4' + env: + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + run: "application=\"$SDK_PHP_CI_STATE/data/laravel-fresh-config-cache\"\nexercised_version=\"\ + ${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\ncomposer create-project\ + \ laravel/laravel:^13.0 \"$application\" \\\n --no-interaction --prefer-dist\ + \ --no-progress\ncomposer --working-dir=\"$application\" require \"$FRAMEWORK_EXERCISED_PACKAGE\"\ + \ \\\n --with-all-dependencies --no-interaction --prefer-dist --no-progress\n\ + php scripts/ci/assert-installed-version.php \"$application\" laravel/framework\ + \ \"$exercised_version\"\ncomposer --working-dir=\"$application\" config repositories.sdk\ + \ path \"$GITHUB_WORKSPACE\"\ncomposer --working-dir=\"$application\" require\ + \ durable-workflow/sdk:@dev \\\n --no-interaction --prefer-dist --no-progress\n\ + php scripts/ci/assert-installed-version.php \"$application\" laravel/framework\ + \ \"$exercised_version\"\n" + - name: Exercise fresh Laravel cached role isolation + if: matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php == + '8.4' + run: 'bash tests/compat/laravel-fresh-config-cache.sh "$SDK_PHP_CI_STATE/data/laravel-fresh-config-cache" + + ' + - name: Exercise native container, diagnostics, and testing integration + env: + COMPAT_SCRIPT: ${{ matrix.script }} + run: "consumer=\"$(cat \"$RUNNER_TEMP/framework-consumer\")\"\nif [ \"$COMPAT_SCRIPT\"\ + \ = laravel.php ]; then\n DURABLE_WORKFLOW_CLIENT_TOKEN=client-secret \\\n\ + \ DURABLE_WORKFLOW_WORKER_TOKEN=worker-secret \\\n php \"tests/compat/${COMPAT_SCRIPT}\"\ + \ \"$consumer/vendor/autoload.php\"\n php tests/compat/laravel-config-cache.php\ + \ \"$consumer/vendor/autoload.php\"\n bridge_path=src/Bridge/Laravel\n compatibility_scripts=(\n\ + \ \"tests/compat/${COMPAT_SCRIPT}\"\n tests/compat/laravel-config-cache.php\n\ + \ tests/compat/laravel-fresh-config-cache.php\n tests/compat/laravel-fresh-role-launch.php\n\ + \ )\nelse\n php \"tests/compat/${COMPAT_SCRIPT}\" \"$consumer/vendor/autoload.php\"\ + \n bridge_path=src/Bridge/Symfony\n compatibility_scripts=(\"tests/compat/${COMPAT_SCRIPT}\"\ + )\nfi\ncompatibility_scripts+=(tests/compat/history-cache.php tests/compat/execution-telemetry.php)\n\ + php tests/compat/static-credentials.php \"$consumer/vendor/autoload.php\"\ + \ \"$COMPAT_SCRIPT\"\nphp \"$consumer/vendor/bin/phpstan\" analyse -c phpstan-framework.neon\ + \ \\\n --autoload-file=\"$consumer/vendor/autoload.php\" \\\n src/Bridge/FrameworkRuntimeException.php\ + \ \\\n src/Bridge/ServiceConfiguration.php src/Bridge/Event \\\n \"$bridge_path\"\ + \ \"${compatibility_scripts[@]}\"\n" + - name: Verify Composer trust before requests + uses: durable-workflow/.github/.github/actions/verify-composer-trust@242c2a7fb23459db2e1ada5f84dbee6d61d9b1e5 + - name: Exercise optional tracing in framework workers + if: (matrix.framework == 'Laravel' && matrix.version == '12' && matrix.php == + '8.2') || (matrix.framework == 'Laravel' && matrix.version == '13' && matrix.php + == '8.4') || (matrix.framework == 'Symfony' && matrix.version == '6.4') + env: + COMPAT_SCRIPT: ${{ matrix.script }} + FRAMEWORK_EXERCISED_PACKAGE: ${{ matrix.exercised_package }} + DURABLE_WORKFLOW_TEST_TRACING: '1' + run: "php -r 'if (getenv(\"DURABLE_WORKFLOW_TEST_TRACING\") !== \"1\") { throw\ + \ new RuntimeException(\"Tracing control flag was not forwarded\"); }'\nconsumer=\"\ + $(cat \"$RUNNER_TEMP/framework-consumer\")\"\ncomposer --working-dir=\"$consumer\"\ + \ require --dev open-telemetry/api:1.10.1 'monolog/monolog:^3.0' \\\n --no-interaction\ + \ --prefer-dist --no-progress\nif [ \"$COMPAT_SCRIPT\" = laravel.php ]; then\n\ + \ php scripts/ci/assert-installed-version.php \"$consumer\" laravel/framework\ + \ \\\n \"${FRAMEWORK_EXERCISED_PACKAGE#laravel/framework:}\"\nfi\nDURABLE_WORKFLOW_CLIENT_TOKEN=client-secret\ + \ \\\n DURABLE_WORKFLOW_WORKER_TOKEN=worker-secret \\\n php \"tests/compat/${COMPAT_SCRIPT}\"\ + \ \"$consumer/vendor/autoload.php\"\n" diff --git a/tests/test_composer_trust_contract.py b/tests/test_composer_trust_contract.py index c27d4d9..00b22c2 100644 --- a/tests/test_composer_trust_contract.py +++ b/tests/test_composer_trust_contract.py @@ -660,6 +660,35 @@ def validate(candidate, recipes): with self.assertRaises(PolicyError): validate(changed, catalog) + def test_sdk_framework_jobs_cannot_borrow_another_jobs_runtime(self): + repository = Path(__file__).resolve().parents[1] + catalog = json.loads((repository / "qualification/composer-container-trust.json").read_text()) + catalog["requests"] = {} + document = yaml.safe_load((repository / "tests/fixtures/sdk-php-framework-runtime.yml").read_text()) + policy = json.loads((repository / "qualification/policy.json").read_text()) + + def validate(candidate): + with (mock.patch("scripts.qualification_policy._composer_container_catalog", return_value=catalog), + mock.patch("scripts.qualification_policy._require_composer_runtime_sources")): + return verify_composer_network_sinks(policy, "sdk-php", {"ci.yml": yaml.safe_dump(candidate)}, self.root) + + self.assertTrue(validate(document)) + for job in ("framework-compat81", "framework-compat", "framework-compat84"): + for command in (catalog["runtime_setups"]["sdk-php-carbon-ci"]["commands"][0], + catalog["runtime_setups"]["sdk-php-unit-ci"]["commands"][0]): + changed = deepcopy(document) + setup = next(step for step in changed["jobs"][job]["steps"] + if "setup-php-container.sh" in step.get("run", "")) + setup["run"] = command + with self.subTest(job=job, command=command), self.assertRaises(PolicyError): + validate(changed) + changed = deepcopy(document) + setup = next(step for step in changed["jobs"]["framework-compat"]["steps"] + if "setup-php-container.sh" in step.get("run", "")) + setup["run"] = catalog["runtime_setups"]["sdk-php-framework-84-ci"]["commands"][0] + with self.assertRaises(PolicyError): + validate(changed) + def test_a_symlinked_build_input_directory_refuses_even_when_bytes_match(self): original = self.root / "docker/php" moved = self.root / "actual-build-input"