Contribution

Please consider helping out and joining this project to make it even better.

There are many features to add and a growing backlog of SIRs, I am happy to accept GitHub pull requests or Shelved Swarm reviews. Any questions please contact me via our support team support@perforce.com.

Overview

The P4 Plugin has been fully tested against Helix P4D release version 2015.1

The plugin supports:

Credential authentication

Client Workspace management

Synchronisation behaviour

Polling and filtered builds

External review tools (Swarm)

Change-list browsing

Labeling builds (Tagging)

External repository browsers (P4Web, Swarm)

Submit assets back to Perforce Helix (Publish)

Requirements

Jenkins 1.642.3 or greater.

Helix Versioning Engine 2015.1 or greater.

Minimum Protection of 'open' for the Jenkins user.

If you wish to use the Review Build feature you will need Swarm.

Swarm 2015.1 or greater.

Issues

All issues are managed on the JIRA Agile Board, when reporting an issue please set the Component to `P4` (not `Perforce`).

Limitations

Some parameters are not available during Polling. As a result these variables will not get expanded leading to unexpected results (e.g. new workspaces being created resulting in continuous polling). Jenkins job and multi configuration parameters should be expand, but custom or parameterised build variables are unlikely to be available.

I have configured the plugin as per specification, also checked the setting. but when i run the job i get below error, need helpjava.io.IOException: remote file operation failed: /scratch/builds/jenkins/workspace/xxxx_bug-fix_SUSE11_SP2_cde_linux64i8 at hudson.remoting.Channel@72afe16b:Rhel5.7-sucd606: java.io.IOException: Remote call on Rhel5.7-sucd606 failed
at hudson.FilePath.act(FilePath.java:976)
at hudson.FilePath.act(FilePath.java:958)
at org.jenkinsci.plugins.p4.PerforceScm.checkout(PerforceScm.java:285)
at hudson.model.AbstractProject.checkout(AbstractProject.java:1253)
at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild.java:622)
at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:86)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:528)
at hudson.model.Run.execute(Run.java:1745)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:89)
at hudson.model.Executor.run(Executor.java:240)
Caused by: java.io.IOException: Remote call on Rhel5.7-sucd606 failed
at hudson.remoting.Channel.call(Channel.java:760)
at hudson.FilePath.act(FilePath.java:969)
... 10 more
Caused by: java.lang.ClassFormatError: Failed to load org.kohsuke.stapler.Stapler
at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:325)
at hudson.remoting.RemoteClassLoader.findClass(RemoteClassLoader.java:237)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at hudson.util.Secret.<clinit>(Secret.java:239)
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:140)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:936)
at java.lang.reflect.Field.getFieldAccessor(Field.java:917)
at java.lang.reflect.Field.getLong(Field.java:546)
at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1631)
at java.io.ObjectStreamClass.access$700(ObjectStreamClass.java:69)
at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:442)
at java.security.AccessController.doPrivileged(Native Method)
at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:430)
at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:327)
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:564)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
at hudson.remoting.UserRequest.deserialize(UserRequest.java:185)
at hudson.remoting.UserRequest.perform(UserRequest.java:99)
at hudson.remoting.UserRequest.perform(UserRequest.java:49)
at hudson.remoting.Request$2.run(Request.java:324)
at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
at ......remote call to Rhel5.7-sucd606(Native Method)
at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1356)
at hudson.remoting.UserResponse.retrieve(UserRequest.java:221)
at hudson.remoting.Channel.call(Channel.java:752)
... 11 more
Caused by: java.lang.ClassFormatError: Failed to load javax.servlet.http.HttpServlet
at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:325)
at hudson.remoting.RemoteClassLoader.findClass(RemoteClassLoader.java:237)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.lang.ClassLoader.defineClass(ClassLoader.java:480)
at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:323)
at hudson.remoting.RemoteClassLoader.findClass(RemoteClassLoader.java:237)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at hudson.util.Secret.<clinit>(Secret.java:239)
at sun.misc.Unsafe.ensureClassInitialized(Native Method)
at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:43)
at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:140)
at java.lang.reflect.Field.acquireFieldAccessor(Field.java:936)
at java.lang.reflect.Field.getFieldAccessor(Field.java:917)
at java.lang.reflect.Field.getLong(Field.java:546)
at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1631)
at java.io.ObjectStreamClass.access$700(ObjectStreamClass.java:69)
at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:442)
at java.security.AccessController.doPrivileged(Native Method)
at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:430)
at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:327)
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:564)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1887)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
at hudson.remoting.UserRequest.deserialize(UserRequest.java:185)
at hudson.remoting.UserRequest.perform(UserRequest.java:99)
at hudson.remoting.UserRequest.perform(UserRequest.java:49)
at hudson.remoting.Request$2.run(Request.java:324)
at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Caused by: java.lang.UnsupportedClassVersionError: javax/servlet/http/HttpServlet : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.lang.ClassLoader.defineClass(ClassLoader.java:480)
at hudson.remoting.RemoteClassLoader.loadClassFile(RemoteClassLoader.java:323)
... 51 more
Sending e-mails to: narayanpradhan7876@gmail.com
Started calculate disk usage of build
Finished Calculation of disk usage of build in 0 seconds
Started calculate disk usage of workspace
Finished Calculation of disk usage of workspace in 0 seconds
Notifying upstream projects of job completion
Finished: FAILURE

I would very much appreciate an option to fail the job if any kind of errors occur when synching the workspace. This seems critical to me. Currently, a syntax error in a view spec, or any number of other issues can cause my build to use the wrong source code, but there is no indication of a problem, unless I read the console output (which I obviously don't do on every build).

I've recently upgraded from v1.4.2 to v1.4.4 and started to notice interesting behavior: if my workspace has a soft link to another directory unrelated to this job, the files are get cleaned up in this referenced directory (only files, recursively in all dirs, dirs themselves are kept).

Before upgrading (when was @ v1.4.2) the referenced dirs never cleaned up.

Do you have any ideas if this is a bug or feature and whether the changes between 1.4.2 and 1.4.4 may affect such behavior or should I search for an issue in other directions?

I'll try to downgrade back to 1.4.2 soon, just pending awaiting the next maintenance window.

Thanks!

p.s. investigated a bit and found more details on this issue, finally filed a JIRA for this:
JENKINS-40948
-
Getting issue details...STATUS
however, it doesn't get much attention through all this time.....

"Pin build at Perforce Label" option in Source Code Management section of the job configuration is responsible for this.

You can put either plain changelist number (e.g. 147081) or p4 label to sync to. Keeping it blank will sync to head revision prior the build.

To automate this process you can make the job parametrized, add a string (or Validating String for checking user input) parameter, e.g. CUSTOM_REV. By default you can leave the value empty for it and put "${CUSTOM_REV}" to "Pin build at Perforce Label" field to ask the value when user builds it and pass it to P4 plugin then. User can keep the default value to sync to head or enter different value if required. The default value is also used when build is triggered automatically (e.g. via SCM polling).

So I have a build with "Sync Only" selected as the sync option. I want the ability to be able to set a Boolean to enable the ability to change it to a "Force Clean and Sync" when manually building the job.

Doesn't have to actually change the job option, but would change the perforce command to have the -f in the sync command, this is useful in a number of circumstances.

I would like this too. We have a large C++ project that we want to do incremental builds on (don't wipe the workspace!). However, every so often we need to do a full re-build. The only way to accomplish this is to edit the job config, run the job enough times that it wipes all node workspaces, then edit the job config back.

It would be extremely helpful if we could choose the sync options with a job parameter or environment variable or something.

Subsequent builds (my poll schedule is every 5 minutes) all have the same CL number (88146), since there were no changes committed anywhere within the worksapce view mapping. We're using manual workspace definition, if that makes any difference.

I have been struggling with that all day and still couldn't come up with a good solution.

I am too using a manual view where a bunch a variable such as computer and node name are used to make up a workspace name.

The problem seems to come from the fact that polling is executed on master node, therefore creating an empty workspace view to check the poll but then build is executed on a slave node where the workspace depot is up to date.

Is there a way to have the poll check on the node it would be executed? Or do I have to make "static" workspace name?

There might be a similar JIRA open if not please consider raising the issue on the Jenkins JIRA issue page issues.jenkins-ci.org. If you have Perforce support please contact us and/or ping me the JIRA ID / Support case number. I don't check the old wiki page very often as the Jenkins community favour JIRA.

If you raise a JIRA issue please set the component to 'p4-plugin', include the plugin version e.g. 1.8.4 and provide as much detail about your Jenkins Job setup e.g. are you using FreeStyle, MatrixBuilds, Pipeline, MultiBranch, etc...

What variables do you use in your Workspace Format name e.g. jenkins-${NODE_NAME}-${JOB_NAME}-${EXECUTOR_NUMBER}

'Skipping Parent build...' Parent build? - Is this a Matrix Project? What Axes do you have and do you use any variables in the workspace view?

Jenkins polls on the master and I rely on the SyncID to track changes. The workspace view should be the same as the slave (at least the depot side of the mapping). Polling should then use 'p4 changes' with the view to see if there are any new changes since the last SyncID.

Try a 'Build Now' to 'reset' the SyncID if you have recently changed the workspace view or other configuration settings.

Paul Allen This is a matrix build, I have one axis (multiple platforms via labels), and I do use workspace variables (so we check out platform specific stuff only). Jenkins seems to poll on one of the slave nodes rather than the master. We put ${NODE_NAME} into workspace name specifically to keep the workspaces for each build slave seaprate, as we were running into issues. Are you saying I should keep the workspace name the same across the nodes in the matrix? (ie. jenkins-${JOB_NAME}, without NODE_NAME). Other than that, the actual workspace mapping is identical between the matrix nodes.

This above execution strategy seemed to have solved my problem, but the option is quite hidden if you don't know to look for it. There also seem to be no documentation on what "Perforce: Matrix Options" exactly means or does (as opposed to classic), but these settings seemed to have done it for now.

I had forgotten about the Execution Strategy for Matrix Builds; the past few years have been focused on Pipeline/MultiBranch for Jenkins 2. Updating the markdown documentation, would help other users - I will have to remind myself of the behaviour.

Try and keep your workspaces unique (use NODE_NAME and other variables to help), this is important if concurrent builds are used and more efficient if you are using AutoClean as the Perforce 'have' data is used during the sync.

I originally added the computer and node name (${COMPUTERNAME}-${NODE_NAME}) to the worspace name as I thought workspace name should be unique per computer per user in perforce but it made Jenkins confused when master was checking if it needed to poll or not. As it was checking a non-existing workspace, the polling was always validate.

I just remove Node and computer name from the workspace name so master now check the same workspace created by worker node and it works much better.

I didn't write any JIRA issue as I now realize I might have been asking for something that can't be done. (poll on the worker node)

Unless it's a feature you want and can add, I'm not gonna report any issue.

I don't usually check the old wiki page as the Jenkins community favour JIRA. Please raise issues on the Jenkins JIRA issue page issues.jenkins-ci.org (setting 'p4-plugin' as the component) and if you have Perforce Support contact us and include the JIRA issue number.

The credentials being used for the SSL connection have worked fine for months. However, now the "Test Connection" button now gives this error as well, regardless of the username/password credentials being used.

What sort of issue could be happening to cause this error? The error message doesn't seem to help me determine how to fix the issue. All of the nodes (including the master) have successfully trusted this server (I've verified the entries in the .p4trust file), the fingerprint doesn't appear to have expired, and to my knowledge no changes have been made to the Jenkins server, the Perforce host, or the credentials in the last day.

After further investigation, it turns out that P4Plugin had filled the drive so no new files could be made in the /tmp directory - it was full of files in the form of "p4auth_XXXXXXXXXXXXXXXXXXX.txt" containing server fingerprints for SSL connections. The timestamps of the files appear to correspond to the automated SCM polling used by the job (which happens every 5 minutes).

Is there a way to disable the creation of these files, or configure P4Plugin to clean them up when it's done? As a temporary fix we are periodically removing all *.txt files created by the Jenkins user.

If P4Java (the API used by Jenkins) does not have write access to update the '.p4ticket' file then the 'p4auth_*' file is left behind. The code attempts to move the 'p4auth_*' file over the '.p4ticket' file; perhaps on error we should cleanup the 'p4auth_*' file?

I need to change from the old perforce plugin to the newer p4 plugin. It is a bit "difficult" as all of the jobs created by a previous owner are based off of templates without my knowing where the original jobs used for the templates are. So with some suggestions of co-workers created a new example job and I am exploring the differences of the new config.xml to the old template XML.

I have tried various Google searches trying to find any porting tips, but nothing good. The other thing I have tried is to briefly look through the code for the new plugin to see if I could find where the tags in the config.xml are processed for setup. Haven't found much yet... probably have skipped a obvious directory. Likewise I'd like to find similar documentation for the old plugin so I could more accurately match up configuration.

Any tips or pointers would be appreciated. It may be time to just copy and paste some XML into the template and experiment. All 10+ multijobs are blocked so breaking the config will not make things worse!

There is no Perforce Job (p4 fix) link when submitting with the p4-plugin, however it does sound like a good SIR. Please can you create an issue on issues.jenkins-ci.org and set the component to 'p4-plugin'.