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

时间:2012-12-21 11:10:13

标签: shell artifactory continuous-deployment

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

我有什么选择?像Wget / SCP之类的东西?我如何获得工件的路径?

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

是否可以在没有用户界面的情况下从Artifactory下载而没有Pro-Version?有什么经历?

如果重要的话,请参阅OpenSUSE 12.1(x86_64)。

14 个答案:

答案 0 :(得分:61)

以下bash脚本之类的内容将从com.company:artifact repo中检索最新的snapshot快照:

# 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

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

答案 1 :(得分:31)

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

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

选项1 - 搜索:

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

选项2 - Maven方式:

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

答案 2 :(得分:11)

使用shell / unix工具

  1. curl 'http://$artiserver/artifactory/api/storage/$repokey/$path/$version/?lastModified'
  2. 上面的命令用一个带有两个元素的JSON响应 - &#34; uri&#34;和#34; lastModified&#34;

    1. 获取uri中的链接会返回另一个JSON,其中包含&#34; downloadUri&#34;神器。

    2. 获取&#34; downloadUri&#34;中的链接你有最新的人工制品。

    3. 使用Jenkins Artifactory插件

      如果Jenkins Artifactory插件用于在另一个作业中发布到artifactory,那么

      (需要Pro)来解析和下载最新的工件:

      1. 选择Generic Artifactory Integration
      2. 使用已解决的工件作为 ${repokey}:**/${component}*.jar;status=${STATUS}@${PUBLISH_BUILDJOB}#LATEST=>${targetDir}

答案 3 :(得分:4)

您可以使用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 :(得分:3)

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即可复制。

答案 5 :(得分:3)

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

答案 6 :(得分:3)

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

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

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

name =&gt; 'com.acme.derp'
version =&gt; 0.1.0
repo name =&gt; “富”
快照1 =&gt; DERP-0.1.0-20161121.183847-3.jar
快照2 =&gt; 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 :(得分:3)

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

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

答案 8 :(得分:1)

这可能是新的:

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

从example.com加载模块foo。逐字保留[RELEASE]部分。这在文档中提到,但是你并没有非常清楚地知道你可以将[RELEASE]放入URL(而不是开发人员的替换模式)。

答案 9 :(得分:1)

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

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

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

答案 10 :(得分:0)

如果要在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

用例:詹金斯管道

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个或多个存储库之间的最新软件包时,这很有帮助。希望它也对您有帮助! 有关Jenkins脚本化管道的更多信息,请访问Jenkins docs

答案 11 :(得分:0)

使用awk:

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

使用sed:

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

答案 12 :(得分:0)

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

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

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

但是,Docker best practises强烈建议不要使用ADD并建议使用wget或curl。

答案 13 :(得分:-1)

我使用Nexus并且此代码适合我 - 可以检索发布 last snaphsot ,具体取决于存储库类型:

server="http://example.com/nexus/content/repositories"
repo="snapshots"
name="com.exmple.server"
artifact="com/example/$name"
path=$server/$repo/$artifact
mvnMetadata=$(curl -s "$path/maven-metadata.xml")
echo "Metadata: $mvnMetadata"
jar=""
version=$( echo "$mvnMetadata" | xpath -e "//versioning/release/text()" 2> /dev/null)
if [[ $version = *[!\ ]* ]]; then
  jar=$name-$version.jar
else
  version=$(echo "$mvnMetadata" | xpath -e "//versioning/versions/version[last()]/text()")
  snapshotMetadata=$(curl -s "$path/$version/maven-metadata.xml")
  timestamp=$(echo "$snapshotMetadata" | xpath -e "//snapshot/timestamp/text()")
  buildNumber=$(echo "$snapshotMetadata" | xpath -e "//snapshot/buildNumber/text()")
  snapshotVersion=$(echo "$version" | sed 's/\(-SNAPSHOT\)*$//g')
  jar=$name-$snapshotVersion-$timestamp-$buildNumber.jar
fi
jarUrl=$path/$version/$jar
echo $jarUrl
mkdir -p /opt/server/
wget -O /opt/server/server.jar -q -N $jarUrl