Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions qualification/composer-container-trust.json
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,84 @@
"mode": 420
}
}
},
"sdk-php-transition82-ci": {
"target": "sdk-php",
"workflows": {
"ci.yml": [
"laravel-transition-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
}
}
}
}
}
52 changes: 52 additions & 0 deletions tests/fixtures/sdk-php-transition-runtime.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Proposed SDK source 094eb50771d8e5a42297b85c51aba1021888d031.
jobs:
laravel-transition-compat:
name: Laravel ${{ matrix.source }} to service mode
runs-on: ubuntu-24.04
timeout-minutes: 20
needs: action-policy
strategy:
fail-fast: false
matrix:
include:
- source: embedded-v1
source_mode: embedded_v1
php: '8.2'
laravel: ^12.0
workflow: ^1.0
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: Exercise the established Laravel application transition
env:
LARAVEL_REQUIREMENT: ${{ matrix.laravel }}
SDK_PATH: ${{ github.workspace }}
SOURCE_MODE: ${{ matrix.source_mode }}
WORKFLOW_REQUIREMENT: ${{ matrix.workflow }}
run: scripts/ci/laravel-service-transition-smoke.sh
26 changes: 26 additions & 0 deletions tests/test_composer_trust_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,32 @@ def validate(candidate):
with self.assertRaises(PolicyError):
validate(changed)

def test_sdk_transition_job_requires_its_own_fixed_minor_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-transition-runtime.yml").read_text())
policy = json.loads((repository / "qualification/policy.json").read_text())
# Expand the actual driver path into its first request sink. The SDK's
# full transition qualification owns execution of the complete script.
driver = self.root / "scripts/ci/laravel-service-transition-smoke.sh"
driver.parent.mkdir(parents=True, exist_ok=True)
driver.write_text('composer create-project "laravel/laravel:${laravel_requirement}" "$application"\n')

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 recipe in ("sdk-php-unit-ci", "sdk-php-carbon-ci", "sdk-php-framework-81-ci", "sdk-php-framework-84-ci"):
changed = deepcopy(document)
setup = next(step for step in changed["jobs"]["laravel-transition-compat"]["steps"]
if "setup-php-container.sh" in step.get("run", ""))
setup["run"] = catalog["runtime_setups"][recipe]["commands"][0]
with self.subTest(recipe=recipe), 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"
Expand Down
Loading