package org.jenkinsci.plugins.p4.tagging; import com.perforce.p4java.impl.generic.core.Label; import hudson.EnvVars; import hudson.FilePath; import hudson.model.Run; import hudson.model.TaskListener; import hudson.scm.AbstractScmTagAction; import hudson.util.LogTaskListener; import org.jenkinsci.plugins.p4.PerforceScm; import org.jenkinsci.plugins.p4.changes.P4ChangeRef; import org.jenkinsci.plugins.p4.changes.P4LabelRef; import org.jenkinsci.plugins.p4.changes.P4Ref; import org.jenkinsci.plugins.p4.changes.P4Revision; import org.jenkinsci.plugins.p4.client.ClientHelper; import org.jenkinsci.plugins.p4.client.ConnectionHelper; import org.jenkinsci.plugins.p4.credentials.P4BaseCredentials; import org.jenkinsci.plugins.p4.review.P4Review; import org.jenkinsci.plugins.p4.review.ReviewProp; import org.jenkinsci.plugins.p4.tasks.CheckoutStatus; import org.jenkinsci.plugins.p4.tasks.TaggingTask; import org.jenkinsci.plugins.p4.workspace.Expand; import org.jenkinsci.plugins.p4.workspace.Workspace; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import javax.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; public class TagAction extends AbstractScmTagAction { private static Logger logger = Logger.getLogger(TagAction.class.getName()); private String tag; private List<String> tags = new ArrayList<String>(); private List<P4Ref> refChanges; private P4Revision buildChange; private P4Review review; private File changelog; private final String credential; private final String p4port; private final String p4user; private final String p4ticket; // Set when workspace is defined private Workspace workspace; private String client; private String syncID; private String charset; public TagAction(Run<?, ?> run, String credential) throws IOException, InterruptedException { super(run); P4BaseCredentials auth = ConnectionHelper.findCredential(credential, run); this.credential = credential; this.p4port = auth.getP4port(); this.p4user = auth.getUsername(); ConnectionHelper p4 = new ConnectionHelper(auth, null); this.p4ticket = p4.getTicket(); p4.disconnect(); } public String getIconFileName() { if (!getACL().hasPermission(PerforceScm.TAG)) return null; return "/plugin/p4/icons/label.gif"; } public String getDisplayName() { if (isTagged()) return "Perforce Label"; else return "Label This Build"; } @Override public boolean isTagged() { return tags != null && !tags.isEmpty(); } public void doSubmit(StaplerRequest req, StaplerResponse rsp) throws Exception, ServletException { getACL().checkPermission(PerforceScm.TAG); String description = req.getParameter("desc"); String name = req.getParameter("name"); TaskListener listener = new LogTaskListener(logger, Level.INFO); labelBuild(listener, name, description, null); rsp.sendRedirect("."); } public void labelBuild(TaskListener listener, String name, String description, final FilePath nodeWorkspace) throws Exception { // Expand label name and description EnvVars env = getRun().getEnvironment(listener); Expand expand = new Expand(env); name = expand.format(name, false); description = expand.format(description, false); TaggingTask task = new TaggingTask(name, description); task.setListener(listener); task.setCredential(credential, getRun().getParent()); task.setWorkspace(workspace); task.setBuildChange(getRefChange()); FilePath buildWorkspace = nodeWorkspace; if (nodeWorkspace == null) { buildWorkspace = build.getWorkspace(); } if (buildWorkspace == null) { logger.warning("FilePath is null!"); return; } // Invoke the Label Task Boolean ok = buildWorkspace.act(task); // save label if (ok && !tags.contains(name)) { tags.add(name); getRun().save(); } } public void setRefChanges(List<P4Ref> refChanges) { this.refChanges = refChanges; } public List<P4Ref> getRefChanges() { // parse Legacy XML data from P4Revision to P4Ref if (refChanges == null || refChanges.isEmpty()) { refChanges = new ArrayList<>(); if (buildChange != null) { if (buildChange.isLabel()) { P4LabelRef label = new P4LabelRef(buildChange.toString()); refChanges.add(label); } else { P4ChangeRef change = new P4ChangeRef(buildChange.getChange()); refChanges.add(change); } } } return refChanges; } public P4Ref getRefChange() { for (P4Ref change : refChanges) { if (change instanceof P4ChangeRef) { return change; } if (change instanceof P4LabelRef) { return change; } } return null; } @Deprecated public void setBuildChange(P4Revision buildChange) { this.buildChange = buildChange; } @Deprecated public P4Revision getBuildChange() { return buildChange; } public String getCredential() { return credential; } public Workspace getWorkspace() { return workspace; } public void setWorkspace(Workspace workspace) { this.workspace = workspace; this.client = workspace.getFullName(); this.syncID = workspace.getSyncID(); this.charset = workspace.getCharset(); Expand expand = workspace.getExpand(); String id = expand.get(ReviewProp.REVIEW.toString()); if (id != null && !id.isEmpty()) { String type = expand.get(ReviewProp.STATUS.toString()); review = new P4Review(id, CheckoutStatus.parse(type)); } } public String getPort() { return p4port; } public String getClient() { return client; } public String getSyncID() { return syncID; } public String getUser() { return p4user; } public String getTicket() { return p4ticket; } public String getTag() { return tag; } public List<String> getTags() { return tags; } /** * Method used by Jelly code to show Label information (do not remove) * * @param tag Label name * @return Perforce Label object */ public Label getLabel(String tag) { ClientHelper p4 = new ClientHelper(ClientHelper.findCredential(credential, getRun()), null, client, charset); try { Label label = p4.getLabel(tag); return label; } catch (Exception e) { logger.warning("Unable to get label from tag: " + tag); } finally { p4.disconnect(); } return null; } /** * Change reporting... * * @param run The current build * @param listener Listener for logging * @param syncID Changelist Sync ID * @return Perforce change */ public static List<P4Ref> getLastChange(Run<?, ?> run, TaskListener listener, String syncID) { List<P4Ref> changes = new ArrayList<>(); List<TagAction> actions; // Check for actions until the build is complete // Workaround for JENKINS-40722 do { actions = lastActions(run); } while(actions == null && run != null && run.isBuilding()); if (actions == null || syncID == null || syncID.isEmpty()) { listener.getLogger().println("No previous build found..."); return changes; } // look for action matching view // (clone ID now filtered from the syncID to addresses JENKINS-43877) for (TagAction action : actions) { if (syncID.equals(action.getSyncID())) { changes = action.getRefChanges(); for (P4Ref change : changes) { listener.getLogger().println("Found last change " + change.toString() + " on syncID " + syncID); } } } return changes; } /** * Find the last action; use this for environment variable as the last action has the latest values. * * @param run The current build * @return Action */ public static TagAction getLastAction(Run<?, ?> run) { List<TagAction> actions = lastActions(run); if (actions == null) { return null; } // #Review 21165 TagAction tagAction = run.getAction(TagAction.class); for (TagAction t : run.getActions(TagAction.class)) { tagAction = (t != null) ? t : tagAction; } return tagAction; } private static List<TagAction> lastActions(Run<?, ?> run) { // get last run, if none then build now. if (run == null) { return null; } // get last action, if no previous action then build now. List<TagAction> actions = run.getActions(TagAction.class); if (actions.isEmpty()) { return null; } return actions; } public P4Review getReview() { return review; } public void setChangelog(File changelog) { this.changelog = changelog; } public File getChangelog() { return changelog; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#48 | 28508 | Paul Allen |
Cache P4TICKET in session. Session cache now keyed on Credential ID and stores: User, Expiry time and Ticket. |
||
#47 | 26617 | Paul Allen |
Prevent `ssl:` string from appearing in the P4PORT Jelly field. Jelly uses getP4port() method for binding the fields; adding the ssl prefix was causing issues. JENKINS-63246 |
||
#46 | 26352 | Paul Allen | [SECURITY-1765] | ||
#45 | 26112 | Paul Allen |
Merge pull request #110 from p4charu/jenkinsci-master Fix for JENKINS-58639. If last build is not completely built look for last build… |
||
#44 | 25115 | Paul Allen |
Merge pull request #91 from p4charu/jenkinsci-master Fixed JENKINS-39107 and JENKINS-55826 |
||
#43 | 25056 | Paul Allen |
Check for duplicate syncIDs and test polling after failed build. JENKINS-55075 |
||
#42 | 24805 | Paul Allen |
Tidy up connection methods. Cache TagAction calls to getTicket() when adding P4_TICKET to the Environment. JENKINS-54222 |
||
#41 | 24529 | Paul Allen |
Swarm Commit Event support, refactoring and test. JENKINS-52605 (Fix doc in 'Includes' help bubble for MultiBranch) JENKINS-52066 (Improve Swarm Commit and Branch Event support) |
||
#40 | 24501 | Paul Allen | Refactor to use P4SCMXxx naming convention. | ||
#39 | 24487 | Paul Allen | Perforce Connection Refactor. | ||
#38 | 23218 | Paul Allen |
Merge pull request #63 from ADTRAN/JENKINS-34052 [FIX JENKINS-34052] Poll for concurrent jobs |
||
#37 | 23018 | Paul Allen |
Support null changelogFile if checkout sets changelog:false JENKINS-46352 |
||
#36 | 22987 | Paul Allen |
Clean up changelogFilename reporting for HUDSON_CHANGELOG_FILE. JENKINS-37442 |
||
#35 | 22926 | Paul Allen |
Expose P4_REVIEW and P4_REVIEW_STATUS. Extended test coverage and removed duplicate code for building the environment. |
||
#34 | 22821 | Paul Allen |
Merge pull request #53 from jenkinsci/TagAction-order Get Last TagAction. JENKINS-37618 JENKINS-45613 |
||
#33 | 22702 | Paul Allen |
Fix polling if Jenkinsfile and project workspace names are similar. Removes an old patch for JENKINS-43877 as concurrent build IDs are now filtered out of the syncID. |
||
#32 | 22701 | Paul Allen |
SyncID to ignore clone ID in workspace name. Tracking build history during concurrent builds. |
||
#31 | 22128 | Paul Allen |
Helix Graph support for Jenkins. JENKINS-40354 |
||
#30 | 22084 | Paul Allen |
Merge pull request #43 from tangkun75 JENKINS-43877: P4 plugin fails during polling for freestyle job |
||
#29 | 22038 | Paul Allen |
Merge pull request #42 from tangkun75/JENKINS-43770_p4sync_in_parallel_causes_invalid_SCM_triggering [JENKINS-43770] p4sync in parallel causes invalid SCM triggering |
||
#28 | 21794 | Paul Allen |
Merge pull request #39 from Dohbedoh/JENKINS-34825 Jenkins 34825 |
||
#27 | 21659 | Paul Allen |
Cleanup TagAction. Only call get method on TagAction once per entry. Fetch values at construction or workspace creation, not on demand. |
||
#26 | 21463 | Paul Allen | SyncID code doc fix. | ||
#25 | 21372 | Paul Allen |
Support custom SyncID. Exclude BUILD_NUMBER from SyncID. Pushed logging to higher level, so it is not reporting TagActions when building the Environment. JENKINS-40460 |
||
#24 | 21324 | Paul Allen |
Create syncID to track syncs when polling. Original design used the client name to track the sync from previous builds, however as polling is on the master if NODE_NAME is used it breaks with slaves. JENKINS-40356 |
||
#23 | 21228 | Paul Allen |
Prevent NPE if client is not found. If the workspace client name is changed in the Jenkins file, then getLastChange() will not find a previous actions and should return null. JENKINS-40258 |
||
#22 | 21215 | Paul Allen |
Polling fix for Multi client support in Pipeline. Jenkins polls for each SCM checkout, so must poll each workplace and therefore need to lookup last build information for each sync. Polling now uses same lookup as Change Summary. Added extra test cases multi sync poll and poll again. JENKINS-38401 JENKINS-37462 JENKINS-39652 |
||
#21 | 21207 | Paul Allen |
Multi client support in Pipeline. If two or more `p4sync` operations are called in one Pipeline script, they MUST have different client names. During a build, multiple entries are added to the build history; on subsequent builds they are used in the three following situations: - Polling: largest change number across all the checkouts is used. - Change Summary: last change with the same client name is used. - Environment: last change recorded (regardless of client). Added two test cases to cover basic multi sync build/poll situations. JENKINS-38401 JENKINS-37462 JENKINS-39652 |
||
#20 | 20179 | Paul Allen | Javadoc fixes for java 8 builds. | ||
#19 | 19593 | Paul Allen | More minor fixes to satisfy FindBugs Analysis. | ||
#18 | 19581 | Paul Allen | Minor fixes to satisfy FindBugs Analysis. | ||
#17 | 16815 | Paul Allen |
Enable early binding for CHARSET Expose CHARSET to AbstractTask to allow the charset to be set at the point the client workspace is set as current in ClientHelper. |
||
#16 | 15750 | Paul Allen |
Use a P4Revision object and not int/String as Object. In sure that there is no ambiguity with the revision specifier. Should fix change summary when using the Workflow plugin. JENKINS-30425 |
||
#15 | 15663 | Paul Allen |
Added P4_USER and P4_TICKET environment variables. Added Perforce environment variables to the buildEnv documentation. JENKINS-24591 |
||
#14 | 15379 | Paul Allen |
Ground-work for Workflow-DSL (Split out Sven’s DSL changes to the core) @sven_erik_knop |
||
#13 | 15347 | Paul Allen | Moved the Expand setup into labelBuild() in order to pass listener (and not null) to getEnvironment(). | ||
#12 | 13701 | Paul Allen |
Move Labelling into a Task. Logging improvements. |
||
#11 | 13681 | Paul Allen |
Abstracted Expand class from Workspace. Added support for Label variable expansion in the name and description. |
||
#10 | 12931 | Paul Allen |
#review-12907 @mjoubert Added P4PORT to env for command line calls. |
||
#9 | 11626 | Paul Allen |
Workflow support. - Updated the plugin to the latest LTS Jenkins release 1.580.3. - Updated P4Java to 2014.1 Tested with simple ‘static’ workspace, there may be limitations with ‘manual’ workspace. Plan to add DSL support by extending the SCMStep class. #review-11537 JENKINS-24206 |
||
#8 | 11084 | Paul Allen |
(mjoubert) Fully populate changelog.xml Replaces sparse change log which only recorded the change number. The change is now recorded in full allowing faster page load times. The number of files listed in the change is limited to 50; to view larger changes please add a repo browser such as Swarm, Fisheye, P4Web, etc… |
||
#7 | 9986 | Paul Allen | Re-added getLabel method used by Jelly. | ||
#6 | 9984 | Paul Allen |
Set P4_CHANGELIST to change for Automatic Labels. P4_CHANGELIST is set to a change number or label if defined in Populate as pinned or a build parameter. |
||
#5 | 9851 | Paul Allen | Merging using p4-jenkins | ||
#4 | 9819 | Paul Allen | Merging using p4-jenkins | ||
#3 | 9769 | Paul Allen | Copying using p4-jenkins | ||
#2 | 9696 | Paul Allen | Updated install notes and removed old ref to p4-client | ||
#1 | 9690 | Paul Allen |
[Branching using p4-jenkins] Release 1.0.1 |
||
//guest/paul_allen/dev/p4-jenkins/p4-client/src/main/java/org/jenkinsci/plugins/p4/tagging/TagAction.java | |||||
#1 | 9672 | Paul Allen | Refactor name from 'p4_client' to 'p4'. | ||
//guest/paul_allen/dev/p4-jenkins/p4-client/src/main/java/org/jenkinsci/plugins/p4_client/tagging/TagAction.java | |||||
#3 | 9126 | Paul Allen | Added Perforce label icon to TagAction. | ||
#2 | 9077 | Paul Allen |
Added support for automatic Labels as a post-build Action. Ported original code for promoted builds, but not tested. |
||
#1 | 9069 | Paul Allen |
Adding initial support for tagging Jenkins builds as Perforce Automatic Labels. Only implements TagAction (manual labels); TagNotifier and test cases TODO. |