Skip to content

ci(pin-compat): split into two workflows so each gets a narrow paths filter - #2199

Merged
HongmingWang-Rabbit merged 1 commit into
stagingfrom
fix/pin-compat-narrow-pypi-job-trigger
Apr 28, 2026
Merged

ci(pin-compat): split into two workflows so each gets a narrow paths filter#2199
HongmingWang-Rabbit merged 1 commit into
stagingfrom
fix/pin-compat-narrow-pypi-job-trigger

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Summary

Closes #134. Splits the previously-merged runtime-pin-compat.yml (which had two jobs sharing a union paths: filter) into two workflows so each job gets a paths: filter matching its actual inputs.

Problem

The combined workflow's filter triggered both jobs on any workspace/** change. The pypi-latest-install job tests against the published PyPI artifact, which can't change based on our workspace/ source — only on actual PyPI publishes. So adapter / doc / README edits would run a job whose verdict couldn't change.

Fix

File Job paths: filter
runtime-pin-compat.yml (kept) PyPI-latest install + import smoke narrow: workspace/requirements.txt, the workflow itself
runtime-prbuild-compat.yml (new) PR-built wheel + import smoke broad: workspace/**, scripts/build_runtime_package.py, the workflow itself

Cron stays only on pin-compat (testing for upstream-yank doesn't depend on our source). No new third-party actions; identical job-body logic to before.

Verification

  • Both workflows YAML-parse.
  • Job content unchanged from the previously-merged combined version (verified by diff against staging).

Test plan

  • CI green on this PR
  • On a doc-only PR (no workspace/requirements.txt change), only runtime-prbuild-compat.yml fires; the pypi-latest job stays quiet.

🤖 Generated with Claude Code

…filter

Closes #134. The post-merge review of #2196 flagged that the combined
workflow's `paths:` filter (the union of both jobs' needs:
`workspace/**` + `scripts/build_runtime_package.py` + the workflow
itself) caused the `pypi-latest-install` job to fire on every
doc-only / adapter-only / unrelated workspace/ edit. The PyPI artifact
that job tests against can't change based on our workspace/ source —
only on actual PyPI publishes — so those runs add noise without
information.

Splits the previously-merged combined workflow:

  runtime-pin-compat.yml (kept):
    - PyPI-latest install + import smoke (was: pypi-latest-install)
    - Narrow `paths:` filter — only fires when workspace/requirements.txt
      or this workflow file changes
    - Cron-driven daily for upstream-yank detection (unchanged)

  runtime-prbuild-compat.yml (new):
    - PR-built wheel + import smoke (was: local-build-install)
    - Broad `paths:` filter — fires on any workspace/ source change,
      scripts/build_runtime_package.py, or this workflow file
    - No cron (workspace/ doesn't change between firings)

Behavior identical to before for content; only the trigger surface is
narrower per-job. Each workflow's name is its own status check, so
branch protection (which currently lists neither as required) can
gate them independently in future.

The prior comment in the combined file explicitly acknowledged the
asymmetry and proposed this split as a follow-up; this is that
follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@HongmingWang-Rabbit
HongmingWang-Rabbit added this pull request to the merge queue Apr 28, 2026
Merged via the queue into staging with commit e7eeeb4 Apr 28, 2026
17 checks passed
@HongmingWang-Rabbit
HongmingWang-Rabbit deleted the fix/pin-compat-narrow-pypi-job-trigger branch April 28, 2026 18:25
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
)

The canvas-readiness loop added in PR #2195 captured the curl status
into CODE with `CODE=$(curl -s -o /dev/null -w '%{http_code}' ...
|| echo 000)`. That shape is exactly the BAD_STATUS_CAPTURE pattern
that .gitea/scripts/lint-curl-status-capture.py rejects — curl -w can
write a status to stdout before the || echo 000 fallback fires,
producing polluted values such as a concatenated status string rather
than one code.

Adopt the lint-approved tempfile pattern already used by
e2e-staging-external.yml (set +e / curl -w '...' > file / set -e /
cat file || echo '000') so the captured value is always a clean HTTP
code or '000'.

Closes #2198 (main-red after #2195).
Closes #2199 (auto-filed main-red watchdog, root cause identical to #2198).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…empfile (resolves #2198, #2199)' (#2201) from fix/e2e-chat-readiness-curl-tempfile-2198 into main
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…2199)

E2E Staging Canvas (Playwright) / "Canvas tabs E2E" went red on main HEAD
b9d2f02. The actual failure (runner-6 task 258160) is in the Playwright
globalSetup, NOT in any spec assertion:

  [staging-setup] Workspace created: 8e5c7354-...
  Error: Workspace failed: (no last_sample_error) full body:
    {... "runtime":"hermes","status":"failed","uptime_seconds":0,
     "last_sample_error":null ...}
    at canvas/e2e/staging-setup.ts:272 (waitFor "workspace online")

Root cause — NOT a canvas/test regression and NOT timing fragility. It is
a deterministic consequence of workspace-server #2162 (merged 2026-06-03,
"platform-managed workspace must fail-closed when CP proxy env absent"),
which is a correct production safety fix. The canvas E2E creates a bare
hermes/gpt-4o workspace that defaults closed to platform_managed; on a
staging tenant without MOLECULE_LLM_BASE_URL / MOLECULE_LLM_USAGE_TOKEN,
the agent now aborts at boot with MISSING_PLATFORM_PROXY — surfacing as
the pre-start credential-abort shape (status:"failed", uptime_seconds:0,
no last_sample_error). Pre-#2162 the same workspace booted credential-less
(the bug #2162 fixed) so the old harness happened to pass.

The fix is in the harness, because this test does not need a booted agent:
staging-tabs.spec.ts only opens the 13 side-panel tabs and asserts no hard
crash / no "Failed to load" toast. It makes zero LLM calls and even mocks
/cp/auth/me + 401→200. All it needs is a workspace ROW so the node + tabs
render.

So step 6 now waits for RENDERABLE instead of strictly online:
  - online                                 -> happy path (staging with proxy env)
  - failed + uptime_seconds==0 + no sample -> pre-start credential-abort:
      agent never ran, row still renders -> proceed, with a loud console.warn
  - any other failed (last_sample_error present, OR uptime_seconds>0 i.e.
      the agent started then crashed)      -> still hard-throws (no masking)

Real infra/provision failure stays loud one step earlier at the org level
(instance_status === "failed", unchanged).

Verification: tsc clean for canvas/e2e/staging-* (pre-existing tsc errors
are all in unrelated __tests__ files); `playwright test --list` resolves
globalSetup + the single spec. Full live run needs staging CP creds not
available locally; the changed branch is the globalSetup readiness gate,
verified by inspection against the captured failing-run body.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…DERABLE, not online (#2199)' (#2202) from fix/e2e-staging-canvas-tabs-red into main
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.

channels: Security Auditor and DevOps Engineer have no external notification channel

1 participant