7 # ##############################################################################
9 # ##############################################################################
11 # The digit representation of a version can be in the format 0.6.4 or 0.6.4.1
12 declare versionRegexDigits="([[:digit:]]+.[[:digit:]]+.[[:digit:]]+)(.[[:digit:]]+)?"
14 # The version for source code can be in the format:
15 # - 0.6.4 or 0.6.4.1 or pre-0.6.4 or pre-0.6.4.1
16 declare versionRegexSources="(|pre-)(${versionRegexDigits})"
18 # The version for a release tag is in the format v0.6.4 or v0.6.4.1
19 declare versionRegexReleaseTag="v(${versionRegexDigits})"
21 # A release branch is in the format release-0.6.4 or release-0.6.4.1
22 declare relBranchRegex="release-(${versionRegexDigits})"
27 # ##############################################################################
29 # ##############################################################################
32 # Trim a string: remove spaces from the beginning and end of the string
35 # return=trimmed string
36 function stringTrim() {
37 if [[ -z "${1}" ]]; then
41 # remove leading whitespace characters
42 local var="${1#${1%%[![:space:]]*}}"
44 # remove trailing whitespace characters
45 echo "${var%${var##*[![:space:]]}}"
50 # Get the canonical path of a file or directory
51 # This is the physical path without any links
53 # 1=the file or directory
54 function pathCanonicalPath() {
55 local src="$(stringTrim "${1}")"
57 if [[ -h "${src}" ]] && [[ -d "${src}" ]]; then
58 # src is a link to a directory
60 cd -P "${src}" &> /dev/null
66 # we're not dealing with a directory here
67 while [[ -h "${src}" ]]; do
68 # keep getting the link target while src is a link
69 src="$(ls -la "${src}" | \
70 sed -r 's#^.*?[[:space:]]+->[[:space:]]+(.*)$#\1#')"
72 # src is no longer a link here
75 cd -P "$(dirname "${src}")" &> /dev/null
76 echo "$(pwd -P)/$(basename "${src}")"
82 # Determine whether a given directory is a git repository directory
85 # return=0 not a git dir, 1 a git dir
86 function gitIsGitDirectory() {
87 local place="$(stringTrim "${1}")"
90 if [[ -d "${place}" ]]; then
91 pushd "${place}" &> /dev/null
93 git rev-parse --git-dir &> /dev/null
99 if [[ ${result} -ne 0 ]]; then
108 # Get the version digits from a release tag version
110 # 1=release tag version
111 # return=version digits
112 function getVersionDigitsFromReleaseTag() {
113 echo "$(stringTrim "${1}")" | sed -r "s/${versionRegexReleaseTag}/\1/"
118 # Get the next version digits by incrementing the micro digit
120 # 1=version in format 0.6.4 or 0.6.4.1
121 # return=incremented version in format 0.6.5
122 function getNextVersionDigitsMicro() {
123 local version="$(stringTrim "${1}")"
124 local -a versionDigits=( ${version//\./ } )
125 local -i versionMicroNext=$(( ${versionDigits[2]} + 1 ))
126 echo "${versionDigits[0]}.${versionDigits[1]}.${versionMicroNext}"
131 # Get the next version digits by incrementing the patchlevel digit
133 # 1=version in format 0.6.4 or 0.6.4.0
134 # return=incremented version in format 0.6.4.1
135 function getNextVersionDigitsPatchLevel() {
136 local version="$(stringTrim "${1}")"
137 local -a versionDigits=( ${version//\./ } )
138 local -i versionPatchLevelNext=1
139 if [[ ${#versionDigits[*]} -ne 3 ]]; then
140 versionPatchLevelNext=$(( ${versionDigits[3]} + 1 ))
142 echo "${versionDigits[0]}.${versionDigits[1]}.${versionDigits[2]}.${versionPatchLevelNext}"
147 # Adjust the branch name so that we can release 0.6.4.x from the
148 # release-0.6.4 branch
150 # prevTagVersionDigits relBranchVersionDigits relBranchVersionDigits (adjusted)
151 # 0.6.4 0.6.4 0.6.4.1
155 # 0.6.4.5 0.6.4 0.6.4.6
159 function adjustBranchName() {
160 local -a prevTagVersionDigitsArray=( ${prevTagVersionDigits//\./ } )
161 local -a relBranchVersionDigitsArray=( ${relBranchVersionDigits//\./ } )
162 local -i prevTagVersionDigitsCount=${#prevTagVersionDigitsArray[*]}
163 local -i relBranchVersionDigitsCount=${#relBranchVersionDigitsArray[*]}
164 local prevTagVersionTrain="$(echo "$(stringTrim "${prevTagVersionDigits}")" | \
165 sed -r "s/${versionRegexDigits}/\1/")"
167 if [[ "${prevTagVersionDigits}" == "${relBranchVersionDigits}" ]] || \
168 ([[ "${prevTagVersionTrain}" == "${relBranchVersionDigits}" ]] && \
169 [[ ${prevTagVersionDigitsCount} -eq 4 ]] && \
170 [[ ${relBranchVersionDigitsCount} -eq 3 ]]); then
171 relBranchVersionDigits="$(getNextVersionDigitsPatchLevel "${prevTagVersionDigits}")"
177 # Check that the new version is incrementing
181 function checkVersionIncrementing() {
182 local lastVersion="$(stringTrim "${1}")"
183 local newVersion="$(stringTrim "${2}")"
184 local errorstr="* The new version ${newVersion} is not greater than the previous version ${lastVersion}"
186 local -a lastVersionDigits=( ${lastVersion//\./ } )
187 local -a newVersionDigits=( ${newVersion//\./ } )
189 # if the last version is in the format 0.6.4 then assume 0.6.4.0
190 if [[ ${#lastVersionDigits[*]} -ne 4 ]]; then
191 lastVersionDigits[3]=0
194 # if the new version is in the format 0.6.4 then assume 0.6.4.0
195 if [[ ${#newVersionDigits[*]} -ne 4 ]]; then
196 newVersionDigits[3]=0
200 if [[ ${newVersionDigits[0]} -lt ${lastVersionDigits[0]} ]]; then
204 if [[ ${newVersionDigits[0]} -gt ${lastVersionDigits[0]} ]]; then
209 if [[ ${newVersionDigits[1]} -lt ${lastVersionDigits[1]} ]]; then
213 if [[ ${newVersionDigits[1]} -gt ${lastVersionDigits[1]} ]]; then
218 if [[ ${newVersionDigits[2]} -lt ${lastVersionDigits[2]} ]]; then
222 if [[ ${newVersionDigits[2]} -gt ${lastVersionDigits[2]} ]]; then
227 if [[ ${newVersionDigits[3]} -lt ${lastVersionDigits[3]} ]]; then
231 if [[ ${newVersionDigits[3]} -gt ${lastVersionDigits[3]} ]]; then
235 # everything is equal
242 # Commit the current changes, allow an empty commit, or amend (when the commit
243 # message is the same as that of the last commit)
246 function commitChanges() {
247 local -i allowEmpty=${1}
248 local msg="$(stringTrim "${2}")"
250 local lastMsg="$(git log -1 --format="%s")"
251 lastMsg="$(stringTrim "${lastMsg}")"
253 if [[ ${allowEmpty} -ne 0 ]]; then
254 extra="${extra} --allow-empty"
256 if [[ "${msg}" == "${lastMsg}" ]]; then
257 extra="${extra} --amend"
260 git commit -s -q ${extra} -m "${msg}" &> /dev/null
266 # Update the version in all relevant files
268 # 1=the new version (in the format of versionRegexSources)
269 function updateVersions() {
270 local newVersion="$(stringTrim "${1}")"
273 # Adjust debug settings in Makefile.inc
275 local src="Makefile.inc"
277 -e 's/^[[:space:]]*DEBUG[[:space:]]*?=.*$/DEBUG ?= 1/' \
278 -e 's/^[[:space:]]*NO_DEBUG_MESSAGES[[:space:]]*?=.*$/NO_DEBUG_MESSAGES ?= 0/' \
286 # Adjust version in Makefile
289 sed -ri "s/^([[:space:]]*VERS[[:space:]]*=[[:space:]]*)${versionRegexSources}[[:space:]]*\$/\1${newVersion}/" "${src}"
296 # Adjust version in win32 gui installer
298 local src="gui/win32/Inst/installer.nsi"
299 local grepStr="^([[:space:]]*MessageBox[[:space:]]+MB_YESNO[[:space:]]+\".+?[[:space:]]+olsr.org[[:space:]]+)${versionRegexSources}([[:space:]]+.+?\"[[:space:]]+IDYES[[:space:]]+NoAbort)[[:space:]]*$"
300 local replStr="\1${newVersion}\6"
301 sed -ri "s/${grepStr}/${replStr}/" "${src}"
308 # Adjust version in win32 gui front-end
310 local src="gui/win32/Main/Frontend.rc"
311 local grepStr="^([[:space:]]*CAPTION[[:space:]]+\"olsr.org[[:space:]]+Switch[[:space:]]+)${versionRegexSources}([[:space:]]*\")[[:space:]]*\$"
312 local replStr="\1${newVersion}\6"
313 sed -ri "s/${grepStr}/${replStr}/" "${src}"
324 function signTextFile() {
325 local txtFile="$(stringTrim "${1}")"
326 gpg -u "$(git config --get user.name)" --clearsign "${txtFile}"
327 mv "${txtFile}.asc" "${txtFile}"
333 # ##############################################################################
335 # ##############################################################################
337 declare script="$(pathCanonicalPath "${0}")"
338 declare scriptDir="$(dirname "${script}")"
339 declare baseDir="$(dirname "${scriptDir}")"
344 # Check the number of arguments
346 if [[ ${#} -ne 0 ]]; then
347 echo "* Need no arguments"
353 # Go into the root of the checkout and check some key files
356 if [[ "$(gitIsGitDirectory ".")" == "0" ]] || \
357 [[ ! -r ./Makefile.inc ]] || \
358 [[ ! -r ./files/olsrd.conf.default.full ]]; then
359 echo "* You do not appear to be running the script from an olsrd git checkout"
365 # Check that a signing key is configured
367 declare gpgKeyId="$(git config --get user.signingkey)"
368 if [[ -z "${gpgKeyId}" ]]; then
370 * No signing key is setup for git, please run
371 git config --global user.signingkey <key ID>
373 You can get keys and IDs by running 'gpg --list-keys'
380 # Check that the signing key is present
383 gpg --list-key "${gpgKeyId}" &> /dev/null
384 declare -i gpgKeyIdPresentResult=${?}
386 if [[ ${gpgKeyIdPresentResult} -ne 0 ]]; then
388 * Your signing key with ID ${gpgKeyId} is not found, please run
389 git config --global user.signingkey <key ID>
390 to setup a valid key ID.
392 You can get keys and IDs by running 'gpg --list-keys'
399 # Get the previous release tag and check
402 declare prevRelTagVersion="$(git describe --abbrev=0 | \
403 grep -E "^${versionRegexReleaseTag}$")"
405 if [[ -z "${prevRelTagVersion}" ]]; then
406 echo "* Could not find the previous release tag"
409 declare prevTagVersionDigits="$(getVersionDigitsFromReleaseTag "${prevRelTagVersion}")"
413 # Get the current branch and check that we're on a release branch
415 declare relBranch="$(git rev-parse --abbrev-ref HEAD)"
416 declare relBranch="$(stringTrim "${relBranch}")"
417 if [[ -z "$(echo "${relBranch}" | grep -E "^${relBranchRegex}\$")" ]]; then
418 echo "* You are not on a release branch (format: release-0.6.4 or release-0.6.4.1)"
424 # Get the version to release from the current branch
426 declare relBranchVersionDigits="$(echo "${relBranch}" | \
427 sed -r "s/${relBranchRegex}/\1/")"
431 declare relTagVersion="v${relBranchVersionDigits}"
432 declare relBranchVersionDigitsNextMicro="$(getNextVersionDigitsMicro "${relBranchVersionDigits}")"
433 declare relBranchVersionDigitsNextPatchLevel="$(getNextVersionDigitsPatchLevel "${relBranchVersionDigits}")"
437 # Check that the version is incrementing
439 checkVersionIncrementing "${prevTagVersionDigits}" "${relBranchVersionDigits}"
443 # Confirm the release
448 * All checks pass, ready to release ${relBranchVersionDigits}.
450 * The previous version found is: ${prevTagVersionDigits}
451 Note: If this is not the version you were expecting, then maybe that
452 version wasn't merged into this branch.
453 * Continuing will DESTROY any modifications you currently have in your tree!
456 read -p "Press [enter] to continue or CTRL-C to exit..."
462 # Clean up the checkout
464 echo "Cleaning the git checkout..."
470 # Update the versions for release
472 echo "Updating the version to ${relBranchVersionDigits}..."
473 updateVersions "${relBranchVersionDigits}"
474 commitChanges 1 "Release ${relTagVersion}"
479 # Generate the changelog
481 echo "Generating the changelog..."
482 declare src="CHANGELOG"
483 declare dst="mktemp -q -p . -t "${src}.XXXXXXXXXX""
484 cat > "${dst}" << EOF
485 ${relBranchVersionDigits} -------------------------------------------------------------------
488 git rev-list --pretty=short "${prevRelTagVersion}..HEAD" | \
489 git shortlog -w80 -- >> "${dst}"
490 cat "${src}" >> "${dst}"
495 commitChanges 1 "Release ${relTagVersion}"
501 echo "Tagging ${relTagVersion}..."
503 git tag -d "${relTagVersion}" &> /dev/null
505 git tag -s -m "OLSRd release ${relBranchVersionDigits}" "${relTagVersion}"
509 # Update the version to the next release
511 echo "Updating the version to pre-${relBranchVersionDigitsNextPatchLevel}..."
512 updateVersions "pre-${relBranchVersionDigitsNextPatchLevel}"
513 commitChanges 1 "Update version after release of ${relTagVersion}"
517 # Update the version (on the master branch) to the next release
519 echo "Updating the version to pre-${relBranchVersionDigitsNextMicro} on the master branch..."
520 git checkout -q master
523 updateVersions "pre-${relBranchVersionDigitsNextMicro}"
524 commitChanges 0 "Update version after release of ${relTagVersion}"
525 git checkout -q "${relBranch}"
531 # Make the release tarballs
533 echo "Generating the release tarballs..."
534 declare tarFile="${scriptDir}/olsrd-${relBranchVersionDigits}.tar"
535 declare tarGzFile="${tarFile}.gz"
536 declare tarBz2File="${tarFile}.bz2"
537 git archive --format=tar --output="${tarFile}" "${relTagVersion}"
538 gzip -c "${tarFile}" > "${tarGzFile}"
539 bzip2 -c "${tarFile}" > "${tarBz2File}"
541 echo "Generating the release tarball checksums..."
542 declare md5File="${scriptDir}/MD5SUM-${relBranchVersionDigits}"
543 declare sha256File="${scriptDir}/SHA256SUM-${relBranchVersionDigits}"
544 md5sum "${tarGzFile}" "${tarBz2File}" > "${md5File}"
545 sha256sum "${tarGzFile}" "${tarBz2File}" > "${sha256File}"
546 echo "Signing the release tarball checksums..."
547 signTextFile "${md5File}"
548 signTextFile "${sha256File}"
556 echo "==================="
557 echo "= Git Updates ="
558 echo "==================="
559 echo "Branch : master"
560 echo "Branch : ${relBranch}"
561 echo "Tag : ${relTagVersion}"
566 echo "==================="
567 echo "= Generated Files ="
568 echo "==================="
579 echo "==================="
580 echo "= Manual Actions ="
581 echo "==================="
582 echo "1. Check that everything is in order. For example, run:"
583 echo " gitk master ${relBranch} ${relTagVersion} "
584 echo "2. Push. For example, run:"
585 echo " git push origin master ${relBranch} ${relTagVersion}"
586 echo "3. Upload the generated files to"
587 echo " http://www.olsr.org/releases/${relBranchVersionDigits}"
588 echo "4. Add a release article on olsr.org."