I wrote a batch file that runs multiple ant builds sequentially. I am wondering if there is a way I can save the results of each build (whether it succeeded or failed) and display it at the end? For example:
Project1 - Success
Project2 - Success
Project3 - Failed
Project4 - Success
I cannot edit any of the ant build files, only the batch file I use to run them:
#echo off
cd c:\<project1_dir>\build
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build1.xml
echo.
cd c:\<project2_dir>\build
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build2.xml
echo.
cd c:\<project3_dir>\build\
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build3.xml
echo.
cd c:\<project4_dir>\build
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build4.xml
Thanks!
UPDATE:
Based on David W's answer, I came up with the following:
#echo off
cd c:\<project1_dir>\build
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build1.xml
set result1=%ErrorLevel%
echo.
cd c:\<project2_dir>\build
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build2.xml
set result2=%ErrorLevel%
echo.
cd c:\<project3_dir>\build\
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build3.xml
set result3=%ErrorLevel%
echo.
cd c:\<project4_dir>\build
call C:\Home\apache-ant-1.9.4\bin\ant -buildfile build4.xml
set result4=%ErrorLevel%
if "%result1%"=="0" (
echo Project1: Succeeded
) else (
echo Project1: Failed
)
if "%result2%"=="0" (
echo Project2: Succeeded
) else (
echo Project2: Failed
)
if "%result3%"=="0" (
echo Project3: Succeeded
) else (
echo Project3: Failed
)
if "%result4%"=="0" (
echo Project4: Succeeded
) else (
echo Project4: Failed
)
The above code does exactly what I wanted it to do. Thanks a bunch!
Ant returns an exit code of 0 on good builds and an exit code of non-zero on bad builds. This is stored in errorLevel and can be tested with an if statement:
if errorlevel 1 (
echo "Job Failed"
)
if %ErrorLevel% EQU 0 (
echo "Job Succeeded
)
Or something like that... I'm not really up on my Windows Batch file syntax. I don't know how call affects the setting of ErrorLevel. You may have to set an environment variable to ErrorLevel in the called script, and then work from there.
Take a look at using a Continuous Build System like Jenkins which will automate a lot of these issues for you. Jenkins can build:
At a particular time.
When source code is changed.
On demand
Or a combination of the above (Build at 5pm everyday, but only if the source code was changed).
This will move builds to an independent server (no more, It works on my machine issues), and Jenkins will keep the build output, show which jobs succeeded or failed on its dashboard, and even email (or tweet or IM) particular people (including the culprit) when a build fails. If you use unit tests, Jenkins can run the unit tests, and show you how many of those tests succeeded or failed.
Jenkins uses Java, but it's fairly easy to setup -- even on a Windows system. It can use Tomcat or JBoss as an application server engine, or it's own internal application server.
Related
When Batch script is run as a job from workflow it exits with errorlevel, but the overall job status gives success, instead of failure. How can I capture the error and get workflow status as failed.
Attaching snippets of the Github Action workflow yaml file
- name: Setup Release directory
id: Release_directory
run: .\\Compile_testsuite.bat
- name: Check on failures
if: (${{ success() }} || ${{ failure() }}) && (${{ steps.Release_directory.outcome }} == 'failure')
run: echo ${{steps.Release_directory.outcome}} #exit 1
Attaching the code snippet of the Batch script
#echo off
rem Get Current Path
set defaultPath=%CD%
set defaultPath=%defaultPath: =%
set /p version=<Version.txt
set ReleasePath=%defaultPath%\Release_%version%
set runPath=%ReleasePath%\run
set workloadsPath=%ReleasePath%\workloads
set commonPath=%workloadsPath%\common
set resultsPath=%ReleasePath%\results
echo %defaultPath%
if not exist %ReleasePath% mkdir %ReleasePath%
if not exist %runPath% mkdir %runPath%
if not exist %workloadsPath% mkdir %workloadsPath%
if not exist %resultsPath% mkdir %resultsPath%
if not exist %commonPath% mkdir %commonPath%
set Identifier=false
rem Iterate over directory
for /D %%w in (*) do (
SETLOCAL ENABLEDELAYEDEXPANSION
set workloadPath=%defaultPath%\%%~nxw
for /f "tokens=1 delims=_" %%a in ("%%~nxw") DO (
set var=%%a
if "!var!" == "Excel" ( set "Identifier=true")
if "!var!" == "Word" ( set "Identifier=true")
if "!var!" == "Outlook" ( set "Identifier=true")
if "!var!" == "Powerpoint" ( set "Identifier=true")
)
if "!Identifier!" == "true" (
REM Print Workload path
echo !workloadPath!
cd !workloadPath!
nuget install !workloadPath!\%%~nxw\packages.config -o !workloadPath!\packages\
echo !workloadPath!\%%~nxw.sln
msbuild !workloadPath!\%%~nxw.sln /t:Rebuild /p:Configuration=Release /p:Platform="Any CPU"
rem echo "ERROR_LEVEL" !errorlevel!
if not !errorlevel! == 0 ( exit /B !errorlevel!)
set exePath=!workloadPath!\%%~nxw\bin\Release\Executable
if not exist !workloadsPath!\%%~nxw\bin mkdir !workloadsPath!\%%~nxw\bin
if not exist !workloadsPath!\%%~nxw\input mkdir !workloadsPath!\%%~nxw\input
copy !exePath! !workloadsPath!\%%~nxw\bin
copy !workloadPath!\%%~nxw\bin\Release\input !workloadsPath!\%%~nxw\input
cd %defaultPath%
)
Output from the Workflow run in Github Actions
I'm trying to run build a vs code solution using "msbuild". If the build is not successful, Batch script should terminate. So I have added if condition to check status of msbuild.
When I run the workflow, I'm trying to check the build of the solution, if build is successful, I need to run the application using next task.
I have directed the output to a new file, and checked for failure keyword in the file. If any error occurred, I will terminate the run in workflow.
When Batch script is run as a job from workflow it exits with errorlevel, but the overall job status gives success, instead of failure.
Yes, this is in turn caused by the default shell in a GH Action being PowerShell Core, which doesn't return the ERRORLEVEL as the exit code from running a batch script.
As can be read here, this behavior is by design. However, the proper way of fixing this, opposed to attempting to capture the output and parsing it, is to use shell: cmd, which will properly propagate the ERRORLEVEL from the batch file.
Here's an example script:
jobs:
build:
name: Build
runs-on: windows-latest
steps:
# checkout the code
- name: checkout-code
uses: actions/checkout#v3
with:
fetch-depth: 0
# setup dotnet based on global.json
- name: setup-dotnet
uses: actions/setup-dotnet#v3
# build it, test it, pack it
- name: Run dotnet build (release)
# see issue #105
# very important, since we use cmd scripts, the default is pwsh, and a bug prevents errorlevel to bubble
shell: cmd
run: ./build.cmd
I have a batch program that executes commands from distinct libraries. The problem is that those libraries finish console automatically when they're executed.
It seems that pause command doesn't work because probably those libraries will have they're own exit command. I tried with the command cmd /k that I found on google, but it doesn't works too.
:start
cls
echo.
echo 1) Desc 1
echo 2) Desc 2
set /p option=Enter an option:
IF "%option%"=="1" (
rem this is an example of library that exit console after being executed
pm2 start ecosystem.config.js --env development
)
IF "%option%"=="2" (
pm2 monit
)
pause
goto start
The main idea is if there's any method or param to avoid closing the console with those kind of libraries without editing the proper libraries.
Using the command call before the methods will work:
:start
cls
echo.
echo 1) Desc 1
echo 2) Desc 2
set /p option=Enter an option:
IF "%option%"=="1" (
rem this is an example of library that exit console after being executed
call pm2 start ecosystem.config.js --env development
)
IF "%option%"=="2" (
call pm2 monit
)
pause
goto start
In my work project, we have to create 4 installers using Inno Setup. That way, I have to run file by file, which ends up demanding more of my time.
Files *.iss:
setup_prog_01.iss;
setup_prog_02.iss;
setup_prog_03.iss;
setup_prog_04.iss;
Would it be possible to create a batch file (.bat) to compile all these *.iss files at once?
There's ISCC.exe command-line Inno Setup compiler.
So you can do:
ISCC.exe setup_prog_01.iss
ISCC.exe setup_prog_02.iss
ISCC.exe setup_prog_03.iss
ISCC.exe setup_prog_04.iss
If you are developing apps using Visual Studio you can use Visual & Installer extension (https://marketplace.visualstudio.com/items?itemName=unSignedsro.VisualInstaller) and build all installers from single solution.
This extension allows you to create regular Inno Setup projects (with single or multiple .iss script file(s)) in Visual Studio and you can perform all Visual Studio actions on them (like Build order, Dependencies etc).
It is much more user friendly than command line and it works with any Continuous Delivery/Integration system. P.S.: I am developer of this extension.
I have a complex build for a lot of signed applications so I created a pair of batch files to handle it – the first one (MAKEALL.BAT) contains the list of applications and calls the second batch file (MAKE.BAT) which does the work.
#echo off
echo MAKEALL.BAT - Building all the installation packages.
echo.
:: Start a new log file
echo Running makeall.cmd > makeall.log
set pass=""
set failed=""
:: prompt for signing password
set /P pass=Enter the certificate password:
:: call make.cmd to build each package
call make.cmd app01
call make.cmd app02
call make.cmd app03
call make.cmd app04
call make.cmd app05
:: clean up and exit
set pass=""
if NOT "%failed%"=="TRUE" (
del makeall.LOG
echo Installation build completed.
) ELSE (
echo Installations encountered some errors.
)
pause
exit
:: Run MAKE.BAT - INNO SETUP command line compiler using name passed from MAKEALL.CMD
:: Usage: "CALL make.cmd <installation>" which will will prompt for the certificate
:: password and store it in the variable %pass%.
setlocal enableDelayedExpansion
echo.
echo Building the %1 installation
:: Build the local strings needed
set "prog=C:\Program Files"
set "inno=\Inno Setup 5\ISCC.exe"
set "ksign=\kSign\ksigncmd.exe"
set bits=
if exist "%SYSTEMDRIVE%\Program Files (x86)\" set "bits= (x86)"
::
set "iscc=%prog%%bits%%inno%"
set "sign=%prog%%bits%%ksign%"
set "time=http://timestamp.verisign.com/scripts/timstamp.dll"
::
:: Prompt for the certificate password if needed
if "%pass%" == "" set /P pass=Enter the certificate password:
::
set signing=%sign% /f %cd%\certificate.pfx /p %pass% /t %time% $p
echo Building the %1 installation >> makeall.log
:REBUILD1
:: Build the registration file (app_reg.iss) if it exists
if exist %1_reg.iss "%iscc%" %1_reg.iss >> makeall.log
if %errorlevel% neq 0 (
set failed=TRUE
echo Phase 1 ERROR - retrying ...
GOTO REBUILD1
)
:REBUILD2
:: Build the user configuration file (app_icn.iss) if it exists
if exist %1_icn.iss "%iscc%" %1_icn.iss >> makeall.log
if %errorlevel% neq 0 (
set failed=TRUE
echo Phase 1 ERROR - retrying ...
GOTO REBUILD2
)
:REBUILD3
:: Delay to allow cloud to sync the registration image that we just built.
ping 127.0.0.1 -n 10 > nul
:: Build and sign the main executable
if exist %1_setup.iss "%iscc%" /skSign="%signing%" %1_setup.iss >> makeall.log
if %errorlevel% neq 0 (
set failed=TRUE
echo Phase 2 ERROR - retrying ...
GOTO REBUILD3
)
echo ... build completed.
echo.
Running MAKEALL.BAT will prompt for the certificate password and then call MAKE.BAT with each of the application names. MAKE.BAT is a little complex because each application needs one or two more setups to handle internal configurations so these are built if the additional files exist and then the application is built and signed. All you have to do to add another application to the build is add one line to the MAKEALL.BAT file.
Note that this assumes that you are using Inno Setup 5, it will need an edit to work with 6 and hasn't been checked with 6 yet.
I am executing a windows bat script through jenkins. Batch file is giving the desired output,however build is failing.My batch file is..
cd /d D:\\Bank\\Member\\ID
if %errorlevel% neq 0 exit /b %errorlevel%
mkdir OTP
if %errorlevel% neq 0 exit /b %errorlevel%
robocopy C:\Corporate D:\\Bank\\Member\\ID\ /E /XF *.bat
if %errorlevel% neq 1 exit /b %errorlevel%
cd /d D:\\Bank\\Staff\\ID
ROBOCOPY GIVES EXIT CODE 1 AFTER SUCESSFULLY COPYING FILES.
BUT JENKINS FAILS BUILD AND GIVING BELOW ERROR:
Build step 'Execute Windows batch command' marked build as failure
Finished: FAILURE
I Want the build to be successful if robocopy exits code 1.
My best advise would be to use jenkins-pipeline, try/catch block, and use bat commands as few as possible (or do not use at all).
But considering your case there's a simple solution as well: just set the field "ERRORLEVEL to set build unstable" to 1 (or other suitable number). The field appears if you click "Advanced" button under the "Execute Windows batch command" block:
This method will check your build as "Unstable", but will continue to execute.
please use like following to avoid:
bat "robocopy /s source dest & EXIT /B 0"
The above will continue the jenkins build even if robocopy returns non-zero errorlevel. Robocopy does not return 0 for various reasons even after successfull copy, as it compared the two folders. Please lookup for it's return code to know more details
As mentioned here, the first criteria to check is the account used to run Jenkins.
Type services.msc to open the Windows services and look for the Jenkins service.
Instead of "Local Service Account", use your own account: that will avoid any right issue.
But: the other criteria is to display the error code.
As mentioned here:
All exit codes up to '3' are fine.
So after robocopy, you can add:
#echo robocopy exit code: %ERRORLEVEL%
#if %ERRORLEVEL% GTR 3 ( echo robocopy ERROR )
#if %ERRORLEVEL% GTR 3 ( exit %ERRORLEVEL% )
#set ERRORLEVEL=0
REM at the end:
exit /b 0
That will ensure Jenkins don't fail the batch step, even though the original error level for robocopy was 1.
I'm currently writing my first batch file for deploying an asp.net solution.
I've been Googling a bit for a general error handling approach and can't find anything really useful.
Basically if any thing goes wrong I want to stop and print out what went wrong.
Can anyone give me any pointers?
I generally find the conditional command concatenation operators much more convenient than ERRORLEVEL.
yourCommand && (
echo yourCommand was successful
) || (
echo yourCommand failed
)
There is one complication you should be aware of. The error branch will fire if the last command in the success branch raises an error.
yourCommand && (
someCommandThatMayFail
) || (
echo This will fire if yourCommand or someCommandThatMayFail raises an error
)
The fix is to insert a harmless command that is guaranteed to succeed at the end of the success branch. I like to use (call ), which does nothing except set the ERRORLEVEL to 0. There is a corollary (call) that does nothing except set the ERRORLEVEL to 1.
yourCommand && (
someCommandThatMayFail
(call )
) || (
echo This can only fire if yourCommand raises an error
)
See Foolproof way to check for nonzero (error) return code in windows batch file for examples of the intricacies needed when using ERRORLEVEL to detect errors.
Using ERRORLEVEL when it's available is the easiest option. However, if you're calling an external program to perform some task, and it doesn't return proper codes, you can pipe the output to 'find' and check the errorlevel from that.
c:\mypath\myexe.exe | find "ERROR" >nul2>nul
if not ERRORLEVEL 1 (
echo. Uh oh, something bad happened
exit /b 1
)
Or to give more info about what happened
c:\mypath\myexe.exe 2&1> myexe.log
find "Invalid File" "myexe.log" >nul2>nul && echo.Invalid File error in Myexe.exe && exit /b 1
find "Error 0x12345678" "myexe.log" >nul2>nul && echo.Myexe.exe was unable to contact server x && exit /b 1
Other than ERRORLEVEL, batch files have no error handling. You'd want to look at a more powerful scripting language. I've been moving code to PowerShell.
The ability to easily use .Net assemblies and methods was one of the major reasons I started with PowerShell. The improved error handling was another. The fact that Microsoft is now requiring all of its server programs (Exchange, SQL Server etc) to be PowerShell drivable was pure icing on the cake.
Right now, it looks like any time invested in learning and using PowerShell will be time well spent.
A successful ping on your local network can be trapped using ERRORLEVEL.
#ECHO OFF
PING 10.0.0.123
IF ERRORLEVEL 1 GOTO NOT-THERE
ECHO IP ADDRESS EXISTS
PAUSE
EXIT
:NOT-THERE
ECHO IP ADDRESS NOT NOT EXIST
PAUSE
EXIT
I guess this feature was added since the OP but for future reference errors that would output in the command window can be redirected to a file independent of the standard output
command 1> file - Write the standard output of command to file
command 2> file - Write the standard error of command to file
Python Unittest, Bat process Error Codes:
if __name__ == "__main__":
test_suite = unittest.TestSuite()
test_suite.addTest(RunTestCases("test_aggregationCount_001"))
runner = unittest.TextTestRunner()
result = runner.run(test_suite)
# result = unittest.TextTestRunner().run(test_suite)
if result.wasSuccessful():
print("############### Test Successful! ###############")
sys.exit(1)
else:
print("############### Test Failed! ###############")
sys.exit()
Bat codes:
#echo off
for /l %%a in (1,1,2) do (
testcase_test.py && (
echo Error found. Waiting here...
pause
) || (
echo This time of test is ok.
)
)
Its extremely easy!
Create a file that contains:
call <filename> // the file you made
cls
echo An error occured!
<Your commands>
pause
So now when you start it, it will launch your program as normal. But when anything goes wrong it exits and continues the script inside the first file. Now there you can put your own commands in.