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.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.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.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.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.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; 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 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(); 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 { String status = connection.getLoginStatus(); 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(int 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) throws Exception { List<IFileSpec> files = connection.getChangelistFiles(id); 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) throws P4JavaException { return connection.getCommitObject(sha); } public List<IFileSpec> getCommitFiles(String repo, String sha) throws P4JavaException { return connection.getCommitFiles(repo, sha); } /** * 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; } 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; } 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 | |
---|---|---|---|---|---|
#8 | 22326 | Paul Allen | Merging down using p4-jenkins | ||
#7 | 22114 | Paul Allen |
Set max change limit for Graph commit. Increased default change limit to 20. |
||
#6 | 22053 | Paul Allen | Graph MultiBranch commit and change detection. | ||
#5 | 22049 | Paul Allen | Basic MultiBranch support for Graph. | ||
#4 | 22000 | Paul Allen |
Use graph p4 describe to fetch committed files. Update P4Ds |
||
#3 | 21990 | Paul Allen |
Reporting Graph changes. Update Browser and Jelly code to use String and not URL for url in Data Binding to Jelly. Use P4AffectedFile object for XML storage and not IFileSpec to allow Graph use. |
||
#2 | 21978 | Paul Allen | Reporting Graph | ||
#1 | 21940 | Paul Allen | Branching using p4-jenkins | ||
//guest/perforce_software/p4jenkins/main/src/main/java/org/jenkinsci/plugins/p4/client/ConnectionHelper.java | |||||
#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. |