From 19a0a7f33ca71a39859706d726eaf70882362c93 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 8 Sep 2015 15:47:26 +0200 Subject: [PATCH] script/release.sh: make it possible to create stable .0 releases This version was used to create samba-4.3.0. Signed-off-by: Stefan Metzmacher Reviewed-by: Karolin Seeger --- script/release.sh | 404 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 398 insertions(+), 6 deletions(-) diff --git a/script/release.sh b/script/release.sh index 9f7379ede23..6771b65df59 100755 --- a/script/release.sh +++ b/script/release.sh @@ -15,6 +15,7 @@ umask 0022 CONF_REPO_URL="ssh://git.samba.org/data/git/samba.git" CONF_UPLOAD_URL="samba-bugs@download-master.samba.org:/home/data/ftp/pub" CONF_DOWNLOAD_URL="https://download.samba.org/pub" +CONF_HISTORY_URL="https://www.samba.org" test -d ".git" || { echo "Run this script from the top-level directory in the" @@ -25,7 +26,7 @@ test -d ".git" || { usage() { echo "Usage: release.sh " echo "" - echo "PRODUCT: ldb, talloc, tevent, tdb, samba-rc" + echo "PRODUCT: ldb, talloc, tevent, tdb, samba-rc, samba-stable" echo "COMMAND: fullrelease, create, push, upload, announce" echo "" return 0 @@ -64,7 +65,9 @@ min_args "$0" "$#" "2" product="$1" globalcmd="$2" shift 2 +oldtagname="" tagname="" +patchfile="" cmds="" next_cmd="" @@ -124,6 +127,92 @@ verify_samba_rc() { return 0 } +verify_samba_stable() { + check_args "${FUNCNAME}" "$#" "0" || return 1 + + test -f VERSION || { + echo "VERSION doesn't exist" + return 1 + } + + grep -q 'SAMBA_VERSION_IS_GIT_SNAPSHOT=no' VERSION || { + echo "SAMBA_VERSION_IS_GIT_SNAPSHOT is not 'no'" + return 1 + } + + local VARS="" + VARS="${VARS} SAMBA_VERSION_REVISION" + VARS="${VARS} SAMBA_VERSION_TP_RELEASE" + VARS="${VARS} SAMBA_VERSION_ALPHA_RELEASE" + VARS="${VARS} SAMBA_VERSION_BETA_RELEASE" + VARS="${VARS} SAMBA_VERSION_PRE_RELEASE" + VARS="${VARS} SAMBA_VERSION_RC_RELEASE" + VARS="${VARS} SAMBA_VERSION_RELEASE_NICKNAME" + VARS="${VARS} SAMBA_VERSION_VENDOR_SUFFIX" + VARS="${VARS} SAMBA_VERSION_VENDOR_PATCH" + for var in ${VARS}; do + grep -q "^${var}" VERSION && { + grep -q "^${var}=$" VERSION || { + echo "${var} found in stable version" + return 1 + } + } + done + + local SAMBA_VERSION_MAJOR=$(grep '^SAMBA_VERSION_MAJOR=' VERSION | cut -d '=' -f2 | xargs) + local SAMBA_VERSION_MINOR=$(grep '^SAMBA_VERSION_MINOR=' VERSION | cut -d '=' -f2 | xargs) + local SAMBA_VERSION_RELEASE=$(grep '^SAMBA_VERSION_RELEASE=' VERSION | cut -d '=' -f2 | xargs) + + test ${SAMBA_VERSION_RELEASE} -gt 0 || { + return 0 + } + + local old_release=$(expr ${SAMBA_VERSION_RELEASE} - 1) + oldtagname="${productbase}-${SAMBA_VERSION_MAJOR}.${SAMBA_VERSION_MINOR}.${old_release}" + + local verify_out="${TMPDIR}/verify-${oldtagname}.out" + + echo "Verifying oldtagname: ${oldtagname}" + + git tag -v "${oldtagname}" >${verify_out} 2>&1 || { + echo "failed to verify old tag[${oldtagname}]" + return 1 + } + + grep -q "${GPG_KEYID}" "${verify_out}" || { + echo "oldtagname[${oldtagname}] was not generated with GPG_KEYID[${GPG_KEYID}]!" + echo "" + cat "${verify_out}" + return 1 + } + + echo "Verifying ${oldtagname}.tar.gz and ${oldtagname}.tar.asc" + + test -f "${oldtagname}.tar.gz" || { + echo "${oldtagname}.tar.gz does not exist" + return 1 + } + + test -f "${oldtagname}.tar.asc" || { + echo "${oldtagname}.tar.asc does not exist" + return 1 + } + + zcat "${oldtagname}.tar.gz" | gpg --verify "${oldtagname}.tar.asc" - 2>${verify_out} || { + echo "Failed to verify ${oldtagname}.tar.asc" + return 1 + } + + grep -q "${GPG_KEYID}" "${verify_out}" || { + echo "${oldtagname}.tar.asc was not generated with GPG_KEYID[${GPG_KEYID}]!" + echo "" + cat "${verify_out}" + return 1 + } + + return 0 +} + verify_release() { check_args "${FUNCNAME}" "$#" "0" || return 1 @@ -157,7 +246,10 @@ create_release() { local tarname=$(basename ${tgzname} .gz) echo "Tarball: ${tarname}" - gunzip -f ${tgzname} || exit 1 + gunzip -f ${tgzname} || { + echo "Failed to decompress tarball ${tarname}" + return 1 + } test -f "${tarname}" || { echo "Failed to decompress tarball ${tarname}" return 1 @@ -172,7 +264,7 @@ create_release() { } CLEANUP_TAGS="${CLEANUP_TAGS} ${tagname}" - echo "signing" + echo "Signing ${tarname} => ${tarname}.asc" rm -f "${tarname}.asc" gpg -u "${GPG_USER}" --detach-sign --armor ${tarname} || { return 1 @@ -182,7 +274,7 @@ create_release() { return 1 } CLEANUP_FILES="${CLEANUP_FILES} ${tarname}.asc" - echo "compressing" + echo "Compressing ${tarname} => ${tgzname}" gzip -f -9 ${tarname} test -f "${tgzname}" || { echo "Failed to compress ${tgzname}" @@ -192,6 +284,55 @@ create_release() { return 0 } +patch_release() { + check_args "${FUNCNAME}" "$#" "0" || return 1 + require_tagname "${FUNCNAME}" + + test -n "${oldtagname}" || { + return 0 + } + + local oldversion=$(echo "${oldtagname}" | sed -e "s!^${productbase}-!!") + local version=$(echo "${tagname}" | sed -e "s!^${productbase}-!!") + + local oldpwd=$(pwd) + + local patchfile="patch-${oldversion}-${version}.diffs" + echo "Generating ${patchfile}" + ( + pushd "${TMPDIR}" + tar xfz "${oldpwd}/${oldtagname}.tar.gz" + tar xfz "${oldpwd}/${tagname}.tar.gz" + diff -Npur "${oldtagname}/" "${tagname}/" > "${patchfile}" + popd + ) + CLEANUP_FILES="${CLEANUP_FILES} ${patchfile}" + mv "${TMPDIR}/${patchfile}" "${patchfile}" || { + echo "failed cmd[mv ${TMPDIR}/${patchfile} ${patchfile}]" + return 1 + } + + echo "Signing ${patchfile} => ${patchfile}.asc" + rm -f "${patchfile}.asc" + CLEANUP_FILES="${CLEANUP_FILES} ${patchfile}.asc" + gpg -u "${GPG_USER}" --detach-sign --armor ${patchfile} || { + return 1 + } + test -f "${patchfile}.asc" || { + echo "Failed to create signature ${patchfile}.asc" + return 1 + } + echo "Compressing ${patchfile} => ${patchfile}.gz" + CLEANUP_FILES="${CLEANUP_FILES} ${patchfile}.gz" + gzip -f -9 ${patchfile} + test -f "${patchfile}.gz" || { + echo "Failed to compress ${patchfile}.gz" + return 1 + } + + return 0 +} + whatsnew_release() { check_args "${FUNCNAME}" "$#" "0" || return 1 require_tagname "${FUNCNAME}" @@ -227,6 +368,44 @@ check_nopatch() { return 0 } +check_withpatch() { + check_args "${FUNCNAME}" "$#" "0" || return 1 + require_tagname "${FUNCNAME}" + + git tag -v "${tagname}" || { + echo "failed to verify tag[${tagname}]" + return 1 + } + + test -f "${tagname}.tar.gz" || { + echo "${tagname}.tar.gz does not exist" + return 1 + } + + test -f "${tagname}.tar.asc" || { + echo "${tagname}.tar.asc does not exist" + return 1 + } + + ls -la ${tagname}.* + + test -n "${patchfile}" || { + return 0 + } + + test -f "${patchfile}.gz" || { + echo "${patchfile}.gz does not exist" + return 1 + } + + test -f "${patchfile}.asc" || { + echo "${patchfile}.asc does not exist" + return 1 + } + + return 0 +} + check_release() { check_args "${FUNCNAME}" "$#" "0" || return 1 @@ -408,6 +587,196 @@ announce_samba_rc() { return 0 } +announce_samba_stable() { + check_args "${FUNCNAME}" "$#" "0" || return 1 + require_tagname "${FUNCNAME}" + + test -f "${tagname}.tar.gz" || { + echo "${tagname}.tar.gz does not exist" + return 1 + } + + echo "extract WHATSNEW.txt" + tar xf ${tagname}.tar.gz --to-stdout ${tagname}/WHATSNEW.txt > ${TMPDIR}/WHATSNEW.txt + + # TODO: up to '^Release notes for older releases follow:' + cp -a ${TMPDIR}/WHATSNEW.txt ${TMPDIR}/WHATSNEW.top + + local t="" + local utcdate=$(date --utc +"%d %B %Y") + local utctime=$(date --utc +"%Y%m%d-%H%M%S") + local version=$(echo "${tagname}" | sed -e 's!^samba-!!') + local href="#${version}" + local series=$(echo "${version}" | cut -d '.' -f1-2) + local release=$(echo "${version}" | cut -d '.' -f3) + local releasename="latest" + case "${release}" in + 1) + releasename="first" + ;; + *) + releasename="latest" + ;; + esac + + { + echo "samba-announce@lists.samba.org, samba@lists.samba.org, samba-technical@lists.samba.org" + } > announce.${tagname}.to.txt + CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.to.txt" + + { + echo "[Announce] Samba ${version} Available for Download" + } > announce.${tagname}.subject.txt + CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.subject.txt" + + { + cat ${TMPDIR}/WHATSNEW.top + echo "" + echo "================" + echo "Download Details" + echo "================" + echo "" + echo "The uncompressed tarballs and patch files have been signed" + echo "using GnuPG (ID 6568B7EA). The source code can be downloaded" + echo "from:" + echo "" + echo " ${download_url}" + echo "" + echo "The release notes are available online at:" + echo "" + echo " ${history_url}${tagname}.html" + echo "" + echo "Our Code, Our Bugs, Our Responsibility." + echo "(https://bugzilla.samba.org/)" + echo "" + echo " --Enjoy" + echo " The Samba Team" + } > announce.${tagname}.mail.txt + CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.mail.txt" + + { + echo -n "-i announce.${tagname}.mail.txt " + echo -n "-s \"$(cat announce.${tagname}.subject.txt | xargs)\" " + echo -n "$(cat announce.${tagname}.to.txt | xargs)" + } > announce.${tagname}.mutt-arguments.txt + CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.mutt-arguments.txt" + + { + local tmp=$(cat ${TMPDIR}/WHATSNEW.top | grep -n '^Reporting bugs & Development Discussion' | head -1 | cut -d ':' -f1) + local lines=$(expr ${tmp} - 2) + + echo '' + echo '' + + echo "" + echo "Samba ${version} - Release Notes" + echo "" + + echo "" + echo "

Samba ${version} Available for Download

" + + echo "

" + echo "Samba ${version} (gzipped)
" + echo "Signature" + echo "

" + + echo "

" + echo "

"
+		head -${lines} ${TMPDIR}/WHATSNEW.top | sed \
+			-e 's!&!\&!g' | sed \
+			-e 's!!\>!g' \
+			-e 's!ä!\ä!g' \
+			-e 's!Ä!\Ä!g' \
+			-e 's!ö!\ö!g' \
+			-e 's!Ö!\Ö!g' \
+			-e 's!ü!\ü!g' \
+			-e 's!Ü!\Ü!g' \
+			-e 's!ß!\ß!g' \
+			-e 's!"!\"!g' \
+			-e "s!'!\'!g" \
+			| cat
+		echo "
" + echo "

" + + echo "" + echo "" + } > announce.${tagname}.html + CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.html" + + local headlinefile="${utctime}.${version}.headline.html" + { + echo "" + echo "
  • ${utcdate} Samba ${version} Available for Download
  • " + echo "" + } > ${headlinefile} + CLEANUP_FILES="${CLEANUP_FILES} ${headlinefile}" + + local bodyfile="${utctime}.${version}.body.html" + { + echo "" + echo "
    ${utcdate}
    " + echo "

    Samba ${version} Available for Download

    " + echo "

    " + echo "This is the ${releasename} stable release of the Samba ${series} release series." + echo "

    " + echo "

    " + echo "The uncompressed tarball has been signed using GnuPG (ID ${GPG_KEYID})." + echo "The source code can be downloaded now." + #test -n "${patchfile}" && { + # echo "A patch against Samba ${oldversion} is also available." + #} + echo "See the release notes for more info." + echo "

    " + echo "" + echo "" + } > ${bodyfile} + CLEANUP_FILES="${CLEANUP_FILES} ${bodyfile}" + + { + ls -lart announce.${tagname}.* ${headlinefile} ${bodyfile} + echo "" + echo "NOTICE:" + echo "You need to do the following manual steps in order" + echo "to finish the announcement of ${tagname}!" + echo "" + echo "Copy the following files into the posted_news/" + echo "subdirectory of the samba-web.git repository and commit them:" + echo " ${headlinefile}" + echo " ${bodyfile}" + echo "" + echo " cp -a ${utctime}.${version}.*.html /path/to/samba-web/posted_news/" + echo " cp -a announce.${tagname}.html /path/to/samba-web/history/${tagname}.html" + echo " pushd /path/to/samba-web" + echo " git add posted_news/${utctime}.${version}.*.html" + echo " git add history/${tagname}.html" + echo " git commit --signoff --message \"NEWS[${version}]: Samba ${version} Available for Download\"" + echo " git show -p --stat HEAD" + echo " git push ..." + echo " popd" + echo "" + echo "Once the resulting commit is pushed a cron job will update " + echo "the content exported by the webserver every 5mins." + echo "" + echo "If the web content is updated, you need to send the announce mail (gpg signed)." + echo "- announce.${tagname}.to.txt contains the mail's recipients for the To: header." + echo "- announce.${tagname}.subject.txt contains the mail's subject line." + echo "- announce.${tagname}.mail.txt contains the content of the mail body." + echo "In case your're using mutt, you can use the following shortcut:" + echo " eval mutt \$(cat announce.${tagname}.mutt-arguments.txt)" + echo "" + echo "NOTICE: you're not done yet! Read the above instructions carefully!" + echo "See: announce.${tagname}.todo.txt" + echo "" + } > announce.${tagname}.todo.txt + CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.todo.txt" + + cat announce.${tagname}.todo.txt + + return 0 +} + announce_release() { check_args "${FUNCNAME}" "$#" "0" || return 1 @@ -459,7 +828,7 @@ samba-rc) announce_fn="announce_samba_rc" fullcmds="verify create check whatsnew push upload announce" ;; -TODO-samba-stable) +samba-stable) test -z "${GPG_USER-}" && { GPG_USER='Samba Distribution Verification Key ' } @@ -473,6 +842,7 @@ TODO-samba-stable) repo_url="${CONF_REPO_URL}" upload_url="${CONF_UPLOAD_URL}/samba/stable/" download_url="${CONF_DOWNLOAD_URL}/samba/stable/" + history_url="${CONF_HISTORY_URL}/samba/history/" verify_fn="verify_samba_stable" check_fn="check_withpatch" @@ -495,7 +865,7 @@ TODO-samba-security) download_url="${CONF_DOWNLOAD_URL}/samba/stable/" verify_fn="verify_samba_stable" - check_fn="check_samba_stable" + check_fn="check_withpatch" announce_fn="announce_samba_security" fullcmds="verify create patch check" next_cmd="push" @@ -533,10 +903,20 @@ trap_handler() { } } done + + for d in ${CLEANUP_DIRS}; do + echo "Removing dir[${d}]" + test -d "${d}" && { + rm -rf "${d}" || { + echo "failed to remove ${d}" + } + } + done } CLEANUP_TAGS="" CLEANUP_FILES="" +CLEANUP_DIRS="" trap trap_handler INT QUIT TERM EXIT cmd_allowed "${globalcmd}" fullrelease ${fullcmds} || { @@ -597,6 +977,12 @@ announce) ;; esac +TMPDIR="release.$$" +CLEANUP_DIRS="${CLEANUP_DIRS} ${TMPDIR}" +umask 0077 +mkdir "${TMPDIR}" +umask 0022 + for cmd in ${cmds}; do echo "Starting subcommand[${cmd}]" ${cmd}_release || { @@ -606,6 +992,12 @@ for cmd in ${cmds}; do echo "Finished subcommand[${cmd}]" done +test -d "${TMPDIR}" && { + rm -rf "${TMPDIR}" || { + echo "failed to remove ${TMPDIR}" + } +} + test -n "${next_cmd}" && { echo "Continue with '$0 ${product} ${next_cmd} ${tagname}'." } -- 2.34.1