diff options
author | John Stebbins <[email protected]> | 2015-08-28 11:16:56 -0700 |
---|---|---|
committer | John Stebbins <[email protected]> | 2015-09-23 11:45:42 -0700 |
commit | 25de99bb279ccf562b53765dfdc0bf459109aab8 (patch) | |
tree | 3b0693e5e1167bb9935ce4de7520aa46d7e704a1 /scripts | |
parent | d2aa5174694bf78040f41d2b3755549f37c31153 (diff) |
build: changes to version numbering and build process
Use date/time for snapshot version numbers, YYYYMMDDHHMMSS-hash-branch.
Add --snapshot configure option to force snapshot builds.
repo-info.sh and tag-release.sh improvements.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/repo-info.sh | 122 | ||||
-rwxr-xr-x | scripts/tag-release.sh | 273 |
2 files changed, 266 insertions, 129 deletions
diff --git a/scripts/repo-info.sh b/scripts/repo-info.sh index 0e402535d..4e8795344 100755 --- a/scripts/repo-info.sh +++ b/scripts/repo-info.sh @@ -2,66 +2,78 @@ # # Retrieves git repository info for directory ${1} using command ${2} -# Args -REPO_DIR='.' -if [[ ${1} ]]; then - REPO_DIR=${1} -fi -GIT_EXE='git' -if [[ ${2} ]]; then - GIT_EXE=${2} -fi +function repo_info() +{ + local repo_dir git_exe commit upstream err -# Switch to working directory -if ! cd ${REPO_DIR} 2>/dev/null; then - echo "Invalid directory ${REPO_DIR}." 1>&2 - exit 1 -fi + # Process args + repo_dir='.' + if [[ ${1} ]]; then + repo_dir=${1} + fi + git_exe='git' + if [[ ${2} ]]; then + git_exe=${2} + fi + + # Switch to working directory + if ! cd ${repo_dir} 2>/dev/null; then + echo "Invalid directory ${repo_dir}." 1>&2 + return 1 + fi -# Check whether we have git -if ! hash ${GIT_EXE} 2>/dev/null; then - echo "Command '${GIT_EXE}' not found." 1>&2 - exit 1 -fi + # Check whether we have git + if ! hash ${git_exe} 2>/dev/null; then + echo "Command '${git_exe}' not found." 1>&2 + return 1 + fi -# Check if there is a valid git repo here -HASH=$(${GIT_EXE} rev-parse HEAD) -ERR=$? -if [[ ${ERR} -ne 0 ]]; then - echo "Not a valid repository." 1>&2 - exit ${ERR} -elif [[ -z ${HASH} ]]; then - echo "Not a valid repository." 1>&2 - exit 1 -fi + # Check if there is a valid git repo here + HASH=$(${git_exe} rev-parse HEAD) + SHORTHASH=$(${git_exe} rev-parse --short HEAD) + err=$? + if [[ ${err} -ne 0 ]]; then + echo "Not a valid repository." 1>&2 + return ${err} + elif [[ -z ${HASH} ]]; then + echo "Not a valid repository." 1>&2 + return 1 + fi -# Retrieve info -URL=$(${GIT_EXE} config remote.origin.url) -TAG=$(${GIT_EXE} describe --tags --abbrev=0) -if [[ ${TAG} ]]; then - REV=$(${GIT_EXE} rev-list ${TAG}.. --count) -else - TAG=$(${GIT_EXE} describe --tags $(${GIT_EXE} rev-list --tags --max-count=1)) + # Retrieve info + URL=$(${git_exe} config remote.origin.url) + + # check if an annotated tag is reachable from HEAD + TAG=$(${git_exe} describe --tags --abbrev=0 --exact-match --match \[0-9\]\*.\[0-9\]\*.\[0-9\]\* HEAD 2> /dev/null) if [[ ${TAG} ]]; then - REV=$(${GIT_EXE} rev-list $(${GIT_EXE} merge-base ${TAG} HEAD).. --count) + # if TAG is a release tag and HASH == TAG_HASH, this is release code + TAG_HASH=$(${git_exe} rev-list ${TAG} --max-count=1) + REV=$(${git_exe} rev-list $(${git_exe} merge-base ${TAG} HEAD).. --count) else - REV=$(${GIT_EXE} rev-list HEAD --count) + REV=$(${git_exe} rev-list HEAD --count) + fi + + BRANCH=$(${git_exe} symbolic-ref -q --short HEAD) + REMOTE="${URL}" + upstream=$(${git_exe} config branch.${BRANCH}.remote) + if [[ ${upstream} ]]; then + REMOTE="${upstream}" fi -fi -BRANCH=$(${GIT_EXE} symbolic-ref -q --short HEAD) -REMOTE="${URL}" -UPSTREAM=$(${GIT_EXE} config branch.${BRANCH}.remote) -if [[ ${UPSTREAM} ]]; then - REMOTE="${UPSTREAM}" -fi -DATE=$(${GIT_EXE} log -1 --format="format:%ai") + DATE=$(${git_exe} log -1 --format="format:%ci") + + # Output + # Only write tag and rev if they exist. + echo "URL=${URL}" + echo "HASH=${HASH}" + echo "SHORTHASH=${SHORTHASH}" + if [[ ${TAG} ]]; then echo "TAG=${TAG}"; fi + if [[ ${TAG_HASH} ]]; then echo "TAG_HASH=${TAG_HASH}"; fi + if [[ ${REV} ]]; then echo "REV=${REV}"; fi + echo "BRANCH=${BRANCH}" + echo "REMOTE=${REMOTE}" + echo "DATE=${DATE}" + + return 0 +} -# Output -# Only write tag and rev if they exist. -echo "URL=${URL}" -echo "HASH=${HASH}" -if [[ ${TAG} ]]; then echo "TAG=${TAG}"; fi -if [[ ${REV} ]]; then echo "REV=${REV}"; fi -echo "BRANCH=${BRANCH}" -echo "REMOTE=${REMOTE}" -echo "DATE=${DATE}" +repo_info "$@" diff --git a/scripts/tag-release.sh b/scripts/tag-release.sh index 66e33e308..9f7d488f6 100755 --- a/scripts/tag-release.sh +++ b/scripts/tag-release.sh @@ -1,86 +1,211 @@ #! /bin/bash # -# Usage: tag-release.sh <release-ver> [<commit>] +# Usage: tag-release.sh <release-ver> [<ref>] # -# Creates a new branch and tag for the release -# Optionally, the release can be based off a specific git commit. +# Creates a new bugfix branch and release tag for a release. +# Optionally, the release can be based off a specific git ref. +# Default is HEAD of the current branch. +# +# The script does a lot of error checking, but boils down to +# the following actions. +# +# For major/minor releases (X.Y.0) from master branch: +# git checkout -b X.Y.x +# git tag -a X.Y.Z -m "X.Y.Z" HEAD +# and optionally: +# git push -u origin X.Y.x +# git push origin refs/tags/X.Y.Z +# +# For bugfix releases from associated branch (X.Y.x): +# git tag -a X.Y.Z -m "X.Y.Z" HEAD +# and optionally: +# git push origin refs/tags/X.Y.Z # -TAG=${1} -COMMIT=${2} - -if [ "x${TAG}" == "x" ]; then - echo "Missing release tag (e.g. 0.10.0)" -fi - -if [ "x${COMMIT}" == "x" ]; then - echo "Creating release tag ${TAG} and branch ${TAG}-dev from HEAD, proceed?" -else - echo "Creating release tag ${TAG} and branch ${TAG}-dev from ${COMMIT}, proceed?" -fi -read proceed -if [[ ( "x${proceed}" != "xy" ) && ( "x${proceed}" != "xY" ) ]] ; then - echo "Aborting..." - exit 0 -fi - -if [ "x${COMMIT}" != "x" ]; then - # create release branch from specific commit - git checkout "${COMMIT}" -b "${TAG}-dev" - ERR=$? -else - # create release branch from head of current branch - git checkout -b "${TAG}-dev" - ERR=$? -fi -if [ ${ERR} -ne 0 ]; then - echo "Failed to create branch ${TAG}-dev" - exit ${ERR} -fi - -# create tag -git tag -a "${TAG}" -m "Release ${TAG}" HEAD -ERR=$? -if [ ${ERR} -ne 0 ]; then - echo "Failed to create tag ${TAG}" - # cleanup... remove the branch that was created - git branch -d "${TAG}-dev" - exit ${ERR} -fi - -# checkout tag in preparation for building release -# this should put you in a "detached HEAD" state -git checkout "${TAG}" -ERR=$? -if [ ${ERR} -ne 0 ]; then - echo "Failed to checkout tag ${TAG}" - # cleanup... remove the branch that was created - git branch -d "${TAG}-dev" - exit ${ERR} -fi - -remote=$(git config remote.origin.url) -echo -echo "Do you wish to push this release branch and tag to $remote? (y/N)" -echo "You may want to do this manually after creating and verifying release." -echo "e.g." -echo " git push -u origin ${TAG}-dev" -echo " git push origin ${TAG}" -read proceed -if [[ ( "x${proceed}" == "xy" ) || ( "x${proceed}" == "xY" ) ]] ; then - git push -u origin "${TAG}-dev" +GIT_EXE='git' + +function validate_repo() +{ + local HASH err AHEAD BEHIND proceed + + # Check whether we have git + if ! hash ${GIT_EXE} 2>/dev/null; then + echo "Command '${GIT_EXE}' not found." 1>&2 + return 1 + fi + + # Check if there is a valid git repo here + HASH=$(${GIT_EXE} rev-parse HEAD) + err=$? + if [[ ${err} -ne 0 ]]; then + echo "Not a valid repository." 1>&2 + return ${err} + elif [[ -z ${HASH} ]]; then + echo "Not a valid repository." 1>&2 + return 1 + fi + + if [[ -n "$(${GIT_EXE} status --porcelain)" ]]; then + echo "There are uncommitted changes. Aborting." 1>&2 + return 1 + fi + + echo "Fetching repo data..." + ${GIT_EXE} fetch + err=$? + if [[ ${err} -ne 0 ]]; then + echo "Failed to fetch repo data." 1>&2 + return ${err} + fi + AHEAD=$(${GIT_EXE} rev-list @{u}..HEAD --count) + BEHIND=$(${GIT_EXE} rev-list HEAD..@{u} --count) + if [[ ${AHEAD} -ne 0 ]]; then + echo "There are unpushed changes. Continue anyway? (y/N)" + read proceed + if [[ ( "x${proceed}" != "xy" ) && ( "x${proceed}" != "xY" ) ]] ; then + echo "Aborting..." + return 1 + fi + fi + if [[ ${BEHIND} -ne 0 ]]; then + echo "There are unmerged upstream changes. Continue anyway? (y/N)" + read proceed + if [[ ( "x${proceed}" != "xy" ) && ( "x${proceed}" != "xY" ) ]] ; then + echo "Aborting..." + return 1 + fi + fi +} + +function tag_release() +{ + local TAG REF COMMIT BRANCH proceed new_branch ERR HASH + + TAG=${1} + REF=${2} + + if [ "x${TAG}" == "x" ]; then + echo "Missing release tag (e.g. 0.10.0)" + fi + + # bugfix branch name + BRANCH=${TAG%.[0-9]*}.x + + if [ "x${REF}" == "x" ]; then + echo "Creating release tag ${TAG} and branch ${BRANCH} from HEAD, proceed? (y/N)" + # retrive full hash of HEAD + COMMIT=$(${GIT_EXE} rev-list HEAD --max-count=1) + else + echo "Creating release tag ${TAG} and branch ${BRANCH} from ${REF}, proceed? (y/N)" + # retrieve full hash from ref or short hash + COMMIT=$(${GIT_EXE} rev-list ${REF} --max-count=1) + fi + read proceed + if [[ ( "x${proceed}" != "xy" ) && ( "x${proceed}" != "xY" ) ]] ; then + echo "Aborting..." + return 0 + fi + + # check if the remote branch already exists + ${GIT_EXE} rev-parse --quiet --verify origin/${BRANCH} > /dev/null + if [ $? -ne 0 ]; then + # remote branch does not exist + new_branch=1 + # does the branch already exist locally? + ${GIT_EXE} rev-parse --quiet --verify ${BRANCH} > /dev/null + if [ $? -ne 0 ]; then + # local branch does not exist + # create bugfix branch from commit + ${GIT_EXE} checkout "${COMMIT}" -b "${BRANCH}" + ERR=$? + if [ ${ERR} -ne 0 ]; then + echo "Failed to create branch ${BRANCH}" + return ${ERR} + fi + else + # local branch already exists + # When the branch already exists, make sure it is being used! + current_branch=$(${GIT_EXE} rev-parse --abbrev-ref HEAD) + if [ "$current_branch" != "${BRANCH}" ]; then + echo "You did not checkout the correct branch ${BRANCH} for tag ${TAG}" + return 1 + fi + fi + else + new_branch=0 + # When the branch already exists, make sure it is being used! + current_branch=$(${GIT_EXE} rev-parse --abbrev-ref HEAD) + if [ "$current_branch" != "${BRANCH}" ]; then + echo "You did not checkout the correct branch ${BRANCH} for tag ${TAG}" + return 1 + fi + fi + + # at this point we should be at the head of the tracking branch + # for this release. Make certain that HEAD matches COMMIT + HASH=$(${GIT_EXE} rev-list HEAD --max-count=1) + if [ ${HASH} != ${COMMIT} ]; then + echo "Commit specified does not match current branch HEAD" + return 1 + fi + + # create tag + ${GIT_EXE} tag -a "${TAG}" -m "${TAG}" HEAD ERR=$? if [ ${ERR} -ne 0 ]; then - echo "Failed to push branch ${TAG}-dev to remote" - exit ${ERR} + echo "Failed to create tag ${TAG}" + # cleanup... remove the branch that was created + ${GIT_EXE} branch -d "${BRANCH}" + return ${ERR} fi - git push origin "${TAG}" + + # checkout tag in preparation for building release + # this should put you in a "detached HEAD" state + ${GIT_EXE} checkout "${TAG}" ERR=$? if [ ${ERR} -ne 0 ]; then - echo "Failed to push tag ${TAG}-dev to remote" - exit ${ERR} + echo "Failed to checkout tag ${TAG}" + # cleanup... remove the branch that was created + ${GIT_EXE} branch -d "${BRANCH}" + return ${ERR} + fi + + remote=$(${GIT_EXE} config remote.origin.url) + echo + echo "Do you wish to push this release branch and tag to $remote? (y/N)" + echo "You may want to do this manually after creating and verifying release." + echo "e.g." + echo " git push -u origin ${BRANCH}" + echo " git push origin refs/tags/${TAG}" + read proceed + if [[ ( "x${proceed}" == "xy" ) || ( "x${proceed}" == "xY" ) ]] ; then + if [ $new_branch .eq 1 ]; then + ${GIT_EXE} push -u origin "${BRANCH}" + ERR=$? + if [ ${ERR} -ne 0 ]; then + echo "Failed to push branch ${BRANCH} to remote" + return ${ERR} + fi + fi + ${GIT_EXE} push origin refs/tags/"${TAG}" + ERR=$? + if [ ${ERR} -ne 0 ]; then + echo "Failed to push tag ${BRANCH} to remote" + return ${ERR} + fi + else + echo "Branch and tag are local, changes not pushed to remote!" + fi + +} + +function main() +{ + if validate_repo; then + tag_release "$@" + else + return $? fi -else - echo "Branch and tag are local, changes not pushed to remote!" -fi +} +main "$@" |