You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps Pipeline中Cache@2+Poetry缓存命中后poetry run失败求助

问题:缓存命中时Poetry执行poetry run coverage失败

在Azure DevOps托管构建代理中运行以下azure-pipelines.yml配置时,Cache@2步骤缓存命中后,poetry run coverage命令报错"Command not found: coverage",但跳过缓存重新安装依赖则正常运行。

配置文件内容

- task: UsePythonVersion@0
  inputs:
    versionSpec: $(pythonVersion)
  displayName: 'Use Python 3.10.8'

- script: |
    export POETRY_VERSION=$(poetryVersion)
    curl -sSL https://install.python-poetry.org | python -
    echo "##vso[task.setvariable variable=PATH]${PATH}:$HOME/.local/bin"
  displayName: 'Install poetry'

- ${{ if eq(parameters.usePoetryCache, true) }}:
  - task: Cache@2
    inputs:
      key: 'poetry | "$(Agent.OS)" | poetry.lock'
      # restoreKeys: |
      #   poetry | "$(Agent.OS)"
      #   poetry
      path: $(venv)
      cacheHitVar: POETRY_CAHCE_RESTORED

- script: |
      poetry config virtualenvs.in-project true
      poetry config virtualenvs.path $(venv)
  displayName: Configure Poetry

- script: |
    poetry install
  displayName: Install dependencies
  condition: eq(variables.POETRY_CAHCE_RESTORED, 'false')

- script: |
    poetry show coverage
  displayName: Check coverage installation

- script: |
    poetry run coverage run -m pytest && poetry run coverage xml -o ${{ parameters.workingDirectory }}/${{ parameters.testResultsDir }}/coverage.xml
  displayName: Run tests & code coverage # THIS FAILS

关键日志详情

Cache@2 缓存命中日志

Resolving key:
 - poetry      [string]
 - "Linux"     [string]
 - poetry.lock [file] --> 7AFBEE979DA4396BFE2D0AEF57A0A6A210629F38EFE50786DF26B396ECD935E0
Resolved to: poetry|"Linux"|VHTXv4eVo2iEXIULm/6DKwpSuYJEqaI86WbrPgZ3/T4=
Using default max parallelism.
Max dedup parallelism: 192
Getting a pipeline cache artifact with one of the following fingerprints:
Fingerprint: `poetry|"Linux"|VHTXv4eVo2iEXIULm/6DKwpSuYJEqaI86WbrPgZ3/T4=`
There is a cache hit: `poetry|"Linux"|VHTXv4eVo2iEXIULm/6DKwpSuYJEqaI86WbrPgZ3/T4=`
Used scope: 3012;5b97d788-43ec-45d8-836e-eaa18049b8fb;refs/heads/feature/pipeline-work;ff191ef6-ebfd-4d63-9d61-e7d1f8ceaf65
Entry found at fingerprint: `poetry|"Linux"|VHTXv4eVo2iEXIULm/6DKwpSuYJEqaI86WbrPgZ3/T4=`
Expected size to be downloaded: 121.7 MB
Downloaded 0.0 MB out of 121.7 MB (0%).
Downloaded 121.7 MB out of 121.7 MB (100%).

Download statistics:
Total Content: 121.7 MB
Physical Content Downloaded: 48.8 MB
Compression Saved: 72.9 MB
Local Caching Saved: 0.0 MB
Chunks Downloaded: 1,483
Nodes Downloaded: 3

检查Coverage安装日志

name         : coverage                             
 version      : 6.5.0                                
 description  : Code coverage measurement for Python 

dependencies
 - tomli *

执行测试报错日志

poetry run coverage run -m pytest && poetry run coverage xml -o /agent/_work/22/s/TestResults/coverage.xml
========================== Starting Command Output ===========================
/bin/bash --noprofile --norc /agent/_work/_temp/XXXXXXXXXXXXXXXXXX.sh
Command not found: coverage
##[error]Bash exited with code '1'.
Finishing: Run tests & code coverage
原因分析
  • 虚拟环境关联失效:缓存恢复了虚拟环境目录,但Poetry未自动识别该环境,poetry run仍尝试使用默认环境(未安装coverage)。
  • 变量拼写错误:缓存步骤中cacheHitVar写成了POETRY_CAHCE_RESTORED(多了一个C),虽然不影响条件判断,但会导致变量名不规范,增加排查难度。
  • 配置时机错误:在缓存恢复后才配置Poetry虚拟环境路径,导致缓存的环境未被纳入Poetry的识别范围。
解决方法

方法1:修复拼写错误并强制关联缓存环境

  1. 修正cacheHitVar的拼写为POETRY_CACHE_RESTORED,统一变量命名。
  2. 在缓存命中后添加步骤,让Poetry明确关联缓存的虚拟环境:
    - ${{ if eq(parameters.usePoetryCache, true) }}:
      - task: Cache@2
        inputs:
          key: 'poetry | "$(Agent.OS)" | poetry.lock'
          path: $(venv)
          cacheHitVar: POETRY_CACHE_RESTORED
      - script: |
          poetry env use $(venv)/bin/python
        displayName: Associate cached virtual environment with Poetry
        condition: eq(variables.POETRY_CACHE_RESTORED, 'true')
    
  3. 保持poetry install的条件判断为eq(variables.POETRY_CACHE_RESTORED, 'false'),缓存命中时跳过安装。

方法2:调整虚拟环境配置时机

将Poetry虚拟环境配置步骤移到缓存步骤之前,确保缓存恢复时配置已生效:

- script: |
      poetry config virtualenvs.in-project true
      poetry config virtualenvs.path $(venv)
  displayName: Configure Poetry

- ${{ if eq(parameters.usePoetryCache, true) }}:
  - task: Cache@2
    inputs:
      key: 'poetry | "$(Agent.OS)" | poetry.lock'
      path: $(venv)
      cacheHitVar: POETRY_CACHE_RESTORED

方法3:缓存后验证环境可用性

在缓存恢复后添加验证步骤,确认虚拟环境可正常使用:

- script: |
    if [ -d $(venv) ]; then
      echo "Virtual environment exists at $(venv)"
      source $(venv)/bin/activate
      which coverage
    fi
  displayName: Verify cached virtual environment
  condition: eq(variables.POETRY_CACHE_RESTORED, 'true')

若which coverage能输出有效路径,说明环境可用,后续poetry run即可正常执行。


内容的提问来源于stack exchange,提问作者bitnahian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 17:01:09