在与已发布的 Artifact 不同的阶段使用 $(Build.ArtifactStagingDirectory) 感到困惑
Confused by the use of $(Build.ArtifactStagingDirectory) in separate stage from published Artifact
问题:
$(Build.ArtifactStagingDirectory)
为空,尽管能够在 Azure DevOps 管道 UI 中查看已发布的工件,这会导致管道失败。
我想做什么:
- 构建微服务(例如,
/api
)。
- 运行 单元测试。
- 如果单元测试通过,将构建发布为工件。
- Docker使用
buildContext
调整构建工件。
这是基于建议here, here, and 。
发布阶段配置
单元测试通过后我的发布配置如下:
- publish: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }}
artifact: ${{ parameters.pathName }}
condition: succeeded()
$(System.DefaultWorkingDirectory)
根据我的收集应该是 /home/vsts/work/1/s/
。
${{ parameters.pathName }}
就是 api
.
- 我可以看到在 Azure DevOps 管道中生成了正确的工件 UI。
Docker buildAndPush
舞台配置
我获取神器并在 Docker buildAndPush
配置中使用它的配置如下:
- 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/
。
- 但是,它是空的,这个阶段失败了。
$(dockerfilePath)
等于 $(Build.SourcesDirectory)
.
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
为单元测试构建到 Docker 图像而不是使用不同版本的东西。
我很确定这不是我想要的,因为它看起来只是在这个阶段开始时再次将回购克隆到 /home/vsts/work/1/a/
。
问题
- 为什么
$(Build.ArtifactStagingDirectory)
是空的?
- 它是已弃用的环境变量吗?
- 使用“有效方法”中的内容应该是处理此问题的正确方法吗? (我觉得不是).
- 那么我应该如何在单元测试阶段和 Docker 阶段之间保留经过测试的构建,以便我可以使用单元测试阶段的确切构建?
当您使用时:
- publish: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }}
artifact: ${{ parameters.pathName }}
condition: succeeded()
在后台它使用 Publish Pipeline Artifact task
默认下载
downloads files to $(Pipeline.Workspace). This is the default and recommended path for all types of artifacts.
所以请尝试
buildContext: $(Pipeline.Workspace)
或
buildContext: $(Pipeline.Workspace)/${{ parameters.pathName }}
但是,当您拥有多级管道时(我不确定,因为您没有发布整个管道),这很有意义。请检查 here
For build artifacts, it's common to copy files to $(Build.ArtifactStagingDirectory) and then use the Publish Build Artifacts task to publish this folder. With the Publish Pipeline Artifact task, you can just publish directly from the path containing the files.
所以这里没有必要在发布文件之前将文件移动到$(Build.ArtifactStagingDirectory)
。因此,对于更新和推荐的任务,此 foler 可能始终为空。
问题:
$(Build.ArtifactStagingDirectory)
为空,尽管能够在 Azure DevOps 管道 UI 中查看已发布的工件,这会导致管道失败。
我想做什么:
- 构建微服务(例如,
/api
)。 - 运行 单元测试。
- 如果单元测试通过,将构建发布为工件。
- Docker使用
buildContext
调整构建工件。
这是基于建议here, here, and
发布阶段配置
单元测试通过后我的发布配置如下:
- publish: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }}
artifact: ${{ parameters.pathName }}
condition: succeeded()
$(System.DefaultWorkingDirectory)
根据我的收集应该是/home/vsts/work/1/s/
。${{ parameters.pathName }}
就是api
.- 我可以看到在 Azure DevOps 管道中生成了正确的工件 UI。
Docker buildAndPush
舞台配置
我获取神器并在 Docker buildAndPush
配置中使用它的配置如下:
- 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/
。 - 但是,它是空的,这个阶段失败了。
$(dockerfilePath)
等于$(Build.SourcesDirectory)
.
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
为单元测试构建到 Docker 图像而不是使用不同版本的东西。
我很确定这不是我想要的,因为它看起来只是在这个阶段开始时再次将回购克隆到 /home/vsts/work/1/a/
。
问题
- 为什么
$(Build.ArtifactStagingDirectory)
是空的? - 它是已弃用的环境变量吗?
- 使用“有效方法”中的内容应该是处理此问题的正确方法吗? (我觉得不是).
- 那么我应该如何在单元测试阶段和 Docker 阶段之间保留经过测试的构建,以便我可以使用单元测试阶段的确切构建?
当您使用时:
- publish: $(System.DefaultWorkingDirectory)/${{ parameters.pathName }}
artifact: ${{ parameters.pathName }}
condition: succeeded()
在后台它使用 Publish Pipeline Artifact task
默认下载
downloads files to $(Pipeline.Workspace). This is the default and recommended path for all types of artifacts.
所以请尝试
buildContext: $(Pipeline.Workspace)
或
buildContext: $(Pipeline.Workspace)/${{ parameters.pathName }}
但是,当您拥有多级管道时(我不确定,因为您没有发布整个管道),这很有意义。请检查 here
For build artifacts, it's common to copy files to $(Build.ArtifactStagingDirectory) and then use the Publish Build Artifacts task to publish this folder. With the Publish Pipeline Artifact task, you can just publish directly from the path containing the files.
所以这里没有必要在发布文件之前将文件移动到$(Build.ArtifactStagingDirectory)
。因此,对于更新和推荐的任务,此 foler 可能始终为空。