Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from rodrigolopes/master
[FIXED JENKINS-3785] Created a Publisher to create a label on TFS.
- Loading branch information
Showing
6 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package hudson.plugins.tfs; | ||
|
||
import hudson.EnvVars; | ||
import hudson.Extension; | ||
import hudson.FilePath; | ||
import hudson.Launcher; | ||
import hudson.Util; | ||
import hudson.model.*; | ||
import hudson.plugins.tfs.commands.LabelCommand; | ||
import hudson.plugins.tfs.model.Server; | ||
import hudson.plugins.tfs.util.BuildVariableResolver; | ||
import hudson.scm.SCM; | ||
import hudson.tasks.BuildStepDescriptor; | ||
import hudson.tasks.BuildStepMonitor; | ||
import hudson.tasks.Notifier; | ||
import hudson.tasks.Publisher; | ||
import hudson.util.VariableResolver; | ||
import hudson.util.VariableResolver.Union; | ||
import net.sf.json.JSONObject; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
import org.kohsuke.stapler.StaplerRequest; | ||
|
||
import java.io.IOException; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* Used to create a label in TFS after a build is completed. | ||
* @author Rodrigo Lopes (rodrigolopes) | ||
*/ | ||
public class TFSLabeler extends Notifier { | ||
|
||
private String whenToLabel; | ||
private String labelName; | ||
|
||
private static final Logger logger = Logger.getLogger(TFSLabeler.class.getName()); | ||
|
||
@Extension | ||
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> { | ||
public DescriptorImpl() { | ||
super(TFSLabeler.class); | ||
} | ||
|
||
@Override | ||
public String getDisplayName() { | ||
return "Create a label in TFS"; | ||
} | ||
|
||
@Override | ||
public boolean isApplicable(Class<? extends AbstractProject> jobType) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public Publisher newInstance(StaplerRequest req, JSONObject formData) throws FormException { | ||
return new TFSLabeler( | ||
req.getParameter("tfsLabeler.whenToLabel"), | ||
req.getParameter("tfsLabeler.labelName") | ||
); | ||
} | ||
|
||
} | ||
|
||
@DataBoundConstructor | ||
public TFSLabeler(String whenToLabel, String labelName) { | ||
this.whenToLabel = whenToLabel; | ||
this.labelName = labelName; | ||
} | ||
|
||
@Override | ||
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { | ||
SCM scm = build.getProject().getScm(); | ||
if (!(scm instanceof TeamFoundationServerScm)) { | ||
listener.getLogger().println("Labels are only supported for projects using TFS SCM"); | ||
return false; | ||
} | ||
|
||
FilePath workspace = build.getWorkspace(); | ||
|
||
TeamFoundationServerScm tfsScm = (TeamFoundationServerScm) scm; | ||
|
||
boolean buildSucess = Result.SUCCESS.equals(build.getResult()); | ||
|
||
String whenCreateLabel = getWhenToLabel(); | ||
if ("always".equals(whenCreateLabel) || ("success".equals(whenCreateLabel) && buildSucess)) { | ||
|
||
final Launcher localLauncher = launcher != null ? launcher : new Launcher.LocalLauncher(listener); | ||
final TfTool tool = new TfTool(tfsScm.getDescriptor().getTfExecutable(), localLauncher, listener, workspace); | ||
Server server = new Server(tool, tfsScm.getServerUrl(build), tfsScm.getUserName(), tfsScm.getUserPassword()); | ||
|
||
Computer computer = Computer.currentComputer(); | ||
String normalizedLabelName = computeDynamicValue(build, getLabelName()); | ||
String tfsWorkspace = tfsScm.getWorkspaceName(build, computer); | ||
|
||
try { | ||
logger.info(String.format("Create label '%s' on workspace '%s'", normalizedLabelName, tfsWorkspace)); | ||
LabelCommand labelCommand = new LabelCommand(server, normalizedLabelName, tfsWorkspace, tfsScm.getLocalPath()); | ||
server.execute(labelCommand.getArguments()); | ||
} catch (Exception e) { | ||
return false; | ||
} finally { | ||
server.close(); | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Replace an expression in the form ${name} in the given String | ||
* by the value of the matching environment variable or build parameter.<Br/> | ||
*/ | ||
private String computeDynamicValue(AbstractBuild build, String parameterizedValue) | ||
throws IllegalStateException, InterruptedException, IOException { | ||
|
||
final EnvVars envVars = build.getEnvironment(TaskListener.NULL); | ||
final VariableResolver<String> environmentVariables = new VariableResolver<String>() { | ||
public String resolve(String name) { | ||
return envVars.get(name); | ||
} | ||
|
||
}; | ||
final BuildVariableResolver buildVariables = new BuildVariableResolver(build.getProject()); | ||
@SuppressWarnings("unchecked") | ||
final Union<String> bothVariables = new VariableResolver.Union<String>(buildVariables, environmentVariables); | ||
String value = Util.replaceMacro(parameterizedValue, bothVariables); | ||
|
||
logger.fine("oldValue = " + parameterizedValue + "; newValue = " + value); | ||
return value; | ||
} | ||
|
||
public BuildStepMonitor getRequiredMonitorService() { | ||
return BuildStepMonitor.STEP; | ||
} | ||
|
||
public String getWhenToLabel() { | ||
return whenToLabel; | ||
} | ||
|
||
public String getLabelName() { | ||
return labelName; | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
src/main/java/hudson/plugins/tfs/commands/LabelCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package hudson.plugins.tfs.commands; | ||
|
||
import hudson.plugins.tfs.util.MaskedArgumentListBuilder; | ||
|
||
/** | ||
* Command to create a label on TFS. | ||
* @author Rodrigo Lopes (rodrigolopes) | ||
*/ | ||
public class LabelCommand extends AbstractCommand { | ||
|
||
private String labelName; | ||
private String workspaceName; | ||
private String projectPath; | ||
|
||
public LabelCommand(ServerConfigurationProvider configurationProvider, String labelName, String workspaceName, String projectPath) { | ||
super(configurationProvider); | ||
this.labelName = labelName; | ||
this.workspaceName = workspaceName; | ||
this.projectPath = projectPath; | ||
} | ||
|
||
public MaskedArgumentListBuilder getArguments() { | ||
MaskedArgumentListBuilder arguments = new MaskedArgumentListBuilder(); | ||
arguments.add("label"); | ||
arguments.add(labelName); | ||
arguments.add(projectPath); | ||
arguments.add(String.format("-version:W%s", workspaceName)); | ||
arguments.add(String.format("-comment:%s", getLabelComment())); | ||
arguments.add("-noprompt"); | ||
arguments.add("-recursive"); | ||
addServerArgument(arguments); | ||
addLoginArgument(arguments); | ||
return arguments; | ||
} | ||
|
||
private String getLabelComment() { | ||
// TODO 1. Solve issue with quotes and spaces | ||
// TODO 2. Include build information in the comment. | ||
return "Automatically_applied_by_Jenkins_TFS_plugin"; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/resources/hudson/plugins/tfs/TFSLabeler/config.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> | ||
<f:entry title="Label" help="/plugin/tfs/labelname.html"> | ||
<f:textbox name="tfsLabeler.labelName" value="${instance.labelName}" /> | ||
</f:entry> | ||
<f:entry title="Always"> | ||
<f:radio name="tfsLabeler.whenToLabel" value="always" checked="${instance.whenToLabel=='always'}"/> | ||
</f:entry> | ||
<f:entry title="If the build is successful"> | ||
<f:radio name="tfsLabeler.whenToLabel" value="success" checked="${instance.whenToLabel=='success'}"/> | ||
</f:entry> | ||
</j:jelly> |
3 changes: 3 additions & 0 deletions
3
src/main/resources/hudson/plugins/tfs/TFSLabeler/global.jelly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> | ||
|
||
</j:jelly> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<div> | ||
<p> | ||
The name of the label to be created.<br> | ||
It supports the usage of environment variables for example ${BUILD_NUMBER}, ${JOB_NAME} and ${BUILD_TAG}. | ||
</p> | ||
</div> |
24 changes: 24 additions & 0 deletions
24
src/test/java/hudson/plugins/tfs/commands/LabelCommandTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package hudson.plugins.tfs.commands; | ||
|
||
import hudson.plugins.tfs.util.MaskedArgumentListBuilder; | ||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotNull; | ||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.when; | ||
|
||
public class LabelCommandTest { | ||
|
||
@Test | ||
public void assertArguments() { | ||
ServerConfigurationProvider config = mock(ServerConfigurationProvider.class); | ||
when(config.getUrl()).thenReturn("https://tfs02.codeplex.com"); | ||
when(config.getUserName()).thenReturn("snd\\user_cp"); | ||
when(config.getUserPassword()).thenReturn("password"); | ||
|
||
MaskedArgumentListBuilder arguments = new LabelCommand(config, "int_build.10", "Jenkins-JOB-MASTER", ".").getArguments(); | ||
assertNotNull("Arguments were null", arguments); | ||
assertEquals("label int_build.10 . -version:WJenkins-JOB-MASTER -comment:Automatically_applied_by_Jenkins_TFS_plugin -noprompt -recursive -server:https://tfs02.codeplex.com -login:snd\\user_cp,password", arguments.toStringWithQuote()); | ||
} | ||
} |