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 # Go into the root of the checkout and check some key files
110 function checkIsOlsrdGitCheckout() {
111 if [[ "$(gitIsGitDirectory ".")" == "0" ]] || \
112 [[ ! -r ./Makefile.inc ]] || \
113 [[ ! -r ./files/olsrd.conf.default.full ]]; then
114 echo "* You do not appear to be running the script from an olsrd git checkout"
121 # Check that a signing key is configured
123 function checkGitSigningKeyIsConfigured() {
124 local gpgKeyId="$(git config --get user.signingkey)"
125 if [[ -z "${gpgKeyId}" ]]; then
127 * No signing key is setup for git, please run
128 git config --global user.signingkey <key ID>
130 You can get keys and IDs by running 'gpg --list-keys'
136 # Check that the signing key is present
139 gpg --list-key "${gpgKeyId}" &> /dev/null
140 local -i gpgKeyIdPresentResult=${?}
142 if [[ ${gpgKeyIdPresentResult} -ne 0 ]]; then
144 * Your signing key with ID ${gpgKeyId} is not found, please run
145 git config --global user.signingkey <key ID>
146 to setup a valid key ID.
148 You can get keys and IDs by running 'gpg --list-keys'
156 # Get the version digits from a release tag version
158 # 1=release tag version
159 # return=version digits
160 function getVersionDigitsFromReleaseTag() {
161 echo "$(stringTrim "${1}")" | sed -r "s/${versionRegexReleaseTag}/\1/"
166 # Get the previous release tag and check
168 declare prevRelTagVersion=""
169 function getPrevRelTag() {
171 prevRelTagVersion="$(git describe --abbrev=0 | \
172 grep -E "^${versionRegexReleaseTag}$")"
174 if [[ -z "${prevRelTagVersion}" ]]; then
175 echo "* Could not find the previous release tag"
182 # Get the next version digits by incrementing the micro digit
184 # 1=version in format 0.6.4 or 0.6.4.1
185 # return=incremented version in format 0.6.5
186 function getNextVersionDigitsMicro() {
187 local version="$(stringTrim "${1}")"
188 local -a versionDigits=( ${version//\./ } )
189 local -i versionMicroNext=$(( ${versionDigits[2]} + 1 ))
190 echo "${versionDigits[0]}.${versionDigits[1]}.${versionMicroNext}"
195 # Get the next version digits by incrementing the patchlevel digit
197 # 1=version in format 0.6.4 or 0.6.4.0
198 # return=incremented version in format 0.6.4.1
199 function getNextVersionDigitsPatchLevel() {
200 local version="$(stringTrim "${1}")"
201 local -a versionDigits=( ${version//\./ } )
202 local -i versionPatchLevelNext=1
203 if [[ ${#versionDigits[*]} -ne 3 ]]; then
204 versionPatchLevelNext=$(( ${versionDigits[3]} + 1 ))
206 echo "${versionDigits[0]}.${versionDigits[1]}.${versionDigits[2]}.${versionPatchLevelNext}"
211 # Adjust the branch name so that we can release 0.6.4.x from the
212 # release-0.6.4 branch
214 # prevTagVersionDigits relBranchVersionDigits relBranchVersionDigits (adjusted)
215 # 0.6.4 0.6.4 0.6.4.1
219 # 0.6.4.5 0.6.4 0.6.4.6
223 function adjustBranchName() {
224 local -a prevTagVersionDigitsArray=( ${prevTagVersionDigits//\./ } )
225 local -a relBranchVersionDigitsArray=( ${relBranchVersionDigits//\./ } )
226 local -i prevTagVersionDigitsCount=${#prevTagVersionDigitsArray[*]}
227 local -i relBranchVersionDigitsCount=${#relBranchVersionDigitsArray[*]}
228 local prevTagVersionTrain="$(echo "$(stringTrim "${prevTagVersionDigits}")" | \
229 sed -r "s/${versionRegexDigits}/\1/")"
231 if [[ "${prevTagVersionDigits}" == "${relBranchVersionDigits}" ]] || \
232 ([[ "${prevTagVersionTrain}" == "${relBranchVersionDigits}" ]] && \
233 [[ ${prevTagVersionDigitsCount} -eq 4 ]] && \
234 [[ ${relBranchVersionDigitsCount} -eq 3 ]]); then
235 relBranchVersionDigits="$(getNextVersionDigitsPatchLevel "${prevTagVersionDigits}")"
241 # Check that the new version is incrementing
245 function checkVersionIncrementing() {
246 local lastVersion="$(stringTrim "${1}")"
247 local newVersion="$(stringTrim "${2}")"
248 local errorstr="* The new version ${newVersion} is not greater than the previous version ${lastVersion}"
250 local -a lastVersionDigits=( ${lastVersion//\./ } )
251 local -a newVersionDigits=( ${newVersion//\./ } )
253 # if the last version is in the format 0.6.4 then assume 0.6.4.0
254 if [[ ${#lastVersionDigits[*]} -ne 4 ]]; then
255 lastVersionDigits[3]=0
258 # if the new version is in the format 0.6.4 then assume 0.6.4.0
259 if [[ ${#newVersionDigits[*]} -ne 4 ]]; then
260 newVersionDigits[3]=0
264 if [[ ${newVersionDigits[0]} -lt ${lastVersionDigits[0]} ]]; then
268 if [[ ${newVersionDigits[0]} -gt ${lastVersionDigits[0]} ]]; then
273 if [[ ${newVersionDigits[1]} -lt ${lastVersionDigits[1]} ]]; then
277 if [[ ${newVersionDigits[1]} -gt ${lastVersionDigits[1]} ]]; then
282 if [[ ${newVersionDigits[2]} -lt ${lastVersionDigits[2]} ]]; then
286 if [[ ${newVersionDigits[2]} -gt ${lastVersionDigits[2]} ]]; then
291 if [[ ${newVersionDigits[3]} -lt ${lastVersionDigits[3]} ]]; then
295 if [[ ${newVersionDigits[3]} -gt ${lastVersionDigits[3]} ]]; then
299 # everything is equal
306 # Commit the current changes, allow an empty commit, or amend (when the commit
307 # message is the same as that of the last commit)
310 function commitChanges() {
311 local -i allowEmpty=${1}
312 local msg="$(stringTrim "${2}")"
314 local lastMsg="$(git log -1 --format="%s")"
315 lastMsg="$(stringTrim "${lastMsg}")"
317 if [[ ${allowEmpty} -ne 0 ]]; then
318 extra="${extra} --allow-empty"
320 if [[ "${msg}" == "${lastMsg}" ]]; then
321 extra="${extra} --amend"
324 git commit -s -q ${extra} -m "${msg}" &> /dev/null
330 # Update the version in all relevant files
332 # 1=the new version (in the format of versionRegexSources)
333 function updateVersions() {
334 local newVersion="$(stringTrim "${1}")"
337 # Adjust debug settings in Makefile.inc
339 local src="Makefile.inc"
341 -e 's/^[[:space:]]*DEBUG[[:space:]]*?=.*$/DEBUG ?= 1/' \
342 -e 's/^[[:space:]]*NO_DEBUG_MESSAGES[[:space:]]*?=.*$/NO_DEBUG_MESSAGES ?= 0/' \
350 # Adjust version in Makefile
353 sed -ri "s/^([[:space:]]*VERS[[:space:]]*=[[:space:]]*)${versionRegexSources}[[:space:]]*\$/\1${newVersion}/" "${src}"
360 # Adjust version in win32 gui installer
362 local src="gui/win32/Inst/installer.nsi"
363 local grepStr="^([[:space:]]*MessageBox[[:space:]]+MB_YESNO[[:space:]]+\".+?[[:space:]]+olsr\.org[[:space:]]+)${versionRegexSources}([[:space:]]+.+?\"[[:space:]]+IDYES[[:space:]]+NoAbort)[[:space:]]*$"
364 local replStr="\1${newVersion}\6"
365 sed -ri "s/${grepStr}/${replStr}/" "${src}"
372 # Adjust version in win32 gui front-end
374 local src="gui/win32/Main/Frontend.rc"
375 local grepStr="^([[:space:]]*CAPTION[[:space:]]+\"olsr\.org[[:space:]]+Switch[[:space:]]+)${versionRegexSources}([[:space:]]*\")[[:space:]]*\$"
376 local replStr="\1${newVersion}\6"
377 sed -ri "s/${grepStr}/${replStr}/" "${src}"
388 function signTextFile() {
389 local txtFile="$(stringTrim "${1}")"
390 gpg -u "$(git config --get user.name)" --clearsign "${txtFile}"
391 mv "${txtFile}.asc" "${txtFile}"
397 # ##############################################################################
399 # ##############################################################################
401 declare script="$(pathCanonicalPath "${0}")"
402 declare scriptDir="$(dirname "${script}")"
403 declare baseDir="$(dirname "${scriptDir}")"
410 # Check the number of arguments
412 if [[ ${#} -ne 0 ]]; then
413 echo "* Need no arguments"
418 checkIsOlsrdGitCheckout
419 checkGitSigningKeyIsConfigured
421 declare prevTagVersionDigits="$(getVersionDigitsFromReleaseTag "${prevRelTagVersion}")"
425 # Get the current branch and check that we're on a release branch
427 declare relBranch="$(git rev-parse --abbrev-ref HEAD)"
428 declare relBranch="$(stringTrim "${relBranch}")"
429 if [[ -z "$(echo "${relBranch}" | grep -E "^${relBranchRegex}\$")" ]]; then
430 echo "* You are not on a release branch (format: release-0.6.4 or release-0.6.4.1)"
436 # Get the version to release from the current branch
438 declare relBranchVersionDigits="$(echo "${relBranch}" | \
439 sed -r "s/${relBranchRegex}/\1/")"
443 declare relTagVersion="v${relBranchVersionDigits}"
444 declare relBranchVersionDigitsNextMicro="$(getNextVersionDigitsMicro "${relBranchVersionDigits}")"
445 declare relBranchVersionDigitsNextPatchLevel="$(getNextVersionDigitsPatchLevel "${relBranchVersionDigits}")"
449 # Check that the version is incrementing
451 checkVersionIncrementing "${prevTagVersionDigits}" "${relBranchVersionDigits}"
455 # Confirm the release
460 * All checks pass, ready to release ${relBranchVersionDigits}.
462 * The previous version found is: ${prevTagVersionDigits}
463 Note: If this is not the version you were expecting, then maybe that
464 version wasn't merged into this branch.
465 * Continuing will DESTROY any modifications you currently have in your tree!
468 read -p "Press [enter] to continue or CTRL-C to exit..."
474 # Clean up the checkout
476 echo "Cleaning the git checkout..."
482 # Update the versions for release
484 echo "Updating the version to ${relBranchVersionDigits}..."
485 updateVersions "${relBranchVersionDigits}"
486 commitChanges 1 "Release ${relTagVersion}"
491 # Generate the changelog
493 echo "Generating the changelog..."
494 declare src="CHANGELOG"
495 declare dst="mktemp -q -p . -t "${src}.XXXXXXXXXX""
496 cat > "${dst}" << EOF
497 ${relBranchVersionDigits} -------------------------------------------------------------------
500 git rev-list --pretty=short "${prevRelTagVersion}..HEAD" | \
501 git shortlog -w80 -- >> "${dst}"
502 cat "${src}" >> "${dst}"
507 commitChanges 1 "Release ${relTagVersion}"
513 echo "Tagging ${relTagVersion}..."
515 git tag -d "${relTagVersion}" &> /dev/null
517 git tag -s -m "OLSRd release ${relBranchVersionDigits}" "${relTagVersion}"
521 # Update the version to the next release
523 echo "Updating the version to pre-${relBranchVersionDigitsNextPatchLevel}..."
524 updateVersions "pre-${relBranchVersionDigitsNextPatchLevel}"
525 commitChanges 1 "Update version after release of ${relTagVersion}"
529 # Update the version (on the master branch) to the next release
531 echo "Updating the version to pre-${relBranchVersionDigitsNextMicro} on the master branch..."
532 git checkout -q master
535 updateVersions "pre-${relBranchVersionDigitsNextMicro}"
536 commitChanges 0 "Update version after release of ${relTagVersion}"
537 git checkout -q "${relBranch}"
543 # Make the release tarballs
545 echo "Generating the release tarballs..."
546 declare tarFile="${scriptDir}/olsrd-${relBranchVersionDigits}.tar"
547 declare tarGzFile="${tarFile}.gz"
548 declare tarBz2File="${tarFile}.bz2"
549 git archive --format=tar --output="${tarFile}" "${relTagVersion}"
550 gzip -c "${tarFile}" > "${tarGzFile}"
551 bzip2 -c "${tarFile}" > "${tarBz2File}"
553 echo "Generating the release tarball checksums..."
554 declare md5File="${scriptDir}/MD5SUM-${relBranchVersionDigits}"
555 declare sha256File="${scriptDir}/SHA256SUM-${relBranchVersionDigits}"
556 md5sum "${tarGzFile}" "${tarBz2File}" > "${md5File}"
557 sha256sum "${tarGzFile}" "${tarBz2File}" > "${sha256File}"
558 echo "Signing the release tarball checksums..."
559 signTextFile "${md5File}"
560 signTextFile "${sha256File}"
568 echo "==================="
569 echo "= Git Updates ="
570 echo "==================="
571 echo "Branch : master"
572 echo "Branch : ${relBranch}"
573 echo "Tag : ${relTagVersion}"
578 echo "==================="
579 echo "= Generated Files ="
580 echo "==================="
591 echo "==================="
592 echo "= Manual Actions ="
593 echo "==================="
594 echo "1. Check that everything is in order. For example, run:"
595 echo " gitk master ${relBranch} ${relTagVersion} "
596 echo "2. Push. For example, run:"
597 echo " git push origin master ${relBranch} ${relTagVersion}"
598 echo "3. Upload the generated files to"
599 echo " http://www.olsr.org/releases/${relBranchVersionDigits}"
600 echo "4. Add a release article on olsr.org."