2 # make a release of Samba or a library
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"
21 echo "Run this script from the top-level directory in the"
27 echo "Usage: release.sh <PRODUCT> <COMMAND>"
29 echo "PRODUCT: ldb, talloc, tevent, tdb, samba-rc, samba-stable"
30 echo "COMMAND: fullrelease, create, push, upload, announce"
40 test x
"${got_args}" = x
"${take_args}" ||
{
42 echo "cmd[${cmd}] takes ${take_args} instead of ${got_args}"
54 test "${got_args}" -ge "${min_args}" ||
{
56 echo "cmd[${cmd}] takes at least ${min_args} instead of ${got_args}"
63 min_args
"$0" "$#" "2"
75 min_args
"${FUNCNAME}" "$#" "1" ||
return 1
78 test -n "${tagname}" ||
{
79 echo "cmd[${cmd}] requires '\${tagname}' variable to be set"
83 local name
=$
(echo "${tagname}" | cut
-d '-' -f1)
84 test x
"${name}" = x
"${productbase}" ||
{
85 echo "Invalid tagname[${tgzname}]"
93 min_args
"${FUNCNAME}" "$#" "2" ||
return 1
97 echo "$@" |
grep -q "\<${cmd}\>" ||
{
105 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
108 echo "VERSION doesn't exist"
112 grep -q 'SAMBA_VERSION_IS_GIT_SNAPSHOT=no' VERSION ||
{
113 echo "SAMBA_VERSION_IS_GIT_SNAPSHOT is not 'no'"
117 grep -q '^SAMBA_VERSION_RC_RELEASE=' VERSION ||
{
118 echo "SAMBA_VERSION_RC_RELEASE= missing"
122 grep -q '^SAMBA_VERSION_RC_RELEASE=$' VERSION
&& {
123 echo "SAMBA_VERSION_RC_RELEASE= missing the rc version"
130 load_samba_stable_versions
() {
131 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
133 test -n "${version-}" && {
137 local SAMBA_VERSION_MAJOR
=$
(grep '^SAMBA_VERSION_MAJOR=' VERSION | cut
-d '=' -f2 |
xargs)
138 local SAMBA_VERSION_MINOR
=$
(grep '^SAMBA_VERSION_MINOR=' VERSION | cut
-d '=' -f2 |
xargs)
139 local SAMBA_VERSION_RELEASE
=$
(grep '^SAMBA_VERSION_RELEASE=' VERSION | cut
-d '=' -f2 |
xargs)
141 version
="${SAMBA_VERSION_MAJOR}.${SAMBA_VERSION_MINOR}.${SAMBA_VERSION_RELEASE}"
142 tagname
="${productbase}-${version}"
144 test ${SAMBA_VERSION_RELEASE} -gt 0 ||
{
148 oldversion
="${SAMBA_VERSION_MAJOR}.${SAMBA_VERSION_MINOR}.$(expr ${SAMBA_VERSION_RELEASE} - 1)"
149 oldtagname
="${productbase}-${oldversion}"
150 patchfile
="${productbase}-${oldversion}-${version}.diffs"
155 verify_samba_stable
() {
156 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
159 echo "VERSION doesn't exist"
163 grep -q 'SAMBA_VERSION_IS_GIT_SNAPSHOT=no' VERSION ||
{
164 echo "SAMBA_VERSION_IS_GIT_SNAPSHOT is not 'no'"
169 VARS
="${VARS} SAMBA_VERSION_REVISION"
170 VARS
="${VARS} SAMBA_VERSION_TP_RELEASE"
171 VARS
="${VARS} SAMBA_VERSION_ALPHA_RELEASE"
172 VARS
="${VARS} SAMBA_VERSION_BETA_RELEASE"
173 VARS
="${VARS} SAMBA_VERSION_PRE_RELEASE"
174 VARS
="${VARS} SAMBA_VERSION_RC_RELEASE"
175 VARS
="${VARS} SAMBA_VERSION_RELEASE_NICKNAME"
176 VARS
="${VARS} SAMBA_VERSION_VENDOR_SUFFIX"
177 VARS
="${VARS} SAMBA_VERSION_VENDOR_PATCH"
178 for var
in ${VARS}; do
179 grep -q "^${var}" VERSION
&& {
180 grep -q "^${var}=$" VERSION ||
{
181 echo "${var} found in stable version"
187 load_samba_stable_versions
189 test x
"${product}" = x
"samba-stable" && {
190 test -f "announce.${tagname}.quotation.txt" ||
{
192 echo "announce.${tagname}.quotation.txt missing!"
194 echo "Please create it and retry"
196 echo "The content should look like this:"
197 echo "cat announce.${tagname}.quotation.txt"
198 echo '======================================================'
200 echo ' from someone."'
203 echo '======================================================'
209 test -n "${oldtagname}" ||
{
213 local verify_out
="${TMPDIR}/verify-${oldtagname}.out"
215 echo "Verifying oldtagname: ${oldtagname}"
217 git tag
-v "${oldtagname}" >${verify_out} 2>&1 ||
{
218 echo "failed to verify old tag[${oldtagname}]"
224 grep -q "${GPG_KEYID}" "${verify_out}" ||
{
225 echo "oldtagname[${oldtagname}] was not generated with GPG_KEYID[${GPG_KEYID}]!"
231 echo "Verifying ${oldtagname}.tar.gz and ${oldtagname}.tar.asc"
233 test -f "${oldtagname}.tar.gz" ||
{
234 echo "${oldtagname}.tar.gz does not exist"
238 test -f "${oldtagname}.tar.asc" ||
{
239 echo "${oldtagname}.tar.asc does not exist"
243 zcat
"${oldtagname}.tar.gz" | gpg --verify "${oldtagname}.tar.asc" - 2>${verify_out} || {
244 echo "Failed to verify
${oldtagname}.
tar.asc
"
248 grep -q "${GPG_KEYID}" "${verify_out}" || {
249 echo "${oldtagname}.
tar.asc was not generated with GPG_KEYID
[${GPG_KEYID}]!"
259 check_args "${FUNCNAME}" "$#" "0" || return 1
261 test -n "${verify_fn}" || {
262 echo "verify_fn variable empty
"
266 echo "Running
${verify_fn}"
271 check_args "${FUNCNAME}" "$#" "0" || return 1
273 echo "Releasing product
${product}"
275 test -n "${tagname}" && {
276 git tag -l "${tagname}" | grep -q "${tagname}" && {
277 echo "tagname
[${tagname}] already exist
"
281 local _tgzname="${tagname}.
tar.gz
"
282 test -e "${_tgzname}" && {
283 echo "_tgzname
[${_tgzname}] already exist
"
288 echo "Building release tarball
"
289 local tgzname=$(make dist 2>&1 | grep ^Created | cut -d' ' -f2)
290 test -f "${tgzname}" || {
291 echo "Failed to create tarball
"
294 CLEANUP_FILES="${CLEANUP_FILES} ${tgzname}"
296 local name=$(echo "${tgzname}" | cut -d '-' -f1)
297 test x"${name}" = x"${productbase}" || {
298 echo "Invalid tgzname
[${tgzname}]"
302 local _tagname=$(basename ${tgzname} .tar.gz)
303 test -n "${tagname}" && {
304 test x"${_tagname}" = x"${tagname}" || {
305 echo "Invalid tgzname
[${tgzname}]"
309 tagname="${_tagname}"
311 local tarname=$(basename ${tgzname} .gz)
312 echo "Tarball
: ${tarname}"
313 gunzip -f ${tgzname} || {
314 echo "Failed to decompress tarball
${tarname}"
317 test -f "${tarname}" || {
318 echo "Failed to decompress tarball
${tarname}"
321 CLEANUP_FILES="${CLEANUP_FILES} ${tarname}"
324 echo "Tagging as
${tagname}"
325 git tag -u ${GPG_KEYID} -s "${tagname}" -m "${productbase}: tag release ${tagname}" ||
{
328 CLEANUP_TAGS
="${CLEANUP_TAGS} ${tagname}"
330 echo "Signing ${tarname} => ${tarname}.asc"
331 rm -f "${tarname}.asc"
332 gpg
-u "${GPG_USER}" --detach-sign --armor ${tarname} ||
{
335 test -f "${tarname}.asc" ||
{
336 echo "Failed to create signature ${tarname}.asc"
339 CLEANUP_FILES
="${CLEANUP_FILES} ${tarname}.asc"
340 echo "Compressing ${tarname} => ${tgzname}"
341 gzip -f -9 ${tarname}
342 test -f "${tgzname}" ||
{
343 echo "Failed to compress ${tgzname}"
351 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
352 require_tagname
"${FUNCNAME}"
354 test -n "${patchfile}" ||
{
359 echo "Generating ${patchfile}"
364 tar xfz
"${oldpwd}/${oldtagname}.tar.gz"
365 tar xfz
"${oldpwd}/${tagname}.tar.gz"
366 diff -Npur "${oldtagname}/" "${tagname}/" > "${patchfile}"
369 CLEANUP_FILES
="${CLEANUP_FILES} ${patchfile}"
370 mv "${TMPDIR}/${patchfile}" "${patchfile}" ||
{
371 echo "failed cmd[mv ${TMPDIR}/${patchfile} ${patchfile}]"
375 echo "Signing ${patchfile} => ${patchfile}.asc"
376 rm -f "${patchfile}.asc"
377 CLEANUP_FILES
="${CLEANUP_FILES} ${patchfile}.asc"
378 gpg
-u "${GPG_USER}" --detach-sign --armor ${patchfile} ||
{
381 test -f "${patchfile}.asc" ||
{
382 echo "Failed to create signature ${patchfile}.asc"
385 echo "Compressing ${patchfile} => ${patchfile}.gz"
386 CLEANUP_FILES
="${CLEANUP_FILES} ${patchfile}.gz"
387 gzip -f -9 ${patchfile}
388 test -f "${patchfile}.gz" ||
{
389 echo "Failed to compress ${patchfile}.gz"
397 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
398 require_tagname
"${FUNCNAME}"
400 echo "extract ${tagname}.WHATSNEW.txt"
401 tar xf
${tagname}.tar.gz --to-stdout ${tagname}/WHATSNEW.txt > ${tagname}.WHATSNEW.txt
402 CLEANUP_FILES
="${CLEANUP_FILES} ${tagname}.WHATSNEW.txt"
408 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
409 require_tagname
"${FUNCNAME}"
411 local verify_out
="${TMPDIR}/verify-${oldtagname}.out"
413 echo "Verifying tagname: ${tagname}"
415 git tag
-v "${tagname}" >${verify_out} 2>&1 ||
{
416 echo "failed to verify tag[${tagname}]"
421 grep -q "${GPG_KEYID}" "${verify_out}" ||
{
422 echo "tagname[${tagname}] was not generated with GPG_KEYID[${GPG_KEYID}]!"
428 echo "Verifying ${tagname}.tar.gz and ${tagname}.tar.asc"
430 test -f "${tagname}.tar.gz" ||
{
431 echo "${tagname}.tar.gz does not exist"
435 test -f "${tagname}.tar.asc" ||
{
436 echo "${tagname}.tar.asc does not exist"
440 zcat
"${tagname}.tar.gz" | gpg --verify "${tagname}.tar.asc" - 2>${verify_out} || {
441 echo "Failed to verify
${tagname}.
tar.asc
"
444 grep -q "${GPG_KEYID}" "${verify_out}" || {
445 echo "${tagname}.
tar.asc was not generated with GPG_KEYID
[${GPG_KEYID}]!"
456 check_samba_stable() {
457 check_args "${FUNCNAME}" "$#" "0" || return 1
458 require_tagname "${FUNCNAME}"
460 load_samba_stable_versions
462 local verify_out="${TMPDIR}/verify-
${oldtagname}.out
"
464 echo "Verifying tagname
: ${tagname}"
466 git tag -v "${tagname}" >${verify_out} 2>&1 || {
467 echo "failed to verify tag
[${tagname}]"
472 grep -q "${GPG_KEYID}" "${verify_out}" || {
473 echo "tagname
[${tagname}] was not generated with GPG_KEYID
[${GPG_KEYID}]!"
479 echo "Verifying
${tagname}.
tar.gz and
${tagname}.
tar.asc
"
481 test -f "${tagname}.
tar.gz
" || {
482 echo "${tagname}.
tar.gz does not exist
"
486 test -f "${tagname}.
tar.asc
" || {
487 echo "${tagname}.
tar.asc does not exist
"
491 zcat "${tagname}.tar.gz" | gpg --verify "${tagname}.tar.asc" - 2>${verify_out} ||
{
492 echo "Failed to verify ${tagname}.tar.asc"
495 grep -q "${GPG_KEYID}" "${verify_out}" ||
{
496 echo "${tagname}.tar.asc was not generated with GPG_KEYID[${GPG_KEYID}]!"
502 test -n "${patchfile}" ||
{
503 ls -lart ${tagname}.
*
507 echo "Verifying ${patchfile}.gz and ${patchfile}.asc"
509 test -f "${patchfile}.gz" ||
{
510 echo "${patchfile}.gz does not exist"
514 test -f "${patchfile}.asc" ||
{
515 echo "${patchfile}.asc does not exist"
519 zcat
"${patchfile}.gz" | gpg --verify "${patchfile}.asc" - 2>${verify_out} || {
520 echo "Failed to verify
${patchfile}.asc
"
523 grep -q "${GPG_KEYID}" "${verify_out}" || {
524 echo "${patchfile}.asc was not generated with GPG_KEYID
[${GPG_KEYID}]!"
530 ls -lart ${tagname}.* ${patchfile}.*
535 check_args "${FUNCNAME}" "$#" "0" || return 1
537 test -n "${check_fn}" || {
538 echo "check_fn variable empty
"
542 echo "Running
${check_fn}"
547 check_args "${FUNCNAME}" "$#" "0" || return 1
548 require_tagname "${FUNCNAME}"
550 echo "Push git tag
${tagname} to
'${repo_url}'"
551 git push "${repo_url}" "refs/tags/${tagname}:refs/tags/${tagname}" || {
559 check_args "${FUNCNAME}" "$#" "0" || return 1
560 require_tagname "${FUNCNAME}"
562 echo "Upload
${tagname}.
* to
'${upload_url}'"
563 rsync -Pav --delay-updates ${tagname}.* "${upload_url}/" || {
566 rsync ${upload_url}/${tagname}.*
571 upload_samba_stable() {
572 check_args "${FUNCNAME}" "$#" "0" || return 1
573 require_tagname "${FUNCNAME}"
575 load_samba_stable_versions
577 local release_url="${upload_url}samba
/stable
/"
578 local patch_url="${upload_url}samba
/patches
/"
580 echo "Upload
${tagname}.
tar.
* to
'${release_url}'"
581 ls -lart ${tagname}.tar.*
582 rsync -Pav --delay-updates ${tagname}.tar.* "${release_url}/" || {
585 rsync ${release_url}/${tagname}.tar.*
587 test -n "${patchfile}" || {
591 echo "Upload
${patchfile}.
* to
'${patch_url}'"
592 ls -lart ${patchfile}.*
593 rsync -Pav --delay-updates ${patchfile}.* "${patch_url}/" || {
596 rsync ${patch_url}/${patchfile}.*
602 check_args "${FUNCNAME}" "$#" "0" || return 1
604 test -n "${upload_fn}" || {
605 echo "upload_fn variable empty
"
609 echo "Running
${upload_fn}"
613 announcement_samba_rc() {
614 check_args "${FUNCNAME}" "$#" "0" || return 1
615 require_tagname "${FUNCNAME}"
617 test -f "${tagname}.WHATSNEW.txt
" || {
618 echo "${tagname}.WHATSNEW.txt does not exist
"
623 local version=$(echo "${tagname}" | sed -e 's!^samba-!!')
624 local href="#${version}"
625 local series
=$
(echo "${version}" | cut
-d '.' -f1-2)
626 local rc
=$
(echo "${version}" |
sed -e 's!.*rc\([0-9][0-9]*\)!\1!')
627 local rcname
="${rc}th"
646 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.to.txt"
648 echo "samba-announce@lists.samba.org, samba@lists.samba.org, samba-technical@lists.samba.org"
649 } > announce.
${tagname}.to.txt
651 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.subject.txt"
653 echo "[Announce] Samba ${version} Available for Download"
654 } > announce.
${tagname}.subject.txt
656 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.mail.txt"
658 cat ${tagname}.WHATSNEW.txt
660 echo "================"
661 echo "Download Details"
662 echo "================"
664 echo "The uncompressed tarballs and patch files have been signed"
665 echo "using GnuPG (ID ${GPG_KEYID}). The source code can be downloaded"
668 echo " ${download_url}"
670 echo "The release notes are available online at:"
672 echo " ${download_url}${tagname}.WHATSNEW.txt"
674 echo "Our Code, Our Bugs, Our Responsibility."
675 echo "(https://bugzilla.samba.org/)"
678 echo " The Samba Team"
679 } > announce.
${tagname}.
mail.txt
681 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.mutt-arguments.txt"
683 echo -n "-i announce.${tagname}.mail.txt "
684 echo -n "-s \"$(cat announce.${tagname}.subject.txt | xargs)\" "
685 echo -n "$(cat announce.${tagname}.to.txt | xargs)"
686 } > announce.
${tagname}.mutt-arguments.txt
688 local headlinefile
="posted_news/@UTCTIME@.${version}.headline.html"
689 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.headline.html"
691 echo "<!-- BEGIN: ${headlinefile} -->"
692 echo "<li> @UTCDATE@ <a href=\"${href}\">Samba ${version} Available for Download</a></li>"
693 echo "<!-- END: ${headlinefile} -->"
694 } > announce.
${tagname}.headline.html
696 local bodyfile
="posted_news/@UTCTIME@.${version}.body.html"
697 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.body.html"
699 echo "<!-- BEGIN: ${bodyfile} -->"
700 echo "<h5><a name=\"${version}\">@UTCDATE@</a></h5>"
701 echo "<p class="headline
">Samba ${version} Available for Download</p>"
703 echo "This is the ${rcname} release candidate of the upcoming Samba ${series} release series."
706 echo "The uncompressed tarball has been signed using GnuPG (ID ${GPG_KEYID})."
707 echo "The source code can be <a href=\"${download_url}${tagname}.tar.gz\">downloaded now</a>."
708 echo "See <a href=\"${download_url}${tagname}.WHATSNEW.txt\">the release notes for more info</a>."
710 echo "<!-- END: ${bodyfile} -->"
711 } > announce.
${tagname}.body.html
713 local webrepo
="${TMPDIR}/webrepo"
715 mkdir
"${webrepo}" ||
{
718 git
-C "${webrepo}" init ||
{
722 mkdir
-p "$(dirname ${webrepo}/${headlinefile})" ||
{
725 cp -a "announce.${tagname}.headline.html" "${webrepo}/${headlinefile}" ||
{
729 mkdir
-p "$(dirname ${webrepo}/${bodyfile})" ||
{
732 cp -a "announce.${tagname}.body.html" "${webrepo}/${bodyfile}" ||
{
736 git
-C "${webrepo}" add "${headlinefile}" "${bodyfile}" ||
{
739 git
-C "${webrepo}" commit --signoff --message "NEWS[${version}]: Samba ${version} Available for Download" ||
{
742 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.patch.txt"
743 git
-C "${webrepo}" format-patch
--stdout -1 HEAD
> announce.
${tagname}.
patch.txt ||
{
747 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.todo.txt"
749 ls -lart announce.
${tagname}.
*
752 echo "You need to do the following manual steps in order"
753 echo "to finish the announcement of ${tagname}!"
755 echo "Change to a samba-web checkout and run"
756 echo " ./announce_samba_release.sh ${version} $(pwd)/announce.${tagname}.patch.txt"
758 echo "Once the resulting commit is pushed a cron job will update "
759 echo "the content exported by the webserver every 5-10 mins."
760 echo "Check https://www.samba.org"
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)"
769 echo "NOTICE: you're not done yet! Read the above instructions carefully!"
770 echo "See: announce.${tagname}.todo.txt"
772 } > announce.
${tagname}.todo.txt
774 ls -lart announce.
${tagname}.
*
778 announcement_samba_stable
() {
779 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
780 require_tagname
"${FUNCNAME}"
782 load_samba_stable_versions
784 test -f "${tagname}.tar.gz" ||
{
785 echo "${tagname}.tar.gz does not exist"
789 test -f "announce.${tagname}.quotation.txt" ||
{
790 echo "announce.${tagname}.quotation.txt missing!"
794 local release_url
="${download_url}samba/stable/"
795 local patch_url
="${download_url}samba/patches/"
797 echo "extract WHATSNEW.txt"
798 tar xf
${tagname}.tar.gz --to-stdout ${tagname}/WHATSNEW.txt > ${TMPDIR}/WHATSNEW.txt
801 local oldversion
=$
(echo "${oldtagname}" |
sed -e 's!^samba-!!')
802 local version
=$
(echo "${tagname}" |
sed -e 's!^samba-!!')
803 local href
="#${version}"
804 local series
=$
(echo "${version}" | cut
-d '.' -f1-2)
805 local release
=$
(echo "${version}" | cut
-d '.' -f3)
806 local releasename
="latest"
816 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.to.txt"
818 echo "samba-announce@lists.samba.org, samba@lists.samba.org, samba-technical@lists.samba.org"
819 } > announce.
${tagname}.to.txt
821 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.subject.txt"
823 echo "[Announce] Samba ${version} Available for Download"
824 } > announce.
${tagname}.subject.txt
826 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.mail.txt"
828 local top
=$
(cat ${TMPDIR}/WHATSNEW.txt |
grep -n '^Release notes for older releases follow:' |
head -1 | cut
-d ':' -f1)
829 test -n "${top}" ||
{
830 top
=$
(cat ${TMPDIR}/WHATSNEW.txt |
wc -l)
832 local skip
=$
(cat ${TMPDIR}/WHATSNEW.txt |
grep -n '^[^ ]' |
head -1 | cut
-d ':' -f1)
833 local headlimit
=$
(expr ${top} - 1 )
834 local taillimit
=$
(expr ${headlimit} - \
( ${skip} - 1 \
))
836 cat "announce.${tagname}.quotation.txt"
839 echo "Release Announcements"
840 echo "---------------------"
842 head -${headlimit} ${TMPDIR}/WHATSNEW.txt | tail -${taillimit}
844 echo "================"
845 echo "Download Details"
846 echo "================"
848 echo "The uncompressed tarballs and patch files have been signed"
849 echo "using GnuPG (ID ${GPG_KEYID}). The source code can be downloaded"
852 echo " ${release_url}"
854 echo "The release notes are available online at:"
856 echo " ${history_url}${tagname}.html"
858 echo "Our Code, Our Bugs, Our Responsibility."
859 echo "(https://bugzilla.samba.org/)"
862 echo " The Samba Team"
863 } > announce.
${tagname}.
mail.txt
865 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.mutt-arguments.txt"
867 echo -n "-i announce.${tagname}.mail.txt "
868 echo -n "-s \"$(cat announce.${tagname}.subject.txt | xargs)\" "
869 echo -n "$(cat announce.${tagname}.to.txt | xargs)"
870 } > announce.
${tagname}.mutt-arguments.txt
872 local htmlfile
="history/${tagname}.html"
873 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.html"
875 local tmp
=$
(cat ${TMPDIR}/WHATSNEW.txt |
grep -n '^Reporting bugs & Development Discussion' |
head -1 | cut
-d ':' -f1)
876 local lines
=$
(expr ${tmp} - 2)
878 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
879 echo ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
880 echo '<html xmlns="http://www.w3.org/1999/xhtml">'
883 echo "<title>Samba ${version} - Release Notes</title>"
887 echo "<H2>Samba ${version} Available for Download</H2>"
890 echo "<a href=\"${release_url}${tagname}.tar.gz\">Samba ${version} (gzipped)</a><br>"
891 echo "<a href=\"${release_url}${tagname}.tar.asc\">Signature</a>"
894 test -n "${patchfile}" && {
896 echo "<a href=\"${patch_url}${patchfile}.gz\">Patch (gzipped) against Samba ${oldversion}</a><br>"
897 echo "<a href=\"${patch_url}${patchfile}.asc\">Signature</a>"
903 head -${lines} ${TMPDIR}/WHATSNEW.txt |
sed \
904 -e 's!&!\&!g' |
sed \
907 -e 's!ä!\ä!g' \
908 -e 's!Ä!\Ä!g' \
909 -e 's!ö!\ö!g' \
910 -e 's!Ö!\Ö!g' \
911 -e 's!ü!\ü!g' \
912 -e 's!Ãœ!\Ü!g' \
913 -e 's!ß!\ß!g' \
922 } > announce.
${tagname}.html
924 local headlinefile
="posted_news/@UTCTIME@.${version}.headline.html"
925 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.headline.html"
927 echo "<!-- BEGIN: ${headlinefile} -->"
928 echo "<li> @UTCDATE@ <a href=\"${href}\">Samba ${version} Available for Download</a></li>"
929 echo "<!-- END: ${headlinefile} -->"
930 } > announce.
${tagname}.headline.html
932 local bodyfile
="posted_news/@UTCTIME@.${version}.body.html"
933 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.body.html"
935 echo "<!-- BEGIN: ${bodyfile} -->"
936 echo "<h5><a name=\"${version}\">@UTCDATE@</a></h5>"
937 echo "<p class="headline
">Samba ${version} Available for Download</p>"
939 echo "This is the ${releasename} stable release of the Samba ${series} release series."
942 echo "The uncompressed tarball has been signed using GnuPG (ID ${GPG_KEYID})."
943 echo "The source code can be <a href=\"${release_url}${tagname}.tar.gz\">downloaded now</a>."
944 test -n "${patchfile}" && {
945 echo "A <a href=\"${patch_url}${patchfile}.gz\">patch against Samba ${oldversion}</a> is also available."
947 echo "See <a href=\"${history_url}${tagname}.html\">the release notes for more info</a>."
949 echo "<!-- END: ${bodyfile} -->"
950 } > announce.
${tagname}.body.html
952 local webrepo
="${TMPDIR}/webrepo"
954 mkdir
"${webrepo}" ||
{
957 git
-C "${webrepo}" init ||
{
961 mkdir
-p "$(dirname ${webrepo}/${htmlfile})" ||
{
964 cp -a "announce.${tagname}.html" "${webrepo}/${htmlfile}" ||
{
968 mkdir
-p "$(dirname ${webrepo}/${headlinefile})" ||
{
971 cp -a "announce.${tagname}.headline.html" "${webrepo}/${headlinefile}" ||
{
975 mkdir
-p "$(dirname ${webrepo}/${bodyfile})" ||
{
978 cp -a "announce.${tagname}.body.html" "${webrepo}/${bodyfile}" ||
{
982 git
-C "${webrepo}" add "${htmlfile}" "${headlinefile}" "${bodyfile}" ||
{
985 git
-C "${webrepo}" commit --signoff --message "NEWS[${version}]: Samba ${version} Available for Download" ||
{
988 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.patch.txt"
989 git
-C "${webrepo}" format-patch
--stdout -1 HEAD
> announce.
${tagname}.
patch.txt ||
{
993 CLEANUP_FILES
="${CLEANUP_FILES} announce.${tagname}.todo.txt"
995 ls -lart announce.
${tagname}.
*
998 echo "You need to do the following manual steps in order"
999 echo "to finish the announcement of ${tagname}!"
1001 echo "Change to a samba-web checkout and run"
1002 echo " ./announce_samba_release.sh ${version} $(pwd)/announce.${tagname}.patch.txt"
1004 echo "Once the resulting commit is pushed a cron job will update "
1005 echo "the content exported by the webserver every 5-10 mins."
1006 echo "Check https://www.samba.org"
1008 echo "If the web content is updated, you need to send the announce mail (gpg signed)."
1009 echo "- announce.${tagname}.to.txt contains the mail's recipients for the To: header."
1010 echo "- announce.${tagname}.subject.txt contains the mail's subject line."
1011 echo "- announce.${tagname}.mail.txt contains the content of the mail body."
1012 echo "In case your're using mutt, you can use the following shortcut:"
1013 echo " eval mutt \$(cat announce.${tagname}.mutt-arguments.txt)"
1015 echo "NOTICE: you're not done yet! Read the above instructions carefully!"
1016 echo "See: announce.${tagname}.todo.txt"
1018 } > announce.
${tagname}.todo.txt
1020 ls -lart announce.
${tagname}.
*
1024 announcement_release
() {
1025 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
1027 test -n "${announcement_fn}" ||
{
1028 echo "announcement_fn variable empty"
1032 echo "Running ${announcement_fn}"
1036 announce_release
() {
1037 check_args
"${FUNCNAME}" "$#" "0" ||
return 1
1038 require_tagname
"${FUNCNAME}"
1040 test -f "announce.${tagname}.todo.txt" ||
{
1041 echo "announce.${tagname}.todo.txt does not exist"
1045 cat announce.
${tagname}.todo.txt
1049 case "${product}" in
1050 talloc | tdb | tevent | ldb
)
1051 test -z "${GPG_USER-}" && {
1052 GPG_USER
='Samba Library Distribution Key <samba-bugs@samba.org>'
1055 test -z "${GPG_KEYID-}" && {
1056 GPG_KEYID
='4793916113084025'
1059 productbase
="${product}"
1060 srcdir
="lib/${product}"
1061 repo_url
="${CONF_REPO_URL}"
1062 upload_url
="${CONF_UPLOAD_URL}/${product}/"
1063 download_url
="${CONF_DOWNLOAD_URL}/${product}/"
1065 check_fn
="check_nopatch"
1066 upload_fn
="upload_nopatch"
1067 fullcmds
="create check push upload"
1070 test -z "${GPG_USER-}" && {
1071 GPG_USER
='Samba Distribution Verification Key <samba-bugs@samba.org>'
1074 test -z "${GPG_KEYID-}" && {
1075 GPG_KEYID
='6F33915B6568B7EA'
1080 repo_url
="${CONF_REPO_URL}"
1081 upload_url
="${CONF_UPLOAD_URL}/samba/rc/"
1082 download_url
="${CONF_DOWNLOAD_URL}/samba/rc/"
1084 verify_fn
="verify_samba_rc"
1085 check_fn
="check_nopatch"
1086 upload_fn
="upload_nopatch"
1087 announcement_fn
="announcement_samba_rc"
1088 fullcmds
="verify create check whatsnew announcement push upload announce"
1091 test -z "${GPG_USER-}" && {
1092 GPG_USER
='Samba Distribution Verification Key <samba-bugs@samba.org>'
1095 test -z "${GPG_KEYID-}" && {
1096 GPG_KEYID
='6F33915B6568B7EA'
1101 repo_url
="${CONF_REPO_URL}"
1102 upload_url
="${CONF_UPLOAD_URL}/"
1103 download_url
="${CONF_DOWNLOAD_URL}/"
1104 history_url
="${CONF_HISTORY_URL}/samba/history/"
1106 verify_fn
="verify_samba_stable"
1107 check_fn
="check_samba_stable"
1108 upload_fn
="upload_samba_stable"
1109 announcement_fn
="announcement_samba_stable"
1110 fullcmds
="verify create patch check announcement push upload announce"
1112 TODO-samba-security
)
1113 test -z "${GPG_USER-}" && {
1114 GPG_USER
='Samba Distribution Verification Key <samba-bugs@samba.org>'
1117 test -z "${GPG_KEYID-}" && {
1118 GPG_KEYID
='6F33915B6568B7EA'
1123 repo_url
="${CONF_REPO_URL}"
1124 upload_url
="${CONF_UPLOAD_URL}/"
1125 download_url
="${CONF_DOWNLOAD_URL}/"
1126 history_url
="${CONF_HISTORY_URL}/samba/history/"
1128 verify_fn
="verify_samba_stable"
1129 check_fn
="check_samba_stable"
1130 upload_fn
="upload_samba_stable"
1131 announcement_fn
="announcement_samba_security"
1132 fullcmds
="verify create patch check announcement"
1137 echo "Unknown product ${product}"
1141 pushd ${srcdir} ||
{
1142 echo "srcdir[${srcdir}] does not exist"
1148 echo "ERROR: cleaning up"
1151 for t
in ${CLEANUP_TAGS}; do
1152 echo "Removing tag[${t}]"
1153 git tag
-v "${t}" && {
1154 git tag
-d "${t}" ||
{
1155 echo "failed to remove tag ${t}"
1160 for f
in ${CLEANUP_FILES}; do
1161 echo "Removing file[${f}]"
1164 echo "failed to remove ${f}"
1169 for d
in ${CLEANUP_DIRS}; do
1170 echo "Removing dir[${d}]"
1173 echo "failed to remove ${d}"
1182 trap trap_handler INT QUIT TERM EXIT
1184 cmd_allowed
"${globalcmd}" fullrelease
${fullcmds} ||
{
1186 echo "command[${globalcmd}] not supported for product[${product}]"
1190 case "${globalcmd}" in
1192 check_args
"${globalcmd}" "$#" "0" ||
exit 1
1196 check_args
"${globalcmd}" "$#" "0" ||
exit 1
1197 check_args
"create" "$#" "0" ||
exit 1
1200 cmd_allowed
"verify" ${fullcmds} && {
1201 cmds
="${cmds} verify"
1203 cmds
="${cmds} create"
1204 cmd_allowed
"whatsnew" ${fullcmds} && {
1205 cmds
="${cmds} whatsnew"
1207 cmd_allowed
"patch" ${fullcmds} && {
1208 cmds
="${cmds} patch"
1210 cmds
="${cmds} check"
1211 cmd_allowed
"announcement" ${fullcmds} && {
1212 cmds
="${cmds} announcement"
1217 check_args
"${globalcmd}" "$#" "1" ||
exit 1
1223 check_args
"${globalcmd}" "$#" "1" ||
exit 1
1226 cmd_allowed
"announce" ${fullcmds} && {
1231 check_args
"${globalcmd}" "$#" "1" ||
exit 1
1233 cmds
="check announce"
1237 echo "Unknown command ${globalcmd}"
1243 CLEANUP_DIRS
="${CLEANUP_DIRS} ${TMPDIR}"
1248 for cmd
in ${cmds}; do
1249 echo "Starting subcommand[${cmd}]"
1251 echo "Failed subcommand[${cmd}]"
1254 echo "Finished subcommand[${cmd}]"
1257 test -d "${TMPDIR}" && {
1258 rm -rf "${TMPDIR}" ||
{
1259 echo "failed to remove ${TMPDIR}"
1263 test -n "${next_cmd}" && {
1264 echo "Continue with '$0 ${product} ${next_cmd} ${tagname}'."
1267 trap - INT QUIT TERM EXIT