7
votes

Comment prévenir les artefacts libérés (versions non instantanées) dans le référentiel Maven sur Hudson

Description problématique

Considérez que le boîtier Maven est utilisé sur Hudson.

Maintenant, quelqu'un a pris la caisse d'un projet, modifié certains fichiers, mais utilisé accidentellement le même identifiant d'artefact et le même numéro de version (non instantané).

Il / elle construit ensuite ce projet sur Hudson et a fait Maven Installer. L'artefact modifié est maintenant à Hudson .m2. Tout autre projet qui lui dépendra sera construit avec des artefact modifiés. Personne ne le trouve si la compilation n'échoue pas. Même si l'artefact correct réside dans le référentiel central, il n'est jamais utilisé car il est modifié, on est récupéré à partir de .m2 lorsque Hudson commence à bâtir.

Je cherche donc un moyen d'empêcher cette erreur humaine accidentelle.

  1. De toute façon pour révoquer des autorisations de Maven Installer sur des versions non instantanées (artefacts libérés) sur Hudson?
  2. Toute façon de comparer les checksums de .m2 à Hudson et sur le référentiel central distant de sorte que les défaillances de la somme de contrôle puissent générer des avertissements ou une construction d'échec?

    J'ai déjà vérifié qu'il n'ya aucun moyen de forcer les versions de mise à jour des non-instantanées du référentiel central car elles sont censées être immuables.

    Le référentiel central de purge ou l'utilisation de référentiel séparé pour chaque travail sur Hudson entraînera une augmentation des temps de construction et de l'espace disque de disque respectivement.

    Toute aide serait appréciée.


0 commentaires

5 Réponses :


1
votes

Je ne pense pas que vous allez trouver un moyen d'arrêter une installation d'écraser un artefact. Un serveur de référentiel doit avoir un paramètre pour éviter tout déploiement d'un artefact de libération mis à jour. Voir, par exemple, "Comment désactiver le redéploiement d'artefact" pour Nexus.


1 commentaires

J'ai déjà géré les autorisations de déploiement dans l'artefactory. Mais cela n'aide pas parce que si un artefact écrasé est présent dans le référentiel .m2 et un projet dépendant est construit sur Hudson Maven choisit toujours l'artefact de .m2 au lieu de serveur de référentiel. Il n'y a aucun moyen de forcer Télécharger un artefact à Hudson ou Vérifier la météo .m2 artefact est synchronisé avec le serveur de référentiel.



1
votes

Voici comment nous gérons les versions de notre projet:

Nous travaillons sur un instantané version. Sur Jenkins, nous avons un travail construit rapide qui construit et teste cette application, mais échoue si la version est non A instantané . Ceci est fait par un Custom Enforcer (ceci est l'inverse de la Exiger une version de version Enforcer ).

Lorsque nous voulons faire une libération, nous utilisons un travail Jenkins pour cela. Utilisation du Construction paramétrée et Plugin de version Maven , la personne chargée de faire la libération indiquera simplement la version de la version (la stable Version), la version suivante Snapshot , ainsi que le nom de la balise SCM. Ainsi, seulement Jenkins définira une version stable et les développeurs seront toujours travailler sur un Instantané code.

Mais bien sûr, cela ne l'empêche pas les développeurs de faire ce qu'il veut sur sa machine locale. Mais nous considérons toujours un lieu de confiance: le serveur Jenkins. Il fonctionne sur ma machine est jamais une bonne réponse à un problème; o)


0 commentaires

1
votes

Il n'y avait pas de moyen direct de résoudre ce problème, mais nous avons résolu cela inverse en écrivant un travail cron qui fonctionne toutes les cinq minutes et marque tous les bocaux qui ne sont pas instantanés comme lecture seule dans le référentiel local de Hundson. De cette façon, lorsque certains projets de Hudson tentent de remplacer mon installation MVN ou MVN Déployer, il échoue à la sur-consultation des artefacts tels qu'ils sont réadis.

Tous les nouveaux artefacts à réaliser peuvent facilement être écrits. Une fois écrit dans les cinq minutes suivant, le script ne les marque que comme en lecture seule. P>

Voici le code de l'autorisation de script UNIX-handler.sh p>

#!/bin/bash
cd ~/.m2
date 2>&1>> permission-handler.out
find . -name '*jar' -type f | grep -v 'SNAPSHOT' | xargs chmod -vc 444 2>&1>> permission-handler.out
chmod 777 permission-handler.out


0 commentaires

0
votes

Ceci est résolu en configurant votre référentiel Maven (E.G. Nexus, Artefactory) de ne pas permettre d'écraser les rejets de libération. Dans Nexus, nous avons un repo pour l'instantané et un pour les versions. Le repo de l'instantané permet d'écraser. Mais le repo de libération ne permet pas d'écraser. Ceci est juste une seule fonction de case à cocher à Nexus pour ce repo. Une fois qu'une version de version est placée dans le repo, elle ne peut pas être écrasée. Très bien fonctionne.


2 commentaires

Cela fait-il une erreur si le développeur l'essaie de toute façon ou est-ce juste un avertissement silencieux?


@Dandan je ne me souviens pas.



0
votes

J'ai eu la même exigence. La vérification de l'artefact peut être obtenue avec une demande de repos à partir d'une tâche des grades.

publish.dependsOn lookForArtifacts

task lookForArtifacts {
    group "upload"
    doLast {

        def pomFileName = "${ARTIFACT_ID}-${ARTIFACT_VERSION}.pom"
        def artifactPath = "${ARTIFACT_GROUP.replace(".", "/")}/${ARTIFACT_ID}/${ARTIFACT_VERSION}/${pomFileName}"
        def repositoryUrl = "$MAVEN_SERVER/${artifactPath}"

        println("# searching for existing artifact wit id ${ARTIFACT_VERSION}")
        println("")

        if (urlExists(repositoryUrl)) {
            println("# Existing artifact found")
            println("")
            throw new RuntimeException("Artifact with version $ARTIFACT_VERSION already exist - increase the verion to publish")
        } else {
            println("# No existing artifact found. Preceding to publish")
            println("")
        }
    }
}

def urlExists(String repositoryUrl) {

    try {
        def connection = (HttpURLConnection) new URL(repositoryUrl).openConnection()

        connection.setRequestProperty("Authorization", "Basic " + getBase64EncodedCredentials())
        connection.setConnectTimeout(10000)
        connection.setReadTimeout(10000)
        connection.setRequestMethod("HEAD")

        def responseCode = connection.getResponseCode()

        if (responseCode == 401) {
            throw new RuntimeException("Unauthorized MavenUser user. Please provide valid username and password.")
        }

        return (200 == responseCode)

    } catch (IOException ignored) {
        println(ignored)
        return false
    }
}

def getBase64EncodedCredentials() {
    def s = "$MAVEN_USERNAME" + ":" + "$MAVEN_PASSWORD"
    return s.bytes.encodeBase64().toString()
}


0 commentaires