2009-03-11 8 views
9

У нас есть внутренний артефактивный репозиторий. На данный момент все снимки будут развернуты. Мы также хотим иметь другой сервер с веб-интерфейсом и хотим скопировать ему созданные артефакты.Несколько развертываний в maven

Для наших сборников мы используем Hudson, но действие post-build «Развертывание артефактов в репозиторий Maven» вместе с scp не работает. Таким образом, возникает вопрос сделать это каким-то другим элегантным способом. Почему у maven не может быть несколько репозиториев дистрибутивов? Есть идеи?

Самое приятное, если artifactory будет поддерживать (автоматический!) Инкрементный экспорт в стандартный репозиторий maven после каждого нового развертывания.

ответ

11

Я не думаю, что maven поддерживает развертывание для нескольких репозиториев для одного профиля, но, возможно, профили могут изменять идентификаторы и URL-адреса репозитория.

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

Maven Deployment

Затем использовать профили, чтобы выбрать, который Repo для развертывания на:

<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

спасибо! это сработало хорошо для меня, с одним изменением - если вы уже используете профили для других вещей, вам, вероятно, понадобится активация на основе свойств (например, '! repo2' для активации repo2 и аналогично ! для repo2, затем просто '-Drepo2') –

+2

или поместите' distributionManagement' непосредственно в определение 'profile', если вы предпочитаете не использовать свойства –

0

Artifactory делает имеет функцию автоматического экспорта. От the documentation:

Вы можете автоматически и периодически создавать резервные копии всей системы Artifactory. Процесс резервного копирования создает временную директорию (или zip-файл) в целевом резервном каталоге и в основном идентичен запуску полного экспорта системы с метаданными. [...] Каждая резервная копия может иметь свой собственный график и исключать определенные репозитории [...]

Содержимое резервной копии (при извлечении) находится в стандартном формате Maven и может быть загружено в любой внешний репозиторий Maven [ ...]

Artifactory поддерживает резервное копирование поэтапно в один и тот же целевой каталог (именуемый «текущий») в целевом резервном каталоге. Такой вид резервного копирования записывает только дельта в выходной каталог, что приводит к чрезвычайно быстрым резервным копиям.

Разве это не то, что вам нужно? Чтобы передать файлы, вы можете либо установить общий каталог на удаленный сервер, либо сделать резервную копию там, либо сделать резервную копию локально, а затем rsync.

0

Я думаю, что в Artifactory по умолчанию он поддерживает разные логические репозитории для загрузки моментальных снимков и не-снимков. Используя разрешения, вы можете сделать репозиторий снимков видимым только для некоторых.

Если этого недостаточно, другое решение, которое работает с Artifactory 2.0, заключается в том, что Artifactory использует базу данных MySQL, которая выполняет асинхронную репликацию в другую базу данных MySQL, которая, в свою очередь, считывается отдельной установкой Artifactory. Если это слишком реальное время, вы можете просто иметь две разные установки, которые делают обновления на основе бизнес-правил.

3

Если вы хотите использовать собственный плагин, вы можете настроить Maven для развертывания в список «зеркальных» мест одновременно с стандартным развертыванием. Я бы рекомендовал определить это в профиле, чтобы вы могли контролировать, какие развертывания зеркалируются (возможно, это не подходит для каждой сборки).

Чтобы определить новый плагин вам нужно создать новый проект Maven и указать POM имеет упаковки Maven-плагин:

<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> 

В Src/основной/Java определяют настоев. Приведенный ниже код объявляет цель «зеркало», он принимает список элементов mirrorRepository (содержащий репозиторий и URL-адрес), чтобы отразить развертывание артефакта. Плагин использует тот же подход к развертыванию, что и maven-deploy-plugin, и использует большинство параметров.

Обратите внимание, что вам по-прежнему необходимо определить сервер в вашем файле settings.xml для каждого репозитория с соответствующими разрешениями для развертывания или сборки.

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

колдовскую ссылается на MirrorRepository типа для инкапсулирования repositoryId и URL, это простой боб:

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; 
    } 
} 

Вот пример конфигурации с помощью плагина. Обратите внимание, что поддерживаются все форматы развертывания (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

Этот плагин опубликован для удобства потребления? – Gunnar