Télécharger des artefacts à Nexus, sans Maven

J'ai un projet non-Java qui produit un artefact de construction versionné, et je veux le télécharger dans un référentiel Nexus. Parce que le projet N'est pas Java, il n'utilise pas Maven pour les builds. Et je préfère ne pas introduire les fichiers Maven / POM juste pour obtenir des fichiers dans Nexus.

Les liens sur les blogs vers L'API REST Nexus se retrouvent tous sur un mur de connexion, sans lien "Créer un utilisateur" que je peux voir.

Alors, quel est le meilleur moyen (ou tout moyen raisonnable) de télécharger des artefacts de construction dans un référentiel Nexus sans Maven? "bash + curl" serait génial, ou même un script Python.

88
demandé sur Adam Vandenberg 2010-10-27 06:21:06

11 réponses

Avez-vous envisagé d'utiliser la ligne de commande Maven pour télécharger des fichiers?

mvn deploy:deploy-file \
    -Durl=$REPO_URL \
    -DrepositoryId=$REPO_ID \
    -DgroupId=org.myorg \
    -DartifactId=myproj \
    -Dversion=1.2.3  \
    -Dpackaging=zip \
    -Dfile=myproj.zip

Cela générera automatiquement le POM Maven pour l'artefact.

Mettre à jour

L'article Sonatype suivant indique que le plugin maven "deploy-file" est la solution la plus simple, mais il fournit également quelques exemples utilisant curl:

Https://support.sonatype.com/entries/22189106-How-can-I-programatically-upload-an-artifact-into-Nexus-

93
répondu Mark O'Connor 2014-01-07 09:08:17

En utilisant curl:

curl -v \
    -F "r=releases" \
    -F "g=com.acme.widgets" \
    -F "a=widget" \
    -F "v=0.1-1" \
    -F "p=tar.gz" \
    -F "file=@./widget-0.1-1.tar.gz" \
    -u myuser:mypassword \
    http://localhost:8081/nexus/service/local/artifact/maven/content

Vous pouvez voir ce que les paramètres signifient ici: https://support.sonatype.com/entries/22189106-How-can-I-programatically-upload-an-artifact-into-Nexus-

Pour que les autorisations pour ce travail, j'ai créé un nouveau rôle dans l'interface graphique d'administration et j'ai ajouté deux privilèges à ce rôle: téléchargement D'artefact et téléchargement D'artefact. Le rôle standard "Repo: all Maven Repositories (Full Control)"ne suffit pas. Vous ne trouverez pas cela dans la documentation de L'API REST qui livré avec le serveur Nexus, de sorte que ces paramètres pourraient changer à l'avenir.

Sur un problème Sonatype JIRA , il a été mentionné qu'ils "vont réviser L'API REST (et la façon dont sa documentation est générée) dans une prochaine version, probablement plus tard cette année".

59
répondu Ed I 2016-06-25 22:35:35

Vous pouvez Absolument le faire sans utiliser quoi que ce soit lié à MAVEN. J'utilise personnellement le Ning HttpClient (v1. 8. 16, pour supporter java6).

Pour une raison quelconque, Sonatype rend incroyablement difficile de comprendre ce que les URL, en-têtes et charges utiles corrects sont supposés être; et j'ai dû renifler le trafic et deviner... Il y a quelques à peine blogs/documentation utiles là-bas, mais il est soit hors de propos de oss.sonatype.org, ou il est basé sur XML (et je découvert que cela ne fonctionne même pas). Documentation de merde de leur part, à mon humble avis, et nous espérons que les futurs chercheurs peuvent trouver cette réponse utile. Merci beaucoup à https://stackoverflow.com/a/33414423/2101812 pour leur poste, car cela a beaucoup aidé.

Si vous relâchez ailleurs que oss.sonatype.org, remplacez - le simplement par l'hôte correct.

Voici le code (sous licence CC0) que j'ai écrit pour accomplir cela. Où profile est votre Sonatype / nexus profileID (tel que 4364f3bbaf163) et repo (tel comme comdorkbox-1003) sont analysés à partir de la réponse lorsque vous téléchargez votre POM/Jar initial.

Fermer repo:

/**
 * 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);
}

Promouvoir repo:

/**
 * 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);
}

Déposer repo:

/**
 * 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);
}

Supprimer les crottes de signature:

/**
 * 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);
}

Téléchargements de fichiers:

    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:

Comment obtenir l'activité / statut pour un repo

/**
 * 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);
}
8
répondu Nathan 2017-05-23 11:54:59

Pas besoin d'utiliser ces commandes .. vous pouvez directement utiliser l'Interface web nexus afin de télécharger votre JAR en utilisant les paramètres GAV.

entrez la description de l'image ici

Donc c'est très simple.

7
répondu Praneel PIDIKITI 2011-02-22 17:36:17

Les appels que vous devez effectuer contre Nexus sont des appels d'api REST.

Le plugin Maven-nexus est un plugin Maven que vous pouvez utiliser pour effectuer ces appels. Vous pouvez créer un pom factice avec les propriétés nécessaires et effectuer ces appels via le plugin Maven.

Quelque Chose comme:

mvn -DserverAuthId=sonatype-nexus-staging -Dauto=true nexus:staging-close

Choses supposées:

  1. , Vous avez défini un serveur dans votre ~/.m2/paramètres.xml nommé Sonatype-nexus-mise en scène avec votre utilisateur sonatype et mot de passe mis en place - vous aurez probablement cela a déjà été fait si vous déployez des instantanés. Mais vous pouvez trouver plus d'Informations ici .
  2. vos paramètres locaux.xml inclut les plugins nexus comme spécifié ici .
  3. le pom.xml assis dans votre répertoire actuel a les coordonnées Maven correctes dans sa définition. Si ce n'est pas le cas, vous pouvez spécifier groupId, artifactId et version sur la ligne de commande.
  4. Le-Dauto=true désactivera les invites interactives afin que vous puissiez écrire des scripts ce.

En fin de compte, tout cela crée des appels REST dans Nexus. Il y a une api REST Nexus complète, mais j'ai eu peu de chance de trouver de la documentation pour cela qui n'est pas derrière un paywall. Vous pouvez activer le mode de débogage pour le plugin ci-dessus et le comprendre Cependant en utilisant -Dnexus.verboseDebug=true -X.

Vous pouvez également théoriquement aller dans l'interface utilisateur, allumer le panneau Firebug Net, et surveiller les messages / service et en déduire un chemin.

6
répondu Alex Miller 2011-07-01 22:05:49

Pour ceux qui en ont besoin en Java, en utilisant 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;
    }
}
3
répondu McMosfet 2015-10-29 12:51:25

Curl est la voie difficile à suivre. Si vous ne voulez pas utiliser maven (par exemple : not allowed)

Prendre un coup d'oeil à ivy :

Autre option gradle : http://www.gradle.org/docs/current/userguide/artifact_management.html#N14566

2
répondu mestachs 2012-12-07 11:34:26

Vous pouvez également utiliser la méthode de déploiement direct à l'aide de curl. Vous n'avez pas besoin d'un pom de votre dossier, mais il ne sera pas généré ainsi donc, si vous en voulez un, vous devrez le télécharger séparément.

Voici la commande:

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
1
répondu Djidiouf 2016-07-29 01:45:02

Si vous avez besoin d'une interface de ligne de commande pratique ou D'une API python, regardez repositorytools

0
répondu Michel Samia 2016-05-11 15:12:31

Vous pouvez utiliser curl à la place.

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
-2
répondu Scott Jones 2017-11-15 15:42:52