如何将 azure repo 文件夹复制到管道环境中 VM 上的文件夹?

How do you copy azure repo folders to a folder on a VM in an Environment in a pipeline?

我有一个名为 'Dev' 的环境,它有一个资源,它是一个虚拟机。作为 'Dev' 管道的一部分,我想将文件从特定回购开发分支上的特定文件夹复制到环境中 VM 上的特定文件夹。

我之前没有使用过 Environments 或 yaml 管道,但我想我需要使用 CopyFiles@2 任务。

所以我有一个类似这样的 azure pipeline yaml 文件:

variables:
  isDev: $[eq(variables['Build.SourceBranch'], 'refs/heads/develop')]

stages:
- stage: Build
  jobs:
  - job: Build
    pool:
      vmImage: 'windows-latest'
    steps:
    - task: CopyFiles@2
      displayName: 'Copy Files'
      inputs:
        contents: 'myFolder\**'
        Overwrite: true
        targetFolder: $(Build.ArtifactStagingDirectory)

    - task: PublishBuildArtifacts@1
      inputs:
        pathToPublish: $(Build.ArtifactStagingDirectory)
        artifactName: myArtifact

- stage: Deployment
  dependsOn: Build
  condition: and(succeeded(), eq(variables.isDev, true))
  jobs:
  - deployment: Deploy
    displayName: Deploy to Dev
    pool:
      vmImage: 'windows-latest'
    environment: Dev
    strategy:
      runOnce:
        deploy:
          steps:
          - script: echo Foo Bar

第一个问题是如何将文件复制到开发环境中的特定路径?

真的需要 PublishBuildArtifacts 吗?我问的原因是我希望每次管道 运行 时都复制文件,如果工件已经存在则不会出错。

用这种方式检查分支是否正确也感觉有点脏。有更好的方法吗?

您使用的部署策略依赖于指定代理池,这意味着它不会 运行 在环境中的计算机上。如果您使用诸如 rolling 之类的策略,它将自动在这些机器上 运行 指定的步骤,包括任何 download 下载工件的步骤。

参考:https://docs.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs?view=azure-devops#deployment-strategies

如果您希望工件自动可用于 down-stream 个作业,则需要将工件作为管道的一部分发布。每个 运行 将获得一组不同的工件,即使实际工件内容相同。

也就是说,根据您发布的 YAML,您可能不需要。事实上,您根本不需要“构建”阶段。您可以在滚动部署期间添加一个 checkout 步骤,然后将在每台目标计算机上克隆 repo。

如果您只想下载特定文件夹而不是存储库中的所有源文件,您可以尝试使用 REST API“Items - Get”单独下载每个特定文件夹。

GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/items?path={path}&download=true&$format=zip&versionDescriptor.version={versionDescriptor.version}&resolveLfs=true&api-version=6.0

例如: 拥有如下所示的存储库。

现在,在 YAML 管道中,我只想从 main[= 下载“TestFolder01”文件夹50=] 分支.

jobs:
- job: build
  . . .
  steps:
  - checkout: none  # Do not check out all the source files.
  - task: Bash@3
    displayName: 'Download particular folder'
    env:
      SYSTEM_ACCESSTOKEN: $(System.AccessToken)
    inputs:
      targetType: inline
      script: |
        curl -X GET \
        -o TestFolder01.zip \
        -u :$SYSTEM_ACCESSTOKEN 'https://dev.azure.com/MyOrg/MyProj/_apis/git/repositories/ShellScripts/items?path=/res/TestFolder01&download=true&$format=zip&versionDescriptor.version=main&resolveLfs=true&api-version=6.0'

这会将“TestFolder01”文件夹作为 ZIP 文件 (TestFolder01.zip) 下载到当前工作目录。可以使用unzip命令解压

[更新]

如果您想下载部署作业中针对您的 VM 环境的特定文件夹,是的,这些文件夹将被下载到 VM 上的管道工作目录中。

实际上,您可以认为虚拟机类型的环境资源是安装在虚拟机上的self-hosted代理。因此,当您的部署作业针对 VM 环境资源时,它是 运行 在 VM 上的 self-hosted 代理上。

管道工作目录在您安装VM环境资源(self-hosted代理)的目录下。通常,您可以使用变量 $(Pipeline.Workspace) 来获取此路径的值(参见 here)。

stages:
- stage: Deployment
  jobs:
  - deployment: Deploy
    displayName: 'Deploy to Dev'
    environment: 'Dev.VM-01'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: Bash@3
            displayName: 'Download particular folder'
            env:
              SYSTEM_ACCESSTOKEN: $(System.AccessToken)
            inputs:
              targetType: inline
              script: |
                echo "Current working directory: $PWD"
                curl -X GET \
                -o TestFolder01.zip \
                -u :$SYSTEM_ACCESSTOKEN 'https://dev.azure.com/MyOrg/MyProj/_apis/git/repositories/ShellScripts/items?path=/res/TestFolder01&download=true&$format=zip&versionDescriptor.version=main&resolveLfs=true&api-version=6.0'

好的,在这篇文章的帮助下解决了这个问题:https://dev.to/kenakamu/azure-devops-yaml-release-pipeline-trigger-when-build-pipeline-completed-54d5

我听取了 Daniel Mann 关于 'rolling' 战略的建议。然后我将我的管道分成 2 个管道; 1 用于构建工件,1 用于发布(复制它们)。