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

修复Azure Pipeline动态同步JFrog到Azure Artifacts的NuGet脚本错误

解决Azure Pipeline同步JFrog最新NuGet包到Azure Artifacts的问题

问题背景

原本有一个可正常运行的Azure Pipeline,用于将指定版本的NuGet包从JFrog Artifactory推送到Azure DevOps Artifacts。现在需要修改为动态同步指定包的最新版本,但修改后的脚本执行时出现JFrog CLI搜索命令参数错误。

原工作脚本

trigger: none

schedules:
  - cron: "0/10 * * * *"
    displayName: Nuget JFrog to Azure DevOps Artifacts
    branches:
      include:
      - main
    always: true

jobs:
  - job: SyncArtifactory
    pool:
      name: 'Ubuntu-latest'

    steps:
          - task: JfrogCliV2@1
            inputs:
              jfrogPlatformConnection: 'JFrog Artifactory'
              command: 'jf rt dl randomPath/Random.Nuget.Package.1.0.1.nupkg'

          - task: NuGetCommand@2
            inputs:
              command: 'push'
              packagesToPush: '$(System.DefaultWorkingDirectory)/Random.Nuget.Package.1.0.1.nupkg'
              nuGetFeedType: 'internal'
              publishVstsFeed: '<Azure_Devops_Feed>'

修改后的问题脚本

trigger: none

schedules:
  - cron: "0/10 * * * *"
    displayName: Nuget JFrog to Azure DevOps Artifacts
    branches:
      include:
      - main
    always: true

parameters:
  - name: packages
    type: object
    default:
      - name: "Random.Nuget.Package.1"
        version: "latest"
      - name: "Random.Nuget.Package.2"
        version: "latest"
      - name: "Random.Nuget.Package.3"
        version: "latest"


jobs:
  - job: SyncArtifactory
    pool:
      name: 'Ubuntu-latest'

    steps:
      - ${{ each package in parameters.packages }}:
        - task: JfrogCliV2@1
          inputs:
            jfrogPlatformConnection: 'JFrog Artifactory'
            command: 'jf rt s "randomPath/Random.Nuget.Package/*" --limit 1 --sort-by created --sort-order desc --format json'
          displayName: 'Search for Latest Package ${{ package.name }}'
          name: ${{ format('SearchPackage_{0}', replace(package.name, '.', '_')) }}

        - script: |
            latest_version=$(jq -r '.[].name' $(System.DefaultWorkingDirectory)/${{ format('SearchPackage_{0}', replace(package.name, '.', '_')) }}.json)
            echo "##vso[task.setvariable variable=LATEST_VERSION]$latest_version"
          displayName: 'Set Latest Version Variable'

        - task: JfrogCliV2@1
          inputs:
            jfrogPlatformConnection: 'JFrog Artifactory'
            command: |
              jf rt dl randomPath/${{ package.name }}/${{ variables.LATEST_VERSION }}.nupkg
          displayName: 'Download Latest Package ${{ package.name }}'

        - task: NuGetCommand@2
          inputs:
            command: 'push'
            packagesToPush: '$(System.DefaultWorkingDirectory)/${{ package.name }}.${{ variables.LATEST_VERSION }}.nupkg'
            nuGetFeedType: 'internal'
            publishVstsFeed: '<Azure_Devops_Feed>'
          displayName: 'Push Package to Azure Artifacts'

错误信息

Found tool in cache: jf 2.56.1 x64
Running jfrog-cli from /opt/azdevops/agent-02/_work/_tool/jf/2.56.1/x64/jf
JFrog CLI version: 2.56.1
Executing JFrog CLI Command:
/opt/azdevops/agent-02/_work/_tool/jf/2.56.1/x64/jf c add "test-nuget_20240523.26_jfrog_cli_cmd_1716472614658" --url="https://<my_artifactory>/" --interactive=false --user='***' --basic-auth-only --password-stdin
Executing JFrog CLI Command:
/opt/azdevops/agent-02/_work/_tool/jf/2.56.1/x64/jf c use "test-nuget_20240523.26_jfrog_cli_cmd_1716472614658"
13:57:06 [Info] Using server ID 'test-nuget_20240523.26_jfrog_cli_cmd_1716472614658' (https://<my_artifactory>/)
Executing JFrog CLI Command:
/opt/azdevops/agent-02/_work/_tool/jf/2.56.1/x64/jf rt s "randomPath/Random.Nuget.Package/*" --limit 1 --sort-by created --sort-order desc --format json
13:57:06 [Error] Wrong number of arguments (3).

Name:
jf rt search - Search files in Artifactory.

--server-id               [Optional] Server ID configured using the config command.
--sort-by                 [Optional] List of semicolon-separated(;) fields to sort by. The fields must be part of the 'items' AQL domain.
--sort-order              [Default: asc] The order by which fields in the 'sort-by' option should be sorted. Accepts 'asc' or 'desc'.
--spec                    [Optional] Path to a File Spec.
--spec-vars               [Optional] List of semicolon-separated(;) variables in the form of "key1=value1;key2=value2;..." (wrapped by quotes) to be replaced in the File Spec. In the File Spec, the variables should be used as follows: ${key1}.
--ssh-key-path            [Optional] SSH key file path.
--ssh-passphrase          [Optional] SSH key passphrase.
--transitive              [Default: false] Set to true to look for artifacts also in remote repositories. The search will run on the first five remote repositories within the virtual repository. Available on Artifactory version 7.17.0 or higher.
--url                     [Optional] JFrog Artifactory URL.
--user                    [Optional] JFrog username.

Environment Variables:
JFROG_CLI_FAIL_NO_OP
[Default: false]
Set to true if you'd like the command to return exit code 2 in case of no files are affected.
Support by the following commands: copy, delete, delete-props, set-props, download, move, search and upload

##[error]Error: Command failed: /opt/azdevops/agent-02/_work/_tool/jf/2.56.1/x64/jf rt s "randomPath/Random.Nuget.Package/*" --limit 1 --sort-by created --sort-order desc --format json
Executing JFrog CLI Command:
/opt/azdevops/agent-02/_work/_tool/jf/2.56.1/x64/jf c remove "test-nuget_20240523.26_jfrog_cli_cmd_1716472614658" --quiet

错误原因分析

  1. JFrog CLI参数失效:新版本JFrog CLI(2.x)已移除--limit参数,原命令参数格式不符合当前版本要求。
  2. 搜索路径未动态匹配:原搜索路径固定为randomPath/Random.Nuget.Package/*,未关联当前遍历的目标包名。
  3. 变量作用域冲突:使用全局LATEST_VERSION变量遍历多个包时,会被后续包覆盖,导致版本错误。
  4. 版本提取逻辑错误:直接提取JSON中的name字段得到的是完整包文件名,而非单独的版本号。

修正后的完整脚本

trigger: none

schedules:
  - cron: "0/10 * * * *"
    displayName: Nuget JFrog to Azure DevOps Artifacts
    branches:
      include:
      - main
    always: true

parameters:
  - name: packages
    type: object
    default:
      - name: "Random.Nuget.Package.1"
        version: "latest"
      - name: "Random.Nuget.Package.2"
        version: "latest"
      - name: "Random.Nuget.Package.3"
        version: "latest"

jobs:
  - job: SyncArtifactory
    pool:
      name: 'Ubuntu-latest'

    steps:
      - ${{ each package in parameters.packages }}:
        - task: JfrogCliV2@1
          inputs:
            jfrogPlatformConnection: 'JFrog Artifactory'
            command: 'jf rt search "randomPath/${{ package.name }}/*.nupkg" --sort-by created --sort-order desc --format json'
          displayName: 'Search for Latest Package ${{ package.name }}'
          name: ${{ format('SearchPackage_{0}', replace(package.name, '.', '_')) }}

        - script: |
            # 提取最新包文件名,拆分版本号
            latest_package=$(jq -r '.[0].name' $(System.DefaultWorkingDirectory)/${{ format('SearchPackage_{0}', replace(package.name, '.', '_')) }}.json)
            latest_version=$(echo "$latest_package" | sed -E "s/${{ package.name }}\.([0-9]+\.[0-9]+\.[0-9]+).nupkg/\1/")
            # 设置唯一变量避免冲突
            echo "##vso[task.setvariable variable=LATEST_VERSION_${{ replace(package.name, '.', '_') }};isOutput=true]$latest_version"
          displayName: 'Extract and Set Latest Version for ${{ package.name }}'
          name: ${{ format('SetVersion_{0}', replace(package.name, '.', '_')) }}

        - task: JfrogCliV2@1
          inputs:
            jfrogPlatformConnection: 'JFrog Artifactory'
            command: 'jf rt dl "randomPath/${{ package.name }}/${{ package.name }}.$(SetVersion_${{ replace(package.name, '.', '_') }}.LATEST_VERSION_${{ replace(package.name, '.', '_') }}).nupkg"'
          displayName: 'Download Latest Package ${{ package.name }}'

        - task: NuGetCommand@2
          inputs:
            command: 'push'
            packagesToPush: '$(System.DefaultWorkingDirectory)/${{ package.name }}.$(SetVersion_${{ replace(package.name, '.', '_') }}.LATEST_VERSION_${{ replace(package.name, '.', '_') }}).nupkg'
            nuGetFeedType: 'internal'
            publishVstsFeed: '<Azure_Devops_Feed>'
          displayName: 'Push Package ${{ package.name }} to Azure Artifacts'

关键修正点说明

  1. 修复JFrog搜索命令:移除无效的--limit参数,改用jq取排序后的第一个结果;搜索路径改为动态匹配当前包名。
  2. 隔离变量作用域:为每个包创建唯一的版本变量,避免循环中变量被覆盖。
  3. 修正版本提取逻辑:用sed从完整包文件名中拆分出版本号,适配标准NuGet包命名格式。
  4. 正确引用输出变量:后续步骤引用上一步脚本的输出变量,确保变量作用域正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:40:55