我有一個非Java項目生成版本化構建工件,我想將其上傳到Nexus存儲庫。由於該項目不是Java,因此它不使用Maven進行構建。我寧願不介紹Maven/POM文件只是爲了獲取文件到Nexus中。將工件上傳到Nexus,無需Maven
博客上的鏈接到Nexus REST API都在登錄牆上結束,沒有「創建用戶」鏈接,我可以看到。
那麼,什麼是最好的(或任何合理的)上傳構建工件到沒有Maven的Nexus存儲庫? 「bash + curl」會很棒,甚至是Python腳本。
我有一個非Java項目生成版本化構建工件,我想將其上傳到Nexus存儲庫。由於該項目不是Java,因此它不使用Maven進行構建。我寧願不介紹Maven/POM文件只是爲了獲取文件到Nexus中。將工件上傳到Nexus,無需Maven
博客上的鏈接到Nexus REST API都在登錄牆上結束,沒有「創建用戶」鏈接,我可以看到。
那麼,什麼是最好的(或任何合理的)上傳構建工件到沒有Maven的Nexus存儲庫? 「bash + curl」會很棒,甚至是Python腳本。
您是否考慮過使用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的文章指出,「部署文件」 maven插件是最簡單的解決方案,但它也使用提供了一些例子捲曲:
如果只有這樣才能讓我們直接從這個zip文件中下載文件,但是如果你像這樣上傳它似乎是不可能的。 – sorin 2015-06-29 17:04:31
@sorin使用Maven無法從zip文件中下載文件。這是一個不尋常的要求,我知道唯一可以做到的依賴管理器就是常春藤(而且這不是簡單的),請參閱以下示例:http://stackoverflow.com/questions/3445696/gradle-how-to-declare-a-一個jar中的依賴關係/ – 2015-06-30 06:36:05
無需使用這些命令..你可以直接使用nexus web Interface來使用GAV參數上傳你的JAR。
所以這是非常簡單的。
一個GUI不起作用;我需要能夠通過作爲構建過程一部分的命令行腳本進行上傳。 – 2011-02-22 18:51:59
嗯,它轉換爲HTTP POST請求,你不覺得嗎? – 2013-10-10 07:54:35
@YngveSneenLindal當然,但這並不意味着這些POST參數是一個公開使用的定義良好的API。 – 2014-10-01 16:18:55
您需要針對Nexus進行的調用是REST API調用。
maven-nexus-plugin是一個Maven插件,您可以使用這些插件進行這些調用。您可以創建一個具有必要屬性的虛擬pom,並通過Maven插件進行這些調用。
喜歡的東西:
mvn -DserverAuthId=sonatype-nexus-staging -Dauto=true nexus:staging-close
假設的東西:你的Sonatype的用戶名和密碼
最終,所有這些工作都是將REST調用創建到Nexus中。有一個完整的Nexus REST api,但我沒有找到它的付費牆背後的文檔。您可以打開上述插件的調試模式,然後使用-Dnexus.verboseDebug=true -X
進行計算。
你理論上也可以進入UI,打開Firebug Net面板,並觀察/服務POST並在那裏推導出一條路徑。
捲曲是艱難的路要走。如果你不想使用Maven(如:不允許)
在常春藤請看:
其他選項gradle這個:http://www.gradle.org/docs/current/userguide/artifact_management.html#N14566
使用curl:
curl -v \
-F "r=releases" \
-F "g=com.acme.widgets" \
-F "a=widget" \
-F "v=0.1-1" \
-F "p=tar.gz" \
-F "[email protected]/widget-0.1-1.tar.gz" \
-u myuser:mypassword \
http://localhost:8081/nexus/service/local/artifact/maven/content
你可以看到參數這裏指的是:https://support.sonatype.com/entries/22189106-How-can-I-programatically-upload-an-artifact-into-Nexus-
要使燙髮爲此工作的發佈,我在管理GUI中創建了一個新角色,併爲該角色添加了兩項權限:工件下載和工件上傳。標準的「回購:所有Maven倉庫(完全控制)」 - 角色是不夠的。 您不會在隨Nexus服務器捆綁的REST API文檔中找到它,因此這些參數將來可能會發生變化。
在a Sonatype JIRA issue上,有人提到他們「將在即將發佈的版本中徹底檢查REST API(以及它生成文檔的方式),很可能在今年晚些時候」。
比方說,我們從詹金斯發佈,只允許構建用戶發佈到Nexus ,你如何管理簡單的密碼問題?詹金斯有上傳插件,所以我們可以使用詹金斯憑據? – 2016-01-21 17:45:45
紅寶石https://github.com/RiotGames/nexus_cli Sonatype Nexus REST調用的CLI包裝。
對於那些誰需要它在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;
}
}
第一篇文章。我已經嘗試爲java添加higlight,但cound't沒有得到它。 – McMosfet 2015-10-29 12:53:31
可以ABSOLUTELY做到這一點,而無需使用任何相關MAVEN。我個人使用NING HttpClient(v1.8.16,支持java6)。
無論出於何種原因,Sonatype使其難以置信地難以找出正確的URL,標題和有效載荷應該是什麼;我不得不嗅出交通和猜測......有一些勉強有用的博客/文檔存在,但它是兩種不相干的oss.sonatype.org
,或者它是一個基於XML(和我發現它甚至不工作)。垃圾文件,恕我直言,希望未來的求職者可以找到有用的答案。非常感謝https://stackoverflow.com/a/33414423/2101812他們的帖子,因爲它幫助了很多。
如果放開地方比其他oss.sonatype.org
,只是無論正確的主機是取代它。
這是我寫的(CC0許可)代碼來完成此操作。其中profile
是您在上載初始POM/Jar時從響應中解析出的sonatype/nexus profileID(如4364f3bbaf163
)和repo
(如comdorkbox-1003
)。
關閉回購:
/**
* 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);
}
刪除簽名turds:
/**
* 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);
}
如果你需要一個方便的命令行界面或Python API,看看在repositorytools
您也可以使用使用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
您可以使用捲曲來代替。
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
這個答案不正確。使用curl時,groupId應表示爲org/myorg(用斜槓「/」替換點「。」) – madduci 2017-09-01 06:25:53
請注意,請確保在〜/ .m2中有一個settings.xml,並定義了相應的服務器&auth。 – 2010-10-27 21:39:37