.bat file to shell conversion to pass variable between Jenkins build step and post build step - shell

In my Jenkins post build email (using extended email plugin), I want to use a variable identified in a build step (windows batch) using the EnvInject plugin. The plugin requires a properties file to be created using a shell script. I am having difficulties converting the following batch lines to shell:
svn log --limit 1 > Change_Request.txt
set "ChangeRequest="
for /f "skip=3 delims=" %%i in (Change_Request.txt) do if not defined ChangeRequest set "ChangeRequest=%%i"
echo ChangeRequest=%ChangeRequest% > export.properties

The situation: There is a Jenkins plugin named EnvInject that allows variables to be passed from a build step to a post build step. The variable was not being passed between the steps.
Perceived issue at the time: After reading the error log message and instructions on using the plugin, I thought the plugin only worked with a shell script.
Real issue: I was trying to read the properties file from a different location than where it was written.
Solution: Initially resolved by using a shell script to write the variable to a properties file:
echo ChangeRequest=$(svn log --limit 1|sed '4q;d')>export.properties
This resolved the issue as it created the properties file in the expected location.
But if I had properly identified the issue, it could have been resolved in the initial batch script.
When updating the Jenkins job to pass a second variable, I realized the real reason my initial effort failed. I updated my first batch script to pass the variables to a properties file, in the expected location. I ran my svn command from the repository directory, then returned to my job's workspace directory to write the properties file.
svn log --limit 1 > ..\..\..\Change_Request.txt
for /f "skip=3 delims=" %%i in (..\..\..\Change_Request.txt) do if not defined >ChangeRequest set ChangeRequest=%%i
for /f "delims=: tokens=1,2" %%a in ('svn info %Repository_URL%') do (
if "%%a"=="Revision" (
set /a RevisionNumber=%%b
)
)
CD D:\Jenkins\workspace\JOB_Folder\
echo ChangeRequest=%ChangeRequest% > export.properties
echo RevisionNumber=%RevisionNumber% >> export.properties

Having no svn I can't test this, but it might work.
Coming from windows I'm quite new to shell/bash.
First version quite simmilar:
svn log --limit 1 > Change_Request.txt
ChangeRequest=$(sed '4q;d' Change_Request.txt)
echo ChangeRequest=$ChangeRequest>export.properties
Shorter no var:
svn log --limit 1 > Change_Request.txt
echo ChangeRequest=$(sed '2q;d' Change_Request.txt)>export.properties
Shortest no intermediate file (maybe required)
echo ChangeRequest=$(svn log --limit 1|sed '4q;d')>export.properties
PowerShell variant
svn log --limit 1 > Change_Request.txt
"ChangeRequest=$((gc Change_Request.txt)[4])" > export.properties

Related

TeamCity - problem reading text from same file a second time

I'm seeing some peculiar behaviour in a TeamCity step that uses a cmd script.
In the example below, %USERPROFILE%\myfile.txt contains only the text "abc123" without quotes.
set /p myFileContent=<"%env.USERPROFILE%\myfile.txt"
echo "%%myFileContent%%"
set /p myFileContentTwo=<"%env.USERPROFILE%\myfile.txt"
echo "%%myFileContentTwo%%"
Output:
"abc123"
""
What is going on here? The file is read correctly first time, but not the second time. It works fine if I run the equivalent cmd script outside of TeamCity:
#echo off
set /p myFileContent=<"%USERPROFILE%\myfile.txt"
echo "%myFileContent%"
set /p myFileContentTwo=<"%USERPROFILE%\myfile.txt"
echo "%myFileContentTwo%"
Output:
"abc123"
"abc123"
I first observed this problem when reading the same file in two separate steps, with a wait of several seconds between reads, suggesting it's not a sharing violation. The file is intact and has the expected content after all steps have run.
I'm on TeamCity Enterprise 2021.2.1 (build 99602) on Windows 10.

Detect a Missing file based on its Date

I need to manually monitor a random windows-based backup program for failures and the only way to do this is via checking for the daily backup file it makes.
A batch file would be simplest for me to implement. It would need to scan a directory for a certain file type and then do X if a file doesn't exist that was created/modified yesterday.
C:\backups\random-named-file.tib 27/03/2017
C:\backups\random-named-file.tib 28/03/2017
C:\backups\random-named-file.tib 29/03/2017
So if a random-named-file.tib wasnt created or modified yesterday, it means the backup failed and I would write output to the console saying "Backup Failed"
Does anyone please have any ideas ?
EDIT :
To clarify, the backup files are coming from a custom application that has no way to check for missed backups. The batch file solution I'm looking for will be integrated into our RMM platform, which will take the results of the batch file and raise a support desk ticket for our Service desk to action.
The backup application will apply its own retention policies and delete any backups older then 4 days.
I'm just trying to detect if a backup was missed the previous day. The filenames are variable, the only constant is the file extension ( *.tib)
This backup app doesn't write eventlogs, nor does it create its own log files I can parse for Failure messages.
1) I would suggest you, go through this article
four-ways-to-manage-windows-server-2008-backup-on-multiple-servers
2) There is a windows scheduler which can act according to your situation
Window scheduler Wiki
3) You can write scripts which alert you whenever it fails
4) I have found a Solution for your similar kind of problem
make-windows-task-scheduler-alert-on-fail
TL:Dr --> see step 4
I manged to do what you asked. On a quick note, since it's Windows backup program there should be a way to automatically alert when backup fails.
Note about this example: I did this in a specific folder structure. If you want to change the location of batch file, second line of code inside batch file needs to be updated with appropriate path. In this example the path is relative, but it's easy to change, so I leave that up to you.
Here is my folder structure:
\---batch # Folder with batch file
backups.txt # check_backups.bat creates this file
check_backups.bat # Batch file that does the job
| filename1.tib
| filename2.tib
| filename3.tib
| filename5.tib
Here is the code of batch file (check_backups.bat):
#echo off
dir ..\* /a-d /b > "%~dp0\backups.txt"
set count=1
setlocal EnableDelayedExpansion
FOR /F "delims=*" %%A IN (backups.txt) DO (
SET fl=%%~nA
IF !fl:~8! NEQ !count! (
echo Backup Failed: Missing file is 'filename!count!.tib'
goto failed
)
SET /A count=!count!+1
)
echo All is good
:failed
pause
If filename9.tib is missing you will get a message: "Backup failed: Missing file is filename9.tib".
If everyhing is good you will get a message: "All is good".

TeamCity Command Line Runner: Setting and using variables

Within a TeamCity project running on a windows agent, I would like to read the contents of a file and then create a directory based on the file contents.
Performing this operation as a command line build step seems logical. I have tried creating a local variable "VERSION" as well as a custom teamcity parameter, but I can't get either to work. It does not seem that windows cmd variables are playing nicely with the TeamCity defined env and system variables. I am using the following custom script:
echo "Distributing"
set VERSION=< component_version.txt
echo %VERSION%
echo "Copying files to dir \path\to\dir\%VERSION%\"
mkdir \path\to\dir\%VERSION%\
Any suggestions on how I can achieve this?
You need to escape the variable with %% so it isn't treated as a TeamCity variable.
echo "Distributing"
set VERSION=< component_version.txt
echo %%VERSION%%
echo "Copying files to dir \path\to\dir\%%VERSION%%\"
mkdir \path\to\dir\%%VERSION%%\
Try creating a .bat file or Powershell file that accepts a parameter, and executes the steps you have outlined above.
Then switch your Build step to run an "executable with parameters", and pass the %VERSION% in as a parameter.

Batch process all files in directory

Right now i have a batch job I wrote that calls another file and passes in the variables that executable needs to run (password and filename).
Ex:
> cd f:\test\utils
> admin import-xml -Dimport.file=f:\DB\file1.xml -Dadmin.db.password=test123
I wrote a job that does this, but found out that there would be multiple files.
The username and password never change but the filename differs for like 15 different xml files--with maybe more coming soon.
The files will always be located in the same folder. Instead of ending up with like 15-20 jobs (one for each file), can I write something that will process each file located in this directory. And either wait till one is completed before the next or I can add a 3 min sleep before it starts the next file.
pushd C:\test\utils
for %%F in (F:\DB\*.xml) do (
admin import-xml "-Dimport.file=%%~dpnxF" -Dadmin.db.password=test123
)
popd
The %%~dpnxF expands to d‎rive, p‎ath, base‎n‎ame and e‎x‎tension of the current file.
If you intend to set and use environment variables (%foo%) in that loop, read help set first before you get into trouble.
You can use the for command. Something like this in a batch file:
for %%f in (*.xml) do call myotherbatch.bat %%f
Assuming that the admin command you are running doesn't return until the job is finished, the above loop would process them sequentially.
If you run the command at the prompt (as opposed to in a batch file), only use a single %.
for file in f:\DB\*
do
admin import-xml -Dimport.file="$file" -Dadmin.db.password=test123
done

svn export from post commit does not work on window?

I am setting up a SVN server in a windows environment:
Whenever a tag is made, the post-commit script export a certain number of information about the tag (like author, comments, dependencies ...).
I also want to attach specific files from the tagged repository. To do so, I have been trying the "svn export" commands. This work fine for a "simulated" tag, but does not work using the svn client (tortoise).
svn export --username foo --password bar svn://localhost/My_SVN_DB/tags/My_Tag/My_File.txt My_Export_Directory
I checked the following:
Syntax of the command --> Seems to be ok, it works when calling the post commit and passing test arguments
Access rights for My_Export_Directory --> Seems to be ok as the script write also a debug file there
Now I am wondering if the tag structure is already present when executing the post commit script? (I thought it was..?)
Any ideas ?
Redirecting the standard output & standard error help to find the problem:
svn export --username foo --password bar svn://localhost/My_SVN_DB/tags/My_Tag/My_File.txt My_Export_Directory > tmp.log 2>&1
The problem came from one statement before the export. The DB name was extracted using a for /f loop and overwriting an temporary loop variable ( DBNAME ).
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Extract the DB name
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setLocal EnableDelayedExpansion
for /f "tokens=4 delims=\" %%a in ("%REPOS%") do (set DBNAME=%%a)
echo !DBNAME!>%TMPFILE%
endlocal
REM Here is the problem
set /p DBNAME=<%TMPFILE%
By modifying the last variable name into DBNAME2:
set /p DBNAME2=<%TMPFILE%
The script was able to work properly.
It is still very unclear to me why this happens since the very same trick (for /f + overwrite) is also used in pre-commit script and there it works properly. Any ideas??

Resources