File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\maven-plugin\src\main\java\hudson\maven\RedeployPublisher.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:cactusman, Seiji Sogabe, Olivier Lamy
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 package hudson.maven;
25
26 import hudson.Extension;
27 import hudson.FilePath;
28 import hudson.Launcher;
29 import hudson.Util;
30 import hudson.maven.reporters.MavenAbstractArtifactRecord;
31 import hudson.maven.reporters.MavenArtifactRecord;
32 import hudson.model.AbstractBuild;
33 import hudson.model.AbstractProject;
34 import hudson.model.BuildListener;
35 import hudson.model.Node;
36 import hudson.model.Result;
37 import hudson.model.TaskListener;
38 import hudson.remoting.Callable;
39 import hudson.tasks.BuildStepDescriptor;
40 import hudson.tasks.BuildStepMonitor;
41 import hudson.tasks.Maven.MavenInstallation;
42 import hudson.tasks.Publisher;
43 import hudson.tasks.Recorder;
44
45 import java.io.File;
46 import java.io.IOException;
47 import java.util.ArrayList;
48 import java.util.Collections;
49 import java.util.List;
50 import java.util.Map.Entry;
51 import java.util.Properties;
52
53 import jenkins.model.Jenkins;
54 import jenkins.mvn.GlobalSettingsProvider;
55 import jenkins.mvn.SettingsProvider;
56 import net.sf.json.JSONObject;
57
58 import org.apache.commons.lang.StringUtils;
59 import org.apache.maven.artifact.Artifact;
60 import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
61 import org.apache.maven.artifact.metadata.ArtifactMetadata;
62 import org.apache.maven.artifact.repository.ArtifactRepository;
63 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
64 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
65 import org.apache.maven.artifact.repository.Authentication;
66 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
67 import org.apache.maven.cli.BatchModeMavenTransferListener;
68 import org.apache.maven.repository.Proxy;
69 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
70 import org.kohsuke.stapler.DataBoundConstructor;
71 import org.kohsuke.stapler.StaplerRequest;
72
73 /**
74 * {@link Publisher} for {@link MavenModuleSetBuild} to deploy artifacts
75 * after a build is fully succeeded.
76 * <p>
77 * Note that the - historical given - name of this class is quite misleading as this publisher usually does no REdeployment
78 * of artifacts. If you're looking for the redeploy functionality in the Jenkins UI: that is implemented in
79 * {@link MavenAbstractArtifactRecord#doRedeploy(String, String, boolean)}!
80 *
81 * @author Kohsuke Kawaguchi
82 * @since 1.191
83 */
84 public class RedeployPublisher extends Recorder {
85 /**
86 * Repository ID. This is matched up with <tt>~/.m2/settings.xml</tt> for authentication related information.
87 */
88 public final String id;
89 /**
90 * Repository URL to deploy artifacts to.
91 */
92 public final String url;
93 public final boolean uniqueVersion;
94 public final boolean evenIfUnstable;
95 public final String releaseEnvVar;
96
97 /**
98 * For backward compatibility
99 */
100 @Deprecated
101 public RedeployPublisher(String id, String url, boolean uniqueVersion) {
102 this(id, url, uniqueVersion, false, null);
103 }
104
105 /**
106 * @since 1.347
107 */
108 @Deprecated
109 public RedeployPublisher(String id, String url, boolean uniqueVersion, boolean evenIfUnstable) {
110 this(id, url, uniqueVersion, evenIfUnstable, null);
111 }
112
113 @DataBoundConstructor
114 public RedeployPublisher(String id, String url, boolean uniqueVersion, boolean evenIfUnstable, String releaseEnvVar) {
115 this.id = id;
116 this.url = Util.fixEmptyAndTrim(url);
117 this.uniqueVersion = uniqueVersion;
118 this.evenIfUnstable = evenIfUnstable;
119 this.releaseEnvVar = Util.fixEmptyAndTrim(releaseEnvVar);
120 }
121
122 public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
123 if (build.getResult().isWorseThan(getTreshold()))
124 return true; // build failed. Don't publish
125
126 /**
127 * Check if we should skip or not
128 */
129 if (releaseEnvVar != null) {
130 String envVarValue = build.getEnvironment(listener).get(releaseEnvVar);
131 if ("true".equals(envVarValue)) { // null or false are ignored
132 listener.getLogger().println("[INFO] Skipping deploying artifact as release build is in progress.");
133 return true; // skip the deploy
134 }
135 }
136
137 List<MavenAbstractArtifactRecord> mavenAbstractArtifactRecords = getActions(build, listener);
138 if (mavenAbstractArtifactRecords == null || mavenAbstractArtifactRecords.isEmpty()) {
139 listener.getLogger().println("[ERROR] No artifacts are recorded. Is this a Maven project?");
140 build.setResult(Result.FAILURE);
141 return true;
142 }
143
144
145 if(build instanceof MavenModuleSetBuild && ((MavenModuleSetBuild)build).getParent().isArchivingDisabled()){
146 listener.getLogger().println("[ERROR] You cannot use the \"Deploy artifacts to Maven repository\" feature if you " +
147 "disabled automatic artifact archiving");
148 build.setResult(Result.FAILURE);
149 return true;
150 }
151
152 long startupTime = System.currentTimeMillis();
153
154 try {
155 MavenEmbedder embedder = createEmbedder(listener, build);
156 ArtifactRepositoryLayout layout =
157 (ArtifactRepositoryLayout) embedder.lookup(ArtifactRepositoryLayout.ROLE, "default");
158 ArtifactRepositoryFactory factory =
159 (ArtifactRepositoryFactory) embedder.lookup(ArtifactRepositoryFactory.ROLE);
160 ArtifactRepository artifactRepository = null;
161 if (url != null) {
162 // By default we try to get the repository definition from the job configuration
163 artifactRepository = getDeploymentRepository(factory, layout, id, url);
164 }
165 for (MavenAbstractArtifactRecord mavenAbstractArtifactRecord : mavenAbstractArtifactRecords) {
166 if (artifactRepository == null && mavenAbstractArtifactRecord instanceof MavenArtifactRecord) {
167 // If no repository definition is set on the job level we try to take it from the POM
168 MavenArtifactRecord mavenArtifactRecord = (MavenArtifactRecord) mavenAbstractArtifactRecord;
169 artifactRepository = getDeploymentRepository(factory, layout, mavenArtifactRecord.repositoryId, mavenArtifactRecord.repositoryUrl);
170 }
171 if (artifactRepository == null) {
172 listener.getLogger().println("[ERROR] No Repository settings defined in the job configuration or distributionManagement of the module.");
173 build.setResult(Result.FAILURE);
174 return true;
175 }
176 mavenAbstractArtifactRecord.deploy(embedder, artifactRepository, listener);
177 }
178 listener.getLogger().println("[INFO] Deployment done in " + Util.getTimeSpanString(System.currentTimeMillis() - startupTime));
179 return true;
180 } catch (MavenEmbedderException e) {
181 e.printStackTrace(listener.error(e.getMessage()));
182 } catch (ComponentLookupException e) {
183 e.printStackTrace(listener.error(e.getMessage()));
184 } catch (ArtifactDeploymentException e) {
185 e.printStackTrace(listener.error(e.getMessage()));
186 }
187 // failed
188 build.setResult(Result.FAILURE);
189 listener.getLogger().println("[INFO] Deployment failed after " + Util.getTimeSpanString(System.currentTimeMillis() - startupTime));
190 return true;
191 }
192
193 private ArtifactRepository getDeploymentRepository(ArtifactRepositoryFactory factory, ArtifactRepositoryLayout layout, String repositoryId, String repositoryUrl) throws ComponentLookupException {
194 if (repositoryUrl == null) return null;
195 final ArtifactRepository repository = factory.createDeploymentArtifactRepository(
196 repositoryId, repositoryUrl, layout, uniqueVersion);
197 return new WrappedArtifactRepository(repository, uniqueVersion);
198 }
199
200 /**
201 *
202 * copy from MavenUtil but here we have to ignore localRepo path and setting as thoses paths comes
203 * from the remote node and can not exist in master see http://issues.jenkins-ci.org/browse/JENKINS-8711
204 *
205 */
206 private MavenEmbedder createEmbedder(TaskListener listener, AbstractBuild<?,?> build) throws MavenEmbedderException, IOException, InterruptedException {
207 MavenInstallation m=null;
208 File settingsLoc = null, remoteGlobalSettingsFromConfig = null;
209 String profiles = null;
210 Properties systemProperties = null;
211 String privateRepository = null;
212 FilePath remoteSettingsFromConfig = null;
213
214 File tmpSettings = File.createTempFile( "jenkins", "temp-settings.xml" );
215 try {
216 AbstractProject project = build.getProject();
217
218 if (project instanceof MavenModuleSet) {
219 MavenModuleSet mavenModuleSet = ((MavenModuleSet) project);
220 profiles = mavenModuleSet.getProfiles();
221 systemProperties = mavenModuleSet.getMavenProperties();
222
223 // olamy see
224 // we have to take about the settings use for the project
225 // order tru configuration
226 // TODO maybe in goals with -s,--settings last wins but not done in during pom parsing
227 // or -Dmaven.repo.local
228 // if not we must get ~/.m2/settings.xml then $M2_HOME/conf/settings.xml
229
230 // TODO check if the remoteSettings has a localRepository configured and disabled it
231
232 String altSettingsPath = SettingsProvider.getSettingsRemotePath(((MavenModuleSet) project).getSettings(), build, listener);
233 String remoteGlobalSettingsPath = GlobalSettingsProvider.getSettingsRemotePath(((MavenModuleSet) project).getGlobalSettings(), build, listener);
234 if(remoteGlobalSettingsPath != null){
235 remoteGlobalSettingsFromConfig = new File(remoteGlobalSettingsPath);
236 }
237
238 Node buildNode = build.getBuiltOn();
239
240 if(buildNode == null) {
241 // assume that build was made on master
242 buildNode = Jenkins.getInstance();
243 }
244
245 if (StringUtils.isBlank( altSettingsPath ) ) {
246 // get userHome from the node where job has been executed
247 String remoteUserHome = build.getWorkspace().act( new GetUserHome() );
248 altSettingsPath = remoteUserHome + "/.m2/settings.xml";
249 }
250
251 // we copy this file in the master in a temporary file
252 FilePath filePath = new FilePath( tmpSettings );
253 FilePath remoteSettings = build.getWorkspace().child( altSettingsPath );
254 if (!remoteSettings.exists()) {
255 // JENKINS-9084 we finally use $M2_HOME/conf/settings.xml as maven does
256
257 String mavenHome = ((MavenModuleSet) project).getMaven().forNode(buildNode, listener ).getHome();
258 String settingsPath = mavenHome + "/conf/settings.xml";
259 remoteSettings = build.getWorkspace().child( settingsPath);
260 }
261 listener.getLogger().println( "Maven RedeployPublisher use remote " + (buildNode != null ? buildNode.getNodeName() : "local" )
262 + " maven settings from : " + remoteSettings.getRemote() );
263 remoteSettings.copyTo( filePath );
264 settingsLoc = tmpSettings;
265
266 }
267
268 MavenEmbedderRequest mavenEmbedderRequest = new MavenEmbedderRequest(listener,
269 m!=null?m.getHomeDir():null,
270 profiles,
271 systemProperties,
272 privateRepository,
273 settingsLoc );
274
275 if (remoteGlobalSettingsFromConfig != null) {
276 mavenEmbedderRequest.setGlobalSettings( remoteGlobalSettingsFromConfig );
277 }
278
279 mavenEmbedderRequest.setTransferListener(new BatchModeMavenTransferListener(listener.getLogger()));
280
281 return MavenUtil.createEmbedder(mavenEmbedderRequest);
282 } finally {
283 if (tmpSettings != null) {
284 tmpSettings.delete();
285 }
286 }
287 }
288
289 private static final class GetUserHome implements Callable<String,IOException> {
290 private static final long serialVersionUID = -8755705771716056636L;
291
292 public String call() throws IOException {
293 return System.getProperty("user.home");
294 }
295 }
296
297
298 /**
299 * Obtains the {@link MavenModuleSetBuild} that we'll work on, or null.
300 * <p>
301 * This allows promoted-builds plugin to reuse the code for delayed deployment.
302 */
303 protected MavenModuleSetBuild getMavenBuild(AbstractBuild<?, ?> build) {
304 return (build instanceof MavenModuleSetBuild)
305 ? (MavenModuleSetBuild) build
306 : null;
307 }
308
309 protected List<MavenAbstractArtifactRecord> getActions(AbstractBuild<?, ?> build, BuildListener listener) {
310 List<MavenAbstractArtifactRecord> actions = new ArrayList<MavenAbstractArtifactRecord>();
311 MavenModuleSetBuild mavenBuild = getMavenBuild(build);
312 if (mavenBuild == null) {
313 return actions;
314 }
315 for (Entry<MavenModule, MavenBuild> e : mavenBuild.getModuleLastBuilds().entrySet()) {
316 MavenAbstractArtifactRecord a = e.getValue().getAction( MavenAbstractArtifactRecord.class );
317 if (a == null) {
318 listener.getLogger().println("No artifacts are recorded for module" + e.getKey().getName() + ". Is this a Maven project?");
319 } else {
320 actions.add( a );
321 }
322
323 }
324 return actions;
325 }
326
327 public BuildStepMonitor getRequiredMonitorService() {
328 return BuildStepMonitor.NONE;
329 }
330
331 protected Result getTreshold() {
332 if (evenIfUnstable) {
333 return Result.UNSTABLE;
334 } else {
335 return Result.SUCCESS;
336 }
337 }
338
339 @Extension
340 public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
341 public DescriptorImpl() {
342 }
343
344 /**
345 * @deprecated as of 1.290
346 * Use the default constructor.
347 */
348 protected DescriptorImpl(Class<? extends Publisher> clazz) {
349 super(clazz);
350 }
351
352 public boolean isApplicable(Class<? extends AbstractProject> jobType) {
353 return jobType==MavenModuleSet.class;
354 }
355
356 public RedeployPublisher newInstance(StaplerRequest req, JSONObject formData) throws FormException {
357 return req.bindJSON(RedeployPublisher.class,formData);
358 }
359
360 public String getDisplayName() {
361 return Messages.RedeployPublisher_getDisplayName();
362 }
363
364 public boolean showEvenIfUnstableOption() {
365 // little hack to avoid showing this option on the redeploy action's screen
366 return true;
367 }
368
369 }
370
371 //---------------------------------------------
372
373 @SuppressWarnings("deprecation") // as we're restricted to Maven 2.x API here, but compile against Maven 3.x we cannot avoid deprecations
374 public static class WrappedArtifactRepository implements ArtifactRepository {
375 private ArtifactRepository artifactRepository;
376 private boolean uniqueVersion;
377 public WrappedArtifactRepository (ArtifactRepository artifactRepository, boolean uniqueVersion)
378 {
379 this.artifactRepository = artifactRepository;
380 this.uniqueVersion = uniqueVersion;
381 }
382 public String pathOf( Artifact artifact )
383 {
384 return artifactRepository.pathOf( artifact );
385 }
386 public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
387 {
388 return artifactRepository.pathOfRemoteRepositoryMetadata( artifactMetadata );
389 }
390 public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
391 {
392 return artifactRepository.pathOfLocalRepositoryMetadata( metadata, repository );
393 }
394 public String getUrl()
395 {
396 return artifactRepository.getUrl();
397 }
398 public void setUrl( String url )
399 {
400 artifactRepository.setUrl( url );
401 }
402 public String getBasedir()
403 {
404 return artifactRepository.getBasedir();
405 }
406 public String getProtocol()
407 {
408 return artifactRepository.getProtocol();
409 }
410 public String getId()
411 {
412 return artifactRepository.getId();
413 }
414 public void setId( String id )
415 {
416 artifactRepository.setId( id );
417 }
418 public ArtifactRepositoryPolicy getSnapshots()
419 {
420 return artifactRepository.getSnapshots();
421 }
422 public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy )
423 {
424 artifactRepository.setSnapshotUpdatePolicy( policy );
425 }
426 public ArtifactRepositoryPolicy getReleases()
427 {
428 return artifactRepository.getReleases();
429 }
430 public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy )
431 {
432 artifactRepository.setReleaseUpdatePolicy( policy );
433 }
434 public ArtifactRepositoryLayout getLayout()
435 {
436 return artifactRepository.getLayout();
437 }
438 public void setLayout( ArtifactRepositoryLayout layout )
439 {
440 artifactRepository.setLayout( layout );
441 }
442 public String getKey()
443 {
444 return artifactRepository.getKey();
445 }
446 public boolean isUniqueVersion()
447 {
448 return this.uniqueVersion;
449 }
450
451 public void setUniqueVersion(boolean uniqueVersion) {
452 this.uniqueVersion = uniqueVersion;
453 }
454
455 public boolean isBlacklisted()
456 {
457 return artifactRepository.isBlacklisted();
458 }
459 public void setBlacklisted( boolean blackListed )
460 {
461 artifactRepository.setBlacklisted( blackListed );
462 }
463 public Artifact find( Artifact artifact )
464 {
465 return artifactRepository.find( artifact );
466 }
467 public List<String> findVersions( Artifact artifact )
468 {
469 return artifactRepository.findVersions( artifact );
470 }
471 public boolean isProjectAware()
472 {
473 return artifactRepository.isProjectAware();
474 }
475 public void setAuthentication( Authentication authentication )
476 {
477 artifactRepository.setAuthentication( authentication );
478 }
479 public Authentication getAuthentication()
480 {
481 return artifactRepository.getAuthentication();
482 }
483 public void setProxy( Proxy proxy )
484 {
485 artifactRepository.setProxy( proxy );
486 }
487 public Proxy getProxy()
488 {
489 return artifactRepository.getProxy();
490 }
491 public List<ArtifactRepository> getMirroredRepositories()
492 {
493 return Collections.emptyList();
494 }
495 public void setMirroredRepositories( List<ArtifactRepository> arg0 )
496 {
497 // noop
498 }
499 }
500
501 }
502