roots / roots/setup-trellis-cli
Virtualenv cache key omits the Python version, so a runner Python patch roll breaks deploys
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 34
- Forks
- 5
- PR merge metrics
- No merged PRs in 30d
Description
Summary
cachedInit() keys the virtualenv cache on trellis-venv + hashFiles('**/requirements.txt'):
async function cachedInit() {
return await withCache(async () => {
await exec.exec('trellis init')
}, [path.join('.trellis', 'virtualenv')], 'trellis-venv', '**/requirements.txt');
}
The key does not include the Python version. But a virtualenv's bin/python3 is an absolute symlink into /opt/hostedtoolcache/Python/<patch>/x64. So when requirements.txt is unchanged and the runner's Python patch rolls, the cache still hits and restores a venv pointing at an interpreter that no longer exists:
⠋ Creating virtualenv
Error: [Errno 2] No such file or directory: '.../trellis/.trellis/virtualenv/bin/python3'
[✘] Error creating virtualenv
Project initialization failed due to the error above.
Why it's easy to misdiagnose
The failure is intermittent and appears to correlate with whatever PR merged that morning, because the cache — not the diff — determines the outcome. In our repo it was twice attributed to unrelated application-code PRs before we traced it.
Observed sequence, same workflow, python-version: "3.12" (floating):
| Venv cache | Result |
|---|---|
| hit | fail |
| miss | pass |
| miss (saves new cache) | pass |
| hit | fail |
| hit | fail |
| miss (cache manually deleted) | pass |
Deleting the cache entry is a reliable workaround, which isolates it to the cache rather than the project.
Suggested fix
Include the resolved Python version in the cache key, e.g. append process.env.pythonLocation or the output of python3 --version to the key alongside the requirements.txt hash. That makes the key describe what the artifact is actually bound to, and a Python roll becomes a clean cache miss and rebuild instead of a hard failure.
Workaround for anyone hitting this
Either pin the exact patch:
- uses: actions/setup-python@v5
with:
python-version: "3.12.14" # not "3.12"
or set cache-virtualenv: false. Pinning keeps the cache and turns a future roll into an explicit "version not found" at setup time rather than the venv error above.
Environment
roots/setup-trellis-cli@v1, trellis-cli v1.19.0ubuntu-latest,actions/setup-python@v5, Python 3.12.14
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating cachedInit() and inspect how the virtualenv cache key is assembled, then reproduce the hit and miss behavior described in the issue. Done means the key includes the resolved Python version so a runner version change causes a cache miss and rebuild instead of restoring an unusable virtualenv.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, javascript, python
- Domain
- ci-cd, devops
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100