File indexing completed on 2025-02-16 05:12:26
0001 #!/usr/bin/env bash 0002 # This script is part of the release procedure of the SOCI library based 0003 # on current state of given release branch or master (see RELEASING.md). 0004 # 0005 # Copyright (c) 2019 Mateusz Loskot <mateusz@loskot.net> 0006 # 0007 # This script performs the following steps: 0008 # 1. If given release/X.Y exists 0009 # - on remote as origin/release/X.Y, check it out; 0010 # - locally, then pass option --use-local-branch to check it out; 0011 # and use it as ready for packaging. 0012 # 3. Determine the full release version number from `SOCI_LIB_VERSION` value in include/soci/version.h. 0013 # 4. Build HTML documentation 0014 # 4.1. Create Python virtual environment 0015 # 4.2. Install MkDocs 0016 # 4.3. Build documentation 0017 # 5. Filter unwanted content 0018 # - Website files 0019 # - Markdown documentation and configuration files 0020 # - CI configuration files 0021 # - Development auxiliary files 0022 # - Git auxiliary files 0023 # 6. Create archives (.zip, .tar.gz) 0024 # 0025 usage() 0026 { 0027 echo "Usage: `realpath $0` [OPTIONS] <release/X.Y branch>" 0028 echo " --rc <N> N is number of release candidate (e.g. from 1 to 9)" 0029 echo " --use-local-branch Use existing local release/X.Y branch instead of checking out origin/release/X.Y" 0030 echo " --help, -h Displays this message" 0031 exit 1 0032 } 0033 ME=`basename "$0"` 0034 MSG_TAG="| $ME" 0035 0036 UNAME_S="$(uname -s)" 0037 case "${UNAME_S}" in 0038 Linux*) THIS_SYS=Linux;; 0039 Darwin*) THIS_SYS=Mac;; 0040 CYGWIN*) THIS_SYS=Cygwin;; 0041 MINGW*) THIS_SYS=MinGW;; 0042 *) THIS_SYS="UNKNOWN:${UNAME_S}" 0043 esac 0044 if [[ "$THIS_SYS" != "Linux" ]]; then 0045 echo "${MSG_TAG} ERROR: This script requires Linux. Yours is '$THIS_SYS'. Aborting." 0046 exit 1 0047 fi 0048 if [[ ! -d "$PWD/.git" ]] || [[ ! -r "$PWD/include/soci/version.h" ]]; then 0049 echo "${MSG_TAG} ERROR: Directory '$PWD' is not Git repository. Aborting." 0050 exit 1 0051 fi 0052 0053 OPT_USE_LOCAL_RELEASE_BRANCH=0 0054 OPT_GIT_RELEASE_BRANCH="" 0055 OPT_RC_NUMBER="" 0056 while [[ $# -gt 0 ]]; 0057 do 0058 case $1 in 0059 --rc) test ! -z $2 && OPT_RC_NUMBER=$2; shift; echo "${MSG_TAG} INFO: Setting --rc=$OPT_RC_NUMBER, building release candidate archive";; 0060 --use-local-branch) OPT_USE_LOCAL_RELEASE_BRANCH=1; echo "${MSG_TAG} INFO: Setting --use-local-branch on, using existing local release/X.Y branch";; 0061 -h|--help) usage;; 0062 *) OPT_GIT_RELEASE_BRANCH=$1;; 0063 esac; 0064 shift 0065 done 0066 0067 if [[ -n "$OPT_RC_NUMBER" ]] && [[ ! "$OPT_RC_NUMBER" =~ ^[1-9]+$ ]]; then 0068 echo "${MSG_TAG} ERROR: Release candidate must be single digit integer from 1 to 9, not '$OPT_RC_NUMBER'. Aborting." 0069 exit 1 0070 fi 0071 0072 GIT_RELEASE_BRANCH=$OPT_GIT_RELEASE_BRANCH 0073 if [[ -z "$GIT_RELEASE_BRANCH" ]] || [[ ! "$GIT_RELEASE_BRANCH" =~ ^release/[3-9]\.[0-9]$ ]]; then 0074 echo "${MSG_TAG} ERROR: Missing valid 'release/X.Y' branch name i.e. release/3.0 or later" 0075 usage 0076 exit 1 0077 fi 0078 0079 GIT_CURRENT_BRANCH=$(git branch | grep \* | cut -d ' ' -f2) 0080 echo "${MSG_TAG} INFO: Current branch is $GIT_CURRENT_BRANCH" 0081 echo "${MSG_TAG} INFO: Releasing branch $GIT_RELEASE_BRANCH" 0082 0083 echo "${MSG_TAG} INFO: Fetching branches from origin" 0084 git fetch origin 0085 0086 # Checkout branch release/X.Y 0087 GIT_LOCAL_RELEASE_BRANCH=$(git branch -a | grep -Po "(\*?\s+)\K$GIT_RELEASE_BRANCH") 0088 if [[ $OPT_USE_LOCAL_RELEASE_BRANCH -eq 1 ]]; then 0089 if [[ -n "$GIT_LOCAL_RELEASE_BRANCH" ]]; then 0090 echo "${MSG_TAG} INFO: Checking out branch '$GIT_RELEASE_BRANCH'" 0091 git checkout $GIT_RELEASE_BRANCH || exit 1 0092 echo "${MSG_TAG} INFO: Updating branch '$GIT_RELEASE_BRANCH' from origin" 0093 git pull --ff-only origin $GIT_RELEASE_BRANCH || exit 1 0094 else 0095 echo "${MSG_TAG} ERROR: Local release branch '$GIT_LOCAL_RELEASE_BRANCH' does not exists. Aborting." 0096 exit 1 0097 fi 0098 else 0099 if [[ -n "$GIT_LOCAL_RELEASE_BRANCH" ]]; then 0100 echo "${MSG_TAG} ERROR: Local release branch '$GIT_LOCAL_RELEASE_BRANCH' already exists. Aborting." 0101 echo "${MSG_TAG} INFO: Delete the local branch and run again to checkout 'origin/$GIT_RELEASE_BRANCH'." 0102 exit 1 0103 fi 0104 fi 0105 0106 # Checkout branch origin/release/X.Y as release/X.Y 0107 if [[ $OPT_USE_LOCAL_RELEASE_BRANCH -eq 0 ]]; then 0108 GIT_REMOTE_RELEASE_BRANCH=$(git branch -a | grep -Po "(\*?\s+)\Kremotes/origin/$GIT_RELEASE_BRANCH") 0109 if [[ -n "$GIT_REMOTE_RELEASE_BRANCH" ]]; then 0110 echo "${MSG_TAG} INFO: Release branch 'origin/$GIT_RELEASE_BRANCH' does exist. Checking it out." 0111 git checkout -b $GIT_RELEASE_BRANCH --no-track origin/$GIT_RELEASE_BRANCH || exit 1 0112 git pull --ff-only origin $GIT_RELEASE_BRANCH || exit 1 0113 else 0114 echo "${MSG_TAG} ERROR: Release branch 'origin/$GIT_RELEASE_BRANCH' does not exist. Aborting" 0115 echo "${MSG_TAG} INFO: Create release branch 'origin/$GIT_RELEASE_BRANCH' and run again." 0116 exit 1 0117 fi 0118 fi 0119 0120 GIT_CURRENT_RELEASE_BRANCH=$(git branch -a | grep -Po "(\*\s+)\K$GIT_RELEASE_BRANCH") 0121 if [[ "$GIT_CURRENT_RELEASE_BRANCH" != "$GIT_RELEASE_BRANCH" ]]; then 0122 echo "${MSG_TAG} ERROR: Current branch is not '$GIT_RELEASE_BRANCH' but '$GIT_CURRENT_RELEASE_BRANCH'. Aborting." 0123 exit 1 0124 fi 0125 0126 SOCI_VERSION=$(cat "$PWD/include/soci/version.h" | grep -Po "(.*#define\s+SOCI_LIB_VERSION\s+.+)\K([3-9]_[0-9]_[0-9])" | sed "s/_/\./g") 0127 if [[ ! "$SOCI_VERSION" =~ ^[4-9]\.[0-9]\.[0-9]$ ]]; then 0128 echo "${MSG_TAG} ERROR: Invalid format of SOCI version '$SOCI_VERSION'. Aborting." 0129 exit 1 0130 else 0131 echo "${MSG_TAG} INFO: Releasing version $SOCI_VERSION" 0132 fi 0133 0134 SOCI_FULL_VERSION=$SOCI_VERSION 0135 if [[ -n $OPT_RC_NUMBER ]];then 0136 SOCI_FULL_VERSION=$SOCI_VERSION-rc$OPT_RC_NUMBER 0137 fi 0138 SOCI_ARCHIVE=soci-$SOCI_FULL_VERSION 0139 0140 if [[ -d "$SOCI_ARCHIVE" ]]; then 0141 echo "${MSG_TAG} ERROR: Directory '$SOCI_ARCHIVE' already exists. Aborting." 0142 echo "${MSG_TAG} INFO: Delete it and run again." 0143 exit 1 0144 fi 0145 if [[ -f "${SOCI_ARCHIVE}.zip" ]]; then 0146 echo "${MSG_TAG} ERROR: Archive '${SOCI_ARCHIVE}.zip' already exists. Aborting." 0147 echo "${MSG_TAG} INFO: Delete it and run again." 0148 exit 1 0149 fi 0150 if [[ -f "${SOCI_ARCHIVE}.tar.gz" ]]; then 0151 echo "${MSG_TAG} ERROR: Archive '${SOCI_ARCHIVE}.tar.gz' already exists. Aborting." 0152 echo "${MSG_TAG} INFO: Delete it and run again." 0153 exit 1 0154 fi 0155 0156 if [[ -d $PWD/.venv ]] && [[ ! -f $PWD/.venv/bin/activate ]]; then 0157 echo "${MSG_TAG} ERROR: Directory '$PWD/.venv' already exists. Can not create Python environment. Aborting." 0158 exit 1 0159 fi 0160 0161 if [[ ! -f $PWD/.venv/bin/activate ]]; then 0162 MASTER_PY="" 0163 if command -v python3 &>/dev/null; then 0164 MASTER_PY=$(which python3) 0165 fi 0166 if [[ -z "$MASTER_PY" ]] && command -v python &>/dev/null; then 0167 MASTER_PY=$(which python) 0168 fi 0169 if [[ -z "$MASTER_PY" ]] || [[ ! $($MASTER_PY --version) =~ ^Python.+3 ]]; then 0170 echo "${MSG_TAG} ERROR: Python 3 not found. Aborting." 0171 exit 1 0172 else 0173 echo "${MSG_TAG} INFO: Creating Python virtual environment using $MASTER_PY (`$MASTER_PY --version`)" 0174 fi 0175 $MASTER_PY -m venv $PWD/.venv || exit 1 0176 fi 0177 0178 if [[ ! -f $PWD/.venv/bin/activate ]]; then 0179 echo "${MSG_TAG} ERROR: Python virtual environment script '$PWD/.venv/bin/activate' not found. Aborting." 0180 exit 1 0181 fi 0182 source $PWD/.venv/bin/activate 0183 echo "${MSG_TAG} INFO: Using Python from `which python` (`python --version`)" 0184 python -m pip --quiet install --upgrade pip 0185 python -m pip --quiet install --upgrade mkdocs 0186 0187 echo "${MSG_TAG} INFO: Building documentation with `mkdocs --version`" 0188 mkdocs build --clean 0189 0190 echo "${MSG_TAG} INFO: Exiting Python virtual environment" 0191 deactivate 0192 0193 echo "${MSG_TAG} INFO: Preparing release archive in '$SOCI_ARCHIVE'" 0194 mkdir $SOCI_ARCHIVE 0195 cp -a cmake $SOCI_ARCHIVE 0196 cp -a include $SOCI_ARCHIVE 0197 cp -a languages $SOCI_ARCHIVE 0198 cp -a src $SOCI_ARCHIVE 0199 cp -a tests $SOCI_ARCHIVE 0200 cp -a AUTHORS CMakeLists.txt LICENSE_1_0.txt README.md Vagrantfile $SOCI_ARCHIVE/ 0201 mv site $SOCI_ARCHIVE/docs 0202 0203 # Add git SHA-1 to version in CHANGES file 0204 RELEASE_BRANCH_SHA1=$(git show-ref --hash=8 origin/$GIT_RELEASE_BRANCH) 0205 echo "${MSG_TAG} INFO: Appending '$RELEASE_BRANCH_SHA1' hash to version in '$SOCI_ARCHIVE/CHANGES'" 0206 cat CHANGES | sed "s/Version $SOCI_VERSION.*differs/Version $SOCI_FULL_VERSION ($RELEASE_BRANCH_SHA1) differs/" > $SOCI_ARCHIVE/CHANGES 0207 0208 echo "${MSG_TAG} INFO: Building release archive '$SOCI_ARCHIVE.zip'" 0209 zip -q -r $SOCI_ARCHIVE.zip $SOCI_ARCHIVE 0210 if [[ $? -ne 0 ]]; then 0211 echo "${MSG_TAG} ERROR: zip failed. Aborting." 0212 exit 1 0213 fi 0214 0215 echo "${MSG_TAG} INFO: Building release archive '$SOCI_ARCHIVE.tar.gz'" 0216 tar -czf $SOCI_ARCHIVE.tar.gz $SOCI_ARCHIVE 0217 if [[ $? -ne 0 ]]; then 0218 echo "${MSG_TAG} ERROR: tar failed. Aborting." 0219 exit 1 0220 fi 0221 0222 echo "${MSG_TAG} INFO: Cleaning up" 0223 rm -rf "${SOCI_ARCHIVE}" 0224 git checkout $GIT_CURRENT_BRANCH 0225 0226 if [[ $OPT_USE_LOCAL_RELEASE_BRANCH -eq 0 ]]; then 0227 echo "${MSG_TAG} INFO: Deleting '$GIT_RELEASE_BRANCH' checked out from 'origin/$GIT_RELEASE_BRANCH'." 0228 git branch -D $GIT_RELEASE_BRANCH 0229 fi 0230 0231 echo "${MSG_TAG} INFO: Done"