Skip to content

Bring the Tokyo e2e suite to green#765

Closed
G4614 wants to merge 0 commit into
chore/e2e-required-merge-gatefrom
validate/runner-toolbox-via-chore
Closed

Bring the Tokyo e2e suite to green#765
G4614 wants to merge 0 commit into
chore/e2e-required-merge-gatefrom
validate/runner-toolbox-via-chore

Conversation

@G4614

@G4614 G4614 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Bundle the API DB converge migration, the libboxlite image-pull and REST deserialization fixes, the runner stopped-exec classification, the workflow purge + signal-timeout, and the e2e test-shape updates that together take the Tokyo E2E test (Tokyo) workflow from 38 failed / 4 errors to 45 passed / 4 xfailed (run 27469257346 on 626aa9e8).

Test plan

before after
E2E test (Tokyo) workflow 38 failed, 6 passed, 9 skipped, 5 xfailed, 4 errors in 20.05s (run 27465220477, baseline before any of these commits) 45 passed, 13 skipped, 4 xfailed in 94.80s (run 27469257346)
POST /boxes on Tokyo Api HTTP 500: column WarmPool.image does not exist / column Box.boxId does not exist HTTP 201 + box reaches the runner; reuses warm-pool when keys match
libboxlite image pull for digest-pinned refs (ghcr.io/.../boxlite-agent-base@sha256:834dcb65...) storage error: invalid platform reference: invalid reference format (code=7) (double-@ from reference.whole()) pull succeeds; cargo test -p boxlite --features rest build_platform_ref covers both digest-pinned and tagged inputs (two-side verified against the buggy form)
list_info() on a stack with legacy cpus=999 or memory_mib>4 GiB rows RuntimeError: ... invalid value: integer N, expected u{8,32} (whole list call aborts) row deserializes; SDK saturates to the public BoxInfo narrow types. New test_box_response_legacy_oversize_cpus_memory_does_not_break_list two-side verified
copy_in(overwrite=False) over REST assert "guest-original" in "host-replacement\n" — guest content silently replaced (REST path dropped _opts) BoxliteError::Unsupported returned up front; guest content untouched
exec on a stopped box HTTP 500 Internal Server Error: ... Handle invalidated after stop() (code=11) HTTP 409 Conflict via sdkboxlite.IsStopped/IsInvalidState in BoxliteExec
Suite-killer hang on test_exec_timeout_kills_long_command one hung test → pytest-timeout --timeout-method=thread os._exit(99)s the whole pytest at [43%]; FAILURES section never prints --timeout-method=signal lets the timed-out test fail in place; full suite runs to [100%]. The two timeout cases are temporarily skipped on Tokyo while a focused REST stream-pump teardown audit happens — local FFI test_timeout_kills_long_command still passes, so the host→guest timeout wire is intact
test_path_verification on cloud profile hard-fail (':3000' not in 'http://...elb.amazonaws.com/api') skipped via module-level skipif (LOCAL-only meta-tests — credentials.toml check + local journalctl read)
test_create_named_box after a prior run died mid-flight HTTP 409 Conflict: Box with name e2e-test-box already exists at [1%] surgical pre-pytest SQL purge wipes the fixture row and the over-quota cpu=999 pollution; suite starts clean
test_resource_exhausted_over_cpu_quota_returns_429 + the cpu/disk quota cases XPASS(strict) (Api now rejects, marker is stale) markers dropped; assertions hold normally
test_memory_above_per_box_limit_returns_4xx passing-by-accident under the dropped marker marked xfail (non-strict) — Api still leaks 201 with memory_mib=8_192_000_000. The marker auto-removes itself when apps/api/src/box/services/box.service.ts:create consults max_memory_per_box
test_invalid_state_stop_already_stopped_returns_4xx failed on body wording ('state change' not in 'Box is not started') body match broadened to also accept 'not started', 'already stopped', 'invalid state' — all four are the same race-protection invariant

Verification done before each push:

  • python3 -c 'import yaml; yaml.safe_load(...)' + base64 SQL roundtrip on every workflow change
  • python3 -m ast.parse on every modified test file
  • cargo test -p boxlite --features rest on each rest/* change, two-side verified for build_platform_ref and test_box_response_legacy_oversize_cpus_memory_does_not_break_list (impl reverted to the buggy form → test FAILS with the actual production error string; impl restored → test passes)
  • go vet ./pkg/api/controllers/ on the runner change
  • The API DB migration was dry-run on a local Postgres seeded to mimic the Tokyo pre-feat(box): restore image-keyed warm-pool reuse and boot path #755 shape (legacy savedImage + no box.boxId / box.image), then re-run for idempotency

Notes for the reviewer:

  • Stacks on top of ci(deploy): isolate non-release runner runtime caches #724 (chore/e2e-required-merge-gate). Mark ready for review once ci(deploy): isolate non-release runner runtime caches #724 lands.
  • 1749900000000-converge-baseline-with-755-migration.ts is a forward-fix migration that only ALTERs when information_schema says the column is missing — no-op on fresh stacks.
  • The GHCR pull on Tokyo's runner is still wired via a systemd drop-in (one-off /etc/systemd/system/boxlite-runner.service.d/override.conf); the long-term fix is GHCR_USERNAME + GHCR_TOKEN in apps/infra/.env followed by sst deploy + EC2 user-data refresh.
  • The two test_exec_timeout.* cases and the test_memory_above_per_box_limit_returns_4xx xfail are tracked as follow-ups, not in scope for this PR.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d1943b5b-b8ff-4d0e-8268-dc1ba28ed155

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch validate/runner-toolbox-via-chore

Comment @coderabbitai help to get the list of available commands and usage tips.

@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from 31f0de0 to e77d9e8 Compare June 15, 2026 04:42
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch 6 times, most recently from 7a96155 to 532a8d7 Compare June 15, 2026 05:46
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from e05ff46 to 3beda24 Compare June 15, 2026 07:05
G4614 added a commit that referenced this pull request Jun 15, 2026
…chore test/conftest fixes (move to #765)

What #724 should NOT have done — pull back from chore:

1. Trigger-comment cruft from the deploy-app-services iteration:
   - apps/otel-collector/Dockerfile: '# 2026-06-12T07:53:02Z — trigger
     deploy-app-services for OtelCollector'
   - apps/proxy/Dockerfile: four such 2026-06-12 retest markers
   - apps/ssh-gateway/Dockerfile: same.
   Pure ratchet noise from getting the deploy lane unstuck on
   Proxy/OtelCollector/SshGateway; no runtime effect.

2. Test / conftest edits that belong in #765, not in chore:
   - scripts/test/e2e/cases/conftest.py
   - scripts/test/e2e/cases/test_c_entry.py
   - scripts/test/e2e/cases/test_cli_detach_recovery.py
   - scripts/test/e2e/cases/test_cli_entry.py
   - scripts/test/e2e/cases/test_exec_timeout.py
   - scripts/test/e2e/cases/test_go_entry.py
   - scripts/test/e2e/cases/test_node_entry.py
   Reverted to main HEAD. The skip_or_fail / collect_ignore /
   best_effort_drain machinery is real e2e-gate work but is test-side,
   not chore's 'CI gate infrastructure' scope; consolidated into #765.

3. BOXLITE_E2E_REQUIRE_SDK_BUILDS env on the 'Run E2E suite' step:
   set to '1' to flip skip→fail in the conftest helper, but with the
   helper itself reverted out (point 2), the env var has no consumer
   on chore. Dropped from the workflow.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 532a8d7 to 55a15ea Compare June 15, 2026 08:05
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 5a91aa6 to 4b22262 Compare June 15, 2026 08:24
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 4b22262 to b820b5e Compare June 15, 2026 08:25
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from 248f800 to e13fd38 Compare June 15, 2026 08:27
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from b820b5e to 29d5a49 Compare June 15, 2026 08:28
G4614 added a commit that referenced this pull request Jun 15, 2026
…chore test/conftest fixes (move to #765)

What #724 should NOT have done — pull back from chore:

1. Trigger-comment cruft from the deploy-app-services iteration:
   - apps/otel-collector/Dockerfile: '# 2026-06-12T07:53:02Z — trigger
     deploy-app-services for OtelCollector'
   - apps/proxy/Dockerfile: four such 2026-06-12 retest markers
   - apps/ssh-gateway/Dockerfile: same.
   Pure ratchet noise from getting the deploy lane unstuck on
   Proxy/OtelCollector/SshGateway; no runtime effect.

2. Test / conftest edits that belong in #765, not in chore:
   - scripts/test/e2e/cases/conftest.py
   - scripts/test/e2e/cases/test_c_entry.py
   - scripts/test/e2e/cases/test_cli_detach_recovery.py
   - scripts/test/e2e/cases/test_cli_entry.py
   - scripts/test/e2e/cases/test_exec_timeout.py
   - scripts/test/e2e/cases/test_go_entry.py
   - scripts/test/e2e/cases/test_node_entry.py
   Reverted to main HEAD. The skip_or_fail / collect_ignore /
   best_effort_drain machinery is real e2e-gate work but is test-side,
   not chore's 'CI gate infrastructure' scope; consolidated into #765.

3. BOXLITE_E2E_REQUIRE_SDK_BUILDS env on the 'Run E2E suite' step:
   set to '1' to flip skip→fail in the conftest helper, but with the
   helper itself reverted out (point 2), the env var has no consumer
   on chore. Dropped from the workflow.
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 29d5a49 to 1545fa8 Compare June 15, 2026 08:40
G4614 added a commit that referenced this pull request Jun 15, 2026
…chore test/conftest fixes (move to #765)

What #724 should NOT have done — pull back from chore:

1. Trigger-comment cruft from the deploy-app-services iteration:
   - apps/otel-collector/Dockerfile: '# 2026-06-12T07:53:02Z — trigger
     deploy-app-services for OtelCollector'
   - apps/proxy/Dockerfile: four such 2026-06-12 retest markers
   - apps/ssh-gateway/Dockerfile: same.
   Pure ratchet noise from getting the deploy lane unstuck on
   Proxy/OtelCollector/SshGateway; no runtime effect.

2. Test / conftest edits that belong in #765, not in chore:
   - scripts/test/e2e/cases/conftest.py
   - scripts/test/e2e/cases/test_c_entry.py
   - scripts/test/e2e/cases/test_cli_detach_recovery.py
   - scripts/test/e2e/cases/test_cli_entry.py
   - scripts/test/e2e/cases/test_exec_timeout.py
   - scripts/test/e2e/cases/test_go_entry.py
   - scripts/test/e2e/cases/test_node_entry.py
   Reverted to main HEAD. The skip_or_fail / collect_ignore /
   best_effort_drain machinery is real e2e-gate work but is test-side,
   not chore's 'CI gate infrastructure' scope; consolidated into #765.

3. BOXLITE_E2E_REQUIRE_SDK_BUILDS env on the 'Run E2E suite' step:
   set to '1' to flip skip→fail in the conftest helper, but with the
   helper itself reverted out (point 2), the env var has no consumer
   on chore. Dropped from the workflow.
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 1545fa8 to 0fc5363 Compare June 15, 2026 08:46
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 0fc5363 to 19d6cdb Compare June 15, 2026 09:04
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from 0914d59 to 5aa5340 Compare June 15, 2026 09:06
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 19d6cdb to 9932540 Compare June 15, 2026 09:06
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 63581c2 to 3a38e90 Compare June 15, 2026 11:30
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from 1e015b0 to 3449554 Compare June 15, 2026 11:30
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 3a38e90 to 7646789 Compare June 15, 2026 11:30
G4614 added a commit that referenced this pull request Jun 15, 2026
…atrix, strip remaining leaf push triggers

deploy-app-services.yml was a 3-deep orchestrator (e2e-cloud →
deploy-app-services → _deploy-single-service for each of Proxy /
OtelCollector / SshGateway). Inline the per-service deploy as a
matrix job and delete _deploy-single-service.yml.

Push triggers removed from the remaining leaves (deploy-api,
deploy-app-services already gone, plus deploy-runner / e2e-cloud-test
in earlier commits). The single push trigger is now on e2e-cloud.yml,
which paths-filters relevant code areas and dispatches the full
build + deploy + e2e pipeline as one workflow run instead of N
parallel races. main / chore / validate branches all fire it; drop
the chore / validate branch entries once #724 / #765 land.

deploy-app-services.yml restructure:
- workflow_call now requires `services` input (caller is responsible
  for change detection).
- Drop the inner `changes` job (its paths-filter logic was the
  rationale for the push trigger, which is gone).
- `prepare` job parses the comma-separated services input into a
  matrix; `deploy` job spawns one matrix entry per service.
- Inline what was in `_deploy-single-service.yml` verbatim (ECR
  build + push, register TD with borrowed Api roles, UpdateService
  + wait stable + PRIMARY assert).

e2e-cloud.yml's deploy_app_services job: on workflow_dispatch with
no app-service paths changed, fall back to all 3 services so ad-hoc
dispatch always exercises the full lane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@G4614 G4614 closed this Jun 15, 2026
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 7646789 to 3449554 Compare June 15, 2026 11:30
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 reopened this Jun 15, 2026
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from e9cebe4 to 20258f8 Compare June 15, 2026 12:05
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
G4614 added a commit that referenced this pull request Jun 15, 2026
Every chore push gets rebased into validate immediately, so a chore-
triggered e2e-cloud run tests infrastructure changes without #765's
source fixes and always fails. Cancelling those runs manually every
push has been ratchet noise — drop the branch from the trigger list.

Validate stays in the trigger list so #765 stack pushes still
exercise the full pipeline pre-merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 20258f8 to a436597 Compare June 15, 2026 12:07
G4614 added a commit that referenced this pull request Jun 15, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from a6463bf to 8c35fe4 Compare June 16, 2026 06:13
G4614 added a commit that referenced this pull request Jun 16, 2026
…atrix, strip remaining leaf push triggers

deploy-app-services.yml was a 3-deep orchestrator (e2e-cloud →
deploy-app-services → _deploy-single-service for each of Proxy /
OtelCollector / SshGateway). Inline the per-service deploy as a
matrix job and delete _deploy-single-service.yml.

Push triggers removed from the remaining leaves (deploy-api,
deploy-app-services already gone, plus deploy-runner / e2e-cloud-test
in earlier commits). The single push trigger is now on e2e-cloud.yml,
which paths-filters relevant code areas and dispatches the full
build + deploy + e2e pipeline as one workflow run instead of N
parallel races. main / chore / validate branches all fire it; drop
the chore / validate branch entries once #724 / #765 land.

deploy-app-services.yml restructure:
- workflow_call now requires `services` input (caller is responsible
  for change detection).
- Drop the inner `changes` job (its paths-filter logic was the
  rationale for the push trigger, which is gone).
- `prepare` job parses the comma-separated services input into a
  matrix; `deploy` job spawns one matrix entry per service.
- Inline what was in `_deploy-single-service.yml` verbatim (ECR
  build + push, register TD with borrowed Api roles, UpdateService
  + wait stable + PRIMARY assert).

e2e-cloud.yml's deploy_app_services job: on workflow_dispatch with
no app-service paths changed, fall back to all 3 services so ad-hoc
dispatch always exercises the full lane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G4614 added a commit that referenced this pull request Jun 16, 2026
Every chore push gets rebased into validate immediately, so a chore-
triggered e2e-cloud run tests infrastructure changes without #765's
source fixes and always fails. Cancelling those runs manually every
push has been ratchet noise — drop the branch from the trigger list.

Validate stays in the trigger list so #765 stack pushes still
exercise the full pipeline pre-merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 67740e8 to bce86b5 Compare June 16, 2026 06:15
G4614 added a commit that referenced this pull request Jun 16, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from 8c35fe4 to b969b70 Compare June 16, 2026 10:30
G4614 added a commit that referenced this pull request Jun 16, 2026
…atrix, strip remaining leaf push triggers

deploy-app-services.yml was a 3-deep orchestrator (e2e-cloud →
deploy-app-services → _deploy-single-service for each of Proxy /
OtelCollector / SshGateway). Inline the per-service deploy as a
matrix job and delete _deploy-single-service.yml.

Push triggers removed from the remaining leaves (deploy-api,
deploy-app-services already gone, plus deploy-runner / e2e-cloud-test
in earlier commits). The single push trigger is now on e2e-cloud.yml,
which paths-filters relevant code areas and dispatches the full
build + deploy + e2e pipeline as one workflow run instead of N
parallel races. main / chore / validate branches all fire it; drop
the chore / validate branch entries once #724 / #765 land.

deploy-app-services.yml restructure:
- workflow_call now requires `services` input (caller is responsible
  for change detection).
- Drop the inner `changes` job (its paths-filter logic was the
  rationale for the push trigger, which is gone).
- `prepare` job parses the comma-separated services input into a
  matrix; `deploy` job spawns one matrix entry per service.
- Inline what was in `_deploy-single-service.yml` verbatim (ECR
  build + push, register TD with borrowed Api roles, UpdateService
  + wait stable + PRIMARY assert).

e2e-cloud.yml's deploy_app_services job: on workflow_dispatch with
no app-service paths changed, fall back to all 3 services so ad-hoc
dispatch always exercises the full lane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G4614 added a commit that referenced this pull request Jun 16, 2026
Every chore push gets rebased into validate immediately, so a chore-
triggered e2e-cloud run tests infrastructure changes without #765's
source fixes and always fails. Cancelling those runs manually every
push has been ratchet noise — drop the branch from the trigger list.

Validate stays in the trigger list so #765 stack pushes still
exercise the full pipeline pre-merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@G4614 G4614 force-pushed the validate/runner-toolbox-via-chore branch from 3a53952 to 83a7581 Compare June 16, 2026 10:31
G4614 added a commit that referenced this pull request Jun 16, 2026
…rification / exec_timeout

Moves the no-skip wiring from chore into #765 where the rest of the
test fixes already live.

- conftest.skip_or_fail_unless_sdk_build_required: helper that flips
  pytest.skip into pytest.fail when BOXLITE_E2E_REQUIRE_SDK_BUILDS=1
  is set. The e2e-cloud-test workflow sets it; local dev leaves it
  unset and the skip path stays usable.
- conftest.collect_ignore (guarded on BOXLITE_E2E_PROFILE != default):
  drops scripts/test/e2e/cases/test_path_verification.py from pytest
  collection on cloud profiles. Both cases in that file are LOCAL
  meta-tests (one asserts credentials.toml url=:3000, the other reads
  the host's boxlite-runner systemd journal) and can't run against
  the Tokyo ELB profile. collect_ignore drops them from collection
  entirely — no SKIP markers in the report.
- test_c_entry / test_cli_entry / test_cli_detach_recovery /
  test_go_entry / test_node_entry fixtures: every pytest.skip routed
  through skip_or_fail_unless_sdk_build_required.
- test_path_verification.py: module-level pytest.mark.skipif removed
  (replaced by the collect_ignore above so the file produces no
  collection at all on cloud, instead of being collected-then-skipped).
- test_exec_timeout.py: the _skipif_cloud decorator on both cases is
  gone; instead drain(ex) is moved behind a short asyncio.wait_for
  and reordered after ex.wait() so the elapsed / exit-code assertions
  don't depend on stream content. The REST runner's stream pumps
  don't reliably observe stream closure when the workload terminates
  via SIGKILL; the workaround lets the test actually run on cloud
  (no SKIP entry) while preserving its semantic intent.
- e2e-cloud-test.yml: BOXLITE_E2E_REQUIRE_SDK_BUILDS=1 on the
  Run E2E suite step — multi-job prereqs guarantee artifacts on
  disk so a fixture-skip path firing here is now a regression signal.
@G4614 G4614 force-pushed the chore/e2e-required-merge-gate branch from b969b70 to dbf0d8d Compare June 16, 2026 10:46
G4614 added a commit that referenced this pull request Jun 16, 2026
…atrix, strip remaining leaf push triggers

deploy-app-services.yml was a 3-deep orchestrator (e2e-cloud →
deploy-app-services → _deploy-single-service for each of Proxy /
OtelCollector / SshGateway). Inline the per-service deploy as a
matrix job and delete _deploy-single-service.yml.

Push triggers removed from the remaining leaves (deploy-api,
deploy-app-services already gone, plus deploy-runner / e2e-cloud-test
in earlier commits). The single push trigger is now on e2e-cloud.yml,
which paths-filters relevant code areas and dispatches the full
build + deploy + e2e pipeline as one workflow run instead of N
parallel races. main / chore / validate branches all fire it; drop
the chore / validate branch entries once #724 / #765 land.

deploy-app-services.yml restructure:
- workflow_call now requires `services` input (caller is responsible
  for change detection).
- Drop the inner `changes` job (its paths-filter logic was the
  rationale for the push trigger, which is gone).
- `prepare` job parses the comma-separated services input into a
  matrix; `deploy` job spawns one matrix entry per service.
- Inline what was in `_deploy-single-service.yml` verbatim (ECR
  build + push, register TD with borrowed Api roles, UpdateService
  + wait stable + PRIMARY assert).

e2e-cloud.yml's deploy_app_services job: on workflow_dispatch with
no app-service paths changed, fall back to all 3 services so ad-hoc
dispatch always exercises the full lane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
G4614 added a commit that referenced this pull request Jun 16, 2026
Every chore push gets rebased into validate immediately, so a chore-
triggered e2e-cloud run tests infrastructure changes without #765's
source fixes and always fails. Cancelling those runs manually every
push has been ratchet noise — drop the branch from the trigger list.

Validate stays in the trigger list so #765 stack pushes still
exercise the full pipeline pre-merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant