2009-03-11 12 views
9

Tenemos un repositorio interno de artefactos. Por el momento, todas las instantáneas se implementarán allí. También queremos tener un servidor diferente con una interfaz web, y queremos copiar los artefactos creados.Múltiples implementaciones en maven

Para nuestras versiones usamos Hudson, pero la acción posterior a la construcción "Implementar artefactos en el repositorio Maven" junto con scp no funciona. Entonces, está la cuestión de hacerlo de otra manera elegante. ¿Por qué Maven no puede tener varios repositorios de distribución? ¿Algunas ideas?

Lo mejor sería si el artefactory admite una exportación incremental (automática) a un repositorio maven estándar después de cada nueva implementación.

Respuesta

11

No creo que maven admita la implementación en múltiples repositorios para un solo perfil, pero quizás los perfiles podrían cambiar la identificación y las URL del repositorio.

<distributionManagement> 
    <repository> 
     <id>${repo-id}</id> 
     <name>${repo-name}</name> 
     <url>${repo-url}</url> 
    </repository> 
    </distributionManagement> 

Maven Deployment

Entonces utilizar perfiles para elegir qué Repo implementar en:

<profiles> 
    <profile> 
    <id>repo1</id> 
    <activation> 
     <activeByDefault>true</activeByDefault> 
    </activation> 
    <properties> 
     <repo-id>repo1</repo-id> 
     <repo-name>Repo1 Name </repo-name> 
     <repo-url>http://url.com/maven2</repo-url> 
    </properties> 
    </profile> 
    <profile> 
    <id>repo2</id> 
    <properties> 
     <repo-id>repo2</repo-id> 
     <repo-name>Repo2 Name </repo-name> 
     <repo-url>http://url2.com/maven2</repo-url> 
    </properties> 
    </profile> 
</profiles> 

Maven profiles

+1

gracias! esto funcionó bien para mí, con un cambio: si ya está usando perfiles para otras cosas, probablemente querrá la activación basada en propiedades (por ejemplo, '! repo2' para activar repo2, y de manera similar ! para repo2, luego simplemente '-Drepo2') –

+2

o ponga' distributionManagement' directamente en la definición 'profile', si prefiere no usar las propiedades –

0

Artifactory hace tener una función automática de exportación. De the documentation:

Puede hacer una copia de seguridad automática y periódica de todo el sistema Artifactory. El proceso de copia de seguridad crea un directorio con marca de tiempo (o archivo zip) en el directorio de copia de seguridad de destino, y es básicamente idéntico a la ejecución de exportación completa del sistema con metadatos. [...] Cada copia de seguridad puede tener su propio horario y excluye ciertos repositorios [...]

El contenido de la copia de seguridad (cuando se extrae) está en formato estándar Maven y se puede cargar en cualquier repositorio de Maven externa [ ...]

Artifactory admite la copia de seguridad de forma incremental en el mismo directorio de destino (denominado "actual") en el directorio de copia de seguridad de destino. Este tipo de copia de seguridad solo está escribiendo deltas en el directorio de salida, lo que resulta en copias de seguridad extremadamente rápidas.

¿No es eso exactamente lo que necesita? Para transferir los archivos, puede montar un directorio compartido en el servidor remoto y hacer la copia de seguridad allí, o hacer la copia de seguridad localmente y luego sincronizarla.

0

Creo que en Artifactory, de forma predeterminada, mantiene diferentes repositorios lógicos para cargar instantáneas y no instantáneas. Al usar permisos, puede hacer que el repositorio de instantáneas sea visible solo para algunos.

Si eso no es suficiente, otra solución que funciona con Artifactory 2.0 es hacer que Artifactory utilice una base de datos MySQL que realice una replicación asíncrona a otra base de datos MySQL, que a su vez se lee mediante una instalación separada de Artifactory. Si es demasiado tiempo real, simplemente puede tener dos instalaciones diferentes que realicen actualizaciones según las reglas comerciales.

3

Si está dispuesto a utilizar un complemento personalizado, puede configurar Maven para implementar en una lista de ubicaciones "espejo" al mismo tiempo que la implementación estándar. Recomiendo definir esto en un perfil para que pueda controlar qué implementaciones se duplican (puede que no sea apropiado hacerlo en cada compilación).

Para definir un nuevo plugin es necesario crear un nuevo proyecto Maven y especifique el POM ha envasado experto-plugin:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>name.seller.rich</groupId> 
    <artifactId>maven-mirror-plugin</artifactId> 
    <packaging>maven-plugin</packaging> 
    <version>0.0.1</version> 
    <dependencies> 
    <dependency> 
     <groupId>org.apache.maven</groupId> 
     <artifactId>maven-plugin-api</artifactId> 
     <version>2.2.0</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-deploy-plugin</artifactId> 
     <version>2.4</version> 
    </dependency> 
    </dependencies> 
</project> 

En src/main/java definir un Mojo. El código siguiente declara un objetivo "espejo", toma una lista de elementos mirrorRepository (que contiene un repositoryId y url) para reflejar el despliegue de artefactos. El complemento utiliza el mismo enfoque para la implementación que maven-deploy-plugin, y toma la mayoría de los mismos parámetros.

Tenga en cuenta que todavía necesita definir un servidor en su settings.xml para cada repositorio con los permisos adecuados para realizar la implementación o la compilación fallará.

package name.seller.rich; 

import java.io.File; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Map; 

import org.apache.maven.artifact.Artifact; 
import org.apache.maven.artifact.deployer.ArtifactDeployer; 
import org.apache.maven.artifact.deployer.ArtifactDeploymentException; 
import org.apache.maven.artifact.metadata.ArtifactMetadata; 
import org.apache.maven.artifact.repository.ArtifactRepository; 
import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; 
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; 
import org.apache.maven.plugin.AbstractMojo; 
import org.apache.maven.plugin.MojoExecutionException; 
import org.apache.maven.plugin.MojoFailureException; 
import org.apache.maven.project.MavenProject; 
import org.apache.maven.project.artifact.ProjectArtifactMetadata; 

/** 
* @goal mirror 
* @phase deploy 
*/ 
public class MirrorMojo extends AbstractMojo { 
    /** 
    * @parameter expression= 
    *   "${component.org.apache.maven.artifact.deployer.ArtifactDeployer}" 
    * @required 
    * @readonly 
    */ 
    private ArtifactDeployer deployer; 

    /** 
    * Map that contains the layouts 
    * 
    * @component role= 
    *   "org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout" 
    */ 
    private Map repositoryLayouts; 

    /** 
    * Component used to create a repository 
    * 
    * @component 
    */ 
    private ArtifactRepositoryFactory repositoryFactory; 

    /** 
    * The type of remote repository layout to deploy to. Try <i>legacy</i> for 
    * a Maven 1.x-style repository layout. 
    * 
    * @parameter expression="${repositoryLayout}" default-value="default" 
    * @required 
    */ 
    private String repositoryLayout; 

    /** 
    * Parameter used to update the metadata to make the artifact as release. 
    * 
    * @parameter expression="${updateReleaseInfo}" default-value="false" 
    */ 
    private boolean updateReleaseInfo; 

    /** 
    * Whether to deploy snapshots with a unique version or not. 
    * 
    * @parameter expression="${uniqueVersion}" default-value="true" 
    */ 
    private boolean uniqueVersion; 

    /** 
    * @parameter expression="${mirrorRepositories}" 
    * @required 
    */ 
    private MirrorRepository[] mirrorRepositories; 

    /** 
    * @parameter expression="${localRepository}" 
    * @required 
    * @readonly 
    */ 
    private ArtifactRepository localRepository; 

    /** 
    * @parameter expression="${project}" 
    * @required 
    * @readonly 
    */ 
    private MavenProject project; 

    /** 
    * Deploy all artifacts for the project to each mirror repository. 
    */ 
    public void execute() throws MojoExecutionException, MojoFailureException { 
     ArtifactRepositoryLayout layout; 

     layout = (ArtifactRepositoryLayout) repositoryLayouts 
       .get(repositoryLayout); 

     for (int i = 0; i < mirrorRepositories.length; i++) { 
      MirrorRepository mirrorRepository = mirrorRepositories[i]; 

      ArtifactRepository deploymentRepository = repositoryFactory 
        .createDeploymentArtifactRepository(mirrorRepository 
          .getRepositoryId(), mirrorRepository.getUrl(), 
          layout, uniqueVersion); 

      String protocol = deploymentRepository.getProtocol(); 

      if ("".equals(protocol) || protocol == null) { 
       throw new MojoExecutionException("No transfer protocol found."); 
      } 

      deployToRepository(deploymentRepository); 
     } 

    } 

    /** 
    * Deploy all artifacts to the passed repository. 
    */ 
    private void deployToRepository(ArtifactRepository repo) 
      throws MojoExecutionException { 
     String protocol = repo.getProtocol(); 

     if (protocol.equalsIgnoreCase("scp")) { 
      File sshFile = new File(System.getProperty("user.home"), ".ssh"); 

      if (!sshFile.exists()) { 
       sshFile.mkdirs(); 
      } 
     } 

     File pomFile = project.getFile(); 
     Artifact artifact = project.getArtifact(); 
     // Deploy the POM 
     boolean isPomArtifact = "pom".equals(project.getPackaging()); 
     if (!isPomArtifact) { 
      ArtifactMetadata metadata = new ProjectArtifactMetadata(artifact, 
        pomFile); 
      artifact.addMetadata(metadata); 
     } 

     if (updateReleaseInfo) { 
      artifact.setRelease(true); 
     } 

     try { 
      List attachedArtifacts = project.getAttachedArtifacts(); 

      if (isPomArtifact) { 
       deployer.deploy(pomFile, artifact, repo, localRepository); 
      } else { 
       File file = artifact.getFile(); 

       if (file != null && !file.isDirectory()) { 
        deployer.deploy(file, artifact, repo, localRepository); 
       } else if (!attachedArtifacts.isEmpty()) { 
        getLog() 
          .info(
            "No primary artifact to deploy, deploy attached artifacts instead."); 
       } else { 
        String message = "The packaging for this project did not assign a file to the build artifact"; 
        throw new MojoExecutionException(message); 
       } 
      } 

      for (Iterator i = attachedArtifacts.iterator(); i.hasNext();) { 
       Artifact attached = (Artifact) i.next(); 

       deployer.deploy(attached.getFile(), attached, repo, 
         localRepository); 
      } 
     } catch (ArtifactDeploymentException e) { 
      throw new MojoExecutionException(e.getMessage(), e); 
     } 
    } 
} 

El mojo referencia a un tipo MirrorRepository para encapsular el repositoryId y url, es un grano simple:

package name.seller.rich; 

public class MirrorRepository { 
    private String repositoryId; 
    private String url; 

    public String getRepositoryId() { 
     return repositoryId; 
    } 

    public void setRepositoryId(String repositoryId) { 
     this.repositoryId = repositoryId; 
    } 

    public String getUrl() { 
     return url; 
    } 

    public void setUrl(String url) { 
     this.url = url; 
    } 
} 

Aquí es un ejemplo de configuración usando el plugin. Tenga en cuenta que todos los formatos de implementación son compatibles (http, scp, ftp):

<plugin> 
    <groupId>name.seller.rich</groupId> 
    <artifactId>maven-mirror-plugin</artifactId> 
    <executions> 
    <execution> 
     <id>mirror</id> 
     <phase>deploy</phase> 
     <goals> 
     <goal>mirror</goal> 
     </goals> 
    </execution> 
    </executions> 
    <configuration> 
    <mirrorRepositories> 
     <mirrorRepository> 
     <repositoryId>mirror</repositoryId> 
     <url>http://path/to/mirror</url> 
     </mirrorRepository> 
    </mirrorRepositories> 
    <!--any other deploy configuration needed--> 
    </configuration> 
</plugin> 
+0

¿Este plugin está publicado para un fácil consumo? – Gunnar

Cuestiones relacionadas