feat(P61): L2 lifecycle pipeline — extend matrix + workflows + tests

Extend the modules-lifecycle pipeline with L2 composition modules
(static-assets, microservice) per REQ-128:

- pipelines/modules-lifecycle.yml: added l2-lifecycle-apply/modify/destroy
  stages + l2_modules matrix entry
- .gitea/workflows/modules-lifecycle.yml + .github/workflows/modules-lifecycle.yml:
  added l2-lifecycle job (byte-identical), matrix over [static-assets,
  microservice], needs ci-vpc-apply, has apply/modify/destroy steps.
  ci-vpc-destroy now needs both [lifecycle, l2-lifecycle].
- schemas/modules-lifecycle-pipeline.schema.json: added l2_modules to matrix
- scripts/run_l2_lifecycle_test.sh + run_l2_lifecycle_destroy.sh: L2 wrappers
  that set ACDL_REMOTE_STATE_KEY=spike/ci-vpc/terraform.tfstate so the
  microservice composition's terraform_remote_state reads from the CI VPC
- adapters/terraform/adapter.py: parameterized remote_state key via
  ACDL_REMOTE_STATE_KEY env var (default: platform/terraform.tfstate)
- modules/l2/static-assets/examples/complex.yml: fixed bucket_name to match
  simple (my-static-site) so terraform modifies in-place (adds CDN + WAF)
- modules/l2/microservice/examples/complex.yml: fixed bucket_name to match
  simple (my-microservice-demo), added desired_count:2 (modify variant)
- tests/test_pipeline_contract.py: 7 new L2 tests (l2 job exists, matrix
  lists both modules, apply/modify/destroy steps, needs ci-vpc-apply,
  ci-vpc-destroy needs both, contract matrix lists l2_modules)
- pipelines/README.md: updated stages for L2

Regression: 485 passed, 5 deselected. Gitea + GitHub workflows byte-identical.

---ci---
project: acdl
phase: P61
milestone: v1.11
status: execute
---/ci---
This commit is contained in:
Jon Chery
2026-07-28 20:17:27 +00:00
parent 0c5c4d1c40
commit 361fe600a9
11 changed files with 227 additions and 21 deletions
+32 -3
View File
@@ -549,9 +549,9 @@ class TestModulesLifecyclePipeline:
contract = _load_yaml("pipelines/modules-lifecycle.yml")
assert wf["name"] == contract["name"]
def test_workflow_has_three_jobs(self):
def test_workflow_has_four_jobs(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
assert set(wf["jobs"].keys()) == {"ci-vpc-apply", "lifecycle", "ci-vpc-destroy"}
assert set(wf["jobs"].keys()) == {"ci-vpc-apply", "lifecycle", "l2-lifecycle", "ci-vpc-destroy"}
def test_workflow_triggers_match_contract(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
@@ -584,4 +584,33 @@ class TestModulesLifecyclePipeline:
def test_platform_vpc_destroy_always_runs(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
destroy_job = wf["jobs"]["ci-vpc-destroy"]
assert destroy_job.get("if") == "always()", "ci-vpc-destroy must always run (cleanup)"
assert destroy_job.get("if") == "always()", "ci-vpc-destroy must always run (cleanup)"
def test_l2_lifecycle_job_exists(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
assert "l2-lifecycle" in wf["jobs"]
def test_l2_matrix_lists_both_l2_modules(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
matrix_modules = wf["jobs"]["l2-lifecycle"]["strategy"]["matrix"]["module"]
assert set(matrix_modules) == {"static-assets", "microservice"}
def test_l2_lifecycle_job_has_apply_modify_destroy_steps(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
steps = wf["jobs"]["l2-lifecycle"]["steps"]
step_names = [s.get("name", "") for s in steps]
assert any("Apply" in n for n in step_names), "Missing L2 apply step"
assert any("Modify" in n for n in step_names), "Missing L2 modify step"
assert any("Destroy" in n for n in step_names), "Missing L2 destroy step"
def test_l2_lifecycle_job_needs_ci_vpc_apply(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
assert wf["jobs"]["l2-lifecycle"]["needs"] == "ci-vpc-apply"
def test_ci_vpc_destroy_needs_both_lifecycle_and_l2(self):
wf = _load_workflow(".gitea/workflows/modules-lifecycle.yml")
assert set(wf["jobs"]["ci-vpc-destroy"]["needs"]) == {"lifecycle", "l2-lifecycle"}
def test_contract_matrix_lists_l2_modules(self):
contract = _load_yaml("pipelines/modules-lifecycle.yml")
assert set(contract["matrix"]["l2_modules"]) == {"static-assets", "microservice"}