I have a Jenkins job that deploys an artifact to a server. I want to give the job runner the ability to disable the job for a set amount of time - could be one hour, could be one month. I also want them to have to enter a reason. The reason (along with various other info - build name, runner name etc.) then needs to be emailed to a distribution list.
Is there a way to disable a job for a set amount of time from within itself, on successful completion?
I'm guessing I need the parameterised build plugin, which I'm already successfully using for a couple of jobs.
EDIT:
I'm thinking I could do this by checking for a lock file in a pre-step, and writing a lock file either containing or named for the time at which the build becomes unlocked. I thought there might be a plugin or something I could use instead though.
Ok, so I went with my method in the end. Using a parameterised build (using the Parameterised Build Plugin), I ask the builder to enter the date they wish the job to be locked until. This is then written to a .lock file as a post-build step.
Subsequently, as a pre-build step, I look for a .lock file and read the contents. I then compare the date in the file to the current date, and either fail the build if the job is locked, or continue.
The code is below.
Pre-Step:
#!/bin/bash
echo ''
EXIT_CODE=0
LOCK_FILE_NAME=$DEPLOYMENT_ENV'.lock'
#Check chosen branch isn't master
if [ $BRANCH_NAME = 'master' ]
then
echo 'This job is for building feature branches. To build master, use the Deploy Master Artifact To Staging job.'
EXIT_CODE=666;
else
#Check if lock file exists for selected environment
if [ -f $LOCK_FILE_NAME ]
then
echo 'Lock file found for' $DEPLOYMENT_ENV
FILE_CONTENTS=`head -n 1 $LOCK_FILE_NAME`
LOCK_DATE=`date -d $FILE_CONTENTS +'%Y%m%d'`
NOW=`date +'%Y%m%d'`
#Compare lock date to today. Has the lock expired?
if [ $NOW -gt $LOCK_DATE ]
then
echo $DEPLOYMENT_ENV 'no longer locked. Proceeding with deployment...'
else
echo 'Job locked until:' `date -d $LOCK_DATE +'%d-%m-%Y'`
echo 'Aborting job...'
EXIT_CODE=666
fi
else
echo 'No lock file present for' $DEPLOYMENT_ENV
echo 'Proceeding with deployment...'
fi
echo ''
exit $EXIT_CODE
Post-Step:
#!/bin/bash
echo '**********' $WORKSPACE
#Copy artifact to web server
#Start web server
#Set lock
echo 'Now lock the environment until:' $LOCK_UNTIL;
echo $LOCK_UNTIL > $WORKSPACE'/'$DEPLOYMENT_ENV'.lock'
Scripting isn't really my forte, so if anyone has any better suggestions I'd be pleased to hear them :)
Related
In a Jenkins freestyle job (on an older 1.6x version, no support for 2.x pipeline jobs) I would like to run a shell command (curl -XPOST ...) as a post build step if the build status recovered(!) from FAILED to SUCCESS.
However, all plugins for determining the build status I am aware of can only do something if the current build status IS FAILED or SUCCESS but don't take into account whether it recovered in comparison to the last build.
Is there any way how to achieve this, e.g. using the Groovy Post build plugin and some lines of scripting?
I found that something like this is a good way to go.
You can build up some interesting logic, and the "currentBuild" variable has some decent documentation here: currentBuild variable doc
script {
if ( ( currentBuild.resultIsBetterOrEqualTo("SUCCESS") && currentBuild.previousBuild.resultIsWorseOrEqualTo("UNSTABLE") ) || currentBuild.resultIsWorseOrEqualTo("UNSTABLE")) {
echo "If current build is good, and last build is bad, or current build is bad"
}
}
Meanwhile I found a way to achieve this. It is not necessarily pretty and I still appreciate alternative solutions :)
First of all, a plugin is needed which lets you execute shell commands in a Post Build step. There might be different ones, I am using the PostBuildScript plugin for that.
Then, create a "Execute a set of scripts" post build step, set the step to execute to Build step and select Execute shell, for me this looks like this:
In there, I run the following shell script lines which use my Jenkins server's REST API in combination with a Python one-liner (you could also use jq or something else for this) to determine the status of the current build as well as of the last completed build:
statusOfCurrentBuild=$(curl --silent "${BUILD_URL}api/json" | python -c "import sys, json; print json.load(sys.stdin)['result']")
statusOfLastBuild=$(curl --silent "${JOB_URL}/lastCompletedBuild/api/json" | python -c "import sys, json; print json.load(sys.stdin)['result']")
if [ "${statusOfCurrentBuild}" == "SUCCESS" ] && [ "${statusOfLastBuild}" == "FAILURE" ]
then
echo "Build was fixed"
# do something interesting here
fi
Depending on your Jenkins settings, using the REST API might require authentication.
Jenkins HockeyApp plugin can automatically create reasonably nicely formatted release notes from git changes. However, this does not seem to work if HockeyApp upload is done in promotion phase, using promotion plugin. In that case the change log is empty.
This can be partially solved by selecting "Load Release Notes from File" and giving path to changelog.xml in the project (../builds/${PROMOTED_NUMBER}/changelog.xml), but the output is not as clean as it is with the "Use Change Log" selection, containing also the file names and commit id's.
What is the best way to automatically create nicely formatted logs for HockeyApp transfer, when the transfer happens in promotion phase and possibly on a Jenkins slave machine?
Answering to myself: It is possible to get the change log from jenkins master to jenkins slave
and parsing the obtained changelog.xml to more user readable by using this simple script:
#!/bin/bash
PROJECT_NAME="$1"
BUILD_NUMBER="$2"
BUILD_DATE="$3"
CHANGELOG=changelog.xml
echo "project=${PROJECT_NAME} build=${BUILD_NUMBER}"
PROJECT_NAME=`basename ${PROJECT_NAME}`
curl ${PROMOTED_URL}api/xml?xpath=/*/changeSet/item/comment\&wrapper=changelog > ${CHANGELOG}
PARSEDLOG=`sed -e 's/<\/[^>]*>/€€/g' ${CHANGELOG} | sed -e 's/<[^>]*>/- /g' | tr €€, '\r' | sed '/^ \s*$/d'`
echo "${PROJECT_NAME} ${BUILD_NUMBER} ${BUILD_DATE} change log:
=====================================================================
${PARSEDLOG}" > changelog.txt
I know there are much better and reliable ways to clean up the xml than the sequence of sed and tr commands I have used, but this works for now.
As a newbie to puppet, i'am trying to track deployment of my files through puppet plugin in Jenkins. Since by default, puppet track the file resources i'am able to do that.
My question is whether there is a way to tell puppet to when to send the report to Jenkins?
In my scenario, i'm getting the file from Jenkins archive, and after that i'm doing a service stop and then unzip the file and copy the content to install location and restart the service.
My requirement is if i can somehow configure puppet to wait until all those resources task run in puppet and if and only if all succeed only, send the report to Jenkins, then i'll be able to know deployment is 100% complete.
Also would like to know is there a way to notify Jenkins about deployment failures?
If I understand it correctly, you can do the next thing:
when the jenkins job starts, run on the puppet agent:
puppet agent --disable
then:
puppet agent -t
EXIT_CODE=$?
if [[ ${EXIT_CODE} == 0 ]] || [[ ${EXIT_CODE} == 2 ]]; then
true
exit $?
else
exit ${EXIT_CODE}
fi
That way if puppet status is 0 or 2 - which means if it's run changed successfully or unchanged (successfully) - you will get true.
else, you will exit your shell run with false, and the job will fail.
You can also print comments and such and use https://wiki.jenkins-ci.org/display/JENKINS/Log+Parser+Plugin plugin to make the build green / yellow / red as you like.
I want to setup master and slave relationship in Jenkins without opening the jenkins link.
Is it possible to change the config.xml and form this setup?
The value of slave node will be passed as parameter and will be put in the config file.
If I understand your question correctly, you can try this following solution. Actually my current Test framework is working as CI configured just like you want. What you need to do is:
find suitable Plugin that you can use and support
set your Jenkins jobs to get configurations form your Code project e.g. from VCS
(goto Job Config > Source Code Management > Check-out Strategy must be set to 'as much as possible')
This can be done in following steps:
install Powershell/Batch plugin for Jenkins
prepare update script and put it in your code project
every time you need to configure your Jenkins job, just set properties in your script
update/commit your code project into the VCS
run your Jenkins job
As example you can use this sample batch code as configurable pre-steps:
#echo off
call %WORKSPACE%/jenkins-scripts/set-properties.bat "myRootFolder=/user/project" "rootRefDataFolder=12345" "standartVersion=1.2.3" "alwaysReload=false"
call %WORKSPACE%/jenkins-scripts/do-something-else.bat
And this one as set-properties.bat:
#echo off
echo ----------------------------------------------------------
SET PROP_NAME=base.Project.properties
echo Task: [Update %PROP_NAME%] started
echo Workspace: %WORKSPACE%
SET PROJECT_PATH=projectPath=%WORKSPACE:\=/%
SET RESULT_FOLDER=testResultFolder=report
SET PROP_PATH=%WORKSPACE%\test\resources
DEL "%PROP_PATH%\%PROP_NAME%"
echo %PROJECT_PATH%>> "%PROP_PATH%\%PROP_NAME%"
echo %RESULT_FOLDER%>> "%PROP_PATH%\%PROP_NAME%"
for %%x in (%*) do echo %%~x>> "%PROP_PATH%\%PROP_NAME%"
echo Current properties:
echo __________________________________________________________
type "%PROP_PATH%\%PROP_NAME%"
echo __________________________________________________________
echo Task: [Update %PROP_NAME%] finished
echo ----------------------------------------------------------
Just be sure to set your own paths and variables.
I have a bash script that looks like this:
#!/bin/sh
previousRelease=`git describe --tags --match "release*" origin/release`
git diff --name-status $previousRelease..origin/release
Is there a way of having Jenkins execute it as part of a build process? The intention is to see a list of files that have changed since the last release, as a manual step to confirm that the release should go up. The user who has triggered the build needs to read the output and then confirm the release should go ahead.
Most things are possible to do in Jenkins but if it is the best way of doing it is another question.
To solve this I would use an approach with two jobs one for checking the diff (hock that one on to the git repository) The other job for doing the actual release.
The check diff job
1 Create a job of the type freestyle project with build type "execute shell" and run your script above. Add some prints at the end of the log to create a clickable link to manually start the release job with current git-id as argument.
Just printing an URL in console output will make it clickable so:
export GITID=`git log -n| grep and sed or awk something`
echo http://jenkins.example.com:8888/job/releaseme/buildWithParameters?label=$GITID¶meters=build
will create the accept changes user interface you requested.
The release job
2 Create another job(above I assumed you named it releaseme) let the job have one parameter as argument (tick "This build is parameterized") make let the argument be the git-id you would like to release. Create your release script in this job.