script/release.sh: make it possible to create stable .0 releases
[Samba.git] / script / release.sh
blob6771b65df59f6c774e48c3de0525e378d78213a7
1 #!/bin/bash
2 # make a release of Samba or a library
4 LC_ALL=C
5 export LC_ALL
6 LANG=C
7 export LANG
8 LANGUAGE=C
9 export LANGUAGE
11 set -u
12 set -e
13 umask 0022
15 CONF_REPO_URL="ssh://git.samba.org/data/git/samba.git"
16 CONF_UPLOAD_URL="samba-bugs@download-master.samba.org:/home/data/ftp/pub"
17 CONF_DOWNLOAD_URL="https://download.samba.org/pub"
18 CONF_HISTORY_URL="https://www.samba.org"
20 test -d ".git" || {
21 echo "Run this script from the top-level directory in the"
22 echo "repository"
23 exit 1
26 usage() {
27 echo "Usage: release.sh <PRODUCT> <COMMAND>"
28 echo ""
29 echo "PRODUCT: ldb, talloc, tevent, tdb, samba-rc, samba-stable"
30 echo "COMMAND: fullrelease, create, push, upload, announce"
31 echo ""
32 return 0
35 check_args() {
36 local cmd="$1"
37 local got_args="$2"
38 local take_args="$3"
40 test x"${got_args}" = x"${take_args}" || {
41 usage
42 echo "cmd[${cmd}] takes ${take_args} instead of ${got_args}"
43 return 1
46 return 0
49 min_args() {
50 local cmd="$1"
51 local got_args="$2"
52 local min_args="$3"
54 test "${got_args}" -ge "${min_args}" || {
55 usage
56 echo "cmd[${cmd}] takes at least ${min_args} instead of ${got_args}"
57 return 1
60 return 0
63 min_args "$0" "$#" "2"
65 product="$1"
66 globalcmd="$2"
67 shift 2
68 oldtagname=""
69 tagname=""
70 patchfile=""
71 cmds=""
72 next_cmd=""
74 require_tagname() {
75 min_args "${FUNCNAME}" "$#" "1" || return 1
76 local cmd="$1"
78 test -n "${tagname}" || {
79 echo "cmd[${cmd}] requires '\${tagname}' variable to be set"
80 return 1
83 local name=$(echo "${tagname}" | cut -d '-' -f1)
84 test x"${name}" = x"${productbase}" || {
85 echo "Invalid tagname[${tgzname}]"
86 return 1
89 return 0
92 cmd_allowed() {
93 min_args "${FUNCNAME}" "$#" "2" || return 1
94 local cmd="$1"
95 shift 1
97 echo "$@" | grep -q "\<${cmd}\>" || {
98 return 1
101 return 0
104 verify_samba_rc() {
105 check_args "${FUNCNAME}" "$#" "0" || return 1
107 test -f VERSION || {
108 echo "VERSION doesn't exist"
109 return 1
112 grep -q 'SAMBA_VERSION_IS_GIT_SNAPSHOT=no' VERSION || {
113 echo "SAMBA_VERSION_IS_GIT_SNAPSHOT is not 'no'"
114 return 1
117 grep -q '^SAMBA_VERSION_RC_RELEASE=' VERSION || {
118 echo "SAMBA_VERSION_RC_RELEASE= missing"
119 return 1
122 grep -q '^SAMBA_VERSION_RC_RELEASE=$' VERSION && {
123 echo "SAMBA_VERSION_RC_RELEASE= missing the rc version"
124 return 1
127 return 0
130 verify_samba_stable() {
131 check_args "${FUNCNAME}" "$#" "0" || return 1
133 test -f VERSION || {
134 echo "VERSION doesn't exist"
135 return 1
138 grep -q 'SAMBA_VERSION_IS_GIT_SNAPSHOT=no' VERSION || {
139 echo "SAMBA_VERSION_IS_GIT_SNAPSHOT is not 'no'"
140 return 1
143 local VARS=""
144 VARS="${VARS} SAMBA_VERSION_REVISION"
145 VARS="${VARS} SAMBA_VERSION_TP_RELEASE"
146 VARS="${VARS} SAMBA_VERSION_ALPHA_RELEASE"
147 VARS="${VARS} SAMBA_VERSION_BETA_RELEASE"
148 VARS="${VARS} SAMBA_VERSION_PRE_RELEASE"
149 VARS="${VARS} SAMBA_VERSION_RC_RELEASE"
150 VARS="${VARS} SAMBA_VERSION_RELEASE_NICKNAME"
151 VARS="${VARS} SAMBA_VERSION_VENDOR_SUFFIX"
152 VARS="${VARS} SAMBA_VERSION_VENDOR_PATCH"
153 for var in ${VARS}; do
154 grep -q "^${var}" VERSION && {
155 grep -q "^${var}=$" VERSION || {
156 echo "${var} found in stable version"
157 return 1
160 done
162 local SAMBA_VERSION_MAJOR=$(grep '^SAMBA_VERSION_MAJOR=' VERSION | cut -d '=' -f2 | xargs)
163 local SAMBA_VERSION_MINOR=$(grep '^SAMBA_VERSION_MINOR=' VERSION | cut -d '=' -f2 | xargs)
164 local SAMBA_VERSION_RELEASE=$(grep '^SAMBA_VERSION_RELEASE=' VERSION | cut -d '=' -f2 | xargs)
166 test ${SAMBA_VERSION_RELEASE} -gt 0 || {
167 return 0
170 local old_release=$(expr ${SAMBA_VERSION_RELEASE} - 1)
171 oldtagname="${productbase}-${SAMBA_VERSION_MAJOR}.${SAMBA_VERSION_MINOR}.${old_release}"
173 local verify_out="${TMPDIR}/verify-${oldtagname}.out"
175 echo "Verifying oldtagname: ${oldtagname}"
177 git tag -v "${oldtagname}" >${verify_out} 2>&1 || {
178 echo "failed to verify old tag[${oldtagname}]"
179 return 1
182 grep -q "${GPG_KEYID}" "${verify_out}" || {
183 echo "oldtagname[${oldtagname}] was not generated with GPG_KEYID[${GPG_KEYID}]!"
184 echo ""
185 cat "${verify_out}"
186 return 1
189 echo "Verifying ${oldtagname}.tar.gz and ${oldtagname}.tar.asc"
191 test -f "${oldtagname}.tar.gz" || {
192 echo "${oldtagname}.tar.gz does not exist"
193 return 1
196 test -f "${oldtagname}.tar.asc" || {
197 echo "${oldtagname}.tar.asc does not exist"
198 return 1
201 zcat "${oldtagname}.tar.gz" | gpg --verify "${oldtagname}.tar.asc" - 2>${verify_out} || {
202 echo "Failed to verify ${oldtagname}.tar.asc"
203 return 1
206 grep -q "${GPG_KEYID}" "${verify_out}" || {
207 echo "${oldtagname}.tar.asc was not generated with GPG_KEYID[${GPG_KEYID}]!"
208 echo ""
209 cat "${verify_out}"
210 return 1
213 return 0
216 verify_release() {
217 check_args "${FUNCNAME}" "$#" "0" || return 1
219 test -n "${verify_fn}" || {
220 echo "verify_fn variable empty"
221 return 1
224 echo "Running ${verify_fn}"
225 ${verify_fn}
228 create_release() {
229 check_args "${FUNCNAME}" "$#" "0" || return 1
231 echo "Releasing product ${product}"
233 echo "Building release tarball"
234 local tgzname=$(make dist 2>&1 | grep ^Created | cut -d' ' -f2)
235 test -f "${tgzname}" || {
236 echo "Failed to create tarball"
237 return 1
239 CLEANUP_FILES="${CLEANUP_FILES} ${tgzname}"
241 local name=$(echo "${tgzname}" | cut -d '-' -f1)
242 test x"${name}" = x"${productbase}" || {
243 echo "Invalid tgzname[${tgzname}]"
244 return 1
247 local tarname=$(basename ${tgzname} .gz)
248 echo "Tarball: ${tarname}"
249 gunzip -f ${tgzname} || {
250 echo "Failed to decompress tarball ${tarname}"
251 return 1
253 test -f "${tarname}" || {
254 echo "Failed to decompress tarball ${tarname}"
255 return 1
257 CLEANUP_FILES="${CLEANUP_FILES} ${tarname}"
259 # tagname is global
260 tagname=$(basename ${tarname} .tar)
261 echo "Tagging as ${tagname}"
262 git tag -u ${GPG_KEYID} -s "${tagname}" -m "${productbase}: tag release ${tagname}" || {
263 return 1
265 CLEANUP_TAGS="${CLEANUP_TAGS} ${tagname}"
267 echo "Signing ${tarname} => ${tarname}.asc"
268 rm -f "${tarname}.asc"
269 gpg -u "${GPG_USER}" --detach-sign --armor ${tarname} || {
270 return 1
272 test -f "${tarname}.asc" || {
273 echo "Failed to create signature ${tarname}.asc"
274 return 1
276 CLEANUP_FILES="${CLEANUP_FILES} ${tarname}.asc"
277 echo "Compressing ${tarname} => ${tgzname}"
278 gzip -f -9 ${tarname}
279 test -f "${tgzname}" || {
280 echo "Failed to compress ${tgzname}"
281 return 1
284 return 0
287 patch_release() {
288 check_args "${FUNCNAME}" "$#" "0" || return 1
289 require_tagname "${FUNCNAME}"
291 test -n "${oldtagname}" || {
292 return 0
295 local oldversion=$(echo "${oldtagname}" | sed -e "s!^${productbase}-!!")
296 local version=$(echo "${tagname}" | sed -e "s!^${productbase}-!!")
298 local oldpwd=$(pwd)
300 local patchfile="patch-${oldversion}-${version}.diffs"
301 echo "Generating ${patchfile}"
303 pushd "${TMPDIR}"
304 tar xfz "${oldpwd}/${oldtagname}.tar.gz"
305 tar xfz "${oldpwd}/${tagname}.tar.gz"
306 diff -Npur "${oldtagname}/" "${tagname}/" > "${patchfile}"
307 popd
309 CLEANUP_FILES="${CLEANUP_FILES} ${patchfile}"
310 mv "${TMPDIR}/${patchfile}" "${patchfile}" || {
311 echo "failed cmd[mv ${TMPDIR}/${patchfile} ${patchfile}]"
312 return 1
315 echo "Signing ${patchfile} => ${patchfile}.asc"
316 rm -f "${patchfile}.asc"
317 CLEANUP_FILES="${CLEANUP_FILES} ${patchfile}.asc"
318 gpg -u "${GPG_USER}" --detach-sign --armor ${patchfile} || {
319 return 1
321 test -f "${patchfile}.asc" || {
322 echo "Failed to create signature ${patchfile}.asc"
323 return 1
325 echo "Compressing ${patchfile} => ${patchfile}.gz"
326 CLEANUP_FILES="${CLEANUP_FILES} ${patchfile}.gz"
327 gzip -f -9 ${patchfile}
328 test -f "${patchfile}.gz" || {
329 echo "Failed to compress ${patchfile}.gz"
330 return 1
333 return 0
336 whatsnew_release() {
337 check_args "${FUNCNAME}" "$#" "0" || return 1
338 require_tagname "${FUNCNAME}"
340 echo "extract ${tagname}.WHATSNEW.txt"
341 tar xf ${tagname}.tar.gz --to-stdout ${tagname}/WHATSNEW.txt > ${tagname}.WHATSNEW.txt
342 CLEANUP_FILES="${CLEANUP_FILES} ${tagname}.WHATSNEW.txt"
344 return 0
347 check_nopatch() {
348 check_args "${FUNCNAME}" "$#" "0" || return 1
349 require_tagname "${FUNCNAME}"
351 git tag -v "${tagname}" || {
352 echo "failed to verify tag[${tagname}]"
353 return 1
356 test -f "${tagname}.tar.gz" || {
357 echo "${tagname}.tar.gz does not exist"
358 return 1
361 test -f "${tagname}.tar.asc" || {
362 echo "${tagname}.tar.asc does not exist"
363 return 1
366 ls -la ${tagname}.*
368 return 0
371 check_withpatch() {
372 check_args "${FUNCNAME}" "$#" "0" || return 1
373 require_tagname "${FUNCNAME}"
375 git tag -v "${tagname}" || {
376 echo "failed to verify tag[${tagname}]"
377 return 1
380 test -f "${tagname}.tar.gz" || {
381 echo "${tagname}.tar.gz does not exist"
382 return 1
385 test -f "${tagname}.tar.asc" || {
386 echo "${tagname}.tar.asc does not exist"
387 return 1
390 ls -la ${tagname}.*
392 test -n "${patchfile}" || {
393 return 0
396 test -f "${patchfile}.gz" || {
397 echo "${patchfile}.gz does not exist"
398 return 1
401 test -f "${patchfile}.asc" || {
402 echo "${patchfile}.asc does not exist"
403 return 1
406 return 0
409 check_release() {
410 check_args "${FUNCNAME}" "$#" "0" || return 1
412 test -n "${check_fn}" || {
413 echo "check_fn variable empty"
414 return 1
417 echo "Running ${check_fn}"
418 ${check_fn}
421 push_release() {
422 check_args "${FUNCNAME}" "$#" "0" || return 1
423 require_tagname "${FUNCNAME}"
425 echo "Push git tag ${tagname} to '${repo_url}'"
426 git push "${repo_url}" "refs/tags/${tagname}:refs/tags/${tagname}" || {
427 return 1
430 return 0
433 upload_release() {
434 check_args "${FUNCNAME}" "$#" "0" || return 1
435 require_tagname "${FUNCNAME}"
437 echo "Upload ${tagname}.* to '${upload_url}'"
438 rsync -Pav ${tagname}.* "${upload_url}/" || {
439 return 1
441 rsync ${upload_url}/${tagname}.*
443 return 0
446 announce_samba_rc() {
447 check_args "${FUNCNAME}" "$#" "0" || return 1
448 require_tagname "${FUNCNAME}"
450 test -f "${tagname}.WHATSNEW.txt" || {
451 echo "${tagname}.WHATSNEW.txt does not exist"
452 return 1
455 local t=""
456 local utcdate=$(date --utc +"%d %B %Y")
457 local utctime=$(date --utc +"%Y%m%d-%H%M%S")
458 local version=$(echo "${tagname}" | sed -e 's!^samba-!!')
459 local href="#${version}"
460 local series=$(echo "${version}" | cut -d '.' -f1-2)
461 local rc=$(echo "${version}" | sed -e 's!.*rc\([0-9][0-9]*\)!\1!')
462 local rcname="${rc}th"
463 case "${rc}" in
465 rcname="first"
468 rcname="second"
471 rcname="third"
474 rcname="fourth"
477 rcname="fifth"
479 esac
482 echo "samba-announce@lists.samba.org, samba@lists.samba.org, samba-technical@lists.samba.org"
483 } > announce.${tagname}.to.txt
484 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.to.txt"
487 echo "[Announce] Samba ${version} Available for Download"
488 } > announce.${tagname}.subject.txt
489 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.subject.txt"
492 cat ${tagname}.WHATSNEW.txt
493 echo ""
494 echo "================"
495 echo "Download Details"
496 echo "================"
497 echo ""
498 echo "The uncompressed tarballs and patch files have been signed"
499 echo "using GnuPG (ID 6568B7EA). The source code can be downloaded"
500 echo "from:"
501 echo ""
502 echo " ${download_url}"
503 echo ""
504 echo "The release notes are available online at:"
505 echo ""
506 echo " ${download_url}${tagname}.WHATSNEW.txt"
507 echo ""
508 echo "Our Code, Our Bugs, Our Responsibility."
509 echo "(https://bugzilla.samba.org/)"
510 echo ""
511 echo " --Enjoy"
512 echo " The Samba Team"
513 } > announce.${tagname}.mail.txt
514 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.mail.txt"
517 echo -n "-i announce.${tagname}.mail.txt "
518 echo -n "-s \"$(cat announce.${tagname}.subject.txt | xargs)\" "
519 echo -n "$(cat announce.${tagname}.to.txt | xargs)"
520 } > announce.${tagname}.mutt-arguments.txt
521 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.mutt-arguments.txt"
523 local headlinefile="${utctime}.${version}.headline.html"
525 echo "<!-- BEGIN: posted_news/${headlinefile} -->"
526 echo "<li> ${utcdate} <a href=\"${href}\">Samba ${version} Available for Download</a></li>"
527 echo "<!-- END: posted_news/${headlinefile} -->"
528 } > ${headlinefile}
529 CLEANUP_FILES="${CLEANUP_FILES} ${headlinefile}"
531 local bodyfile="${utctime}.${version}.body.html"
533 echo "<!-- BEGIN: posted_news/${bodyfile} -->"
534 echo "<h5><a name=\"${version}\">${utcdate}</a></h5>"
535 echo "<p class="headline">Samba ${version} Available for Download</p>"
536 echo "<p>"
537 echo "This is the ${rcname} release candidate of the upcoming Samba ${series} release series."
538 echo "</p>"
539 echo "<p>"
540 echo "The uncompressed tarball has been signed using GnuPG (ID ${GPG_KEYID})."
541 echo "The source code can be <a href=\"${download_url}${tagname}.tar.gz\">downloaded now</a>."
542 echo "See <a href=\"${download_url}${tagname}.WHATSNEW.txt\">the release notes for more info</a>."
543 echo "</p>"
544 echo "<!-- END: posted_news/${bodyfile} -->"
545 echo ""
546 } > ${bodyfile}
547 CLEANUP_FILES="${CLEANUP_FILES} ${bodyfile}"
550 ls -lart announce.${tagname}.* ${headlinefile} ${bodyfile}
551 echo ""
552 echo "NOTICE:"
553 echo "You need to do the following manual steps in order"
554 echo "to finish the announcement of ${tagname}!"
555 echo ""
556 echo "Copy the following files into the posted_news/"
557 echo "subdirectory of the samba-web.git repository and commit them:"
558 echo " ${headlinefile}"
559 echo " ${bodyfile}"
560 echo ""
561 echo " cp -a ${utctime}.${version}.*.html /path/to/samba-web/posted_news/"
562 echo " pushd /path/to/samba-web"
563 echo " git add posted_news/${utctime}.${version}.*.html"
564 echo " git commit --signoff --message \"NEWS[${version}]: Samba ${version} Available for Download\""
565 echo " git show -p --stat HEAD"
566 echo " git push ..."
567 echo " popd"
568 echo ""
569 echo "Once the resulting commit is pushed a cron job will update "
570 echo "the content exported by the webserver every 5mins."
571 echo ""
572 echo "If the web content is updated, you need to send the announce mail (gpg signed)."
573 echo "- announce.${tagname}.to.txt contains the mail's recipients for the To: header."
574 echo "- announce.${tagname}.subject.txt contains the mail's subject line."
575 echo "- announce.${tagname}.mail.txt contains the content of the mail body."
576 echo "In case your're using mutt, you can use the following shortcut:"
577 echo " eval mutt \$(cat announce.${tagname}.mutt-arguments.txt)"
578 echo ""
579 echo "NOTICE: you're not done yet! Read the above instructions carefully!"
580 echo "See: announce.${tagname}.todo.txt"
581 echo ""
582 } > announce.${tagname}.todo.txt
583 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.todo.txt"
585 cat announce.${tagname}.todo.txt
587 return 0
590 announce_samba_stable() {
591 check_args "${FUNCNAME}" "$#" "0" || return 1
592 require_tagname "${FUNCNAME}"
594 test -f "${tagname}.tar.gz" || {
595 echo "${tagname}.tar.gz does not exist"
596 return 1
599 echo "extract WHATSNEW.txt"
600 tar xf ${tagname}.tar.gz --to-stdout ${tagname}/WHATSNEW.txt > ${TMPDIR}/WHATSNEW.txt
602 # TODO: up to '^Release notes for older releases follow:'
603 cp -a ${TMPDIR}/WHATSNEW.txt ${TMPDIR}/WHATSNEW.top
605 local t=""
606 local utcdate=$(date --utc +"%d %B %Y")
607 local utctime=$(date --utc +"%Y%m%d-%H%M%S")
608 local version=$(echo "${tagname}" | sed -e 's!^samba-!!')
609 local href="#${version}"
610 local series=$(echo "${version}" | cut -d '.' -f1-2)
611 local release=$(echo "${version}" | cut -d '.' -f3)
612 local releasename="latest"
613 case "${release}" in
615 releasename="first"
618 releasename="latest"
620 esac
623 echo "samba-announce@lists.samba.org, samba@lists.samba.org, samba-technical@lists.samba.org"
624 } > announce.${tagname}.to.txt
625 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.to.txt"
628 echo "[Announce] Samba ${version} Available for Download"
629 } > announce.${tagname}.subject.txt
630 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.subject.txt"
633 cat ${TMPDIR}/WHATSNEW.top
634 echo ""
635 echo "================"
636 echo "Download Details"
637 echo "================"
638 echo ""
639 echo "The uncompressed tarballs and patch files have been signed"
640 echo "using GnuPG (ID 6568B7EA). The source code can be downloaded"
641 echo "from:"
642 echo ""
643 echo " ${download_url}"
644 echo ""
645 echo "The release notes are available online at:"
646 echo ""
647 echo " ${history_url}${tagname}.html"
648 echo ""
649 echo "Our Code, Our Bugs, Our Responsibility."
650 echo "(https://bugzilla.samba.org/)"
651 echo ""
652 echo " --Enjoy"
653 echo " The Samba Team"
654 } > announce.${tagname}.mail.txt
655 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.mail.txt"
658 echo -n "-i announce.${tagname}.mail.txt "
659 echo -n "-s \"$(cat announce.${tagname}.subject.txt | xargs)\" "
660 echo -n "$(cat announce.${tagname}.to.txt | xargs)"
661 } > announce.${tagname}.mutt-arguments.txt
662 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.mutt-arguments.txt"
665 local tmp=$(cat ${TMPDIR}/WHATSNEW.top | grep -n '^Reporting bugs & Development Discussion' | head -1 | cut -d ':' -f1)
666 local lines=$(expr ${tmp} - 2)
668 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
669 echo ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
670 echo '<html xmlns="http://www.w3.org/1999/xhtml">'
672 echo "<head>"
673 echo "<title>Samba ${version} - Release Notes</title>"
674 echo "</head>"
676 echo "<body>"
677 echo "<H2>Samba ${version} Available for Download</H2>"
679 echo "<p>"
680 echo "<a href=\"${download_url}${tagname}.tar.gz\">Samba ${version} (gzipped)</a><br>"
681 echo "<a href=\"${download_url}${tagname}.tar.asc\">Signature</a>"
682 echo "</p>"
684 echo "<p>"
685 echo "<pre>"
686 head -${lines} ${TMPDIR}/WHATSNEW.top | sed \
687 -e 's!&!\&amp;!g' | sed \
688 -e 's!<!\&lt;!g' \
689 -e 's!>!\&gt;!g' \
690 -e 's!ä!\&auml;!g' \
691 -e 's!Ä!\&Auml;!g' \
692 -e 's!ö!\&ouml;!g' \
693 -e 's!Ö!\&Ouml;!g' \
694 -e 's!ü!\&uuml;!g' \
695 -e 's!Ü!\&Uuml;!g' \
696 -e 's!ß!\&szlig;!g' \
697 -e 's!"!\&quot;!g' \
698 -e "s!'!\&apos;!g" \
699 | cat
700 echo "</pre>"
701 echo "</p>"
703 echo "</body>"
704 echo "</html>"
705 } > announce.${tagname}.html
706 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.html"
708 local headlinefile="${utctime}.${version}.headline.html"
710 echo "<!-- BEGIN: posted_news/${headlinefile} -->"
711 echo "<li> ${utcdate} <a href=\"${href}\">Samba ${version} Available for Download</a></li>"
712 echo "<!-- END: posted_news/${headlinefile} -->"
713 } > ${headlinefile}
714 CLEANUP_FILES="${CLEANUP_FILES} ${headlinefile}"
716 local bodyfile="${utctime}.${version}.body.html"
718 echo "<!-- BEGIN: posted_news/${bodyfile} -->"
719 echo "<h5><a name=\"${version}\">${utcdate}</a></h5>"
720 echo "<p class="headline">Samba ${version} Available for Download</p>"
721 echo "<p>"
722 echo "This is the ${releasename} stable release of the Samba ${series} release series."
723 echo "</p>"
724 echo "<p>"
725 echo "The uncompressed tarball has been signed using GnuPG (ID ${GPG_KEYID})."
726 echo "The source code can be <a href=\"${download_url}${tagname}.tar.gz\">downloaded now</a>."
727 #test -n "${patchfile}" && {
728 # echo "A <a href=\"...\"> patch against Samba ${oldversion}</a> is also available."
730 echo "See <a href=\"${history_url}${tagname}.html\">the release notes for more info</a>."
731 echo "</p>"
732 echo "<!-- END: posted_news/${bodyfile} -->"
733 echo ""
734 } > ${bodyfile}
735 CLEANUP_FILES="${CLEANUP_FILES} ${bodyfile}"
738 ls -lart announce.${tagname}.* ${headlinefile} ${bodyfile}
739 echo ""
740 echo "NOTICE:"
741 echo "You need to do the following manual steps in order"
742 echo "to finish the announcement of ${tagname}!"
743 echo ""
744 echo "Copy the following files into the posted_news/"
745 echo "subdirectory of the samba-web.git repository and commit them:"
746 echo " ${headlinefile}"
747 echo " ${bodyfile}"
748 echo ""
749 echo " cp -a ${utctime}.${version}.*.html /path/to/samba-web/posted_news/"
750 echo " cp -a announce.${tagname}.html /path/to/samba-web/history/${tagname}.html"
751 echo " pushd /path/to/samba-web"
752 echo " git add posted_news/${utctime}.${version}.*.html"
753 echo " git add history/${tagname}.html"
754 echo " git commit --signoff --message \"NEWS[${version}]: Samba ${version} Available for Download\""
755 echo " git show -p --stat HEAD"
756 echo " git push ..."
757 echo " popd"
758 echo ""
759 echo "Once the resulting commit is pushed a cron job will update "
760 echo "the content exported by the webserver every 5mins."
761 echo ""
762 echo "If the web content is updated, you need to send the announce mail (gpg signed)."
763 echo "- announce.${tagname}.to.txt contains the mail's recipients for the To: header."
764 echo "- announce.${tagname}.subject.txt contains the mail's subject line."
765 echo "- announce.${tagname}.mail.txt contains the content of the mail body."
766 echo "In case your're using mutt, you can use the following shortcut:"
767 echo " eval mutt \$(cat announce.${tagname}.mutt-arguments.txt)"
768 echo ""
769 echo "NOTICE: you're not done yet! Read the above instructions carefully!"
770 echo "See: announce.${tagname}.todo.txt"
771 echo ""
772 } > announce.${tagname}.todo.txt
773 CLEANUP_FILES="${CLEANUP_FILES} announce.${tagname}.todo.txt"
775 cat announce.${tagname}.todo.txt
777 return 0
780 announce_release() {
781 check_args "${FUNCNAME}" "$#" "0" || return 1
783 test -n "${announce_fn}" || {
784 echo "announce_fn variable empty"
785 return 1
788 echo "Running ${announce_fn}"
789 ${announce_fn}
792 case "${product}" in
793 talloc | tdb | tevent | ldb)
794 test -z "${GPG_USER-}" && {
795 GPG_USER='Samba Library Distribution Key <samba-bugs@samba.org>'
798 test -z "${GPG_KEYID-}" && {
799 GPG_KEYID='13084025'
802 productbase="${product}"
803 srcdir="lib/${product}"
804 repo_url="${CONF_REPO_URL}"
805 upload_url="${CONF_UPLOAD_URL}/${product}/"
806 download_url="${CONF_DOWNLOAD_URL}/${product}/"
808 check_fn="check_nopatch"
809 fullcmds="create check push upload"
811 samba-rc)
812 test -z "${GPG_USER-}" && {
813 GPG_USER='Samba Distribution Verification Key <samba-bugs@samba.org>'
816 test -z "${GPG_KEYID-}" && {
817 GPG_KEYID='6568B7EA'
820 productbase="samba"
821 srcdir="."
822 repo_url="${CONF_REPO_URL}"
823 upload_url="${CONF_UPLOAD_URL}/samba/rc/"
824 download_url="${CONF_DOWNLOAD_URL}/samba/rc/"
826 verify_fn="verify_samba_rc"
827 check_fn="check_nopatch"
828 announce_fn="announce_samba_rc"
829 fullcmds="verify create check whatsnew push upload announce"
831 samba-stable)
832 test -z "${GPG_USER-}" && {
833 GPG_USER='Samba Distribution Verification Key <samba-bugs@samba.org>'
836 test -z "${GPG_KEYID-}" && {
837 GPG_KEYID='6568B7EA'
840 productbase="samba"
841 srcdir="."
842 repo_url="${CONF_REPO_URL}"
843 upload_url="${CONF_UPLOAD_URL}/samba/stable/"
844 download_url="${CONF_DOWNLOAD_URL}/samba/stable/"
845 history_url="${CONF_HISTORY_URL}/samba/history/"
847 verify_fn="verify_samba_stable"
848 check_fn="check_withpatch"
849 announce_fn="announce_samba_stable"
850 fullcmds="verify create patch check push upload announce"
852 TODO-samba-security)
853 test -z "${GPG_USER-}" && {
854 GPG_USER='Samba Distribution Verification Key <samba-bugs@samba.org>'
857 test -z "${GPG_KEYID-}" && {
858 GPG_KEYID='6568B7EA'
861 productbase="samba"
862 srcdir="."
863 repo_url="${CONF_REPO_URL}"
864 upload_url="${CONF_UPLOAD_URL}/samba/stable/"
865 download_url="${CONF_DOWNLOAD_URL}/samba/stable/"
867 verify_fn="verify_samba_stable"
868 check_fn="check_withpatch"
869 announce_fn="announce_samba_security"
870 fullcmds="verify create patch check"
871 next_cmd="push"
874 usage
875 echo "Unknown product ${product}"
876 exit 1
877 esac
879 pushd ${srcdir} || {
880 echo "srcdir[${srcdir}] does not exist"
881 exit 1
884 trap_handler() {
885 echo ""
886 echo "ERROR: cleaning up"
887 echo ""
889 for t in ${CLEANUP_TAGS}; do
890 echo "Removing tag[${t}]"
891 git tag -v "${t}" && {
892 git tag -d "${t}" || {
893 echo "failed to remove tag ${t}"
896 done
898 for f in ${CLEANUP_FILES}; do
899 echo "Removing file[${f}]"
900 test -f "${f}" && {
901 rm "${f}" || {
902 echo "failed to remove ${f}"
905 done
907 for d in ${CLEANUP_DIRS}; do
908 echo "Removing dir[${d}]"
909 test -d "${d}" && {
910 rm -rf "${d}" || {
911 echo "failed to remove ${d}"
914 done
917 CLEANUP_TAGS=""
918 CLEANUP_FILES=""
919 CLEANUP_DIRS=""
920 trap trap_handler INT QUIT TERM EXIT
922 cmd_allowed "${globalcmd}" fullrelease ${fullcmds} || {
923 usage
924 echo "command[${globalcmd}] not supported for product[${product}]"
925 exit 1
928 case "${globalcmd}" in
929 fullrelease)
930 check_args "${globalcmd}" "$#" "0" || exit 1
931 cmds="${fullcmds}"
933 create)
934 check_args "${globalcmd}" "$#" "0" || exit 1
935 check_args "create" "$#" "0" || exit 1
937 cmds=""
938 cmd_allowed "verify" ${fullcmds} && {
939 cmds="${cmds} verify"
941 cmds="${cmds} create"
942 cmd_allowed "whatsnew" ${fullcmds} && {
943 cmds="${cmds} whatsnew"
945 cmd_allowed "patch" ${fullcmds} && {
946 cmds="${cmds} patch"
948 cmds="${cmds} check"
949 next_cmd="push"
951 push)
952 check_args "${globalcmd}" "$#" "1" || exit 1
953 tagname="$1"
954 cmds="check push"
955 next_cmd="upload"
957 upload)
958 check_args "${globalcmd}" "$#" "1" || exit 1
959 tagname="$1"
960 cmds="check upload"
961 cmd_allowed "symlinks" ${fullcmds} && {
962 cmds="${cmds} symlinks"
964 cmd_allowed "announce" ${fullcmds} && {
965 next_cmd="announce"
968 announce)
969 check_args "${globalcmd}" "$#" "1" || exit 1
970 tagname="$1"
971 cmds="check announce"
974 usage
975 echo "Unknown command ${globalcmd}"
976 exit 1
978 esac
980 TMPDIR="release.$$"
981 CLEANUP_DIRS="${CLEANUP_DIRS} ${TMPDIR}"
982 umask 0077
983 mkdir "${TMPDIR}"
984 umask 0022
986 for cmd in ${cmds}; do
987 echo "Starting subcommand[${cmd}]"
988 ${cmd}_release || {
989 echo "Failed subcommand[${cmd}]"
990 exit 1
992 echo "Finished subcommand[${cmd}]"
993 done
995 test -d "${TMPDIR}" && {
996 rm -rf "${TMPDIR}" || {
997 echo "failed to remove ${TMPDIR}"
1001 test -n "${next_cmd}" && {
1002 echo "Continue with '$0 ${product} ${next_cmd} ${tagname}'."
1005 trap - INT QUIT TERM EXIT
1007 exit 0