Harden CI: the live-E2E jobs install from a hash-pinned set - #5915
Merged
Conversation
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
✅ Drift Bot (ClawMetry): no drift detectedDrift Bot analyzed the changed files against this project's blueprints and requirements and found no drift. |
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
ci.yml'se2e-criticalandlive-openclaw-e2eeach installed their Python deps from a loosepip install a b cline, so every run resolved whatever the index served that minute with no integrity check on any artifact. Both now install withpip install --require-hashesfrom 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:
e2e-criticalplaywright-e2e.txte2e-nightly,quarantine-sweeplive-openclaw-e2eci-tests.txtBoth 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-testsandlintare not in this batchThey hold the remaining loose installs in this file, and that version match is exactly why they are excluded.
api-testsruns a 3.9 matrix leg andlintis 3.9 only, whileci-tests.txtpinscffi==2.1.1andcryptography==50.0.1— both 3.10+ only, per the dependency notes inCLAUDE.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_needsreads a-rfile this repo owns and checks its contents, precisely so that moving package names out of arun: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-pythononubuntu-latest:pip install --require-hashes -reach file into a clean venv: succeeds for both.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).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.py→ 594 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