diff --git a/changelog.html b/changelog.html index 19aef3e81f205e4cbdf65146aa9ee9e9eab5145b..955b806bb8dc834272ff5d4a99b9d84376f87274 100644 --- a/changelog.html +++ b/changelog.html @@ -65,6 +65,9 @@ Upcoming changes
  • Improve the post deployment job to make a clear error if you disabled artifacts archives (issue 9791) +
  • + Post-build deploy task for Maven jobs : Repositories definitions can now be read from the POMs. + (issue 9786) diff --git a/maven-plugin/src/main/java/hudson/maven/RedeployPublisher.java b/maven-plugin/src/main/java/hudson/maven/RedeployPublisher.java index 8ab914679a0a85ab9b9104120124e34645368be5..09a1ad1505ad8e52c21b38ef15179738d800d5eb 100644 --- a/maven-plugin/src/main/java/hudson/maven/RedeployPublisher.java +++ b/maven-plugin/src/main/java/hudson/maven/RedeployPublisher.java @@ -28,31 +28,15 @@ import hudson.FilePath; import hudson.Launcher; import hudson.Util; import hudson.maven.reporters.MavenAbstractArtifactRecord; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; -import hudson.model.Hudson; -import hudson.model.Node; -import hudson.model.Result; -import hudson.model.TaskListener; +import hudson.maven.reporters.MavenArtifactRecord; +import hudson.model.*; import hudson.remoting.Callable; import hudson.tasks.BuildStepDescriptor; import hudson.tasks.BuildStepMonitor; import hudson.tasks.Maven.MavenInstallation; import hudson.tasks.Publisher; import hudson.tasks.Recorder; -import hudson.util.FormValidation; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; - import net.sf.json.JSONObject; - import org.apache.commons.lang.StringUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.deployer.ArtifactDeploymentException; @@ -65,9 +49,13 @@ import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.repository.Proxy; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.Map.Entry; + /** * {@link Publisher} for {@link MavenModuleSetBuild} to deploy artifacts * after a build is fully succeeded. @@ -90,6 +78,7 @@ public class RedeployPublisher extends Recorder { /** * For backward compatibility */ + @Deprecated public RedeployPublisher(String id, String url, boolean uniqueVersion) { this(id, url, uniqueVersion, false); } @@ -105,47 +94,52 @@ public class RedeployPublisher extends Recorder { this.evenIfUnstable = evenIfUnstable; } - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - if(build.getResult().isWorseThan(getTreshold())) + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + if (build.getResult().isWorseThan(getTreshold())) return true; // build failed. Don't publish - if (url==null) { - listener.getLogger().println("No Repository URL is specified."); + List mavenAbstractArtifactRecords = getActions(build, listener); + if (mavenAbstractArtifactRecords == null || mavenAbstractArtifactRecords.isEmpty()) { + listener.getLogger().println("[ERROR] No artifacts are recorded. Is this a Maven project?"); build.setResult(Result.FAILURE); return true; } - List mars = getActions( build, listener ); - if(mars==null || mars.isEmpty()) { - listener.getLogger().println("No artifacts are recorded. Is this a Maven project?"); - build.setResult(Result.FAILURE); - return true; - } if(build instanceof MavenModuleSetBuild && ((MavenModuleSetBuild)build).getParent().isArchivingDisabled()){ listener.getLogger().println("[ERROR] You cannot use the \"Deploy artifacts to Maven repository\" feature if you " + - "disabled " + - "automatic artifact archiving"); + "disabled automatic artifact archiving"); build.setResult(Result.FAILURE); return true; } - listener.getLogger().println("Deploying artifacts to "+url); + long startupTime = Calendar.getInstance().getTimeInMillis(); + try { - - //MavenEmbedder embedder = MavenUtil.createEmbedder(listener,build); - MavenEmbedder embedder = createEmbedder(listener,build); + MavenEmbedder embedder = createEmbedder(listener, build); ArtifactRepositoryLayout layout = - (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE,"default"); + (ArtifactRepositoryLayout) embedder.lookup(ArtifactRepositoryLayout.ROLE, "default"); ArtifactRepositoryFactory factory = - (ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE); - - final ArtifactRepository repository = factory.createDeploymentArtifactRepository( - id, url, layout, uniqueVersion); - WrappedArtifactRepository repo = new WrappedArtifactRepository(repository,uniqueVersion); - for (MavenAbstractArtifactRecord mar : mars) - mar.deploy(embedder,repo,listener); - + (ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE); + ArtifactRepository artifactRepository = null; + if (url != null) { + // By default we try to get the repository definition from the job configuration + artifactRepository = getDeploymentRepository(factory, layout, id, url); + } + for (MavenAbstractArtifactRecord mavenAbstractArtifactRecord : mavenAbstractArtifactRecords) { + if (artifactRepository == null && mavenAbstractArtifactRecord instanceof MavenArtifactRecord) { + // If no repository definition is set on the job level we try to take it from the POM + MavenArtifactRecord mavenArtifactRecord = (MavenArtifactRecord) mavenAbstractArtifactRecord; + artifactRepository = getDeploymentRepository(factory, layout, mavenArtifactRecord.repositoryId, mavenArtifactRecord.repositoryUrl); + } + if (artifactRepository == null) { + listener.getLogger().println("[ERROR] No Repository settings defined in the job configuration or distributionManagement of the module."); + build.setResult(Result.FAILURE); + return true; + } + mavenAbstractArtifactRecord.deploy(embedder, artifactRepository, listener); + } + listener.getLogger().println("[INFO] Deployment done in " + Util.getTimeSpanString(Calendar.getInstance().getTimeInMillis() - startupTime)); return true; } catch (MavenEmbedderException e) { e.printStackTrace(listener.error(e.getMessage())); @@ -156,9 +150,17 @@ public class RedeployPublisher extends Recorder { } // failed build.setResult(Result.FAILURE); + listener.getLogger().println("[INFO] Deployment failed after " + Util.getTimeSpanString(Calendar.getInstance().getTimeInMillis() - startupTime)); return true; } + private ArtifactRepository getDeploymentRepository(ArtifactRepositoryFactory factory, ArtifactRepositoryLayout layout, String repositoryId, String repositoryUrl) throws ComponentLookupException { + if (repositoryUrl == null) return null; + final ArtifactRepository repository = factory.createDeploymentArtifactRepository( + repositoryId, repositoryUrl, layout, uniqueVersion); + return new WrappedArtifactRepository(repository, uniqueVersion); + } + /** * * copy from MavenUtil but here we have to ignore localRepo path and setting as thoses paths comes @@ -312,13 +314,6 @@ public class RedeployPublisher extends Recorder { return true; } - public FormValidation doCheckUrl(@QueryParameter String url) { - String fixedUrl = hudson.Util.fixEmptyAndTrim(url); - if (fixedUrl==null) - return FormValidation.error(Messages.RedeployPublisher_RepositoryURL_Mandatory()); - - return FormValidation.ok(); - } } //--------------------------------------------- diff --git a/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactArchiver.java b/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactArchiver.java index 65ea22e006b3f2b9bc16f06763602706a304cec8..903a2cab0ebc1c8facbd456ef038d5ce0c17f8f2 100644 --- a/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactArchiver.java +++ b/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactArchiver.java @@ -23,29 +23,24 @@ */ package hudson.maven.reporters; -import hudson.maven.MavenBuildProxy; -import hudson.maven.MavenModule; -import hudson.maven.MavenReporter; -import hudson.maven.MavenReporterDescriptor; -import hudson.maven.MojoInfo; -import hudson.maven.MavenBuild; -import hudson.model.BuildListener; -import hudson.util.InvocationInterceptor; -import hudson.FilePath; import hudson.Extension; +import hudson.FilePath; import hudson.Util; +import hudson.maven.*; +import hudson.model.BuildListener; +import hudson.util.InvocationInterceptor; import org.apache.maven.artifact.Artifact; import org.apache.maven.project.MavenProject; -import java.io.IOException; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.HashSet; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationHandler; /** * Archives artifacts of the build. @@ -99,41 +94,47 @@ public class MavenArtifactArchiver extends MavenReporter { // artifacts that are known to Maven. Set mavenArtifacts = new HashSet(); - if(pom.getFile()!=null) {// goals like 'clean' runs without loading POM, apparently. + if (pom.getFile() != null) {// goals like 'clean' runs without loading POM, apparently. // record POM final MavenArtifact pomArtifact = new MavenArtifact( - pom.getGroupId(), pom.getArtifactId(), pom.getVersion(), null, "pom", pom.getFile().getName(), Util.getDigestOf(new FileInputStream(pom.getFile()))); + pom.getGroupId(), pom.getArtifactId(), pom.getVersion(), null, "pom", pom.getFile().getName(), Util.getDigestOf(new FileInputStream(pom.getFile()))); + + final String repositoryUrl = pom.getDistributionManagementArtifactRepository() == null ? null : Util.fixEmptyAndTrim(pom.getDistributionManagementArtifactRepository().getUrl()); + final String repositoryId = pom.getDistributionManagementArtifactRepository() == null ? null : Util.fixEmptyAndTrim(pom.getDistributionManagementArtifactRepository().getId()); + mavenArtifacts.add(pom.getFile()); - pomArtifact.archive(build,pom.getFile(),listener); + pomArtifact.archive(build, pom.getFile(), listener); // record main artifact (if packaging is POM, this doesn't exist) final MavenArtifact mainArtifact = MavenArtifact.create(pom.getArtifact()); - if(mainArtifact!=null) { + if (mainArtifact != null) { File f = pom.getArtifact().getFile(); mavenArtifacts.add(f); - mainArtifact.archive(build, f,listener); + mainArtifact.archive(build, f, listener); } // record attached artifacts final List attachedArtifacts = new ArrayList(); - for( Artifact a : (List)pom.getAttachedArtifacts() ) { + for (Artifact a : (List) pom.getAttachedArtifacts()) { MavenArtifact ma = MavenArtifact.create(a); - if(ma!=null) { + if (ma != null) { mavenArtifacts.add(a.getFile()); - ma.archive(build,a.getFile(),listener); + ma.archive(build, a.getFile(), listener); attachedArtifacts.add(ma); } } // record the action - build.executeAsync(new MavenBuildProxy.BuildCallable() { + build.executeAsync(new MavenBuildProxy.BuildCallable() { public Void call(MavenBuild build) throws IOException, InterruptedException { // if a build forks lifecycles, this method can be called multiple times List old = Util.filter(build.getActions(), MavenArtifactRecord.class); if (!old.isEmpty()) build.getActions().removeAll(old); - MavenArtifactRecord mar = new MavenArtifactRecord(build,pomArtifact,mainArtifact,attachedArtifacts); + MavenArtifactRecord mar = new MavenArtifactRecord(build, pomArtifact, mainArtifact, attachedArtifacts, + repositoryUrl, + repositoryId); build.addAction(mar); mar.recordFingerprints(); diff --git a/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java b/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java index f2d3bf5106af0cadbdd0f75f34bd84a4048ccd90..8c49e56baaa1846ad97753b01fd7616923961314 100644 --- a/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java +++ b/maven-plugin/src/main/java/hudson/maven/reporters/MavenArtifactRecord.java @@ -23,23 +23,10 @@ */ package hudson.maven.reporters; -import hudson.maven.AggregatableAction; -import hudson.maven.MavenAggregatedReport; -import hudson.maven.MavenBuild; -import hudson.maven.MavenEmbedder; -import hudson.maven.MavenEmbedderException; -import hudson.maven.MavenModule; -import hudson.maven.MavenModuleSetBuild; -import hudson.maven.MavenUtil; +import hudson.maven.*; import hudson.maven.RedeployPublisher.WrappedArtifactRepository; import hudson.model.Action; import hudson.model.TaskListener; - -import java.io.IOException; -import java.io.PrintStream; -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; @@ -51,6 +38,11 @@ import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.project.artifact.ProjectArtifactMetadata; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; +import java.util.Map; + /** * {@link Action} that remembers {@link MavenArtifact artifact}s that are built. * @@ -82,16 +74,34 @@ public class MavenArtifactRecord extends MavenAbstractArtifactRecord */ public final List attachedArtifacts; + /** + * The repository identifier (matching maven settings) used for credentials to deploy artifacts + */ + public final String repositoryId; + + /** + * The repository URL used for credentials to deploy artifacts + */ + public final String repositoryUrl; + + @Deprecated public MavenArtifactRecord(MavenBuild parent, MavenArtifact pomArtifact, MavenArtifact mainArtifact, List attachedArtifacts) { - assert parent!=null; - assert pomArtifact!=null; - assert attachedArtifacts!=null; - if(mainArtifact==null) mainArtifact=pomArtifact; + this(parent, pomArtifact, mainArtifact, attachedArtifacts, null, null); + } + + public MavenArtifactRecord(MavenBuild parent, MavenArtifact pomArtifact, MavenArtifact mainArtifact, + List attachedArtifacts, String repositoryUrl, String repositoryId) { + assert parent != null; + assert pomArtifact != null; + assert attachedArtifacts != null; + if (mainArtifact == null) mainArtifact = pomArtifact; this.parent = parent; this.pomArtifact = pomArtifact; this.mainArtifact = mainArtifact; this.attachedArtifacts = attachedArtifacts; + this.repositoryUrl = repositoryUrl; + this.repositoryId = repositoryId; } public MavenBuild getBuild() { @@ -109,38 +119,38 @@ public class MavenArtifactRecord extends MavenAbstractArtifactRecord @Override public void deploy(MavenEmbedder embedder, ArtifactRepository deploymentRepository, TaskListener listener) throws MavenEmbedderException, IOException, ComponentLookupException, ArtifactDeploymentException { ArtifactHandlerManager handlerManager = embedder.lookup(ArtifactHandlerManager.class); - - ArtifactFactory factory = embedder.lookup(ArtifactFactory.class); + + ArtifactFactory artifactFactory = embedder.lookup(ArtifactFactory.class); PrintStream logger = listener.getLogger(); boolean maven3orLater = MavenUtil.maven3orLater(parent.getModuleSetBuild().getMavenVersionUsed()); boolean uniqueVersion = true; if (!deploymentRepository.isUniqueVersion()) { if (maven3orLater) { - logger.println("uniqueVersion == false is not anymore supported in maven 3"); + logger.println("[ERROR] uniqueVersion == false is not anymore supported in maven 3"); } else { - ((WrappedArtifactRepository) deploymentRepository).setUniqueVersion( false ); + ((WrappedArtifactRepository) deploymentRepository).setUniqueVersion(false); uniqueVersion = false; } } else { - ((WrappedArtifactRepository) deploymentRepository).setUniqueVersion( true ); + ((WrappedArtifactRepository) deploymentRepository).setUniqueVersion(true); } - Artifact main = mainArtifact.toArtifact(handlerManager,factory,parent); - if(!isPOM()) - main.addMetadata(new ProjectArtifactMetadata(main,pomArtifact.getFile(parent))); + Artifact main = mainArtifact.toArtifact(handlerManager, artifactFactory, parent); + if (!isPOM()) + main.addMetadata(new ProjectArtifactMetadata(main, pomArtifact.getFile(parent))); + + + ArtifactDeployer deployer = embedder.lookup(ArtifactDeployer.class, uniqueVersion ? "default" : "maven2"); + logger.println( + "[INFO] Deployment in " + deploymentRepository.getUrl() + "(id=" + deploymentRepository.getId() + ", uniqueVersion=" + deploymentRepository.isUniqueVersion()+")"); // deploy the main artifact. This also deploys the POM logger.println(Messages.MavenArtifact_DeployingMainArtifact(main.getFile().getName())); - - ArtifactDeployer deployer = embedder.lookup(ArtifactDeployer.class,uniqueVersion ? "default":"maven2"); - - deployer.deploy( main.getFile(), main, deploymentRepository, embedder.getLocalRepository() ); - - //deployMavenArtifact( main, deploymentRepository, embedder, uniqueVersion ); + deployer.deploy(main.getFile(), main, deploymentRepository, embedder.getLocalRepository()); for (MavenArtifact aa : attachedArtifacts) { - Artifact a = aa.toArtifact(handlerManager,factory, parent); - logger.println(Messages.MavenArtifact_DeployingAttachedArtifact(a.getFile().getName())); - deployer.deploy( a.getFile(), a, deploymentRepository, embedder.getLocalRepository() ); + Artifact a = aa.toArtifact(handlerManager, artifactFactory, parent); + logger.println(Messages.MavenArtifact_DeployingMainArtifact(a.getFile().getName())); + deployer.deploy(a.getFile(), a, deploymentRepository, embedder.getLocalRepository()); } } diff --git a/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config.jelly b/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config.jelly index d3cd0bb9bf27ee9c3aaeb64c13eeb729abfb9a30..40ad9942bca37ceafbff2f8d91a084f18245675a 100644 --- a/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config.jelly +++ b/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config.jelly @@ -24,10 +24,10 @@ THE SOFTWARE. - - - + + + diff --git a/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config_fr.properties b/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config_fr.properties index 14803c54c11b4d660657d81c49ac7737403573f8..aa7659d8c587653739315eaaef538a21f1d03738 100644 --- a/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config_fr.properties +++ b/maven-plugin/src/main/resources/hudson/maven/RedeployPublisher/config_fr.properties @@ -21,5 +21,6 @@ # THE SOFTWARE. Repository\ URL=URL du repository -Repository\ ID=ID du repository -Assign\ unique\ versions\ to\ snapshots=Affecter des numéros de version uniques aux snapshots +Repository\ ID=Identifiant du repository +Assign\ unique\ versions\ to\ snapshots=Affecter des num\u00e9ros de version uniques aux snapshots +Deploy\ even\ if\ the\ build\ is\ unstable=D\u00e9ploiment\\ m\u00eame si\\ le\\ build est\\ instable.