Last active
September 5, 2023 02:09
-
-
Save pdunnavant/4743895 to your computer and use it in GitHub Desktop.
Script that uses the versions-maven-plugin to automatically increment the build number in the version of a project. This is intended to be used in a continuous delivery environment.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
################################################################################# | |
# WARNING: DO NOT JUST RUN THIS SCRIPT BLINDLY. MAKE SURE YOU UNDERSTAND WHAT IT | |
# IS DOING. IT *WILL* TRY TO COMMIT CHANGES. IT WILL ALSO TRY TO EAT YOUR | |
# CHILDREN. IT MAY CAUSE THE SUN TO GO SUPERNOVA. I CLAIM NO RESPONSIBILITY FOR | |
# WHATEVER HAPPENS AFTER YOU RUN THIS. NOW, CARRY ON. :-) | |
# | |
# This script, run from the root of a Maven single or multi-module project, will | |
# update the pom files to increment the build number on the version. | |
# If a newer version of a parent pom exists, that will also be updated to the | |
# current latest version. | |
# If desired, dependencies (all or a subset) can also be updated. This is | |
# generally useful for internal libraries where you'd probably want to switch to | |
# using the latest as soon as possible. | |
# | |
# Here are some examples as to what this will to with the version | |
# (existing --> after script run): | |
# 1.0-SNAPSHOT --> 1.1 | |
# 1.0.0.0 --> 1.0.0.1 | |
# 1.0.0.1 --> 1.0.0.2 | |
# 8 --> 9 | |
# | |
# Nonstandard versions (e.g. with alphabetic characters) have NOT been tested | |
# thoroughly with this! Test with -d (dry run) to make sure this doesn't hose | |
# things. | |
################################################################################# | |
# The following can contain multiple <groupId>:<artifactId> pairings. If more are | |
# desired, each should be space-delimited. The format of each is: | |
# "groupId:artifactId[:type:classifier:version]" | |
# See http://mojo.codehaus.org/versions-maven-plugin/use-latest-versions-mojo.html#includesList | |
# for more information. If this is left as an empty string, no dependency updates | |
# will be done. | |
#UPDATE_DEPENDENCIES_WITH_GROUPID="com.example*:*" | |
#UPDATE_DEPENDENCIES_WITH_GROUPID="com.example.foo:bar:1.*" | |
#UPDATE_DEPENDENCIES_WITH_GROUPID="com.example.foo:* com.example.bar:* com.example.fluffy:*" | |
UPDATE_DEPENDENCIES_WITH_GROUPID="" | |
################################################################################# | |
MAVEN_BIN=`which mvn` | |
MAVEN_VERSIONS_PLUGIN="org.codehaus.mojo:versions-maven-plugin:1.3.1" | |
MAVEN_VERSIONS_PLUGIN_SET_GOAL="${MAVEN_VERSIONS_PLUGIN}:set -DgenerateBackupPoms=false" | |
MAVEN_VERSIONS_PLUGIN_UPDATE_PARENT_GOAL="${MAVEN_VERSIONS_PLUGIN}:update-parent -DgenerateBackupPoms=false -DallowSnapshots=true" | |
MAVEN_VERSIONS_PLUGIN_UPDATE_DEPENDENCIES_GOAL="${MAVEN_VERSIONS_PLUGIN}:use-latest-versions -DgenerateBackupPoms=false -DallowSnapshots=false" | |
MAVEN_HELP_PLUGIN="org.apache.maven.plugins:maven-help-plugin:2.1.1" | |
MAVEN_HELP_PLUGIN_EVALUATE_VERSION_GOAL="${MAVEN_HELP_PLUGIN}:evaluate -Dexpression=project.version" | |
DRY_RUN=false | |
ALLOW_OUTSIDE_JENKINS=false | |
SKIP_BRANCH_SWITCH=false | |
LAST_COMMIT_HASH=`git log -1 --pretty=format:"%H"` | |
function printUsage() { | |
echo "Usage: ${0} [option(s)]" | |
echo | |
echo " -b Skip branch manipulation. This should not be used on Jenkins, and should normally be used locally." | |
echo " -d Dry run. Do everything except the commit process." | |
echo " -h Show this help text." | |
echo " -j Skip the Jenkins check and allow a run outside of Jenkins (for testing purposes)." | |
echo " -v new_version Override generated version to the specific version." | |
echo " This should be in the format: major.minor.patch.build. (e.g. 2.8.1.0)" | |
} | |
while getopts ":v:bhdj" OPT; do | |
case ${OPT} in | |
b) | |
SKIP_BRANCH_SWITCH=true | |
;; | |
d) | |
DRY_RUN=true | |
SKIP_BRANCH_SWITCH=true | |
ALLOW_OUTSIDE_JENKINS=true | |
;; | |
h) | |
printUsage | |
exit 0 | |
;; | |
j) | |
ALLOW_OUTSIDE_JENKINS=true | |
;; | |
v) | |
NEXT_PROJECT_VERSION="${OPTARG}" | |
;; | |
\?) | |
echo "Invalid option: -${OPTARG}" >&2 | |
printUsage | |
exit 30 | |
;; | |
:) | |
echo "Option -$OPTARG requires an argument." >&2 | |
printUsage | |
exit 1 | |
;; | |
esac | |
done | |
function validateCIServerRun() { | |
IS_JENKINS_SERVER=false | |
if [ ! -z "${JENKINS_URL}" ] ; then | |
echo "This job is being run on Jenkins. JENKINS_URL=${JENKINS_URL}" | |
IS_JENKINS_SERVER=true | |
fi | |
if [ ${IS_JENKINS_SERVER} = false ] ; then | |
echo "Detected that we're not on the Jenkins server. Exiting script with error status." | |
exit 10 | |
fi | |
} | |
function validatePomExists() { | |
CURRENT_DIRECTORY=`pwd` | |
if [ -f pom.xml ] ; then | |
echo "Found pom.xml file: [${CURRENT_DIRECTORY}/pom.xml]" | |
else | |
echo "ERROR: No pom.xml file detected in current directory [${CURRENT_DIRECTORY}]. Exiting script with error status." | |
exit 50 | |
fi | |
} | |
function validatePom() { | |
${MAVEN_BIN} validate | |
STATUS=`echo $?` | |
if [ ${STATUS} -ne 0 ] ; then | |
echo "ERROR: Maven POM did not validate successfully. Exiting script with error status." | |
exit 40 | |
fi | |
} | |
function initCurrentProjectVersion() { | |
echo -n "Detecting current project version number..." | |
CURRENT_PROJECT_VERSION=`${MAVEN_BIN} ${MAVEN_HELP_PLUGIN_EVALUATE_VERSION_GOAL} | egrep '^[0-9\.]*(-SNAPSHOT)?$'` | |
if [ -z ${CURRENT_PROJECT_VERSION} ] ; then | |
echo " ERROR: Couldn't detect current version. Validating pom in case there was a validation issue." | |
validatePom | |
echo " ERROR: Couldn't detect current version. Exiting with error status." | |
exit 20 | |
else | |
echo " Version found: [${CURRENT_PROJECT_VERSION}]" | |
fi | |
} | |
function initNextProjectVersion() { | |
local CLEANED=`echo ${CURRENT_PROJECT_VERSION} | sed -e 's/[^0-9][^0-9]*$//'` | |
local CURRENT_BUILD_NUMBER=`echo ${CLEANED} | sed -e 's/[0-9]*\.//g'` | |
local NEXT_BUILD_NUMBER=`expr ${CURRENT_BUILD_NUMBER} + 1` | |
echo "Sanitized current project version: [${CLEANED}]" | |
echo "Current build number in project version: [${CURRENT_BUILD_NUMBER}]" | |
echo "Calculated next build number: [${NEXT_BUILD_NUMBER}]" | |
if [ -z ${NEXT_PROJECT_VERSION} ] ; then | |
NEXT_PROJECT_VERSION=`echo ${CLEANED} | sed -e "s/[0-9][0-9]*\([^0-9]*\)$/${NEXT_BUILD_NUMBER}/"` | |
else | |
echo "Version number was overridden on the command line. Using [${NEXT_PROJECT_VERSION}] to calculate next version." | |
NEXT_PROJECT_VERSION="${NEXT_PROJECT_VERSION}" | |
fi | |
echo "Next project version: [${NEXT_PROJECT_VERSION}]" | |
} | |
function updateProjectPomsToNextVersion() { | |
echo "Updating project version to [${NEXT_PROJECT_VERSION}]..." | |
${MAVEN_BIN} ${MAVEN_VERSIONS_PLUGIN_SET_GOAL} -DnewVersion=${NEXT_PROJECT_VERSION} | |
} | |
function updateToLatestParentPom() { | |
echo "Updating parent pom to latest version..." | |
${MAVEN_BIN} ${MAVEN_VERSIONS_PLUGIN_UPDATE_PARENT_GOAL} | |
} | |
function updateToLatestDependencies() { | |
echo "Updating dependencies to latest versions..." | |
for DEPENDENCY in ${UPDATE_DEPENDENCIES_WITH_GROUPID} ; do | |
echo "Updating dependencies matching [${DEPENDENCY}]..." | |
${MAVEN_BIN} ${MAVEN_VERSIONS_PLUGIN_UPDATE_DEPENDENCIES_GOAL} -DincludesList=${DEPENDENCY} | |
done | |
} | |
function commitBuildNumberChanges() { | |
echo "Preparing updated files for commit..." | |
git status | |
# add the now updated pom files | |
echo "Adding pom files..." | |
for POM in `find . -name pom.xml` ; do | |
git add ${POM} | |
echo " - ${POM}" | |
done | |
echo "Committing changes..." | |
local BUILD_NUMBER_CHANGES_COMMIT_MESSAGE="Auto commit from CI - incremented build number from [${CURRENT_PROJECT_VERSION}] to [${NEXT_PROJECT_VERSION}]." | |
git commit -m "${BUILD_NUMBER_CHANGES_COMMIT_MESSAGE}" | |
echo "Pushing changes to origin..." | |
git push origin | |
} | |
################################################################################# | |
# Here's where the fun begins. | |
################################################################################# | |
echo "Did you read and understand this script first? Go find and remove this line at your risk." | |
exit 1 | |
# Make sure this script is running on the continuous integration server. | |
if [ ${ALLOW_OUTSIDE_JENKINS} = true ] ; then | |
echo "Skipping Jenkins validation for testing purposes." | |
else | |
validateCIServerRun | |
fi | |
# Make sure that there's a pom that we can do anything with. | |
validatePomExists | |
# Figure out which commit was last done and expose a variable with the branch | |
# name where that commit happened. | |
# TODO: don't do this yet... it's flaky and I need to figure out why. | |
# Assume master for now. | |
LAST_COMMIT_BRANCH="master" | |
# Jenkins uses the master branch to get the codebase, but the workspace itself | |
# is shown to git as (no branch). To get around this, we must check out master | |
# prior to actually touching any files. | |
# TODO: This will obviously not work when the job isn't using master... so | |
# we may need to deal with that at some point. | |
if [ ${SKIP_BRANCH_SWITCH} = true ] ; then | |
echo "Skipping switch to [${LAST_COMMIT_BRANCH}] branch." | |
else | |
switchToBranch | |
fi | |
################################################################################# | |
# Update the project POMs with the new build number. | |
################################################################################# | |
initCurrentProjectVersion | |
initNextProjectVersion | |
updateProjectPomsToNextVersion | |
updateToLatestParentPom | |
updateToLatestDependencies | |
################################################################################# | |
# Commit/Push updated files up to the repository | |
################################################################################# | |
if [ ${DRY_RUN} = false ] ; then | |
commitBuildNumberChanges | |
else | |
echo "Dry run specified. Skipping commit/push process." | |
fi | |
echo "Version updated successfully!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi
Maybe you have full example? with maven, pom.xml etc