package org.jenkinsci.plugins.p4.client; import com.cloudbees.plugins.credentials.CredentialsMatchers; import com.cloudbees.plugins.credentials.CredentialsProvider; import com.cloudbees.plugins.credentials.domains.DomainRequirement; import com.perforce.p4java.admin.IProperty; import com.perforce.p4java.client.IClient; import com.perforce.p4java.core.IChangelistSummary; import com.perforce.p4java.core.IDepot; import com.perforce.p4java.core.IFix; import com.perforce.p4java.core.ILabel; import com.perforce.p4java.core.IRepo; import com.perforce.p4java.core.IStreamSummary; import com.perforce.p4java.core.IUser; import com.perforce.p4java.core.file.FileSpecBuilder; import com.perforce.p4java.core.file.IFileSpec; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.exception.RequestException; import com.perforce.p4java.graph.ICommit; import com.perforce.p4java.impl.generic.core.Label; import com.perforce.p4java.impl.generic.core.file.FileSpec; import com.perforce.p4java.impl.mapbased.server.Server; import com.perforce.p4java.impl.mapbased.server.cmd.ResultMapParser; import com.perforce.p4java.option.server.CounterOptions; import com.perforce.p4java.option.server.DeleteClientOptions; import com.perforce.p4java.option.server.GetChangelistsOptions; import com.perforce.p4java.option.server.GetDepotFilesOptions; import com.perforce.p4java.option.server.GetDirectoriesOptions; import com.perforce.p4java.option.server.GetFixesOptions; import com.perforce.p4java.option.server.GetPropertyOptions; import com.perforce.p4java.option.server.GetStreamsOptions; import com.perforce.p4java.option.server.GraphCommitLogOptions; import com.perforce.p4java.option.server.ReposOptions; import com.perforce.p4java.server.CmdSpec; import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4java.server.callback.ICommandCallback; import com.perforce.p4java.server.callback.IProgressCallback; import hudson.model.Descriptor; import hudson.model.Item; import hudson.model.ItemGroup; import hudson.model.Run; import hudson.model.TaskListener; import hudson.security.ACL; import hudson.util.LogTaskListener; import jenkins.model.Jenkins; import org.acegisecurity.Authentication; import org.jenkinsci.plugins.p4.PerforceScm; import org.jenkinsci.plugins.p4.changes.P4GraphRef; import org.jenkinsci.plugins.p4.changes.P4LabelRef; import org.jenkinsci.plugins.p4.changes.P4Ref; import org.jenkinsci.plugins.p4.console.P4Logging; import org.jenkinsci.plugins.p4.console.P4Progress; import org.jenkinsci.plugins.p4.credentials.P4BaseCredentials; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import static com.perforce.p4java.common.base.ObjectUtils.nonNull; public class ConnectionHelper implements AutoCloseable { private static Logger logger = Logger.getLogger(ConnectionHelper.class.getName()); private boolean abort = false; protected final ConnectionConfig connectionConfig; protected final AuthorisationConfig authorisationConfig; protected IOptionsServer connection; protected final TaskListener listener; protected final P4BaseCredentials p4credential; protected final Validate validate; @Deprecated public ConnectionHelper(String credentialID, TaskListener listener) { this.listener = listener; P4BaseCredentials credential = findCredential(credentialID); this.p4credential = credential; this.connectionConfig = new ConnectionConfig(credential); this.authorisationConfig = new AuthorisationConfig(credential); connectionRetry(); validate = new Validate(listener); } public ConnectionHelper(ItemGroup context, String credentialID, TaskListener listener) { this(findCredential(credentialID, context), listener); } public ConnectionHelper(Item job, String credentialID, TaskListener listener) { this(findCredential(credentialID, job), listener); } public ConnectionHelper(Run run, String credentialID, TaskListener listener) { this(findCredential(credentialID, run), listener); } public ConnectionHelper(P4BaseCredentials credential, TaskListener listener) { this.listener = listener; this.p4credential = credential; this.connectionConfig = new ConnectionConfig(credential); this.authorisationConfig = new AuthorisationConfig(credential); connectionRetry(); validate = new Validate(listener); } public ConnectionHelper(P4BaseCredentials credential) { this.listener = new LogTaskListener(logger, Level.INFO); this.p4credential = credential; this.connectionConfig = new ConnectionConfig(credential); this.authorisationConfig = new AuthorisationConfig(credential); connectionRetry(); validate = new Validate(listener); } public IOptionsServer getConnection() { return connection; } /** * Convenience wrapper to connect and report errors */ private boolean connect() { // Connect to the Perforce server try { this.connection = ConnectionFactory.getConnection(connectionConfig); logger.fine("P4: opened connection OK"); } catch (Exception e) { String err = "P4: Unable to connect: " + e; logger.severe(err); log(err); return false; } // Login to Perforce try { login(); } catch (Exception e) { String err = "P4: Unable to login: " + e; logger.severe(err); log(err); return false; } // Register progress callback IProgressCallback progress = new P4Progress(listener, this); this.connection.registerProgressCallback(progress); // Register logging callback ICommandCallback logging = new P4Logging(listener); this.connection.registerCallback(logging); // Get Environment String ignore = ".p4ignore"; String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) { ignore = "p4ignore.txt"; } // Set p4ignore file Server server = (Server) this.connection; server.setIgnoreFileName(ignore); return true; } /** * Retry Connection with back off for each failed attempt. */ private void connectionRetry() { int trys = 0; int attempt = getRetry(); while (trys <= attempt) { if (connect()) { return; } trys++; String err = "P4: Connection retry: " + trys; logger.severe(err); log(err); // back off n^2 seconds, before retry try { TimeUnit.SECONDS.sleep(trys ^ 2); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } String err = "P4: Connection retry giving up..."; logger.severe(err); log(err); } public int getRetry() { return p4credential.getRetry(); } public String getUser() { return p4credential.getUsername(); } public String getPort() { return p4credential.getP4port(); } public String getTrust() throws Exception { return connection.getTrust(); } public String getTicket() { try { if (login()) { return connection.getAuthTicket(); } } catch (Exception e) { } return null; } public boolean isConnected() { if (connection == null) { return false; } return connection.isConnected(); } public boolean isUnicode() { try { return connection.getServerInfo().isUnicodeEnabled(); } catch (Exception e) { return false; } } /** * Checks the Perforce server version number and returns true if greater * than or equal to the min version. The value of min must be of the form * 20092 or 20073 (corresponding to 2009.2 and 2007.3 respectively). * * @param min Minimum server version * @return true if version supported. */ public boolean checkVersion(int min) { int ver = connection.getServerVersionNumber(); return (ver >= min); } public boolean login() throws Exception { connection.setUserName(authorisationConfig.getUsername()); // CHARSET is not defined (only for client access) if (connection.getServerInfo().isUnicodeEnabled()) { connection.setCharsetName("utf8"); } // Exit early if logged in if (isLogin()) { return true; } switch (authorisationConfig.getType()) { case PASSWORD: String pass = authorisationConfig.getPassword(); connection.login(pass); break; case TICKET: String ticket = authorisationConfig.getTicketValue(); connection.setAuthTicket(ticket); break; case TICKETPATH: String path = authorisationConfig.getTicketPath(); if (path == null || path.isEmpty()) { path = connection.getTicketsFilePath(); } connection.setTicketsFilePath(path); break; default: throw new Exception("Unknown Authorisation type: " + authorisationConfig.getType()); } // return login status... if (isLogin()) { return true; } else { String status = connection.getLoginStatus(); logger.info("P4: login failed '" + status + "'"); return false; } } public void logout() throws Exception { if (isLogin()) { connection.logout(); } } private boolean isLogin() throws Exception { List<Map<String, Object>> resultMaps = connection.execMapCmdList(CmdSpec.LOGIN, new String[]{"-s"}, null); if (nonNull(resultMaps) && !resultMaps.isEmpty()) { for (Map<String, Object> map : resultMaps) { String status = ResultMapParser.getInfoStr(map); if (status == null) { continue; } if (status.contains("not necessary")) { return true; } if (status.contains("ticket expires in")) { return true; } // If there is a broker or something else that swallows the message if (status.isEmpty()) { return true; } } } return false; } /** * Gets a list of Dirs given a path (multi-branch?) * * @param paths list of paths to look for dirs (only takes * as wildcard) * @return list of dirs or empty list * @throws Exception push up stack */ public List<IFileSpec> getDirs(List<String> paths) throws Exception { paths = cleanDirPaths(paths); List<IFileSpec> spec = FileSpecBuilder.makeFileSpecList(paths); GetDirectoriesOptions opts = new GetDirectoriesOptions(); List<IFileSpec> dirs = connection.getDirectories(spec, opts); if (validate.check(dirs, "")) { return dirs; } return new ArrayList<IFileSpec>(); } private List<String> cleanDirPaths(List<String> paths) throws Exception { if (paths.contains("//...")) { return getDepotsForDirs(); } ListIterator<String> list = paths.listIterator(); while (list.hasNext()) { String i = list.next(); if (i.endsWith("/...")) { i = i.substring(0, i.length() - "/...".length()); } if (!i.endsWith("/*")) { list.set(i + "/*"); } } return paths; } private List<String> getDepotsForDirs() throws Exception { List<String> paths = new ArrayList<>(); List<IDepot> depots = connection.getDepots(); for (IDepot depot : depots) { String name = depot.getName(); paths.add("//" + name + "/*"); } return paths; } /** * Gets a list of Dirs given a path (multi-stream?) * * @param paths list of path to look for streams (takes ... or * as wildcard) * @return list of streams or empty list * @throws Exception push up stack */ public List<IStreamSummary> getStreams(List<String> paths) throws Exception { ListIterator<String> list = paths.listIterator(); while (list.hasNext()) { String i = list.next(); if (!i.endsWith("/...") && !i.endsWith("/*")) { list.set(i + "/*"); } } GetStreamsOptions opts = new GetStreamsOptions(); List<IStreamSummary> streams = connection.getStreams(paths, opts); return streams; } public IChangelistSummary getChangeSummary(long id) throws P4JavaException { List<IFileSpec> spec = FileSpecBuilder.makeFileSpecList("@" + id); GetChangelistsOptions cngOpts = new GetChangelistsOptions(); cngOpts.setLongDesc(true); cngOpts.setMaxMostRecent(1); List<IChangelistSummary> summary = connection.getChangelists(spec, cngOpts); if (summary.isEmpty()) { return null; } return summary.get(0); } public List<IFix> getJobs(int id) throws P4JavaException { GetFixesOptions opts = new GetFixesOptions(); opts.setChangelistId(id); List<IFix> fixes = connection.getFixes(null, opts); return fixes; } /** * Test if given name is a counter * * @param name Couner name * @return true if counter * @throws Exception push up stack */ public boolean isCounter(String name) throws Exception { if (name.equals("now")) { return false; } try { CounterOptions opts = new CounterOptions(); String counter = connection.getCounter(name, opts); return (!"0".equals(counter)); } catch (RequestException e) { return false; } } /** * Get Perforce Counter * * @param id Counter name * @return Perforce Counter * @throws Exception push up stack */ public String getCounter(String id) throws Exception { CounterOptions opts = new CounterOptions(); String counter = connection.getCounter(id, opts); return counter; } /** * Test if given name is a label * * @param name Label name * @return true if label. * @throws Exception push up stack */ public boolean isLabel(String name) throws Exception { if (name.equals("now")) { return false; } try { ILabel label = connection.getLabel(name); return (label != null); } catch (RequestException e) { return false; } } /** * Test if given name is a client * * @param name Client name * @return true if client exists. * @throws Exception push up stack */ public boolean isClient(String name) throws Exception { try { if (name == null) { return false; } IClient client = connection.getClient(name); return (client != null); } catch (RequestException e) { return false; } } /** * Delete a client workspace * * @param name Client name * @throws Exception push up stack */ public void deleteClient(String name) throws Exception { DeleteClientOptions opts = new DeleteClientOptions(); connection.deleteClient(name, opts); } public String getEmail(String userName) throws Exception { IUser user = connection.getUser(userName); if (user != null) { String email = user.getEmail(); return email; } return ""; } /** * Get Perforce Label * * @param id Label name * @return Perforce Label * @throws Exception push up stack */ public Label getLabel(String id) throws Exception { return (Label) connection.getLabel(id); } /** * Create/Update a Perforce Label * * @param label Label name * @throws Exception push up stack */ public void setLabel(Label label) throws Exception { // connection.createLabel(label); String user = connection.getUserName(); label.setOwnerName(user); connection.updateLabel(label); } /** * Find all files within a label or change. (Max results limited by limit) * * @param id Label name or change number (as string) * @param limit Max results (-m value) * @return List of file specs * @throws Exception push up stack */ public List<IFileSpec> getLabelFiles(String id, int limit) throws Exception { String path = "//...@" + id; List<IFileSpec> spec = FileSpecBuilder.makeFileSpecList(path); GetDepotFilesOptions opts = new GetDepotFilesOptions(); opts.setMaxResults(limit); List<IFileSpec> tagged = connection.getDepotFiles(spec, opts); return tagged; } // Use a describe for files to avoid MAXSCANROW limits. // (backed-out part of change 16390) public List<IFileSpec> getChangeFiles(int id, int limit) throws Exception { List<IFileSpec> files = connection.getChangelistFiles(id, limit); return files; } /** * Find all files within a shelf. * * @param id Shelf ID * @return List of file specs * @throws Exception push up stack */ public List<IFileSpec> getShelvedFiles(int id) throws Exception { String cmd = CmdSpec.DESCRIBE.name(); String[] args = new String[]{"-s", "-S", "" + id}; List<Map<String, Object>> resultMaps; resultMaps = connection.execMapCmdList(cmd, args, null); List<IFileSpec> list = new ArrayList<IFileSpec>(); if (resultMaps != null) { if ((resultMaps.size() > 0) && (resultMaps.get(0) != null)) { Map<String, Object> map = resultMaps.get(0); if (map.containsKey("shelved")) { for (int i = 0; map.get("rev" + i) != null; i++) { FileSpec fSpec = new FileSpec(map, connection, i); fSpec.setChangelistId(id); list.add(fSpec); } } } } return list; } public String getSwarm() throws P4JavaException { GetPropertyOptions propOpts = new GetPropertyOptions(); String key = "P4.Swarm.URL"; propOpts.setName(key); List<IProperty> values = connection.getProperty(propOpts); for (IProperty prop : values) { if (key.equals(prop.getName())) { return prop.getValue(); } } return null; } public ICommit getGraphCommit(String sha, String repo) throws P4JavaException { return connection.getCommitObject(sha, repo); } public List<IFileSpec> getCommitFiles(String repo, String sha) throws P4JavaException { return connection.getCommitFiles(repo, sha); } /** * Get the last SHA commited to the specified repo. * * @param repo a graph repo * @return a P4Ref of the last commit */ public P4Ref getGraphHead(String repo) { GraphCommitLogOptions opts = new GraphCommitLogOptions(); opts.setMaxResults(1); opts.setRepo(repo); List<ICommit> list = null; try { list = connection.getGraphCommitLogList(opts); } catch (P4JavaException e) { log("P4: no commits under " + repo + " using HEAD."); return new P4LabelRef("HEAD"); } if (!list.isEmpty() && list.get(0) != null) { ICommit commit = list.get(0); return new P4GraphRef(repo, commit); } else { log("P4: commit log empty for " + repo + " using HEAD."); } return new P4LabelRef("HEAD"); } /** * List graph Commits with in range of SHAs * * @param fromRefs Array of potential SHAs (include other repos) * @param to The last SHA to list commits * @return a List or Commits * @throws Exception push up stack */ public List<P4Ref> listCommits(List<P4Ref> fromRefs, P4Ref to) throws Exception { List<P4Ref> list = new ArrayList<P4Ref>(); if (!(to instanceof P4GraphRef)) { return list; } P4GraphRef toGraph = (P4GraphRef) to; for (P4Ref from : fromRefs) { if (!(from instanceof P4GraphRef)) { continue; } P4GraphRef fromGraph = (P4GraphRef) from; // skip mismatched repos if (!fromGraph.getRepo().equals(toGraph.getRepo())) { continue; } // skip matching SHAs if (fromGraph.getSha().equals(toGraph.getSha())) { continue; } GraphCommitLogOptions opts = new GraphCommitLogOptions(); String repo = fromGraph.getRepo(); opts.setRepo(repo); String range = fromGraph.getSha() + ".." + toGraph.getSha(); opts.setCommitValue(range); opts.setMaxResults(getMaxChangeLimit()); List<ICommit> logList = connection.getGraphCommitLogList(opts); for (ICommit log : logList) { P4Ref ref = new P4GraphRef(repo, log); list.add(ref); } } return list; } /** * List all Graph Repos * * @return A list of Graph Repos * @throws Exception push up stack */ public List<IRepo> listAllRepos() throws Exception { List<IRepo> repos = connection.getRepos(); return repos; } /** * List of Graph Repos based on a path * * @param path Path filter * @return A list of Graph Repos * @throws Exception push up stack */ public List<IRepo> listRepos(String path) throws Exception { ReposOptions opts = new ReposOptions(); opts.setNameFilter(path); List<IRepo> repos = connection.getRepos(opts); return repos; } /** * Disconnect from the Perforce Server. */ public void disconnect() { try { connection.disconnect(); logger.fine("P4: closed connection OK"); } catch (Exception e) { String err = "P4: Unable to close Perforce connection."; logger.severe(err); log(err); } } /** * Finds a Perforce Credential based on the String id. * * @param id Credential ID * @return a P4StandardCredentials credential or null if not found. * @deprecated Use {@link #findCredential(String, ItemGroup)} or {@link #findCredential(String, Item)} */ @Deprecated public static P4BaseCredentials findCredential(String id) { Class<P4BaseCredentials> type = P4BaseCredentials.class; Jenkins scope = Jenkins.getInstance(); Authentication acl = ACL.SYSTEM; DomainRequirement domain = new DomainRequirement(); List<P4BaseCredentials> list; list = CredentialsProvider.lookupCredentials(type, scope, acl, domain); for (P4BaseCredentials c : list) { if (c.getId().equals(id)) { return c; } } return null; } /** * Finds a Perforce Credential based on the String id. * * @param credentialsId Credential ID * @param context The context * @return a P4StandardCredentials credential or null if not found. */ public static P4BaseCredentials findCredential(String credentialsId, ItemGroup context) { if (credentialsId == null) { return null; } P4BaseCredentials credentials = CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials(P4BaseCredentials.class, context, ACL.SYSTEM, Collections.<DomainRequirement>emptyList()), CredentialsMatchers.allOf( CredentialsMatchers.withId(credentialsId), CredentialsMatchers.instanceOf(P4BaseCredentials.class))); return credentials; } /** * Finds a Perforce Credential based on credentials ID and {@link Item}. * This also tracks usage of the credentials. * * @param credentialsId Credential ID * @param item The {@link Item} * @return a P4StandardCredentials credential or null if not found. */ public static P4BaseCredentials findCredential(String credentialsId, Item item) { if (credentialsId == null) { return null; } if (item == null) { return findCredential(credentialsId); } P4BaseCredentials credentials = CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials(P4BaseCredentials.class, item, ACL.SYSTEM, Collections.<DomainRequirement>emptyList()), CredentialsMatchers.allOf( CredentialsMatchers.withId(credentialsId), CredentialsMatchers.instanceOf(P4BaseCredentials.class))); CredentialsProvider.track(item, credentials); return credentials; } /** * Finds a Perforce Credential based on the String id and {@link Run}. * This also tracks usage of the credentials. * * @param credentialsId Credential ID * @param run The {@link Run} * @return a P4StandardCredentials credential or null if not found. */ public static P4BaseCredentials findCredential(String credentialsId, Run run) { if (credentialsId == null) { return null; } P4BaseCredentials credentials = CredentialsProvider.findCredentialById(credentialsId, P4BaseCredentials.class, run, Collections.<DomainRequirement>emptyList()); CredentialsProvider.track(run, credentials); return credentials; } protected int getMaxChangeLimit() { int max = 0; Jenkins j = Jenkins.getInstance(); if (j != null) { Descriptor dsc = j.getDescriptor(PerforceScm.class); if (dsc instanceof PerforceScm.DescriptorImpl) { PerforceScm.DescriptorImpl p4scm = (PerforceScm.DescriptorImpl) dsc; max = p4scm.getMaxChanges(); } } max = (max > 0) ? max : PerforceScm.DEFAULT_CHANGE_LIMIT; return max; } public void log(String msg) { if (listener == null) { return; } listener.getLogger().println(msg); } public void stop() throws Exception { connection.execMapCmd("admin", new String[]{"stop"}, null); } public boolean hasAborted() { return abort; } public void abort() { this.abort = true; } @Override public void close() throws Exception { disconnect(); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#90 | 29812 | Sandeep Kumar |
Merge pull request #[178] from [joel-f-brown:masterp] Do not call "p4 counter " when the value is an integer as the helix core server does not allow integer counters. In isCounter() method, check for all digits early. If all digits, return false. |
||
#89 | 28805 | Paul Allen |
Merge pull request #145 from joel-f-brown/master Allow option to not detect changelists for build, JENKINS-68516 |
||
#88 | 28555 | Paul Allen | Update p4java patch version 2021.2.2240592 | ||
#87 | 28464 | Paul Allen |
Formalise user session cache. Added Jelly options to Global Configuration. User cache is disabled by default. Ticket Minimum life is set to 30 minutes. JENKINS-60141 |
||
#86 | 28460 | Paul Allen |
Session cache to track ticket time. Initial design to reduce 'p4 login -s' calls with user session cache to track ticket time. |
||
#85 | 26640 | Paul Allen |
Tick interval message to prevent timeout. An advanced setting in the Credential sets a 'tick' interval to print out a 'waiting' message to the log during long running commands. The value needs to be less than 30,000ms to avoid Jenkins automatic disconnect. JENKINS-58161 |
||
#84 | 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 |
||
#83 | 26601 | Paul Allen | Code cleanup for getHead and getLowestHead. | ||
#82 | 26587 | Paul Allen |
Use default P4IGNORE if unset. Check if P4Java's envrionment has set P4IGNORE for the server connection, otherwise use OS defaults. JENKINS-59726 JENKINS-54707 |
||
#81 | 26579 | Paul Allen |
Prevent logging if Populate quiet flag is set. Originally the Populate quiet flag was passed as a '-q' flag to the command, but some commands using callback streaming handlers still reported output. JENKINS-59750 |
||
#80 | 26210 | charusheela_b |
Merge pull request #93 from lystor/bug-56290 [JENKINS-56290] Impossible to Add Streams with Exact Names to Multibranch Pipeline |
||
#79 | 25973 | Paul Allen | Fix JavaDoc issues | ||
#78 | 25826 | Paul Allen |
Global option to limit change query. By default 'Head change query limit' is set to 0 (no limit) and the plugin will query all changes when looking within a workspace view. For large servers set the value to a range based on commit rate and job queue duration. e.g. 200 global commits/hour and jobs are queued for no longer than 10 hours, so 2000 change query limit (200*10). JENKINS-58116 JENKINS-57870 |
||
#77 | 25014 | Paul Allen |
Scan per change support for MultiBranch with remote Jenkinsfiles. Only the 'Polling per Change' Filter is supported; need to disable or support the other filter types. JENKINS-53936 |
||
#76 | 24944 | Paul Allen |
Merge pull request #86 from p4charu/jenkinsci-master JENKINS-51632 and minor code cleanup |
||
#75 | 24826 | Paul Allen | Update Perforce Server Unicode check. | ||
#74 | 24805 | Paul Allen |
Tidy up connection methods. Cache TagAction calls to getTicket() when adding P4_TICKET to the Environment. JENKINS-54222 |
||
#73 | 24500 | Paul Allen | Tidyup and refactor P4Ref classes. | ||
#72 | 24487 | Paul Allen | Perforce Connection Refactor. | ||
#71 | 24455 | Paul Allen |
Allow query of single streams by appending a `*` to a streams path. https://github.com/p4paul/p4-jenkins/issues/36 |
||
#70 | 23941 | Paul Allen |
Track Credentials at build time. Unable to track when the Job is configured as Pipeline Jobs may use one or more credentials in the Jenkinsfile. JENKINS-44706 |
||
#69 | 23604 | Paul Allen |
Merge pull request #68 from ChadiEM/deleted-jenkinsfile Make sure branch is not discovered when a Jenkinsfile has been removed. |
||
#68 | 23425 | Paul Allen |
Backwards compatibility for p4 describe. Max limit on files for p4 describe (-m flag) was introduced in 2014.1 JENKINS-48433 |
||
#67 | 23327 | Paul Allen | Use client less connection when scanning MultiBranch. | ||
#66 | 22998 | Paul Allen | Remove unused 'admin stop' method. | ||
#65 | 22970 | Paul Allen |
Merge pull request #57 from jfperusse-bhvr/fix-changelog-errors Fix changelog issues caused by NullPointerException in getSwarm JENKINS-47336 |
||
#64 | 22915 | Paul Allen | Advanced AllHosts login option (login -a) | ||
#63 | 22861 | Paul Allen | Use long for change number. | ||
#62 | 22841 | Paul Allen |
Switch to `P4.Swarm.URL` property for Swarm url. JENKINS-45464 |
||
#61 | 22816 | Paul Allen |
Merge pull request #51 from jenkinsci/limit-describe. Limit output from describe. JENKINS-46671 |
||
#60 | 22815 | Paul Allen |
Provide repo with connection.getCommitObject(). The `p4 graph cat-file commit` requires `super` level access if the repo name is not provided. JENKINS-46595 |
||
#59 | 22398 | Paul Allen | Pass Perforce ticket using BasicAuth to Swarm API. | ||
#58 | 22183 | Paul Allen | Ticket Credential; an empty path will use system default. | ||
#57 | 22168 | Paul Allen |
Check all login messages. Fix for 'pre-user-login' triggers. JENKINS-44166 |
||
#56 | 22159 | Paul Allen |
Minor fix on Graph commit change summary. Skip query when listing commits between the same SHAs. |
||
#55 | 22128 | Paul Allen |
Helix Graph support for Jenkins. JENKINS-40354 |
||
#54 | 21794 | Paul Allen |
Merge pull request #39 from Dohbedoh/JENKINS-34825 Jenkins 34825 |
||
#53 | 21781 | Paul Allen | Minor spelling error. | ||
#52 | 21758 | Paul Allen |
Merge pull request #38 from jenkinsci/dev scm-api 2.0.2 updates |
||
#51 | 21658 | Paul Allen |
Reduce login requests. Avoid running `p4 login -s` twice. |
||
#50 | 20986 | Paul Allen |
Ground work for MultiJob support. Pushed validate up to ConnectionHelper and added new Perforce functions. |
||
#49 | 20873 | Paul Allen | Support Pin to a change in a counter. | ||
#48 | 20308 | Paul Allen |
P4Groovy (experimental) Get a P4 object in groovy. Supporting basic functions: ’run’ (to run perforce commands), ‘fetch’ and ‘save’ (to access Perforce specs). |
||
#47 | 20245 | Paul Allen |
Don't disconnect after an abort. Don't disconnect from the P4 server immediately after an abort is detected. JENKINS-37487 @stuartr |
||
#46 | 20179 | Paul Allen | Javadoc fixes for java 8 builds. | ||
#45 | 19712 | Paul Allen | NPE fix when code line has no changes. | ||
#44 | 19593 | Paul Allen | More minor fixes to satisfy FindBugs Analysis. | ||
#43 | 19574 | Paul Allen | Support for guessBrowser and getKey. | ||
#42 | 18889 | Paul Allen |
Asynchronous sync operation. To avoid memory issues with very large sync operations. #review-18773 |
||
#41 | 18809 | Paul Allen |
Use p4 describe -s for listing files in a change. Previously used p4 files @=<change>, but without a client to limit view. |
||
#40 | 18616 | mjoubert |
@pallen Unable to get current change: com.perforce.p4java.exception.RequestException: Can't use a pending changelist number for this command. FATAL: null java.lang.NullPointerException Fix for critial bug |
||
#39 | 16820 | Paul Allen |
Delete client workspace and files on a delete Jenkins Job Global Perforce options for delete files and/or delete client. JENKINS-32454 |
||
#38 | 16585 | Paul Allen |
Fetch full change description. The 'p4 changes' optimisation only fetched the first 32 characters. Added the '-l' flag to fetch the full description. JENKINS-31748 |
||
#37 | 16516 | Paul Allen |
Use empty email "" for deleted users. JENKINS-31169 |
||
#36 | 16515 | Paul Allen |
Extend support for 'now' revision specifier. If 'now' is used it will be substituted for the latest change within the scope of the workspace view. |
||
#35 | 16409 | Paul Allen |
Use Fix records for Job information. 'p4 fixes' is lighter and still provides enough useful data. Includes jelly fix and extra job data in changelog.xml. |
||
#34 | 16390 | Paul Allen |
Update change/file reporting. Use `p4 changes @=1234` to get change summary and `p4 files -m50 @=1234` to get limited file list. |
||
#33 | 16297 | Paul Allen |
Set P4IGNORE filename to defaults. With slaves and different users I can’t rely on the P4IGNORE in the environment, so I set the default ’.p4ignore’ or ‘p4ignore.txt’ on Windows. https://github.com/p4paul/p4-jenkins/issues/14 |
||
#32 | 16085 | Paul Allen |
If Change number is missing try looking for the original. Use p4 change -O if a RequestException is thrown. JENKINS-30525 |
||
#31 | 15866 | Paul Allen |
Abort if unshelve fails. JENKINS-30525 |
||
#30 | 15663 | Paul Allen |
Added P4_USER and P4_TICKET environment variables. Added Perforce environment variables to the buildEnv documentation. JENKINS-24591 |
||
#29 | 15656 | Paul Allen |
Updated credentials to extend BaseStandardCredentials. Allows users to set the ID at creation. JENKINS-29702 |
||
#28 | 15431 | Paul Allen |
Add Perforce User's email to Jenkins User property. JENKINS-28421 |
||
#27 | 15430 | Paul Allen |
Trap User Abort and stop Perforce. Uses the ‘tick’ function on Progress to check if the Thread has been interrupted. If a user aborts the build then the Perforce connection is dropped at the next tick. JENKINS-26650 |
||
#26 | 15293 | Paul Allen |
Add retry attempts to Perforce Tasks. If a task fails due to an exception then the task will retry based on the value specified in the connection Credential. |
||
#25 | 14838 | Paul Allen |
Check if the workspace exists before cleanup. JENKINS-29030 |
||
#24 | 13603 | Paul Allen | Improved Error for Publish step when connection is down. | ||
#23 | 12976 | Paul Allen | Improved logging to include 'actual' Perforce command. | ||
#22 | 12953 | Paul Allen |
Update logging to support expand/collapse divs. - Additional Publish logging |
||
#21 | 12931 | Paul Allen |
#review-12907 @mjoubert Added P4PORT to env for command line calls. |
||
#20 | 12355 | Paul Allen |
Connection retry. Connection retry with 3 attempts and a back off period of n^2 seconds for subsequent attempts. |
||
#19 | 12310 | Paul Allen |
@mjoubert performance/logging Improved performance on validateFileSpecs() Reduce delete logging |
||
#18 | 12297 | Paul Allen |
Only login if there is no valid ticket. JENKINS-27068 |
||
#17 | 12296 | Paul Allen | Monitor P4Java progress, reporting to console log. | ||
#16 | 11452 | Paul Allen |
Push out mjoubert fixes for Force sync. @mjoubert |
||
#15 | 11334 | Paul Allen |
Remote slave support for Publish Perforce Publish commands need to be executed from the remote slave. - Includes refactoring into task package |
||
#14 | 10757 | Paul Allen |
More efficient listing of files. Listing files for the Change reporting used `p4 files //…@=<id>`, this now uses `p4 describe -s <id>` for changes and `p4 files //…@<id>` for labels. The `\\…@label` should be much more efficient as it only looks as the db.label table not db.rev. I can’t limit the scope to a workspace. Often the client name uses ${var}, which are not present at this point in the code. JENKINS-25303 |
||
#13 | 10526 | Paul Allen |
Log all P4JAVA errors/messages. Originally only the first error was reported, before dropping out of validation code. |
||
#12 | 10031 | Paul Allen |
Test URI path before connection. Report Perforce Errors and Trust fingerprint if using SSL. |
||
#11 | 10013 | Paul Allen |
Added Client support to sync check https://issues.jenkins-ci.org/browse/JENKINS-24055 |
||
#10 | 9991 | Paul Allen |
Don't abort on non-error messages. Support the p4broker returning unknown messages. |
||
#9 | 9987 | Paul Allen | Better logging for slave connections. | ||
#8 | 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. |
||
#7 | 9980 | Paul Allen |
Changed error reporting to use AbortException. - Use direct access of scm attributes, not via build.getProject().getScm() - Improved logging around labels/changes. |
||
#6 | 9851 | Paul Allen | Merging using p4-jenkins | ||
#5 | 9819 | Paul Allen | Merging using p4-jenkins | ||
#4 | 9803 | Paul Allen | Merging using p4-jenkins | ||
#3 | 9769 | Paul Allen | Copying using p4-jenkins | ||
#2 | 9738 | Paul Allen | Merging using p4-jenkins | ||
#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/client/ConnectionHelper.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/client/ConnectionHelper.java | |||||
#35 | 9460 | Paul Allen | Skip login, if no password set. | ||
#34 | 9447 | Paul Allen |
Small mod to force a login for each connection. There may be a case with a broker/replica when the login test may incorrectly report the users is logged. |
||
#33 | 9429 | Paul Allen |
Fix SCM Polling bug. Client workspace was not set (unless by an earlier build). - Move listChanges method to ClientHelper. |
||
#32 | 9091 | Paul Allen |
Added Changelist build filtering for SCM polling: - Configuration uses 'repeatableHeteroProperty' - Filter on Perforce username - Filter on Perforce Depot path (no wildcard support) |
||
#31 | 9077 | Paul Allen |
Added support for automatic Labels as a post-build Action. Ported original code for promoted builds, but not tested. |
||
#30 | 9055 | Paul Allen |
Label support. Build at a label using the pram 'label'. This includes adding the label to the ChangeEntry, building the change reports and Browser links to Swarm. (TPI-102) |
||
#29 | 8969 | Paul Allen |
Adds all contributing change-lists for the build to the change log (using p4 cstat). - Includes exception logging for server connection to the Jenkins console. |
||
#28 | 8940 | Paul Allen |
Major refactor for the ConnectionHelper class to simplify serialisation. Fixed remote Jenkins JNLP slave connection issue. ClientHelper now extends ConnectionHelper and takes on all methods that require a client workspace. P4StandardCredentials is sent to the remote node instead of Credentials ID due to an issue accessing the Credentials store over a remote connection. For simplicity Client ID (workspace name) is serialised instead of the Workspace object. |
||
#27 | 8924 | Paul Allen | Sync workspace to last change in workspace (not depot). | ||
#26 | 8915 | Paul Allen |
Support for ChangeLog and RepoBrowser. - Added RepoBrowser for Swarm (porting the others should be easy) - ChangeLog XML file now only stores the changelist number all other information is fetched from Perforce |
||
#25 | 8909 | Paul Allen |
[TPI-83] Clean Workspace that may contain files with wildcards. Added (-f) flag to reconcile and ignore warnings for empty files. |
||
#24 | 8899 | Paul Allen | Move Workspace setup/creation code to Implementation class. | ||
#23 | 8864 | Paul Allen | BugFix on template workspaces; view was not generated during creation. | ||
#22 | 8852 | Paul Allen |
Functional test for unshelve. Includes fix for reconcile and unshelve exclusive locked files. |
||
#21 | 8815 | Paul Allen | P4D test harness. | ||
#20 | 8805 | Paul Allen | Minor fix to ignore Perforce encoding messages when finding 'extra' files during a 'reconcile -a'. | ||
#19 | 8771 | Paul Allen |
Perforce Server 12.1 min check for: Build configuration and password/ticket credentials. Includes: - Added logging for Perforce connections (fine) and set connection pool to 2. - Add 'none' to empty charset list (connection bug?) - Supress P4Java errors for syncing ubinary, xtext, unicode |
||
#18 | 8770 | Paul Allen |
Implemented SCM hook for when Jenkins deletes a workspace. The PerforceScm plugin deletes the workspace, but leaves Jenkins to clean up the local files and directories. (includes dummy 'p4 cstat' code for change reporting) |
||
#17 | 8766 | Paul Allen |
Bug fix: Client Owner not set when creating workspace. Now jenkins will set the owner for new workspaces and take ownership of other manual workspaces it uses for build. |
||
#16 | 8764 | Paul Allen | Supress P4Java warnings, to prevent SCM tasks from failing. | ||
#15 | 8763 | Paul Allen | More Console Output logging | ||
#14 | 8762 | Paul Allen |
Console Ouptut logging for SCM build steps. - Removed SLF4J and used old style logger (matching Jenkins) - Set Client Host filed to null, Jenkins sometimes gives an IP address. - Test p4java setps in SCM tasks for success(true/false) |
||
#13 | 8756 | Paul Allen | Added Stream field to Manual Workspace config. | ||
#12 | 8749 | Paul Allen |
Split off Worksapce Spec from Manual Workspace configuration into a Property Jelly item. Plan to autoload values based on selected client. |
||
#11 | 8744 | Paul Allen |
Support basic SCM Polling. When Jenkins has "Poll SCM" checked the Perforce SCM provider just runs a 'p4 sync -n' on the Workspace. Simple and Fast. |
||
#10 | 8741 | Paul Allen |
Added "Test Connection" to Perforce Password and Ticket Credentials. Does not support SSL connections...yet |
||
#9 | 8738 | Paul Allen |
Workspace Name Formatter. For Template and Stream workspaces it allows the substitution of the following tags: ${node} The name given to the slave Jenkins node. ${hostname} The hostname for the slave Jenkins node. ${project} The name of the Jenkins build Job. ${hash} Unique hash code of the Jenkins node. |
||
#8 | 8725 | Paul Allen |
Minor fixes: - Improved tidy workspace method - Fix for template clients - After an unshelf revert -k files - Minor bug in CheckoutTask - Clear callback urls to prevet reuse |
||
#7 | 8697 | Paul Allen |
Added Manual workspace option for user to define Options/LineEnd/View etc... in Jenkins. |
||
#6 | 8694 | Paul Allen | Added support for unshelve and revert -w behaviour for builds. | ||
#5 | 8664 | Paul Allen | Simplified connection to Perforce to get around the SCM initilisation (or lack of). | ||
#4 | 8662 | Paul Allen | Added auto fill and checks for streams and templates. | ||
#3 | 8661 | Paul Allen | Workspace auto fill | ||
#2 | 8641 | Paul Allen | Added workspace helper (setClient) and template/stream types. | ||
#1 | 8629 | Paul Allen |
Added p4java with connection/authorisation helper classes. Included SSL support and detection of Unicode servers. |