1 package org.apache.maven.continuum.web.action;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.continuum.configuration.BuildAgentConfigurationException;
23 import org.apache.continuum.model.release.ReleaseListenerSummary;
24 import org.apache.continuum.release.distributed.DistributedReleaseUtil;
25 import org.apache.continuum.release.distributed.manager.DistributedReleaseManager;
26 import org.apache.continuum.utils.release.ReleaseUtil;
27 import org.apache.continuum.web.action.AbstractReleaseAction;
28 import org.apache.continuum.web.util.AuditLog;
29 import org.apache.continuum.web.util.AuditLogConstants;
30 import org.apache.maven.continuum.ContinuumException;
31 import org.apache.maven.continuum.installation.InstallationService;
32 import org.apache.maven.continuum.model.project.Project;
33 import org.apache.maven.continuum.model.system.Profile;
34 import org.apache.maven.continuum.release.ContinuumReleaseManager;
35 import org.apache.maven.continuum.release.ContinuumReleaseManagerListener;
36 import org.apache.maven.continuum.release.DefaultReleaseManagerListener;
37 import org.apache.maven.continuum.web.exception.AuthorizationRequiredException;
38 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
39 import org.apache.maven.shared.release.ReleaseResult;
40 import org.codehaus.plexus.util.StringUtils;
41
42 import java.io.File;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.Properties;
48
49
50
51
52
53
54 public class ReleasePrepareAction
55 extends AbstractReleaseAction
56 {
57 private static final String SCM_SVN_PROTOCOL_PREFIX = "scm:svn";
58
59 private static final String SNAPSHOT_VERSION_SUFFIX = "-SNAPSHOT";
60
61 private int projectId;
62
63 private String releaseId;
64
65 private String name;
66
67 private String scmUsername;
68
69 private String scmPassword;
70
71 private String scmTag;
72
73 private String scmTagBase;
74
75 private String scmCommentPrefix;
76
77 private boolean scmUseEditMode = false;
78
79 private List<Map<String, String>> projects = new ArrayList<Map<String, String>>();
80
81 private List<String> projectKeys;
82
83 private List<String> devVersions;
84
85 private List<String> relVersions;
86
87 private String prepareGoals;
88
89 private String arguments;
90
91 private ReleaseResult result;
92
93 private ContinuumReleaseManagerListener listener;
94
95 private String projectGroupName = "";
96
97 private List<Profile> profiles;
98
99 private int profileId;
100
101 private boolean autoVersionSubmodules = false;
102
103 private boolean addSchema = true;
104
105 private ReleaseListenerSummary listenerSummary;
106
107 public String input()
108 throws Exception
109 {
110 try
111 {
112 checkBuildProjectInGroupAuthorization( getProjectGroupName() );
113 }
114 catch ( AuthorizationRequiredException e )
115 {
116 return REQUIRES_AUTHORIZATION;
117 }
118
119 Project project = getContinuum().getProject( projectId );
120 scmUsername = project.getScmUsername();
121 scmPassword = project.getScmPassword();
122 scmTag = project.getScmTag();
123
124 if ( scmTag == null )
125 {
126 String version = project.getVersion();
127 int idx = version.indexOf( SNAPSHOT_VERSION_SUFFIX );
128
129 if ( idx >= 0 )
130 {
131
132 scmTag = project.getArtifactId() + "-" + version.substring( 0, idx );
133 }
134 else
135 {
136 scmTag = project.getArtifactId() + "-" + version;
137 }
138 }
139
140 String scmUrl = project.getScmUrl();
141 if ( scmUrl.startsWith( SCM_SVN_PROTOCOL_PREFIX ) )
142 {
143 scmTagBase = new SvnScmProviderRepository( scmUrl, scmUsername, scmPassword ).getTagBase();
144
145 scmTagBase = scmTagBase.substring( SCM_SVN_PROTOCOL_PREFIX.length() + 1 );
146 }
147 else
148 {
149 scmTagBase = "";
150 }
151
152 ContinuumReleaseManager releaseManager = getContinuum().getReleaseManager();
153
154
155 releaseManager.sanitizeTagName( scmUrl, scmTag );
156
157 prepareGoals = "clean integration-test";
158
159 if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
160 {
161 DistributedReleaseManager distributedReleaseManager = getContinuum().getDistributedReleaseManager();
162
163 try
164 {
165 getReleasePluginParameters( distributedReleaseManager.getReleasePluginParameters( projectId,
166 "pom.xml" ) );
167
168 projects = distributedReleaseManager.processProject( projectId, "pom.xml", autoVersionSubmodules );
169 }
170 catch ( BuildAgentConfigurationException e )
171 {
172 List<Object> args = new ArrayList<Object>();
173 args.add( e.getMessage() );
174
175 addActionError( getText( "distributedBuild.releasePrepare.input.error", args ) );
176 return RELEASE_ERROR;
177 }
178 }
179 else
180 {
181 try
182 {
183 String workingDirectory = getContinuum().getWorkingDirectory( project.getId() ).getPath();
184
185 getReleasePluginParameters( workingDirectory, "pom.xml" );
186
187 ReleaseUtil.processProject( workingDirectory, "pom.xml", autoVersionSubmodules, projects );
188 }
189 catch ( Exception e )
190 {
191 List<Object> args = new ArrayList<Object>();
192 args.add( e.getMessage() );
193
194 addActionError( getText( "releasePrepare.input.error", args ) );
195 return RELEASE_ERROR;
196 }
197 }
198
199 profiles = this.getContinuum().getProfileService().getAllProfiles();
200
201 return SUCCESS;
202 }
203
204 private void getReleasePluginParameters( String workingDirectory, String pomFilename )
205 throws Exception
206 {
207 Map<String, Object> params = ReleaseUtil.getReleasePluginParameters( workingDirectory, pomFilename );
208
209
210 if ( params.get( "scm-tag" ) != null )
211 {
212 scmTag = (String) params.get( "scm-tag" );
213 }
214
215 if ( params.get( "scm-tagbase" ) != null )
216 {
217 scmTagBase = (String) params.get( "scm-tagbase" );
218 }
219
220 if ( params.get( "preparation-goals" ) != null )
221 {
222 prepareGoals = (String) params.get( "preparation-goals" );
223 }
224
225 if ( params.get( "arguments" ) != null )
226 {
227 arguments = (String) params.get( "arguments" );
228 }
229
230 if ( params.get( "scm-comment-prefix" ) != null )
231 {
232 scmCommentPrefix = (String) params.get( "scm-comment-prefix" );
233 }
234
235 if ( params.get( "auto-version-submodules" ) != null )
236 {
237 autoVersionSubmodules = (Boolean) params.get( "auto-version-submodules" );
238 }
239
240 if ( params.get( "add-schema" ) != null )
241 {
242 addSchema = (Boolean) params.get( "add-schema" );
243 }
244 }
245
246 public String execute()
247 throws Exception
248 {
249 try
250 {
251 checkBuildProjectInGroupAuthorization( getProjectGroupName() );
252 }
253 catch ( AuthorizationRequiredException e )
254 {
255 return REQUIRES_AUTHORIZATION;
256 }
257
258 Project project = getContinuum().getProject( projectId );
259
260 name = project.getName();
261 if ( name == null )
262 {
263 name = project.getArtifactId();
264 }
265
266 Profile profile = null;
267
268 if ( profileId != -1 )
269 {
270 profile = getContinuum().getProfileService().getProfile( profileId );
271 }
272
273 String username = getPrincipal();
274
275 Map<String, String> environments = new HashMap<String, String>();
276
277 if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
278 {
279 DistributedReleaseManager distributedReleaseManager = getContinuum().getDistributedReleaseManager();
280
281 environments = getEnvironments( profile, distributedReleaseManager.getDefaultBuildagent( projectId ) );
282
283 try
284 {
285 releaseId = distributedReleaseManager.releasePrepare( project, getReleaseProperties(),
286 getRelVersionMap(), getDevVersionMap(),
287 environments, username );
288
289 if ( releaseId == null )
290 {
291 addActionError( "Failed to release project" );
292 return RELEASE_ERROR;
293 }
294 }
295 catch ( BuildAgentConfigurationException e )
296 {
297 List<Object> args = new ArrayList<Object>();
298 args.add( e.getMessage() );
299
300 addActionError( getText( "distributedBuild.releasePrepare.release.error", args ) );
301 return RELEASE_ERROR;
302 }
303 }
304 else
305 {
306 environments = getEnvironments( profile, null );
307
308 listener = new DefaultReleaseManagerListener();
309
310 listener.setUsername( username );
311
312 String workingDirectory = getContinuum().getWorkingDirectory( projectId ).getPath();
313
314 ContinuumReleaseManager releaseManager = getContinuum().getReleaseManager();
315
316 String executable = getContinuum().getInstallationService().getExecutorConfigurator(
317 InstallationService.MAVEN2_TYPE ).getExecutable();
318
319 if ( environments != null )
320 {
321 String m2Home = environments.get( getContinuum().getInstallationService().getEnvVar(
322 InstallationService.MAVEN2_TYPE ) );
323 if ( StringUtils.isNotEmpty( m2Home ) )
324 {
325 executable = m2Home + File.separator + "bin" + File.separator + executable;
326 }
327 }
328
329 releaseId = releaseManager.prepare( project, getReleaseProperties(), getRelVersionMap(), getDevVersionMap(),
330 listener, workingDirectory, environments, executable );
331 }
332
333 AuditLog event = new AuditLog( "Release id=" + releaseId, AuditLogConstants.PREPARE_RELEASE );
334 event.setCategory( AuditLogConstants.PROJECT );
335 event.setCurrentUser( username );
336 event.log();
337
338 return SUCCESS;
339 }
340
341 public String viewResult()
342 throws Exception
343 {
344 try
345 {
346 checkBuildProjectInGroupAuthorization( getProjectGroupName() );
347 }
348 catch ( AuthorizationRequiredException e )
349 {
350 return REQUIRES_AUTHORIZATION;
351 }
352
353 if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
354 {
355 DistributedReleaseManager distributedReleaseManager = getContinuum().getDistributedReleaseManager();
356
357 try
358 {
359 result = distributedReleaseManager.getReleaseResult( releaseId );
360 }
361 catch ( BuildAgentConfigurationException e )
362 {
363 addActionError( "release" );
364 return "viewResultError";
365 }
366 }
367 else
368 {
369 result = (ReleaseResult) getContinuum().getReleaseManager().getReleaseResults().get( releaseId );
370 }
371
372 return "viewResult";
373 }
374
375 public String checkProgress()
376 throws Exception
377 {
378 try
379 {
380 checkBuildProjectInGroupAuthorization( getProjectGroupName() );
381 }
382 catch ( AuthorizationRequiredException e )
383 {
384 return REQUIRES_AUTHORIZATION;
385 }
386
387 String status;
388
389 listenerSummary = new ReleaseListenerSummary();
390
391 if ( getContinuum().getConfiguration().isDistributedBuildEnabled() )
392 {
393 DistributedReleaseManager distributedReleaseManager = getContinuum().getDistributedReleaseManager();
394 Map listenerMap;
395 try
396 {
397 listenerMap = distributedReleaseManager.getListener( releaseId );
398 }
399 catch ( BuildAgentConfigurationException e )
400 {
401 addActionError( "Failed to retrieve listener for release: " + releaseId );
402 return "";
403 }
404
405 if ( listenerMap != null && !listenerMap.isEmpty() )
406 {
407 int state = DistributedReleaseUtil.getReleaseState( listenerMap );
408
409 if ( state == ContinuumReleaseManagerListener.FINISHED )
410 {
411 distributedReleaseManager.removeListener( releaseId );
412
413 result = distributedReleaseManager.getReleaseResult( releaseId );
414
415 status = "finished";
416 }
417 else
418 {
419 status = "inProgress";
420 }
421
422 listenerSummary.setPhases( DistributedReleaseUtil.getReleasePhases( listenerMap ) );
423 listenerSummary.setCompletedPhases( DistributedReleaseUtil.getCompletedReleasePhases( listenerMap ) );
424 listenerSummary.setInProgress( DistributedReleaseUtil.getReleaseInProgress( listenerMap ) );
425 listenerSummary.setError( DistributedReleaseUtil.getReleaseError( listenerMap ) );
426 }
427 else
428 {
429 throw new Exception( "There is no release on-going or finished with id: " + releaseId );
430 }
431 }
432 else
433 {
434 ContinuumReleaseManager releaseManager = getContinuum().getReleaseManager();
435
436 listenerSummary = releaseManager.getListener( releaseId );
437
438 if ( listenerSummary != null )
439 {
440 if ( listenerSummary.getState() == ContinuumReleaseManagerListener.FINISHED )
441 {
442 releaseManager.getListeners().remove( releaseId );
443
444 result = (ReleaseResult) releaseManager.getReleaseResults().get( releaseId );
445
446 status = "finished";
447 }
448 else
449 {
450 status = "inProgress";
451 }
452 }
453 else
454 {
455 throw new Exception( "There is no release on-going or finished with id: " + releaseId );
456 }
457 }
458
459 return status;
460 }
461
462 private Map<String, String> getDevVersionMap()
463 {
464 return getVersionMap( projectKeys, devVersions );
465 }
466
467 private Map<String, String> getRelVersionMap()
468 {
469 return getVersionMap( projectKeys, relVersions );
470 }
471
472 private Map<String, String> getVersionMap( List<String> keys, List<String> versions )
473 {
474 Map<String, String> versionMap = new HashMap<String, String>();
475
476 for ( int idx = 0; idx < keys.size(); idx++ )
477 {
478 String key = keys.get( idx );
479 String version;
480 if ( !autoVersionSubmodules )
481 {
482 version = versions.get( idx );
483 }
484 else
485 {
486 version = versions.get( 0 );
487 }
488
489 versionMap.put( key, version );
490 }
491
492 return versionMap;
493 }
494
495 private Properties getReleaseProperties()
496 {
497 Properties p = new Properties();
498
499 if ( StringUtils.isNotEmpty( scmUsername ) )
500 {
501 p.setProperty( "scm-username", scmUsername );
502 }
503
504 if ( StringUtils.isNotEmpty( scmPassword ) )
505 {
506 p.setProperty( "scm-password", scmPassword );
507 }
508
509 if ( StringUtils.isNotEmpty( scmTagBase ) )
510 {
511 p.setProperty( "scm-tagbase", scmTagBase );
512 }
513
514 if ( StringUtils.isNotEmpty( scmCommentPrefix ) )
515 {
516
517 p.setProperty( "scm-comment-prefix", scmCommentPrefix.trim() + " " );
518 }
519
520 p.setProperty( "scm-tag", scmTag );
521 p.setProperty( "preparation-goals", prepareGoals );
522 p.setProperty( "arguments", arguments );
523 p.setProperty( "use-edit-mode", Boolean.toString( scmUseEditMode ) );
524 p.setProperty( "add-schema", Boolean.toString( addSchema ) );
525 p.setProperty( "auto-version-submodules", Boolean.toString( autoVersionSubmodules ) );
526
527 return p;
528 }
529
530 private void getReleasePluginParameters( Map context )
531 {
532 if ( StringUtils.isNotEmpty( DistributedReleaseUtil.getScmTag( context, scmTag ) ) )
533 {
534 scmTag = DistributedReleaseUtil.getScmTag( context, scmTag );
535 }
536
537 if ( StringUtils.isNotEmpty( DistributedReleaseUtil.getScmTagBase( context, scmTagBase ) ) )
538 {
539 scmTagBase = DistributedReleaseUtil.getScmTagBase( context, scmTagBase );
540 }
541
542 if ( StringUtils.isNotEmpty( DistributedReleaseUtil.getPrepareGoals( context, prepareGoals ) ) )
543 {
544 prepareGoals = DistributedReleaseUtil.getPrepareGoals( context, prepareGoals );
545 }
546
547 if ( StringUtils.isNotEmpty( DistributedReleaseUtil.getArguments( context, "" ) ) )
548 {
549 arguments = DistributedReleaseUtil.getArguments( context, "" );
550 }
551
552 if ( StringUtils.isNotEmpty( DistributedReleaseUtil.getScmCommentPrefix( context, "" ) ) )
553 {
554 scmCommentPrefix = DistributedReleaseUtil.getScmCommentPrefix( context, "" );
555 }
556
557 autoVersionSubmodules = DistributedReleaseUtil.getAutoVersionSubmodules( context, false );
558
559 addSchema = DistributedReleaseUtil.getAddSchema( context, true );
560 }
561
562 public List<String> getProjectKeys()
563 {
564 return projectKeys;
565 }
566
567 public void setProjectKeys( List<String> projectKeys )
568 {
569 this.projectKeys = projectKeys;
570 }
571
572 public List<String> getDevVersions()
573 {
574 return devVersions;
575 }
576
577 public void setDevVersions( List<String> devVersions )
578 {
579 this.devVersions = devVersions;
580 }
581
582 public List<String> getRelVersions()
583 {
584 return relVersions;
585 }
586
587 public void setRelVersions( List<String> relVersions )
588 {
589 this.relVersions = relVersions;
590 }
591
592 public int getProjectId()
593 {
594 return projectId;
595 }
596
597 public void setProjectId( int projectId )
598 {
599 this.projectId = projectId;
600 }
601
602 public String getScmUsername()
603 {
604 return scmUsername;
605 }
606
607 public void setScmUsername( String scmUsername )
608 {
609 this.scmUsername = scmUsername;
610 }
611
612 public String getScmPassword()
613 {
614 return scmPassword;
615 }
616
617 public void setScmPassword( String scmPassword )
618 {
619 this.scmPassword = scmPassword;
620 }
621
622 public String getScmTag()
623 {
624 return scmTag;
625 }
626
627 public void setScmTag( String scmTag )
628 {
629 this.scmTag = scmTag;
630 }
631
632 public String getScmTagBase()
633 {
634 return scmTagBase;
635 }
636
637 public void setScmTagBase( String scmTagBase )
638 {
639 this.scmTagBase = scmTagBase;
640 }
641
642 public List<Map<String, String>> getProjects()
643 {
644 return projects;
645 }
646
647 public void setProjects( List<Map<String, String>> projects )
648 {
649 this.projects = projects;
650 }
651
652 public ContinuumReleaseManagerListener getListener()
653 {
654 return listener;
655 }
656
657 public void setListener( DefaultReleaseManagerListener listener )
658 {
659 this.listener = listener;
660 }
661
662 public String getName()
663 {
664 return name;
665 }
666
667 public void setName( String name )
668 {
669 this.name = name;
670 }
671
672 public String getReleaseId()
673 {
674 return releaseId;
675 }
676
677 public void setReleaseId( String releaseId )
678 {
679 this.releaseId = releaseId;
680 }
681
682 public ReleaseResult getResult()
683 {
684 return result;
685 }
686
687 public void setResult( ReleaseResult result )
688 {
689 this.result = result;
690 }
691
692 public String getPrepareGoals()
693 {
694 return prepareGoals;
695 }
696
697 public void setPrepareGoals( String prepareGoals )
698 {
699 this.prepareGoals = prepareGoals;
700 }
701
702 public String getArguments()
703 {
704 return arguments;
705 }
706
707 public void setArguments( String arguments )
708 {
709 this.arguments = arguments;
710 }
711
712 public void validate()
713 {
714 }
715
716 public String getProjectGroupName()
717 throws ContinuumException
718 {
719 if ( StringUtils.isEmpty( projectGroupName ) )
720 {
721 projectGroupName = getContinuum().getProjectGroupByProjectId( projectId ).getName();
722 }
723
724 return projectGroupName;
725 }
726
727 public List<Profile> getProfiles()
728 {
729 return profiles;
730 }
731
732 public void setProfiles( List<Profile> profiles )
733 {
734 this.profiles = profiles;
735 }
736
737 public int getProfileId()
738 {
739 return profileId;
740 }
741
742 public void setProfileId( int profileId )
743 {
744 this.profileId = profileId;
745 }
746
747 public boolean isScmUseEditMode()
748 {
749 return scmUseEditMode;
750 }
751
752 public void setScmUseEditMode( boolean scmUseEditMode )
753 {
754 this.scmUseEditMode = scmUseEditMode;
755 }
756
757 public String getScmCommentPrefix()
758 {
759 return scmCommentPrefix;
760 }
761
762 public void setScmCommentPrefix( String scmCommentPrefix )
763 {
764 this.scmCommentPrefix = scmCommentPrefix;
765 }
766
767 public boolean isAutoVersionSubmodules()
768 {
769 return autoVersionSubmodules;
770 }
771
772 public void setAutoVersionSubmodules( boolean autoVersionSubmodules )
773 {
774 this.autoVersionSubmodules = autoVersionSubmodules;
775 }
776
777 public boolean isAddSchema()
778 {
779 return addSchema;
780 }
781
782 public void setAddSchema( boolean addSchema )
783 {
784 this.addSchema = addSchema;
785 }
786
787 public ReleaseListenerSummary getListenerSummary()
788 {
789 return listenerSummary;
790 }
791
792 public void setListenerSummary( ReleaseListenerSummary listenerSummary )
793 {
794 this.listenerSummary = listenerSummary;
795 }
796 }