我有一个非Java项目,它生成一个版本化的构建工件,我想将它上传到Nexus存储库。因为项目不是Java,所以它不使用Maven进行构建。我宁愿不介绍Maven / POM文件只是为了让文件进入Nexus。
Nexus REST API博客上的链接最终都在登录墙上,没有“创建用户”链接,我可以看到。
那么,在没有Maven的情况下,将构建工件上传到Nexus存储库的最佳(或任何合理)方法是什么? “bash + curl”会很棒,甚至是Python脚本。
答案 0 :(得分:94)
您是否考虑过使用Maven命令行上传文件?
mvn deploy:deploy-file \
-Durl=$REPO_URL \
-DrepositoryId=$REPO_ID \
-DgroupId=org.myorg \
-DartifactId=myproj \
-Dversion=1.2.3 \
-Dpackaging=zip \
-Dfile=myproj.zip
这将自动为工件生成Maven POM。
以下Sonatype文章指出“deploy-file”maven插件是最简单的解决方案,但它也提供了一些使用curl的示例:
答案 1 :(得分:8)
无需使用这些命令..您可以直接使用nexus Web界面,以便使用GAV参数上传您的JAR。
所以这很简单。
答案 2 :(得分:8)
您可以绝对执行此操作,而无需使用任何与MAVEN相关的内容。我个人使用NING HttpClient(v1.8.16,支持java6)。
无论出于何种原因,Sonatype都难以确定难以置信难以确定正确的URL,标头和有效负载应该是什么;我不得不嗅到流量并猜测......那里有一些勉强有用的博客/文档,但它与oss.sonatype.org
无关,或者它基于XML(我发现它甚至不起作用。他们自己的垃圾文件,恕我直言,希望未来的寻求者可以找到这个答案有用。非常感谢https://stackoverflow.com/a/33414423/2101812的帖子,因为它有很多帮助。
如果您在oss.sonatype.org
以外的地方发布,只需将其替换为正确的主机即可。
以下是我为完成此操作而编写的(CC0许可的)代码。 profile
是您的sonatype / nexus profileID(例如4364f3bbaf163
)和repo
(例如comdorkbox-1003
)在您上传初始POM / Jar时从响应中解析。
关闭回购:
/**
* Closes the repo and (the server) will verify everything is correct.
* @throws IOException
*/
private static
String closeRepo(final String authInfo, final String profile, final String repo, final String nameAndVersion) throws IOException {
String repoInfo = "{'data':{'stagedRepositoryId':'" + repo + "','description':'Closing " + nameAndVersion + "'}}";
RequestBuilder builder = new RequestBuilder("POST");
Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/profiles/" + profile + "/finish")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Basic " + authInfo)
.setBody(repoInfo.getBytes(OS.UTF_8))
.build();
return sendHttpRequest(request);
}
推广回购:
/**
* Promotes (ie: release) the repo. Make sure to drop when done
* @throws IOException
*/
private static
String promoteRepo(final String authInfo, final String profile, final String repo, final String nameAndVersion) throws IOException {
String repoInfo = "{'data':{'stagedRepositoryId':'" + repo + "','description':'Promoting " + nameAndVersion + "'}}";
RequestBuilder builder = new RequestBuilder("POST");
Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/profiles/" + profile + "/promote")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Basic " + authInfo)
.setBody(repoInfo.getBytes(OS.UTF_8))
.build();
return sendHttpRequest(request);
}
删除回购:
/**
* Drops the repo
* @throws IOException
*/
private static
String dropRepo(final String authInfo, final String profile, final String repo, final String nameAndVersion) throws IOException {
String repoInfo = "{'data':{'stagedRepositoryId':'" + repo + "','description':'Dropping " + nameAndVersion + "'}}";
RequestBuilder builder = new RequestBuilder("POST");
Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/profiles/" + profile + "/drop")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Basic " + authInfo)
.setBody(repoInfo.getBytes(OS.UTF_8))
.build();
return sendHttpRequest(request);
}
删除签名粪便:
/**
* Deletes the extra .asc.md5 and .asc.sh1 'turds' that show-up when you upload the signature file. And yes, 'turds' is from sonatype
* themselves. See: https://issues.sonatype.org/browse/NEXUS-4906
* @throws IOException
*/
private static
void deleteSignatureTurds(final String authInfo, final String repo, final String groupId_asPath, final String name,
final String version, final File signatureFile)
throws IOException {
String delURL = "https://oss.sonatype.org/service/local/repositories/" + repo + "/content/" +
groupId_asPath + "/" + name + "/" + version + "/" + signatureFile.getName();
RequestBuilder builder;
Request request;
builder = new RequestBuilder("DELETE");
request = builder.setUrl(delURL + ".sha1")
.addHeader("Authorization", "Basic " + authInfo)
.build();
sendHttpRequest(request);
builder = new RequestBuilder("DELETE");
request = builder.setUrl(delURL + ".md5")
.addHeader("Authorization", "Basic " + authInfo)
.build();
sendHttpRequest(request);
}
文件上传:
public
String upload(final File file, final String extension, String classification) throws IOException {
final RequestBuilder builder = new RequestBuilder("POST");
final RequestBuilder requestBuilder = builder.setUrl(uploadURL);
requestBuilder.addHeader("Authorization", "Basic " + authInfo)
.addBodyPart(new StringPart("r", repo))
.addBodyPart(new StringPart("g", groupId))
.addBodyPart(new StringPart("a", name))
.addBodyPart(new StringPart("v", version))
.addBodyPart(new StringPart("p", "jar"))
.addBodyPart(new StringPart("e", extension))
.addBodyPart(new StringPart("desc", description));
if (classification != null) {
requestBuilder.addBodyPart(new StringPart("c", classification));
}
requestBuilder.addBodyPart(new FilePart("file", file));
final Request request = requestBuilder.build();
return sendHttpRequest(request);
}
<强> EDIT1:强>
如何获取回购的活动/状态
/**
* Gets the activity information for a repo. If there is a failure during verification/finish -- this will provide what it was.
* @throws IOException
*/
private static
String activityForRepo(final String authInfo, final String repo) throws IOException {
RequestBuilder builder = new RequestBuilder("GET");
Request request = builder.setUrl("https://oss.sonatype.org/service/local/staging/repository/" + repo + "/activity")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Basic " + authInfo)
.build();
return sendHttpRequest(request);
}
答案 3 :(得分:6)
您需要针对Nexus进行的呼叫是REST api呼叫。
maven-nexus-plugin是一个Maven插件,可以用来进行这些调用。您可以使用必要的属性创建一个虚拟pom,并通过Maven插件进行调用。
类似的东西:
mvn -DserverAuthId=sonatype-nexus-staging -Dauto=true nexus:staging-close
假设:
最终,所有这一切都是在Nexus中创建REST调用。有一个完整的Nexus REST api,但是我很幸运找到了没有付费墙的文档。您可以打开上面插件的调试模式,然后使用-Dnexus.verboseDebug=true -X
。
您理论上也可以进入用户界面,打开Firebug Net面板,并观察/服务POST并在那里推断出路径。
答案 4 :(得分:3)
对于那些需要Java的人,使用apache httpcomponents 4.0:
public class PostFile {
protected HttpPost httppost ;
protected MultipartEntity mpEntity;
protected File filePath;
public PostFile(final String fullUrl, final String filePath){
this.httppost = new HttpPost(fullUrl);
this.filePath = new File(filePath);
this.mpEntity = new MultipartEntity();
}
public void authenticate(String user, String password){
String encoding = new String(Base64.encodeBase64((user+":"+password).getBytes()));
httppost.setHeader("Authorization", "Basic " + encoding);
}
private void addParts() throws UnsupportedEncodingException{
mpEntity.addPart("r", new StringBody("repository id"));
mpEntity.addPart("g", new StringBody("group id"));
mpEntity.addPart("a", new StringBody("artifact id"));
mpEntity.addPart("v", new StringBody("version"));
mpEntity.addPart("p", new StringBody("packaging"));
mpEntity.addPart("e", new StringBody("extension"));
mpEntity.addPart("file", new FileBody(this.filePath));
}
public String post() throws ClientProtocolException, IOException {
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
addParts();
httppost.setEntity(mpEntity);
HttpResponse response = httpclient.execute(httppost);
System.out.println("executing request " + httppost.getRequestLine());
System.out.println(httppost.getEntity().getContentLength());
HttpEntity resEntity = response.getEntity();
String statusLine = response.getStatusLine().toString();
System.out.println(statusLine);
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
return statusLine;
}
}
答案 5 :(得分:2)
您还可以使用curl直接部署方法。您不需要为您的文件提供pom,但它也不会生成,因此如果您需要,则必须单独上传。
这是命令:
version=1.2.3
artefact="myartefact"
repoId=yourrepository
groupId=org.myorg
REPO_URL=http://localhost:8081/nexus
curl -u nexususername:nexuspassword --upload-file filename.tgz $REPO_URL/content/repositories/$repoId/$groupId/$artefact/$version/$artefact-$version.tgz
答案 6 :(得分:1)
在ruby中https://github.com/RiotGames/nexus_cli围绕Sonatype Nexus REST调用的CLI包装器。
用法示例:
nexus-cli push_artifact com.mycompany.artifacts:myartifact:tgz:1.0.0 ~/path/to/file/to/push/myartifact.tgz
通过.nexus_cli
文件完成配置。
url: "http://my-nexus-server/nexus/"
repository: "my-repository-id"
username: "username"
password: "password"
答案 7 :(得分:1)
如果您需要方便的命令行界面或python API,请查看repositorytools
使用它,您可以使用命令
将工件上传到nexusartifact upload foo-1.2.3.ext releases com.fooware
要使其工作,您还需要设置一些环境变量
export REPOSITORY_URL=https://repo.example.com
export REPOSITORY_USER=admin
export REPOSITORY_PASSWORD=mysecretpassword
答案 8 :(得分:0)
您可以通过单击Nexus服务器中的“上传工件”按钮来手动上传工件,并提供用于上传的必要GAV属性(通常是用于存储工件的文件结构)
答案 9 :(得分:0)
对于最新版本的Nexus OSS(> = 3.9.0)
版本3.9.0至3.13.0的示例:
curl -D - -u user:pass -X POST "https://nexus.domain/nexus/service/rest/beta/components?repository=somerepo" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "raw.directory=/test/" -F "raw.asset1=@test.txt;type=application/json" -F "raw.asset1.filename=test.txt"
答案 10 :(得分:-1)
@Adam Vandenberg用于将Java代码发布到Nexus。 https://github.com/manbalagan/nexusuploader
updated_at
答案 11 :(得分:-2)
您可以改用curl。
version=1.2.3
artifact="artifact"
repoId=repositoryId
groupId=org/myorg
REPO_URL=http://localhost:8081/nexus
curl -u username:password --upload-file filename.tgz $REPO_URL/content/repositories/$repoId/$groupId/$artefact/$version/$artifact-$version.tgz