对在与已发布的工件分离的阶段中使用$(Build.ArtifactStagingDirectory)感到困惑



问题:

$(Build.ArtifactStagingDirectory)为空,尽管可以在Azure DevOps管道UI中查看已发布的工件,这会导致管道失败。

我想做的事情:

  1. 构建微服务(例如/api(
  2. 运行单元测试
  3. 如果单元测试通过,则将构建发布为工件
  4. 使用buildContext对构建工件进行Dockerize

这是基于这里、这里和这里的建议。

发布阶段配置

我在单元测试通过后发布的配置如下:

- publish: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }} 
artifact: ${{ parameters.pathName }}
condition: succeeded()
根据我收集的信息,$(System.DefaultWorkingDirectory)应该是/home/vsts/work/1/s/
  • ${{ parameters.pathName }}就是api
  • 我可以看到在Azure DevOps Pipelines UI中生成了正确的工件
  • DockerbuildAndPush阶段配置

    我获取工件并在DockerbuildAndPush配置中使用它的配置如下:

    - task: Docker@2
    condition: contains(variables['servicesChanged'], '${{ parameters.serviceName }}')
    displayName: Build and Push ${{ parameters.pathName }} Docker image
    inputs:
    command: buildAndPush
    repository: $(imageRepository)-${{ parameters.pathName }}
    dockerfile: $(dockerfilePath)/${{ parameters.pathName }}/Dockerfile
    buildContext: $(Build.ArtifactStagingDirectory)
    containerRegistry: $(dockerRegistryServiceConnection)
    tags: |
    ${{ parameters.tag }}-${{ parameters.tagVersion }}
    
    • 据我所知,$(Build.ArtifactStagingDirectory)应该是/home/vsts/work/1/a/
    • 但是,它是空的,并且此阶段失败
    • 12等于CCD_ 13

    Dockerfile配置

    信息,但这是Dockerfile包含的内容:

    FROM python:3.8-slim
    WORKDIR /app
    EXPOSE 5000
    COPY . .
    RUN pip install -r requirements.txt
    CMD ["gunicorn", "-b", ":5000", "--log-level", "info", "config.wsgi:application", "-t", "150"]
    

    项目结构

    /project-root
    /admin
    package.json
    Dockerfile
    /api
    requirements.txt
    Dockerfile
    /client
    package.json
    Dockerfile
    

    我尝试过的

    dockerfile: $(dockerfilePath)/${{ parameters.pathName }}/Dockerfile
    buildContext: $(Build.ArtifactStagingDirectory)
    
    Step 5/17 : RUN pip install -r requirements.txt
    ---> Running in 277ce44b61cf
    ERROR: Could not open requirements file: [Errno 2] No such file or directory: 'requirements.txt'
    The command '/bin/sh -c pip install -r requirements.txt' returned a non-zero code: 1
    ##[error]The command '/bin/sh -c pip install -r requirements.txt' returned a non-zero code: 1
    ##[error]The process '/usr/bin/docker' failed with exit code 1
    
    dockerfile: $(dockerfilePath)/${{ parameters.pathName }}/Dockerfile
    buildContext: $(Build.ArtifactStagingDirectory)/${{ parameters.pathName }}
    
    unable to prepare context: path "/home/vsts/work/1/a/api" not found
    ##[error]unable to prepare context: path "/home/vsts/work/1/a/api" not found
    ##[error]The process '/usr/bin/docker' failed with exit code 1
    
    dockerfile: $(Build.ArtifactStagingDirectory)/${{ parameters.pathName }}/Dockerfile
    buildContext: $(Build.ArtifactStagingDirectory)
    
    ##[error]Unhandled: No Dockerfile matching  /home/vsts/work/1/a/api/Dockerfile  was found.
    
    dockerfile: $(Build.ArtifactStagingDirectory)/Dockerfile
    buildContext: $(Build.ArtifactStagingDirectory)
    ##[error]Unhandled: No Dockerfile matching  /home/vsts/work/1/a/Dockerfile  was found.
    

    行之有效的方法

    dockerfile: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }}/Dockerfile
    buildContext: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }}
    

    但这样做似乎否定了publish作为工件的必要性。也许这就是";正确的";我不知道。它似乎在做我想通过COPY实现的事情,CCD_17是为Docker映像中的单元测试而构建的,而不是使用不同的版本。

    我很确定这不是我想要的,因为它看起来只是在这个阶段开始时将repo再次克隆到/home/vsts/work/1/a/

    问题

    • 为什么$(Build.ArtifactStagingDirectory)为空
    • 它是一个不推荐使用的env-var吗
    • 正在使用我在";什么起作用了;应该是正确的处理方式吗(我不认为是(
    • 那么,我应该如何在单元测试阶段和Docker阶段之间持久化测试的构建,以便使用单元测试阶段的确切构建呢

    使用时:

    - publish: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }} 
    artifact: ${{ parameters.pathName }}
    condition: succeeded()
    

    在幕后,它使用默认下载的Publish Pipeline Artifact task

    将文件下载到$(Pipeline.Workspace(。这是所有类型工件的默认和推荐路径。

    所以请尝试

    buildContext: $(Pipeline.Workspace)
    

    buildContext: $(Pipeline.Workspace)/${{ parameters.pathName }}
    

    然而,当您有多阶段管道时,这是有意义的(我不确定,因为您没有发布整个管道(。请在此处查看

    对于构建工件,通常将文件复制到$(build.ArtifactStagingDirectory(,然后使用"发布构建工件"任务来发布此文件夹。使用"发布管道工件"任务,您可以直接从包含文件的路径进行发布。

    因此,在发布文件之前无需将文件移动到$(Build.ArtifactStagingDirectory)。因此,对于更新和推荐的任务,此文件夹可以一直为空。

    相关内容

    • 没有找到相关文章

    最新更新