如何从 Artifactory 存储库下载最新的工件?

Posted

技术标签:

【中文标题】如何从 Artifactory 存储库下载最新的工件?【英文标题】:How to download the latest artifact from Artifactory repository? 【发布时间】:2012-12-08 23:14:36 【问题描述】:

我需要来自Artifactory 存储库的最新工件(例如,快照)。该工件需要通过脚本复制到服务器 (Linux)。

我有哪些选择? Wget / SCP 之类的东西?以及如何获取神器的路径?

我找到了一些需要 Artifactory Pro 的解决方案。但我只有 Artifactory,而不是 Artifactory Pro。

是否可以在没有 UI 且没有专业版的情况下从 Artifactory 下载?体验如何?

如果这很重要,我正在使用 OpenSUSE 12.1 (x86_64)。

【问题讨论】:

查看 Artifactory 文档关于这个确切主题 jfrog.com/confluence/display/RTF/… 获得工件的路径后,您可以使用 WGet 通过添加带有用户令牌的 JFROG 标头轻松下载它。 coding-stream-of-consciousness.com/2019/06/23/…。 (当然,获取最新的工件完全是另一个问题)。 【参考方案1】:

Artifactory 有一个很好的扩展 REST-API,几乎可以在 UI 中完成的任何事情(甚至更多)也可以使用简单的 HTTP 请求来完成。

您提到的功能-检索最新工件确实需要专业版;但也可以通过您的一些工作和一些基本脚本来实现。

选项 1 - 搜索:

对一组组 ID 和工件 ID 坐标执行GAVC 搜索,以检索该组的所有现有版本;那么你可以使用任何版本的字符串比较算法来确定最新版本。

选项 2 - Maven 方式:

Artifactory 生成一个标准XML metadata 供Maven 消费,因为Maven 面临同样的问题——确定最新版本;元数据列出了工件的所有可用版本,并为每个工件级别文件夹生成;通过简单的 GET 请求和一些 XML 解析,您可以发现最新版本。

【讨论】:

GAVC 搜索为空。我从 Jenkins 部署。它是一个 Free-Sytle-Job 和一个“Generic-Artifactory Integration”构建。是否需要 Maven 2/3 Job 或 Maven-Artifactory 集成构建,才能通过 Maven 坐标进行搜索? (当我不使用 Jenkins 部署时,搜索工作)【参考方案2】:

Artifactory 的作用是为Maven(以及其他构建工具,例如 Ivy、Gradle 或 sbt)提供文件。您可以将 Maven 与 maven-dependency-plugin 一起使用来复制工件。这是一个pom 大纲,让您开始...

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>A group id</groupId>
    <artifactId>An artifact id</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>The group id of your artifact</groupId>
                                    <artifactId>The artifact id</artifactId>
                                    <version>The snapshot version</version>
                                    <type>Whatever the type is, for example, JAR</type>
                                    <outputDirectory>Where you want the file to go</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

只需运行mvn install 即可进行复制。

【讨论】:

【参考方案3】:

类似于以下 bash 脚本的内容将从 snapshot 存储库中检索最新的 com.company:artifact 快照:

# Artifactory location
server=http://artifactory.company.com/artifactory
repo=snapshot

# Maven artifact location
name=artifact
artifact=com/company/$name
path=$server/$repo/$artifact
version=$(curl -s $path/maven-metadata.xml | grep latest | sed "s/.*<latest>\([^<]*\)<\/latest>.*/\1/")
build=$(curl -s $path/$version/maven-metadata.xml | grep '<value>' | head -1 | sed "s/.*<value>\([^<]*\)<\/value>.*/\1/")
jar=$name-$build.jar
url=$path/$version/$jar

# Download
echo $url
wget -q -N $url

感觉有点脏,是的,但它完成了工作。

【讨论】:

我不得不用 version=curl -s $path/maven-metadata.xml | grep "&lt;version&gt;" | sed "s/.*&lt;version&gt;\([^&lt;]*\)&lt;\/version&gt;.*/\1/" 替换 "version=" 行 这与问题无关,但它可能对某人有所帮助。如果证书有问题,请使用 -k 和 curl。 我使用的身份验证:'version=curl -u user:pwd -s $path/maven-metadata.xml | grep latest | sed "s/.*&lt;latest&gt;\([^&lt;]*\)&lt;\/latest&gt;.*/\1/"' 在 maven-metadata 中使用“最新”值不是一个好主意。它似乎可以正常工作,直到它不能正常工作,因为在您切换到新的发布版本后它没有更新可靠性。见:articles.javatalks.ru/articles/32【参考方案4】:

您可以使用wget --user=USER --password=PASSWORD .. 命令,但在此之前,您必须允许工件强制身份验证,这可以通过取消选中隐藏存在”来完成artifactory 管理面板中的安全/常规标签中的未授权资源”框。否则 artifactory 发送 404 页面,wget 无法向 artifactory 进行身份验证。

【讨论】:

【参考方案5】:

使用 shell/unix 工具

    curl 'http://$artiserver/artifactory/api/storage/$repokey/$path/$version/?lastModified'

上面的命令响应一个带有两个元素的 JSON - “uri”和“lastModified”

    获取 uri 中的链接会返回另一个 JSON,其中包含工件的“downloadUri”。

    获取“downloadUri”中的链接,您就有了最新的人工制品。

使用 Jenkins Artifactory 插件

(需要专业版)解决和下载最新的工件,如果 Jenkins Artifactory 插件用于在另一个工作中发布到工件:

    选择通用人工制品集成 使用已解决的工件作为 $repokey:**/$component*.jar;status=$STATUS@$PUBLISH_BUILDJOB#LATEST=&gt;$targetDir

【讨论】:

第一个解决方案也需要 Pro,我得到““此 REST API 仅在 Artifactory Pro 中可用(请参阅:jfrog.com/addons.php)” 我使用的是专业版,它适用于内部版本号,但是当我使用最新的内部版本号时,它找不到工件。你以前见过这个问题吗? @Sateesh Potturu 你有第二个建议语法的人工文档链接吗?【参考方案6】:

使用最新版本的 artifactory,您可以通过 api 进行查询。

https://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API#ArtifactoryRESTAPI-RetrieveLatestArtifact

如果您有一个带有 2 个快照的 maven 工件

名称 => 'com.acme.derp' 版本 => 0.1.0 回购名称 => 'foo' 快照 1 => derp-0.1.0-20161121.183847-3.jar 快照 2 => derp-0.1.0-20161122.00000-0.jar

那么完整的路径就是

https://artifactory.example.com/artifactory/foo/com/acme/derp/0.1.0-SNAPSHOT/derp-0.1.0-20161121.183847-3.jar

https://artifactory.example.com/artifactory/foo/com/acme/derp/0.1.0-SNAPSHOT/derp-0.1.0-20161122.00000-0.jar

你会像这样获取最新的:

curl https://artifactory.example.com/artifactory/foo/com/acme/derp/0.1.0-SNAPSHOT/derp-0.1.0-SNAPSHOT.jar

【讨论】:

【参考方案7】:

您可以使用 REST-API 的“Item last modified”。从文档中,它返回如下内容:

GET /api/storage/libs-release-local/org/acme?lastModified

"uri": "http://localhost:8081/artifactory/api/storage/libs-release-local/org/acme/foo/1.0-SNAPSHOT/foo-1.0-SNAPSHOT.pom",
"lastModified": ISO8601

例子:

# Figure out the URL of the last item modified in a given folder/repo combination
url=$(curl \
    -H 'X-JFrog-Art-Api: XXXXXXXXXXXXXXXXXXXX' \
    'http://<artifactory-base-url>/api/storage/<repo>/<folder>?lastModified'  | jq -r '.uri')
# Figure out the name of the downloaded file
downloaded_filename=$(echo "$url" | sed -e 's|[^/]*/||g')
# Download the file
curl -L -O "$url"

【讨论】:

从 4.4.3 版本开始支持使用“X-JFrog-Art-Api”进行身份验证。它不适用于旧版本。 问题是,lastModified 不一定是最新版本 您是否找到任何方法来查找可用的最新版本并更新缓存?感谢您是否可以提供帮助。谢谢@FlorianCastellane【参考方案8】:

您也可以使用Artifactory Query Language 获取最新的工件。

以下 shell 脚本只是一个示例。它使用“items.find()”(在非专业版中可用),例如items.find( "repo": "$eq":"my-repo", "name": "$match" : "my-file*") 搜索存储库名称等于“my-repo”的文件并匹配所有以“my-file”开头的文件。然后它使用shell JSON parser ./jq 通过按日期字段“更新”排序来提取最新文件。最后它使用 wget 下载工件。

#!/bin/bash

# Artifactory settings
host="127.0.0.1"
username="downloader"
password="my-artifactory-token"

# Use Artifactory Query Language to get the latest scraper script (https://www.jfrog.com/confluence/display/RTF/Artifactory+Query+Language)
resultAsJson=$(curl -u$username:"$password" -X POST  http://$host/artifactory/api/search/aql -H "content-type: text/plain" -d 'items.find( "repo": "$eq":"my-repo", "name": "$match" : "my-file*")')

# Use ./jq to pars JSON
latestFile=$(echo $resultAsJson | jq -r '.results | sort_by(.updated) [-1].name')

# Download the latest scraper script
wget -N -P ./libs/ --user $username --password $password http://$host/artifactory/my-repo/$latestFile

【讨论】:

只要考虑 AQL 是在 Artifactory V3.5.0 中引入的 您可能需要在尝试下载工件时添加path 导致resultAsJson【参考方案9】:

这可能是新的:

https://artifactory.example.com/artifactory/repo/com/example/foo/1.0.[RELEASE]/foo-1.0.[RELEASE].tgz

用于从 example.com 加载模块 foo 。逐字保留 [RELEASE] 部分。文档中提到了这一点,但并不清楚您实际上可以将 [RELEASE] 放入 URL(与开发人员的替换模式相反)。

【讨论】:

这在我的 Artifactory (5.3.2) 版本中似乎不起作用。 根据documentation,这需要 Artifactory Pro。 您也可以根据 Daniel 链接到的文档逐字使用SNAPSHOT。但这仅适用于 Pro :( .... 所以返回并获取您跳过的两步脚本答案之一,希望有一种方法可以一步完成。【参考方案10】:

对我来说,最简单的方法是结合 curl、grep、sort 和 tail 来阅读项目的最新版本。

我的格式:service-(version: 1.9.23)-(buildnumber)156.tar.gz

versionToDownload=$(curl -u$user:$password 'https://$artifactory/artifactory/$project/' | grep -o 'service-[^"]*.tar.gz' | sort | tail -1)

【讨论】:

完美!为我工作。【参考方案11】:

如果您想在 2 个存储库之间下载最新的 jar,可以使用此解决方案。我实际上在我的 Jenkins 管道中使用它,它运行良好。假设您有一个 plugins-release-local 和 plugins-snapshot-local 并且您想下载它们之间的最新 jar。你的 shell 脚本应该是这样的

注意:我使用jfrog cli,它配置了我的 Artifactory 服务器。

用例:Shell 脚本

# your repo, you can change it then or pass an argument to the script
# repo = $1 this get the first arg passed to the script
repo=plugins-snapshot-local
# change this by your artifact path, or pass an argument $2
artifact=kshuttle/ifrs16
path=$repo/$artifact
echo $path
~/jfrog rt download --flat $path/maven-metadata.xml version/
version=$(cat version/maven-metadata.xml | grep latest | sed "s/.*<latest>\([^<]*\)<\/latest>.*/\1/")
echo "VERSION $version"
~/jfrog rt download --flat $path/$version/maven-metadata.xml build/
build=$(cat  build/maven-metadata.xml | grep '<value>' | head -1 | sed "s/.*<value>\([^<]*\)<\/value>.*/\1/")
echo "BUILD $build"
# change this by your app name, or pass an argument $3
name=ifrs16
jar=$name-$build.jar
url=$path/$version/$jar

# Download
echo $url
~/jfrog rt download --flat $url

用例:Jenkins 流水线

def getLatestArtifact(repo, pkg, appName, configDir)
    sh """
        ~/jfrog rt download --flat $repo/$pkg/maven-metadata.xml $configDir/version/
        version=\$(cat $configDir/version/maven-metadata.xml | grep latest | sed "s/.*<latest>\\([^<]*\\)<\\/latest>.*/\\1/")
        echo "VERSION \$version"
        ~/jfrog rt download --flat $repo/$pkg/\$version/maven-metadata.xml $configDir/build/
        build=\$(cat  $configDir/build/maven-metadata.xml | grep '<value>' | head -1 | sed "s/.*<value>\\([^<]*\\)<\\/value>.*/\\1/")
        echo "BUILD \$build"
        jar=$appName-\$build.jar
        url=$repo/$pkg/\$version/\$jar

        # Download
        echo \$url
        ~/jfrog rt download --flat \$url
    """


def clearDir(dir)
    sh """
        rm -rf $dir/*
    """



node('mynode')
    stage('mysstage')
        def repos =  ["plugins-snapshot-local","plugins-release-local"]

        for (String repo in repos) 
            getLatestArtifact(repo,"kshuttle/ifrs16","ifrs16","myConfigDir/")
        
        //optional
        clearDir("myConfigDir/")
    

当您想要在 1 个或多个 repos 之间获取最新包时,这很有帮助。希望对你也有帮助! 如需更多 Jenkins 脚本化管道信息,请访问Jenkins docs。

【讨论】:

【参考方案12】:

使用 awk:

     curl  -sS http://the_repo/com/***/the_artifact/maven-metadata.xml | grep latest | awk -F'<latest>' 'print $2' | awk -F'</latest>' 'print $1'

使用 sed:

    curl  -sS http://the_repo/com/***/the_artifact/maven-metadata.xml | grep latest | sed 's:<latest>::' | sed 's:</latest>::'

【讨论】:

【参考方案13】:

如果您需要在 Dockerfile 中下载工件,而不是使用 wget 或 curl 等,您可以简单地使用 'ADD' 指令:

添加 $ARTIFACT_URL /opt/app/app.jar

当然,棘手的部分是确定 ARTIFACT_URL,但在所有其他答案中已经足够了。

但是,Docker best practises 强烈反对为此目的使用 ADD,建议使用 wget 或 curl。

【讨论】:

以上是关于如何从 Artifactory 存储库下载最新的工件?的主要内容,如果未能解决你的问题,请参考以下文章

柯南搜索和下载不适用于虚拟 Artifactory 存储库

Maven 依赖项:从 settings.xml 获取最新的忽略存储库

Ansible,从 Artifactory 的一般 repo 下载 msi 文件

如何从经过身份验证的私有 Artifactory PyPI 存储库中提取 Python 包?

如何使用 maven 从 ivy 存储库下载工件

Artifactory:升级到新的 Artifactory 5.10.3 并支持新的 Pypi 后,本地 Pypi 存储库“慢”