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 org.kohsuke.stapler.DataBoundConstructor; 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 TFVC"; } @Override public boolean isApplicable(Class<? extends AbstractProject> jobType) { return true; } } @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.getRootBuild().getProject().getScm(); if (!(scm instanceof TeamFoundationServerScm)) { listener.getLogger().println("Labels are only supported for projects using the 'Team Foundation Server' SCM"); return false; } FilePath workspace = build.getRootBuild().getWorkspace(); TeamFoundationServerScm tfsScm = (TeamFoundationServerScm) scm; boolean buildSuccess = Result.SUCCESS.equals(build.getResult()); String whenCreateLabel = getWhenToLabel(); if ("always".equals(whenCreateLabel) || ("success".equals(whenCreateLabel) && buildSuccess)) { final Launcher localLauncher = launcher != null ? launcher : new Launcher.LocalLauncher(listener); Server server = tfsScm.createServer(localLauncher, listener, build.getRootBuild()); Computer computer = Computer.currentComputer(); String normalizedLabelName = computeDynamicValue(build, getLabelName()); String tfsWorkspace = tfsScm.getWorkspaceName(build.getRootBuild(), computer); String tfsProjectPath = computeDynamicValue(build, tfsScm.getProjectPath()); try { logger.info(String.format("Create label '%s' on workspace '%s' with project path '%s' ", normalizedLabelName, tfsWorkspace, tfsProjectPath)); LabelCommand labelCommand = new LabelCommand(server, normalizedLabelName, tfsWorkspace, tfsProjectPath); server.execute(labelCommand.getCallable()); } 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; } }