Skip to content

Harden CI: the live-E2E jobs install from a hash-pinned set - #5915

Merged
vivekchand merged 1 commit into
mainfrom
harden/pin-live-e2e-installs
Sep 12, 2026
Merged

Harden CI: the live-E2E jobs install from a hash-pinned set#5915
vivekchand merged 1 commit into
mainfrom
harden/pin-live-e2e-installs

Conversation

@vivekchand

Copy link
Copy Markdown
Owner

What

ci.yml's e2e-critical and live-openclaw-e2e each installed their Python deps from a loose pip install a b c line, so every run resolved whatever the index served that minute with no integrity check on any artifact. Both now install with pip install --require-hashes from a file under .github/requirements/, which refuses anything not listed with a matching hash.

This continues the batch started in #5889 / #5897 / #5899 / #5902 / #5903 / #5907 and closes out the loose installs in this file that can be closed safely today.

No new hashes

Neither job needed a new requirements file. Both dependency sets are already covered by sets this repository generated and proves in CI:

Job Previously resolved loosely Now installs from Already proven by
e2e-critical flask, pytest, pytest-playwright, requests, duckdb playwright-e2e.txt e2e-nightly, quarantine-sweep
live-openclaw-e2e flask, pytest, waitress, duckdb, cryptography, requests ci-tests.txt seven sibling jobs in this file

Both files are Python 3.11 sets and both of these jobs pin 3.11 with setup-python, so this reuses a pin already exercised on a runner rather than introducing hashes that have never been resolved.

Why api-tests and lint are not in this batch

They hold the remaining loose installs in this file, and that version match is exactly why they are excluded. api-tests runs a 3.9 matrix leg and lint is 3.9 only, while ci-tests.txt pins cffi==2.1.1 and cryptography==50.0.1 — both 3.10+ only, per the dependency notes in CLAUDE.md. Pointing either at these files would take those legs red. They need a 3.9-compatible set, which is its own change.

The install-from-source and install-from-wheel smoke jobs (pip-install, wheel-install, eval-suite) are deliberately left loose: resolving clawmetry's own dependencies from the index is the thing they exist to test.

The guard stays honest

tests/test_workflow_yaml_valid.py::test_pytest_jobs_install_what_conftest_needs reads a -r file this repo owns and checks its contents, precisely so that moving package names out of a run: line does not silently retire the guard for that job (the concern #5907 called out). Both changed jobs still assert, not skip — confirmed by node id.

Verification

Run on Linux / CPython 3.11.15, matching what both jobs pin with setup-python on ubuntu-latest:

  • pip install --require-hashes -r each file into a clean venv: succeeds for both.
  • Every module the two run: lines previously named imports from the resulting environment (flask 3.1.3, duckdb 1.5.5, requests 2.34.2, cryptography 50.0.1, waitress, pytest, pytest-playwright, playwright).
  • All 40 workflow files still parse: python3 -c "import yaml,glob; [yaml.safe_load(open(f)) for f in glob.glob('.github/workflows/*.yml')]"
  • tests/test_workflow_yaml_valid.py + tests/test_ci_workflow_invocations_are_real.py594 passed, 369 skipped, unchanged from before this edit.
  • tests/test_action_refs_pinned.py, tests/test_e2e_nightly_workflow.py → pass.

Scope

One concern, one workflow file, 16 insertions / 2 deletions. No permissions: block is added or removed. Under .github/, so exempt from the product-record gate.

No-PRD: CI-only change under .github/, no product code touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ndb2qBqQjscpQY4KjXJxXA


Generated by Claude Code

ci.yml's `e2e-critical` and `live-openclaw-e2e` each installed their
Python deps from a loose `pip install a b c` line, so every run resolved
whatever the index served that minute with no integrity check on any
artifact. Both now install with `pip install --require-hashes` from a
file under .github/requirements/, which refuses anything not listed with
a matching hash.

Neither needed a new requirements file. Both jobs' dependency sets are
already covered by sets this repository generated and proves in CI:

  e2e-critical      -> playwright-e2e.txt  (e2e-nightly, quarantine-sweep)
  live-openclaw-e2e -> ci-tests.txt        (seven sibling jobs in this file)

Both files are Python 3.11 sets and both of these jobs pin 3.11 with
setup-python, so this reuses a pin that is already exercised rather than
introducing hashes that have never been resolved on a runner.

That version match is the reason `api-tests` and `lint` are NOT in this
batch even though they hold the remaining loose installs in this file.
`api-tests` runs a 3.9 leg and `lint` is 3.9 only, while ci-tests.txt
pins cffi==2.1.1 and cryptography==50.0.1 -- both 3.10+ only. Pointing
them here would take those legs red. They need a 3.9-compatible set,
which is its own change.

The install-from-source and install-from-wheel smoke jobs (`pip-install`,
`wheel-install`, `eval-suite`) are deliberately left loose: resolving
clawmetry's own dependencies from the index is the thing they exist to
test.

Verified on Linux / CPython 3.11.15, matching what both jobs pin with
setup-python on ubuntu-latest: `pip install --require-hashes -r` each
file into a clean venv succeeds, and every module the two `run:` lines
previously named imports from the resulting environment. All 40 workflow
files still parse. tests/test_workflow_yaml_valid.py +
tests/test_ci_workflow_invocations_are_real.py: 594 passed / 369 skipped,
unchanged from before this edit -- in particular the conftest-import
guard still ASSERTS for both jobs rather than skipping, which is what
moving package names into a `-r` file would otherwise have retired.

No permissions blocks were touched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ndb2qBqQjscpQY4KjXJxXA
@8090-software-factory

Copy link
Copy Markdown

✅ Drift Bot (ClawMetry): no drift detected

Drift Bot analyzed the changed files against this project's blueprints and requirements and found no drift.

@vivekchand
vivekchand merged commit 73b0118 into main Sep 12, 2026
39 checks passed
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.

2 participants