Azure DevOps Pipeline - Maven 仅在不存在时部署发布

Bru*_*ams 5 maven azure-devops

我是 Azure DevOps 和 Maven 的新手。

我们已经设置了一个 Azure 构建管道,以便它将为快照构建和发布部署工件。

我希望发布工件的部署是幂等的。也就是说,如果工件已经部署,它不应该是一个错误。

问题是我收到409“资源冲突”

Q 有没有办法告诉 maven 仅在工件不存在时才部署,并且如果存在则不是错误。

有没有办法从 DevOps 中做到这一点?

对于我自己的教育,我也想知道如何为 maven(没有 Azure)做到这一点。这可以通过命令行开关、pom.xml 或 maven settings.xml

似乎暗示没有,如果有的话,这是一个令人惊讶的遗漏。我想了解其中的原理。

如果有一种方法可以检查部署的工件是否与管道刚刚构建的工件相同,则加分。

相关的管道片段是:

   task: Maven@3
#          condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
          inputs:
            mavenPomFile: 'pom.xml'
            options: '-B -s $(mvnSettings.secureFilePath) -DWHERE="AzureDevops" clean deploy'
            mavenAuthenticateFeed: true
            publishJUnitResults: true
            testResultsFiles: '**/TEST-*.xml'
Run Code Online (Sandbox Code Playgroud)

作为背景,这是我对 Azure 和 Maven 的了解。如果我误解了什么,那可能是一个促成因素。

Maven 允许您部署两种工件:

快照

  • 快照是包的开发版本。
  • 快照具有后缀 -SNAPSHOT。例如 1.2.0-快照
  • 快照是可变的。部署操作可以用新版本替换 SNAPSHOT(更新的开发版本可以替换开发版本)

发布

  • 任何不以后缀 -SNAPSHOT 结尾的版本都被视为发布版本。
  • 发布是不可变的。如果发布已部署到存储库,则部署操作将失败。

Azure 和 Maven 都认为已发布的工件是不可变的。Azure 在充当 maven 存储库时理解 -SNAPSHOT,并允许覆盖开发版本。这个想法是您不能(或至少不容易)替换其他可能依赖的已发布工件。

409 = 资源冲突

这可能意味着:

  • 工件已经发布,无法覆盖

  • 无法发布工件,因为它的类型错误。例如将发布发布到仅接受快照的存储库或将快照发布到仅接受发布的存储库

我不知道如何告诉 Maven 如果工件已经存在,部署失败是可以的。明显且错误的 hack(在 Linux 中)是:

mvn deploy || /bin/true
Run Code Online (Sandbox Code Playgroud)

这很糟糕,因为如果部署步骤由于其他原因失败,它会将部署步骤报告为成功。

有一个 maven 插件 ( https://github.com/chonton/exists-maven-plugin ) 可以做到这一点。我不确定您将如何在 Azure 中使用它。这个插件是事实上的标准吗?

也可以看看:


更新 23/06/2020

我快到了,但卡住了:

    variables: 
    - name: artifactDoesNotExist
      value: '0'
    - name: mavenRepoURL
      value: 'https://blahblah.visualstudio.com/_packaging/myazurefeedname/maven/v1/com/mycompany/myproject'

    - task: Bash@3
      displayName: 'Check if Maven artifact exists'
      inputs:
        targetType: inline
        failOnStderr: false
        script: |
               #set variable iff artifact exists
               VERSION=`cat VERSION.MVN`; mvn -X -B -s $(mvnSettings.secureFilePath) -DWHERE="AzureDevops" -DremoteRepositories=$(mavenRepoUrl) dependency:get -Dartifact=com.mycompany.project:artifiactId:"$VERSION"
            echo "##vso[task.setvariable variable=artifactDoesNotExist]$?"

    - task: Bash@3
      condition: and(succeeded(), eq(variables['artifactDoesNotExist'], '0'))
      inputs:
        targetType: inline
        script: |
            echo artifactDoesNotExist == 0 -> true

    - task: Bash@3
      condition: and(succeeded(), eq(variables['artifactDoesNotExist'], '1'))
      inputs:
        targetType: inline
        script: |
            echo artifactDoesNotExist == 1 -> true
Run Code Online (Sandbox Code Playgroud)

我怀疑依赖项:get 命令行可能不太正确。

注意:在测试命令时,我必须记住从 ~/.m2/repository 中删除工件,因为它在本地看起来。

另一件奇怪的事情正在发生。尽管我已经部署了工件的新测试版本,但它们并未出现在相关的 Azure 源中。然而,第一次尝试上传成功,而后续上传失败。这些上传文件去哪里了,为什么我在 Dev Ops 中看不到它们?

我发现此问题的版本仍作为 maven 工件“com.mycompany.myproject:artifactId”与版本一起出现在提要中。

另请参阅上传和下载 azure 工件的等效 maven 命令和设置是什么?

Pat*_*SFT 3

这应该与 Maven 更多相关,在 Azure DevOps 端没有什么具体需要配置的。

您可以尝试在构建管道中使用命令行任务来首先检查该发行版本是否存在:

mvn dependency:get -Dartifact=g:a:v -o -DrepoUrl=file://path/to/your/repo
Run Code Online (Sandbox Code Playgroud)

更多详细信息请查看如何从命令行确定 Maven 工件是否在我的存储库中?

如果给定的 (group-artifact-version) 确实存在,那么您就不会继续进行其余的构建。