How can I catch a .ps1 error when its called from CmdExec? - powershell-2.0

I have a SQL Agent job that dynamically builds a .ps1 to copy files, then uses a CmdExec job step to check it exists and run it. If there's nothing to copy the .ps1 won't get built. But if I have an invalid path or other .ps1 error, the CmdExec job step still reports success.
I don't know how to get the CmdExec to catch an error in the .ps1 .
if exists c:\folder\BatchCopy.ps1 Powershell -file "c:\folder\BatchCopy.ps1"

I figured this out by simplifying it. Instead of using CmdExec to run Powershell, just use Powershell. If the job step fails, the job will fail and I'll know about it.
# If the batch script was built - run it
c:
$fileToCheck = "c:\folder\BatchCopy.ps1"
if (Test-Path $fileToCheck -PathType leaf)
{
& "c:\folder\BatchCopy.ps1"
}

Related

Jenkins can't find make.exe

I'm trying to install jenkins on windows and I have Cygwin.
I provided the bash.exe path to jenkins and add a job which executes a .sh file.
The output is like:
Building in workspace C:\Program Files (x86)\Jenkins\workspace\Build_Release
[Build_Release] $ C:\cygwin64\bin\bash.exe -xe C:\WINDOWS\TEMP\jenkins8276366787192439492.sh
+ cd /cygdrive/d/01-Avelabs/001-Projects/001-VGTT/001-Repos/P2.4.0.5/host/AdasHost/Application/
+ ./BuildHost.sh
./BuildHost.sh: line 2: make: command not found
Build step 'Execute shell' marked build as failure
Finished: FAILURE
What am I missing?
To get you going (the problem is not obvious but it should be easy enough to debug): Add a "set" command at the top of the script to dump the environment variables, including the PATH. You will very likely find that PATH is not in any of the folders listed in the value of the PATH env var. (You could also put simply, "echo $PATH".)
Some possibilities:
When I start bash in Windows I typically inherit the Windows path, but not the Linux path: /cygdrive/c/windows/system32 is included, but /bin is not. So, even basic Linux commands like "ls" result in "command not found" errors. I'll typically start a bash session with "export PATH=/bin:$PATH" to get around this.
Even if you initialize the path with a .bash_profile script, the user under which Jenkins is executing is probably not executing the same initialization script.
Finally - and not meaning to say "Is it plugged in? - but: I ran a clean Cygwin install and did not get make by default. So be sure it is included in /your/ installation!

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 deleting batch file before it's completed

I'm running Jenkins on a Server 2012 VM, and I'm noticing that some of my projects are being marked as incomplete when they are successful. I am getting the error 'The batch file cannot be found.' The problem, from what I can tell, is that the batch file Jenkins is creating to run my project is being deleted before it's completed. I'm migrating from a windows 7 box where this issue doesn't happen.
I've been able to watch as the batch file is created in C:\Users\164016\AppData\Local\Temp\ and then it's deleted before the batch file completes. I'm even able to open the batch file before it's deleted.
I've tried placing the Call command at the beginning of the command, but that doesn't resolve the issue.
The LaunchPad.exe command is a custom made script designed to return exit codes from Excel vba macros.
Please let me know if you have any suggestions.
Here is the log:
Building remotely on (164016) Remote Computer in workspace C:\TEMP\Jenkins Slave\workspace\Weekly Claim Edit WQ Age
[Weekly Claim Edit WQ Age] $ cmd /c call C:\Users\164016\AppData\Local\Temp\hudson3188220465265190989.bat
C:\TEMP\Jenkins Slave\workspace\Weekly Claim Edit WQ Age>"O:\Analytics Team\Tasks\Automation Components\Ryan\C#\Launch Pad\LaunchPad\LaunchPad\bin\Debug\LaunchPad.exe" "C:\Program Files (x86)\Quest Software\Toad for Data Analysts 2.7\Toad.exe" -batch=true "O:\Analytics Team\Tasks\Automation Components\Cindy\TAS\Claim_Edit_WQ_Age.tas" "O:\Analytics Team\Tasks\Claim Edit WQ Age\Claim_Edit_WQ_Age.xlsm"
LaunchPad Start Time: 10.7.2014 9:49:10 AM
Time before Stopping Programs: 60 min
Program: "C:\Program Files (x86)\Quest Software\Toad for Data Analysts 2.7\Toad.exe"
Arguments: "-batch=true" "O:\Analytics Team\Tasks\Automation Components\Cindy\TAS\Claim_Edit_WQ_Age.tas"
vba File: "O:\Analytics Team\Tasks\Claim Edit WQ Age\Claim_Edit_WQ_Age.xlsm"
vba Exit File: O:\Analytics Team\Tasks\Claim Edit WQ Age\Claim_Edit_WQ_Age.txt
Report Completed: 10/7/2014 9:50:28 AM 164016 O:\Reports\EPIC\Epic Claim Edit WQ\20141007 Claim Edit WQ Age.xlsx
Exiting LaunchPad: No Errors Detected: 0
The batch file cannot be found.
Build step 'Execute Windows batch command' marked build as failure
Finished: FAILURE
I had a very similar problem. I was running a job in Jenkins that was calling a specialized internal program and causing the "batch file not found" error. It turns out there was a del %TEMP%\*.* /q command in one of the batch files being run. This was deleting all of the Jenkins temporary batch files in the middle of the job and causing the error.
The simple solution is to simply relocate the Jenkins temp folder. This can be done by adding a command line option to your Jenkins startup script. My startup script looks like: java -XX:MaxPermSize=1024m -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -Djava.io.tmpdir=C:\Users\!!My_user_name!!\Desktop\Jenkins_Temp -jar jenkins.war
The important part I added was the -Djava.io.tmpdir=C:\Users\!!My_user_name!!\Desktop\Jenkins_Temp option (Removed my user name for privacy reasons.) This fixed the problem. Don't forget to replace my path with with a valid path name for your system.
The command line option should be added to both the master and slave startup scripts for proper operation.
You've got something else at play here...
When you configure Execute Windows batch command build step, it creates a temporary batch file that Jenkins then executes.
The execution of the temporary batch file starts at:
[Weekly Claim Edit WQ Age] $ cmd /c call C:\Users\164016\AppData\Local\Temp\hudson3188220465265190989.bat
and it finishes at:
Build step 'Execute Windows batch command' marked build as failure
The temporary batch file hudson3188220465265190989.bat would be deleted after that last line.
Your error The batch file cannot be found. happens before that line. So, it's not the Jenkins temporary batch file that cannot be found, but something else.
Unless you provide the content of your Execute Windows batch command, it's difficult to guess what else could be the problem.

Jenkins how to rename war file

I have deployed a war file in a remote machine using Jenkins. Now I want to rename the war file through jenkins before it extracts the work folder? How can this be done? I tried post deployment action -> execute shell and mv file.war to new-file.war but it returns an error saying : mv: cannot stat `file.war': No such file or directory.
Suppose there was something wrong with my path it would not even have gone to remote location. but for me, after scp' ing it to remote location thru jenkins, and when i try to do a mv, it fails.. What could the reason be??
Adding additional Step of Execute shell during Add build Step or Add post-build action stage, normal renaming shell command mv can be used to rename artifacts.
Note: Make sure use the correct path(Relative to project/workspace root)
Your mv command is probably executed in another directory than the one you are expecting.
To know the directory your script is running in without reading the jenkins / plugin documentation add
echo "pwd of script is: " `pwd`
to your shell script and inspect the output of the jenkins build - that way you can be sure about the directory the script is run in.

execute shell step skipped completely in jenkins

I can't seem to run a build execute shell step in Jenkins. I've worked with Hudson in the past on windows and I was able to create shell/batch steps without a problem but I seem to be be missing something here.
It's a fresh jenkins install and I go to "add build step", "execute shell" and enter "echo hi" in the command. I run the build and when I look in the console output, nothing happens.
I've also tried executing a test.sh file which also just echoes hi. I've tested this in both a linux install and an os X installed Jenkins server.
What am I missing in the configuration to run a shell script?
The console output shows that the shell script steps were skipped completely
Started by user admin
Finished: SUCCESS
It looks like Jenkins is not being able to redirect the output from the system. What version of Java are you using? If you're using OpenJDK, could you try with Sun Java/Sun JDK?
First test to try to check if anything is executing at all: add the following to your "Execute Shell"
#!/bin/bash
echo "HELLO WORLD" > /tmp/testfile
Run this and check if there is a /tmp/testfile in on your Linux system, and if it contains the HELLO WORLD text, it means your script is in fact executing.
Which version of Jenkins do you have?
The last good version that I can attest to (last one I know works well at least for us) is 1.447. If you're not using that one, would you be able to try with it?
Also, could you add #!/bin/sh or #!/bin/bash before echo hi on your "Execute Shell" for the Linux system and see if that works.
Also, try running a script using source /path/to/script and see if that works. The script should contain #!/bin/sh or #!/bin/bash as the first line, just to see if that makes a difference.
Note: none of this should be required, but is helpful just to get more information on what's going on. Couldn't fit all this into a comment. I'll update my answer based on your answers to the above, or delete if I can't get anything..
Putting this here for posterity.
I had a Jenkins project configured with Maven running clean test and a execute shell in the pre steps. The logs from Maven where not coming through and the script was not executing. Once I unchecked Build modules in parallel under the Maven build options my logs and scripts started working.
Make sure its in a location where Jenkins can see it, check permissions.

Resources