Perforce unshelve command is not returning the shelved CL's changes - jenkins

I have written a jenkins script to unshelve perforce changelist and then run commands on it.
p4 -c %my_client_name% unshelve -f -s %SHELVED_CL1% %perforce_path%
this when runs gives me a notification that
- "unshelved, opened for edit"
but, when i check the file, it does not have those shelved CL's changes.
Can anyone tell me why this is happening..

I can think of two possible explanations:
1) You're looking at the wrong local file. Run "p4 -c CLIENT where FILE" to see the mapping for that file, and then look at that local path on the machine where your script is running.
2) The unshelve operation gave you some extra info/warning/error that your script is eating (or that you omitted from your question because it didn't sound relevant). Likely messages would include something along the lines of must resolve #=SHELVED_CL or unable to write LOCAL_FILE. If you got a must resolve message it means the file is already open with local changes and you need to run p4 resolve to merge the local changes with the shelved changes. If there was an error about being unable to write the file the error will probably include an explanation in the form of an OS message (access denied, no permission, etc). As a rule of thumb, if there's some sort of error message, you should figure out what it means and then fix the thing it's complaining about.

Related

Trigger Jenkins Build on Perforce submit by keyword

I am wondering if anyone knows if it is possible to trigger a Jenkins build on a Perforce commit, only if it has a certain keyword in it?
My use case is that I am looking to find a way to trigger a Jenkins build that will build a Nuget package of the library I am working on, and place it in the correct Nuget server directory. I don't want to build a Nuget package each and every time I make a submit to Perforce, so I was wondering if it is possible to set up some kind of trigger to only run the Jenkins build if some keyword was included in the changelist description.
Does anyone know if this is possible, or any other possible ideas on how to implement this?
This works for me. I'm sure it could be more efficient, but it works. This looks for the string "buildit" in the changelist description.
First, create a change-submit trigger in Perforce, e.g.,
buildit change-submit //... "/usr/bin/buildthis %changelist%"
(wherever you place it should be writable, and create a file called "description" that should also be writable).
Below is the contents of the buildthis script:
#!/bin/sh
changelist="$1"
P4PORT=perforce:1666
P4CLIENT=myclient
P4USER=myuser
p4 -p $P4PORT -c $P4CLIENT -u $P4USER describe $changelist >/usr/bin/description
if grep -q buildit /usr/bin/description;
then
curl -X POST http://jenkinsserver:port/job/jobname/build?token=TOKEN
else
exit 0
fi

Jenkins - kill process before delete workspace action starts

I am having a Jenkins job that runs Nunit tests on remote machine.
I am using Jenkins's Workspace Cleanup Plugin pluggin (https://wiki.jenkins-ci.org/display/JENKINS/Workspace+Cleanup+Plugin) to clean my workspace.
the problem is that I want to task kill some process on my machine (because otherwise I could not delete the workspace - some files will be in use and threfore could not be deleted) and I want to do it before the delete action takes place (it is always the first action on the job).
I know that there is an option in the pluggin- "External Deletion Command" - but this runs the command on all the files in the workspace where as I need it to run only once (not on a the sepsific workspace files - i.e. only this command: "c:/workspace/taskill nunit")
is there a way to do so?
Thanks
If I can suggest a different approach to use an app called LockHunter which has an API to unlock and delete your workspace. It's much more "sergical" than removing a random task and hope it's the one you meant to.
You can trigger it from command line using "run before SCM" and it'll handle the deletion and unblocking of your specific workspace.
You can also use:
"cmd /c wmic /INTERACTIVE:OFF Path win32_process Where \\"CommandLine Like '%workspace%'\\" call terminate"
Where %workspace% is your current workspace. This will go over all the tasks that are currently running and check the command line path, then it'll call terminate for anything it found.
Good luck!

Jenkins "Console Output" log location in filesystem

I want to access and grep Jenkins Console Output as a post build step in the same job that creates this output. Redirecting logs with >> log.txt is not a solution since this is not supported by my build steps.
Build:
echo "This is log"
Post build step:
grep "is" path/to/console_output
Where is the specific log file created in filesystem?
#Bruno Lavit has a great answer, but if you want you can just access the log and download it as txt file to your workspace from the job's URL:
${BUILD_URL}/consoleText
Then it's only a matter of downloading this page to your ${Workspace}
You can use "Invoke ANT" and use the GET target
On Linux you can use wget to download it to your workspace
etc.
Good luck!
Edit:
The actual log file on the file system is not on the slave, but kept in the Master machine. You can find it under: $JENKINS_HOME/jobs/$JOB_NAME/builds/lastSuccessfulBuild/log
If you're looking for another build just replace lastSuccessfulBuild with the build you're looking for.
Jenkins stores the console log on master. If you want programmatic access to the log, and you are running on master, you can access the log that Jenkins already has, without copying it to the artifacts or having to GET the http job URL.
From http://javadoc.jenkins.io/archive/jenkins-1.651/hudson/model/Run.html#getLogFile(), this returns the File object for the console output (in the jenkins file system, this is the "log" file in the build output directory).
In my case, we use a chained (child) job to do parsing and analysis on a parent job's build.
When using a groovy script run in Jenkins, you get an object named "build" for the run. We use this to get the http://javadoc.jenkins.io/archive/jenkins-1.651/hudson/model/Build.html for the upstream job, then call this job's .getLogFile().
Added bonus; since it's just a File object, we call .getParent() to get the folder where Jenkins stores build collateral (like test xmls, environment variables, and other things that may not be explicitly exposed through the artifacts) which we can also parse.
Double added bonus; we also use matrix jobs. This sometimes makes inferring the file path on the system a pain. .getLogFile().getParent() takes away all the pain.
You can install this Jenkins Console log plugin to write the log in your workspace as a post build step.
You have to build the plugin yourself and install the plugin manually.
Next, you can add a post build step like that:
With an additional post build step (shell script), you will be able to grep your log.
I hope it helped :)
Log location:
${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_NUMBER}/log
Get log as a text and save to workspace:
cat ${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_NUMBER}/log >> log.txt
For very large output logs it could be difficult to open (network delay, scrolling). This is the solution I'm using to check big log files:
https://${URL}/jenkins/job/${jobName}/${buildNumber}/
in the left column you see: View as plain text. Do a right mouse click on it and choose save links as. Now you can save your big log as .txt file. Open it with notepad++ and you can go through your logs easily without network delays during scrolling.
I found the console output of my job in the browser at the following location:
http://[Jenkins URL]/job/[Job Name]/default/[Build Number]/console
This is designed for use when you have a shell script build step. Use only the first two lines to get the file name.
You can get the console log file (using bash magic) for the current build from a shell script this way and check it for some error string, failing the job if found:
logFilename=${JENKINS_HOME}/${JOB_URL:${#JENKINS_URL}}
logFilename=${logFilename//job\//jobs\/}builds/${BUILD_NUMBER}/log
grep "**Failure**" ${logFilename} ; exitCode=$?
[[ $exitCode -ne 1 ]] && exit 1
You have to build the file name by taking the JOB_URL, stripping off the leading host name part, adding in the path to JENKINS_HOME, replacing "/job/" to "/jobs/" to handle all nested folders, adding the current build number and the file name.
The grep returns 0 if the string is found and 2 if there is a file error. So a 1 means it found the error indication string. That makes the build fail.
Easy solution would be:
curl http://jenkinsUrl/job/<Build_Name>/<Build_Number>/consoleText -OutFile <FilePathToLocalDisk>
or for the last successful build...
curl http://jenkinsUrl/job/<Build_Name>/lastSuccessfulBuild/consoleText -OutFile <FilePathToLocalDisk>

Jenkins perforce plugin: can I get it to do full sync if key files are missing?

We are using the Jenkins perforce plugin reasonably successfully in a semi-continuous integration setup. The "reasonably" in generally because our builds are slow, but this is not related to Jenkins and more to do with our own code.
One of the main problems we have is that if files have been deleted outside the builds - e.g. if we are low on diskspace and somebody "prunes" the builds on the build machines - the p4 plugin cannot directly handle that. In the mode we run it (without full-sync flag) it assumes that files sync'd on the previous run are still there.
This is covered under "quirks" on the plugin page - https://wiki.jenkins-ci.org/display/JENKINS/Perforce+Plugin - which suggests that you do a "One Time Force Sync" to get the workspace back to normal. However, we usually have a couple of build machines with each config for a bit of redundancy. In that case, the machine you run next is not always the same as the one that had the problem. This also makes it tricky adding new machines to the pool.
I wondered if somebody had a better solution. E.g. if certain key files are missing (indicative of a build being wiped) it does a forced sync anyway?
OK it took me a while but I eventually twigged an approach that works at least in our setup. Pretty well near the top of the job we check for the existence of a particular file. If this does not exist, we assume the workspace has been wiped (if it does exist, we assume is OK). If it has been wiped, we do the equivalent of a "Remove From Client" of all the files. Actually we modify a few files during the build, so I've added a revert in for good measure. Not sure if it is generally required - I suspect not - but should do no harm.
On a PC this means adding the following to the first build step:
IF NOT EXIST //%P4CLIENT%/sdk/ChangeLog.txt (
REM Remove from client. Throw away any files being modified
p4 revert %WORKSPACE%/...
p4 sync %WORKSPACE%/...#none > nul
)
On a Mac (and Linux boxes I assume):
if ! [ -e //%P4CLIENT%/sdk/ChangeLog.txt ]
then
# Remove from client. Throw away any files being modified
p4 revert $WORKSPACE/...
p4 sync $WORKSPACE/...#none > /dev/null
fi
sdk/ChangeLog.txt is the file we assume marks a valid installation. What this effectively does is to reset the environment so that the next sync is the equivalent of a forced sync.

Trying to run corflags from TFS Build 2010

I am using an InvokeProcess activity in TFS 2010 to try and run the corflags application on a built exe.
C:\Builds\4\testing\Sources\BuildAssets\corflags.exe C:\Builds\4\testing\Binaries\Executable.exe /32bit+
However I am getting the following message:
corflags : error CF001 : Could not open file for writing
I am running the TFS Build Agent on my local machine because I am currently in a testing phase, and when I run the exact same command from the command line, the corflags application completes without error.
Any ideas would be greatly appreciated.
I'm not familiar with the specific situation but some general ideas:
Who is the build running as? Does that user have permissions to the output path?
Another consideration is: Has the build completed before it attempts to execute your command?
Try changing the command to be something really simple eg Type "OutputFile" - Does this hit the same issue? If so, it's a permission/timing issue. If not, it's the specific command - but at least we'll have narrowed the problem down.
I don't know the corflags either, but it is using a file in the workspace (a file that is downloaded from Version Control). There is a readonly flag on this file by default.
So if you need this file to be writable:
1) either checkout the file if you need this file in your version control and afterwards check it in again (tf checkout / tf checkin)
2) remove the file from version control if the file is created by the app
3) remove the readonly flag with the attrib command.

Resources