Bintray支持Eclipse p2存储库

可能这是一个反复出现的问题,但我找不到在Bintray上发布
Eclipse p2存储库的可靠方法.

手动创建repo / product / version并填充文件是可以的,但是,对于生产环境,需要一个可靠的脚本化解决方案.

目的

将Eclipse p2存储库部署到Bintray.

什么是Eclipse p2存储库?

(对不起Eclipse人员,但对于Bintry支持人员,我们更好地定义了我们所谈论的内容).

Eclipse p2存储库是一个文件夹,必须在一个稳定且不会更改的URL上发布,即使多个版本及时发布也是如此.

使用最新版本的Tycho Maven插件生成的Eclipse p2存储库文件夹具有以下结构:

root中的5个文件(p2.index,artifacts.jar,artifacts.xml.xz,content.jar,content.xml.xz)
> 2个子文件夹,插件和功能,每个都有多个.jar文件,具有特定于版本的名称,如ilg.gnuarmeclipse.core_3.3.1.201702251311.jar

例如:

artifacts.jar
artifacts.xml.xz
content.jar
content.xml.xz
features
    ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar
    ...
p2.index
plugins
    ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar
    ...

我要部署的确切p2存储库文件夹是:

> https://sourceforge.net/projects/gnuarmeclipse/files/Eclipse/updates/
> https://sourceforge.net/projects/gnuarmeclipse/files/Eclipse/updates-test/

(均为GNU ARM Eclipse项目的一部分).

必须在Eclipse中配置以访问这两个p2存储库的实际URL是:

> http://gnuarmeclipse.sourceforge.net/updates
> http://gnuarmeclipse.sourceforge.net/updates-test

访问这些p2存储库实际上是对这些URL正下方文件的访问序列,例如:

$curl -L http://gnuarmeclipse.sourceforge.net/updates/p2.index 
#Sat Feb 25 15:11:37 EET 2017 version=1 
metadata.repository.factory.order=content.xml.xz,content.xml,\! 
artifact.repository.factory.order=artifacts.xml.xz,artifacts.xml,\! 
$

使用特定于版本的子文件夹

Eclipse p2存储库没有特定于版本的子文件夹,所使用的子文件夹(插件和功能)在每个版本中都具有相同的名称;无法访问特定于版本的子文件夹.

因此,部署多个版本不应创建特定于版本的子文件夹,因为它们的内容将被忽略.

使用特定于版本的URL

Eclipse插件在其中配置了一个可用于自动获取新更新的URL.这是p2存储库的URL,无法更改为指向特定于版本的URL,因此,要使更新生效,p2存储库应具有唯一的URL.

Eclipse p2存储库生命周期

Eclipse p2存储库的生命周期应该允许新版本完全替换以前的版本,即前5个文件和双子文件夹都应该是单个版本的一部分;如果出于任何原因,发布失败,则以前的版本应继续可见,不变

>一旦发布版本,与其关联的文件将永远不会更改,因此不必允许将给定文件替换为具有相同名称但内容不同的文件
>但是,顶级文件和文件夹对于所有版本都具有相同的名称,并且服务器应允许上载它们而不会抱怨该名称已由先前版本上载
>发布新版本的时刻事先不知道,每个月可能会发布,但也可能会发布超过180天的版本

发布到产品/版本URL

第一次尝试是使用以下bash函数将所有文件上传到产品/版本URL:

curl \
  --request PUT \
  --upload-file "${file_absolute_path}" \
  --user ${BINTRAY_USER}:${BINTRAY_API_KEY} \
"${API}/content/${BINTRAY_OWNER}/${repo}/${package}/${version}/${file_relative_path}?publish=1?override=1?explode=0"

上传成功:

Processing artifacts.jar file...
{"message":"success"}
Processing artifacts.xml.xz file...
{"message":"success"}
Processing content.jar file...
{"message":"success"}
Processing content.xml.xz file...
{"message":"success"}
Processing p2.index file...
{"message":"success"}
Processing feature: features/ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar file...
{"message":"success"}
Processing plugin: plugins/ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar file...
{"message":"success"}

但是,尽管所有文件都是以相同方式上传的,但是有些文件存储在repo文件夹中,而不是存储在product / version文件夹中,如预期的那样:

artifacts.xml.xz
content.xml.xz
features
    ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar
pack3
    3.2.1-201701141320
        artifacts.jar
        content.jar
        p2.index
plugins
    ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar

请注意,虽然我没有明确地将list_in_downloads属性设置为任何文件,但是上传到product / version的一些文件被移动到父repo文件夹.

可以看出,* .xz文件以及功能和插件文件夹被提升到repo文件夹,而* .jar文件和p2.index文件被忽略.

使用此过程创建的存储库是:

> https://dl.bintray.com/ilg-ul/repo3/

使用不同的POST方法发布到产品/版本URL

如文档所述,有3种方法将参数传递给curl.以前的测试使用了一个;在另外两个测试中,我尝试了接下来的两个,使用以下上传代码:

curl \
  --request PUT \
  --upload-file "${file_absolute_path}" \
  --user ${BINTRAY_USER}:${BINTRAY_API_KEY} \
  --header "X-Bintray-Package: ${package}" \
  --header "X-Bintray-Version: ${version}" \
  --header "X-Bintray-Publish: 1" \
  --header "X-Bintray-Override: 1" \
  --header "X-Bintray-Explode: 0" \
  "${API}/content/${BINTRAY_OWNER}/${repo}/${file_relative_path}"

和分开

curl \
  --request PUT \
  --upload-file "${file_absolute_path}" \
  --user ${BINTRAY_USER}:${BINTRAY_API_KEY} \
  "${API}/content/${BINTRAY_OWNER}/${repo}/${file_relative_path};bt_package=${package};bt_version=${version};publish=1;override=1;explode=0"

两者都表现优于上一个测试,第一个版本的上传成功并保留了文件夹结构:

artifacts.jar
artifacts.xml.xz
content.jar
content.xml.xz
features
    ilg.gnuarmeclipse.codered_1.1.1.201701141320.jar
p2.index        
plugins
    ilg.gnuarmeclipse.codered_1.1.1.201701141320.jar

但上传第二个版本时,大多数文件都没问题,只是上传artifacts.xml.xz和content.xml.xz失败:

Upload 'artifacts.jar' to '/repo6/pack6/3.3.1-201702251311/'
{"message":"success"}
Upload 'artifacts.xml.xz' to '/repo6/pack6/3.3.1-201702251311/'
{"message":"Unable to upload files: An artifact with the path 'artifacts.xml.xz' already exists under another version"}
Upload 'content.jar' to '/repo6/pack6/3.3.1-201702251311/'
{"message":"success"}
Upload 'content.xml.xz' to '/repo6/pack6/3.3.1-201702251311/'
{"message":"Unable to upload files: An artifact with the path 'content.xml.xz' already exists under another version"}
Upload 'p2.index' to '/repo6/pack6/3.3.1-201702251311/'
{"message":"success"}
...

请注意,据我所知,这些文件没什么特别之处.

使用此过程创建的存储库是

> https://dl.bintray.com/ilg-ul/repo6/

虽然它看起来像一个有效的p2存储库,但它不是,因为大多数文件来自第二个版本,但artifacts.xml.xz和content.xml.xz来自第一个版本,因此存储库不一致.

发布到repo URL

虽然Bintray文档中没有正式提及,但有些人建议尝试上传到更短的路径,对应于root或repo URL.

我做了,使用以下代码:

curl \
  --request PUT \
  --upload-file "${file_absolute_path}" \
  --user ${BINTRAY_USER}:${BINTRAY_API_KEY} \
  "${API}/content/${BINTRAY_OWNER}/${repo}/${file_relative_path}?publish=1?override=1"

但在这种情况下,我得到了大多数文件的错误:

Processing artifacts.jar file...
{"message":"success"}
Processing artifacts.xml.xz file...
{"message":"Invalid file path and name"}
Processing content.jar file...
{"message":"success"}
Processing content.xml.xz file...
{"message":"Invalid file path and name"}
Processing p2.index file...
{"message":"success"}
Processing feature: features/ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar file...
{"message":"Invalid file path and name"}
Processing plugin: plugins/ilg.gnuarmeclipse.codered_1.1.1.201702231729.jar file...
{"message":"Invalid file path and name"}

看起来上传机制很挑剔,并接受将一些文件(如artifacts.jar,content.jar和p2.index)上传到repo URL,但对于所有其他文件,它都会失败.

使用此过程创建的存储库是:

> https://dl.bintray.com/ilg-ul/repo1/

将其发布到repo和产品/版本URL

我还尝试选择性地将一些文件上传到repo,将一些文件上传到产品/版本(artifacts.xml.xz,content.xml.xz和features / plugins文件夹);这创建了一个正确的p2,但当我尝试为另一个版本重复该过程时,我遇到了错误:

Processing artifacts.jar file...
{"message":"success"}
Processing artifacts.xml.xz file...
{"message":"Unable to upload files: An artifact with the path 'artifacts.xml.xz' already exists under another version"}
Processing content.jar file...
{"message":"success"}
Processing content.xml.xz file...
{"message":"Unable to upload files: An artifact with the path 'content.xml.xz' already exists under another version"}
Processing p2.index file...
{"message":"success"}

覆盖标志

请注意,覆盖标志已在所有测试中设置.

发布标志

请注意,发布标志已在所有测试中设置,但这不是预期的行为.

为了保持存储库的一致性,预期的行为是尝试上传所有没有发布标志的文件,并且只有在所有文件都正确上传的情况下才能在最后进行发布.如果发生错误,未发出发布命令,则预期为先前版本发布的文件仍可访问.

完整的测试脚本

用于这些测试的完整bash脚本(以及更多)可以从GitHub gists获得:

> https://gist.github.com/ilg-ul/568a6806d5e97fcc1384d7acda4ffe36

要下载此脚本,请使用以下命令

mkdir -p "${HOME}/Downloads"
curl -L https://gist.github.com/ilg-ul/568a6806d5e97fcc1384d7acda4ffe36/raw/2df98f4899862f1d7e65f1601ccdbd320dce9021/bintray-test.sh -o "${HOME}/Downloads/bintray-test.sh"

此脚本需要在环境中设置以下变量:

export BINTRAY_USER=<user>
export BINTRAY_API_KEY=<auth>
export BINTRAY_OWNER=${BINTRAY_USER}

要运行脚本,请输入:

bash "${HOME}/Downloads/bintray-test.sh"

发现问题

拒绝服务器上传artifacts.xml.xz和content.xml.xz

考虑到使用不同的POST方法(repo6)发布到产品/版本URL是最高级的测试,唯一确定的问题是拒绝服务器上传artifacts.xml.xz和content.xml.xz.

创建中间文件夹和存储内容

将包和版本作为URL(repo3)的一部分传递,产生了最奇怪的结果,以及其他文件夹:

pack3
    3.2.1-201701141320
        artifacts.jar
        content.jar
        p2.index

所有其他文件都已正确上传,但这三个文件是以特殊的(我会说错误的)方式处理的.

对于大多数文件,尝试发布到repo URL失败

如果这不是向Bintray发布的合法方式,请忽略部分,但尝试发布到repo URL仅对以下3个文件artifacts.jar,content.jar和p2.index成功,并且对所有其他文件都失败.

结论

作为结论,基于现有文档,我找不到一种可靠的方法来将常用的Eclipse p2存储库发布到Bintray.

我看到了一些好奇的解决方案来发布复合p2存储库,但这不是我的情况,我有两个常见的存储库,它们不需要任何版本控制(http://gnuarmeclipse.sourceforge.net/updateshttp://gnuarmeclipse.sourceforge.net/updates-test),我想在Bintray上发布它们.

对Bintray的建议

删除Generic存储库中某些文件的特殊处理

正如这些测试所证明的那样,Bintray通用存储库不是通用的,因为它们不像预期的那样平等地处理所有文件;它看起来像是支持Eclipse p2存储库的尝试,并且服务器上载代码被修补以不同方式处理一些Eclipse文件,但结果不完全正常,并且非常令人困惑.

添加对Eclipse p2存储库的显式支持

如果Bintray支持新的存储库类型“Eclipse p2”,而没有产品或版本,并且每个发布都将被允许删除所有现有文件并添加新文件,那么将不会给Generic repo制作不幸的补丁.那些.

这相当于允许在repo文件夹中发布,并允许以后随时删除和上载文件.

如果无法摆脱版本控制机制,可以接受发布到版本文件夹,但自动将最新版本的文件也显示在产品文件夹中,如repo6所示,但要确保所有文件都是接受,包括artifacts.xml.xz和content.xml.xz.

2017-03-31更新

在与Bintray支持交换无数消息后,他们终于理解了问题并提供了修复.

现在运行脚本对于测试4,5和6是有用的,除了信息传递给Bintray的小变化之外,它们基本上是相同的.

测试结果如下:

>上传到repo根目录不起作用
>直接上传,指定包和版本作为文件目标路径的路径前缀,不起作用
>使用HTTP标头指定包和版本时上传是有效的
>使用HTTP矩阵参数指定包和版本时上载是有效的

总之,不要尝试上传到根URL并使用HTTP头或HTTP矩阵参数.

2017-07-31更新

我已经在Bintray上主持了几个月的更新站点,事情似乎没问题:https://bintray.com/gnu-mcu-eclipse.

用于发布的实际脚本是:https://github.com/gnu-mcu-eclipse/eclipse-plugins/blob/develop/scripts/publish-updates.sh

用于更新站点的公用URL如下所示:https://dl.bintray.com/gnu-mcu-eclipse/updates.

实际上,对于项目的不同“阶段”,有多个Bintray存储库(https://bintray.com/gnu-mcu-eclipse);在他们下面有一个Bintray包(我称之为p2),下面是多个Bintray版本(https://bintray.com/gnu-mcu-eclipse/v4-neon-updates-experimental/p2).

最佳答案 去年我正在努力解决同样的问题

当试图通过curl上传一个简单的Eclipse p2存储库到Bintray.

受到
article of Lorenzo Bettini的启发

我找到了解决方案.

关键是在URL中使用路径和矩阵参数,例如:

curl -X PUT -T $F -u $BINTRAY_USER:$BINTRAY_API_KEY "https://api.bintray.com/content/$BT_OWNER/$BT_REPO/$BT_PACKAGE/$BT_VERSION/$F;bt_package=$BT_PACKAGE;bt_version=$BT_VERSION;publish=1"

随意查看我的shell脚本deployToBintray.sh.

点赞