如何从 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 "<version>" | sed "s/.*<version>\([^<]*\)<\/version>.*/\1/"
替换 "version=" 行
这与问题无关,但它可能对某人有所帮助。如果证书有问题,请使用 -k 和 curl。
我使用的身份验证:'version=curl -u user:pwd -s $path/maven-metadata.xml | grep latest | sed "s/.*<latest>\([^<]*\)<\/latest>.*/\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=>$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 存储库下载最新的工件?的主要内容,如果未能解决你的问题,请参考以下文章
Maven 依赖项:从 settings.xml 获取最新的忽略存储库
Ansible,从 Artifactory 的一般 repo 下载 msi 文件
如何从经过身份验证的私有 Artifactory PyPI 存储库中提取 Python 包?
Artifactory:升级到新的 Artifactory 5.10.3 并支持新的 Pypi 后,本地 Pypi 存储库“慢”