View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.release.phase;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.File;
26  import java.util.List;
27  
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.scm.ScmException;
30  import org.apache.maven.scm.ScmFileSet;
31  import org.apache.maven.scm.ScmTagParameters;
32  import org.apache.maven.scm.command.tag.TagScmResult;
33  import org.apache.maven.scm.manager.NoSuchScmProviderException;
34  import org.apache.maven.scm.provider.ScmProvider;
35  import org.apache.maven.scm.repository.ScmRepository;
36  import org.apache.maven.scm.repository.ScmRepositoryException;
37  import org.apache.maven.shared.release.ReleaseExecutionException;
38  import org.apache.maven.shared.release.ReleaseFailureException;
39  import org.apache.maven.shared.release.ReleaseResult;
40  import org.apache.maven.shared.release.config.ReleaseDescriptor;
41  import org.apache.maven.shared.release.env.ReleaseEnvironment;
42  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
43  import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
44  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
45  import org.apache.maven.shared.release.util.ReleaseUtil;
46  
47  /**
48   * Tag the SCM repository after committing the release.
49   *
50   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
51   */
52  @Singleton
53  @Named("scm-tag")
54  public class ScmTagPhase extends AbstractReleasePhase {
55      /**
56       * Tool that gets a configured SCM repository from release configuration.
57       */
58      private final ScmRepositoryConfigurator scmRepositoryConfigurator;
59  
60      @Inject
61      public ScmTagPhase(ScmRepositoryConfigurator scmRepositoryConfigurator) {
62          this.scmRepositoryConfigurator = scmRepositoryConfigurator;
63      }
64  
65      @Override
66      public ReleaseResult execute(
67              ReleaseDescriptor releaseDescriptor,
68              ReleaseEnvironment releaseEnvironment,
69              List<MavenProject> reactorProjects)
70              throws ReleaseExecutionException, ReleaseFailureException {
71          ReleaseResult relResult = new ReleaseResult();
72  
73          validateConfiguration(releaseDescriptor);
74  
75          if (releaseDescriptor.getWaitBeforeTagging() > 0) {
76              logInfo(
77                      relResult,
78                      "Waiting for " + releaseDescriptor.getWaitBeforeTagging() + " seconds before tagging the release.");
79              try {
80                  Thread.sleep(1000L * releaseDescriptor.getWaitBeforeTagging());
81              } catch (InterruptedException e) {
82                  // Ignore
83              }
84          }
85  
86          logInfo(relResult, "Tagging release with the label " + releaseDescriptor.getScmReleaseLabel() + "...");
87  
88          ReleaseDescriptor basedirAlignedReleaseDescriptor =
89                  ReleaseUtil.createBasedirAlignedReleaseDescriptor(releaseDescriptor, reactorProjects);
90  
91          ScmRepository repository;
92          ScmProvider provider;
93          try {
94              repository = scmRepositoryConfigurator.getConfiguredRepository(
95                      basedirAlignedReleaseDescriptor.getScmSourceUrl(),
96                      releaseDescriptor,
97                      releaseEnvironment.getSettings());
98  
99              repository.getProviderRepository().setPushChanges(releaseDescriptor.isPushChanges());
100 
101             repository.getProviderRepository().setWorkItem(releaseDescriptor.getWorkItem());
102 
103             provider = scmRepositoryConfigurator.getRepositoryProvider(repository);
104         } catch (ScmRepositoryException e) {
105             throw new ReleaseScmRepositoryException(e.getMessage(), e.getValidationMessages());
106         } catch (NoSuchScmProviderException e) {
107             throw new ReleaseExecutionException("Unable to configure SCM repository: " + e.getMessage(), e);
108         }
109 
110         TagScmResult result;
111         try {
112             // TODO: want includes/excludes?
113             ScmFileSet fileSet = new ScmFileSet(new File(basedirAlignedReleaseDescriptor.getWorkingDirectory()));
114             String tagName = releaseDescriptor.getScmReleaseLabel();
115             ScmTagParameters scmTagParameters =
116                     new ScmTagParameters(releaseDescriptor.getScmCommentPrefix() + "copy for tag " + tagName);
117             scmTagParameters.setRemoteTagging(releaseDescriptor.isRemoteTagging());
118             scmTagParameters.setSign(releaseDescriptor.isScmSignTags());
119             scmTagParameters.setScmRevision(releaseDescriptor.getScmReleasedPomRevision());
120             scmTagParameters.setPinExternals(releaseDescriptor.isPinExternals());
121             if (getLogger().isDebugEnabled()) {
122                 getLogger().debug("ScmTagPhase :: scmTagParameters remotingTag " + releaseDescriptor.isRemoteTagging());
123                 getLogger()
124                         .debug("ScmTagPhase :: scmTagParameters scmRevision "
125                                 + releaseDescriptor.getScmReleasedPomRevision());
126                 getLogger().debug("ScmTagPhase :: scmTagParameters pinExternals " + releaseDescriptor.isPinExternals());
127                 getLogger().debug("ScmTagPhase :: fileSet  " + fileSet);
128             }
129             result = provider.tag(repository, fileSet, tagName, scmTagParameters);
130         } catch (ScmException e) {
131             throw new ReleaseExecutionException("An error is occurred in the tag process: " + e.getMessage(), e);
132         }
133 
134         if (!result.isSuccess()) {
135             throw new ReleaseScmCommandException("Unable to tag SCM", result);
136         }
137 
138         relResult.setResultCode(ReleaseResult.SUCCESS);
139 
140         return relResult;
141     }
142 
143     @Override
144     public ReleaseResult simulate(
145             ReleaseDescriptor releaseDescriptor,
146             ReleaseEnvironment releaseEnvironment,
147             List<MavenProject> reactorProjects)
148             throws ReleaseExecutionException, ReleaseFailureException {
149         ReleaseResult result = new ReleaseResult();
150 
151         validateConfiguration(releaseDescriptor);
152 
153         ReleaseDescriptor basedirAlignedReleaseDescriptor =
154                 ReleaseUtil.createBasedirAlignedReleaseDescriptor(releaseDescriptor, reactorProjects);
155 
156         if (releaseDescriptor.isRemoteTagging()) {
157             logInfo(
158                     result,
159                     "Full run would tag working copy '" + basedirAlignedReleaseDescriptor.getWorkingDirectory() + "'");
160         } else {
161             logInfo(result, "Full run would tag remotely '" + basedirAlignedReleaseDescriptor.getScmSourceUrl() + "'");
162         }
163         logInfo(result, "  with label '" + releaseDescriptor.getScmReleaseLabel() + "'");
164         if (releaseDescriptor.isPinExternals()) {
165             logInfo(result, "  and pinned externals");
166         }
167 
168         result.setResultCode(ReleaseResult.SUCCESS);
169 
170         return result;
171     }
172 
173     private static void validateConfiguration(ReleaseDescriptor releaseDescriptor) throws ReleaseFailureException {
174         if (releaseDescriptor.getScmReleaseLabel() == null) {
175             throw new ReleaseFailureException("A release label is required for committing");
176         }
177     }
178 }