This is a cookbook showing the steps required to create a libLASi release at
SourceForge.

INDEX
(1)  Create and test a preliminary tarball from trunk
(2)  Finish release-related trunk changes so they will be in the release
(3)  Create and test the release tarball from trunk
(4)  Update ChangeLog and README.Release_Manager_Cookbook
(5)  Tag the release
(6)  Create and test the release tarball from the tagged version
(7)  Generate a file release at Sourceforge
(8)  Commit the tagged version
(9)  Publicity for the release announcement
(10) Post release tweaking of this file (README.Release_Manager_Cookbook)

(A1) GNU Privacy Guard (gpg).
(A2) Setting the correct date and time on your computer.
End of INDEX

(1)  Create and test a preliminary tarball from trunk

     Do everything in (3) below just to make sure that the trunk
     version is in good shape before you do the following final stages
     of the release process.

(2)  Finish release-related trunk changes so they will be in the release

*    set environment variable for version to make directions below
     more generic.

export LASI_VERSION=1.1.3
# Should refer to first release in this release cycle, i.e., one after
# last release for the last release.
export FIRST_RELEASE_REVISION=r200

*    Prepare a preliminary version of the ChangeLog file to see what
     has been accomplished since the last release.

# This makes the BASE used below correct.
svn update

svn log --revision ${FIRST_RELEASE_REVISION}:BASE --verbose  >| ChangeLog.release_preliminary

     Note the "_preliminary" suffix to distinguish this from the final
     result below which will contain (if all goes well in the steps
     below) a record of all but the last commit (of the ChangeLog
     itself) for this release.

     Note the order of the --revision components puts this preliminary
     version in chronological order.  But it is traditional for the
     final version to have the result in reverse chronological order
     (see below).

*    Update and commit README and cmake/module/lasi_version.cmake to
     reflect the current version. Also, follow the instructions in
     that latter file for updating the SOVERSION, the minor number and
     the patch number.

*    Update and commit the release notes (stored in the README.release
     file) containing a short overview of the most important changes
     noted in the ChangeLog.release_preliminary file since the last
     release.

*    Once completely satisfied with README.release insert it at the
     start of README.cumulated release to keep a historical record in
     reverse chronological order of the notes for all releases in that
     file.  From now on, any further tweaks to README.release should
     be mirrored in README.cumulated release which is why this
     insertion step should be delayed until the release manager is
     completely satisfied with README.release.

*    Check that all local changes (other than this file,
     README.Release_Manager_Cookbook, and ChangeLog) are in the
     repository so they will be reflected in the ChangeLog, tagged
     version of the release, and release tarball.

svn status

(3)  Create and test the release tarball from trunk

*    Do the usual cmake and make in the build tree to build the user
     and developer configurations of the Doxygen documentation in the
     source tree.  For example,

cd /home/software/lasi_svn/HEAD/build_dir
# In case this not set.
LASI_VERSION= 1.1.3
time (rm -rf /home/software/lasi_svn/HEAD/build_dir/* ~/lasi_svn/install; env PATH="/usr/bin:$PATH" cmake -DCMAKE_INSTALL_PREFIX=/home/software/lasi_svn/install -DBUILD_SHARED_LIBS=ON ../lasi_2019 >& cmake.out)
make -j16 all >& all.out

     Then build a preliminary version of the release tarball

make package_source

*    Check that generated tarball by checking its table of contents as follows:

tar ztvf libLASi-$LASI_VERSION.tar.gz |sed "s?  *? ?g" |cut --delimiter=" " --fields="6-" |less

*    Unpack that tarball:

tar zxf libLASi-$LASI_VERSION.tar.gz

*    Test that tarball with shared build, install, and shared examples build

mkdir tarball_build_dir
cd tarball_build_dir
build_tree_dir=$(pwd)
/usr/bin/cmake -DCMAKE_INSTALL_PREFIX=../tarball_install -DBUILD_SHARED_LIBS=ON ../libLASi-$LASI_VERSION >& cmake.out
make -j16 >& make.out
# Inspect EPS results.  Note a white background has to be imposed because
# these results have no background.  So by default the background would be a checkerboard
# imposed by pqiv if this --background-pattern option was not used.

# Inspect same results converted (with opaque white background added) to PNG format
# by inkscape.

for CORE_NAME in MissingGlyphExample SimpleLASiExample ComplexTextLayoutExample ; do
    pqiv -i --background-pattern=white examples/$CORE_NAME.eps
    pqiv -i examples/$CORE_NAME.png
done

# ldd and valgrind tests of the examples including comparisons of the
# results generated with the previous results.  Note, that 2>&1
# redirects stderr to *current" stdout (which defaults to pipe),
# test.eps afterwards means PostScript output goes directly to that
# file rather than stdout (so nothing more is emitted to stdout), and
# >| test.eps afterwards means PostScript output goes to stdout (but
# not stderr) and stdout then overwrites whatever was in test.eps
# before.

for CORE_NAME in MissingGlyphExample SimpleLASiExample ComplexTextLayoutExample ; do
    ldd -r examples/$CORE_NAME 2>&1 | less
    valgrind examples/$CORE_NAME 2>&1 test.eps | less
    cmp test.eps examples/$CORE_NAME.eps
    valgrind examples/$CORE_NAME 2>&1 >| test.eps | less
    cmp test.eps examples/$CORE_NAME.eps
done

# Run ctest
/usr/bin/ctest -j16 --output-log >| ctest.out
# Compare ctest results with above make results.
for CORE_NAME in MissingGlyphExample SimpleLASiExample ComplexTextLayoutExample ; do
    cmp examples/ctest_examples_output_dir/$CORE_NAME.eps examples/$CORE_NAME.eps
done

make -j16 install >& make_install.out
cd ../tarball_install/share/lasi$LASI_VERSION/examples
make -j16 >& make.out

for CORE_NAME in MissingGlyphExample SimpleLASiExample ComplexTextLayoutExample ; do
    ldd -r $CORE_NAME 2>&1 | less
    cmp $CORE_NAME.eps $build_tree_dir/examples/$CORE_NAME.eps
    valgrind ./$CORE_NAME 2>&1 test.eps | less
    cmp test.eps $CORE_NAME.eps
    valgrind ./$CORE_NAME 2>&1 >| test.eps | less
    cmp test.eps $CORE_NAME.eps
done

*    Test that tarball with static build, install, and static examples build

# Repeat all the prior test steps starting with removing prior test results with

cd $build_tree_dir/..
rm -rf tarball_*

# Then follow with all the above steps starting with

mkdir tarball_build_dir
[...]

# but with cmake option -DBUILD_SHARED_LIBS=ON replaced by -DBUILD_SHARED_LIBS=OFF

     If these tests reveal that trunk changes are necessary, do those, commit
them, and retest them.

(4)  Update ChangeLog and README.Release_Manager_Cookbook

*    Update this file (README.Release_Manager_Cookbook) as much as
     possible concerning what has been done to complete this release
     and commit that result.  However, if some subsequent deviations
     occur from the instructions in this cookbook then this file
     should also be tweaked after the release (see (10)).
svn commit README.Release_Manager_Cookbook

*    Prepare a (hopefully) final version of the ChangeLog file and commit it.
svn update
svn log --revision BASE:${LAST_RELEASE_REVISION} --verbose >| ChangeLog.preliminary
mv ChangeLog.preliminary ChangeLog.release
svn commit ChangeLog.release

(5)  Tag the release

     Based on suggestions in the svn manual, the libLASi svn archive
     is configured as follows:

branches/
tags/
trunk/

     For the release, you will be creating (and eventually committing)
     what is essentially a branch of libLASi that is a snapshot record
     of that subproject at the time of the release. This branch will
     be located in the /tags directory and should follow the naming
     convention tags/$LASI_VERSION although prior releases used a
     different naming convention based on CVS (!) requirements.

#ONE TIME ONLY
# The easiest way to get started is to check out the _entire_ lasi svn
# repository as follows:

svn checkout https://svn.code.sf.net/p/lasi/code lasi_allura_complete

#ONE TIME ONLY completed

     If you already have this directory, you will need to make sure
     that all your commits (probably in a different local directory)
     have been done (see above) and that lasi_complete is up to date
     with those commits.

cd lasi_allura_complete
svn update

# Create and commit release tag of lasi
svn copy trunk tags/$LASI_VERSION

(6)  Create and test the release tarball from the tagged version

     Do exactly the same as (3), but for tagged source code in
     tags/$LASI_VERSION

     In the (unlikely event that problems are found in the tarball
     generated from the tagged version during the release process,
     corrections should be made to trunk/, the ChangeLog.release file
     recreated and committed (see instructions above).  Then merge the
     trunk version into the tags as follows:

cd tags/$LASI_VERSION
svn merge -r A:B /path/to/trunk

     Where A and B specify the range of revisions in trunk to be
     applied to tags/$LASI_VERSION in the merge process. These can be
     determined by commit messages.

(7)  Generate a file release at Sourceforge

     A list of your GPG keys can be obtained using the command "gpg --list-keys <first name>"
     where <first name> is the first name you used when creating your gpg key.  The result of
     that command for the current release manager (AWI) is

pub   rsa2048 2011-08-19 [SC] [expires: 2021-12-12]
      A7CED6D2D4903103FCDDFC1E418B8FC4BB159E92
uid           [ultimate] Alan W. Irwin (Time Ephemerides key) <airwin@users.sourceforge.net>
uid           [ultimate] Alan W. Irwin (libLASi key) <airwin@users.sourceforge.net>
uid           [ultimate] Alan W. Irwin (FreeEOS key) <airwin@users.sourceforge.net>
uid           [ultimate] Alan W. Irwin (PLplot key) <airwin@users.sourceforge.net>

     The A7CED6D2D4903103FCDDFC1E418B8FC4BB159E92 field above can be used for key signings,
     but more conveniently its last 8 characters can be used for that purpose, e.g.,
     BB159E92

     Also, a new curveball thrown by the Debian Testing version of gpg
     is you must identify the tty you are using with, e.g.,

export GPG_TTY=$(tty)

     (see remarks at
     <https://www.elliotblackburn.com/importing-pgp-keys-from-keybase-into-gpg/>)

     Otherwise, in my experience, gpg will refuse to sign the tag and
     you will get the error:

error: gpg failed to sign the data
error: unable to sign the tag

     But with the above trick, the following command just worked.

gpg --default-key BB159E92 --detach-sign --armor libLASi-$LASI_VERSION.tar.gz

     where BB159E92 is the last 8 characters of the full key
     identification above and is sufficient to identify the public key
     for Alan W. Irwin as taken from the above key list.  N.B. it
     appears there is no gpg model for signing with a particular user
     id.  So the signature verification below will have all UID's.

     Then verify that result:

gpg --verify libLASi-$LASI_VERSION.tar.gz.asc

     where the output of that commmand should be similar to

gpg: assuming signed data in 'libLASi-1.1.3.tar.gz'
gpg: Signature made Wed 30 Jan 2019 10:58:19 PM PST
gpg:                using RSA key A7CED6D2D4903103FCDDFC1E418B8FC4BB159E92
gpg: Good signature from "Alan W. Irwin (Time Ephemerides key) <airwin@users.sourceforge.net>" [ultimate]
gpg:                 aka "Alan W. Irwin (libLASi key) <airwin@users.sourceforge.net>" [ultimate]
gpg:                 aka "Alan W. Irwin (FreeEOS key) <airwin@users.sourceforge.net>" [ultimate]
gpg:                 aka "Alan W. Irwin (PLplot key) <airwin@users.sourceforge.net>" [ultimate]

     Copy the results to a more permanent location:

cp libLASi-$LASI_VERSION.tar.gz* /home/software/lasi_svn/HEAD/export

     Prepare a temporary file called README.release that concatenates
     README.release and ChangeLog.release.

cd lasi_allura_complete/tags/$LASI_VERSION

echo "

DETAILED CHANGELOG FOR THIS RELEASE

" | \
cat README.release - ChangeLog.release >| /tmp/README.release

     Upload the release to SourceForge using sftp

cd /home/software/lasi_svn/HEAD/export

sftp airwin,lasi@frs.sourceforge.net <<EOF
cd /home/frs/project/l/la/lasi/lasi
mkdir "$LASI_VERSION Source"
cd "$LASI_VERSION Source"
put libLASi-$LASI_VERSION.tar.gz.asc
put libLASi-$LASI_VERSION.tar.gz
lcd /tmp
put README.release
quit
EOF

     Demonstrate with irwin account that can download these uploaded
     results and verify them:

SITE=https://sourceforge.net/projects/lasi/files/lasi/"$LASI_VERSION Source"
wget "$SITE/libLASi-$LASI_VERSION.tar.gz.asc"
wget "$SITE/libLASi-$LASI_VERSION.tar.gz"

gpg --verify libLASi-$LASI_VERSION.tar.gz.asc

# Belt and suspenders....

diff libLASi-$LASI_VERSION.tar.gz.asc /home/software/lasi_svn/HEAD/export
diff libLASi-$LASI_VERSION.tar.gz /home/software/lasi_svn/HEAD/export

     Login to sf.net
 
     Go to the file-release area at
     sf.net/projects/lasi/files/lasi/<LASI_VERSION> Source

     (where <LASI_VERSION> stands for whatever you have set
     LASI_VERSION to above)

     Click on the "i" or "info" button to mark the tar.gz file as the
     default file to download for all platforms.

(8)  Commit the tagged version
cd lasi_allura_complete
svn commit tags/$LASI_VERSION

(9)  Publicity for the release announcement

     Create a news item for the Release:
     Click on the news menu item and then click on

     Click "Submit" for the news feature.

     Experience shows you should edit a temporary file with no line
     feeds except at paragraph breaks, and all URL's should be
     mentioned as-is with no html formatting.  Then cat that file, and
     cut and paste the result to the form generated above.  SF then
     turns that result into something readable as HTML with the URL's
     turned into clickable links.

     Other publicity:

     Barbara: linuxtoday.com, lwn.net, lxer.com

(10) Post release tweaking of this file (README.Release_Manager_Cookbook)

     This only needs to be done if the actual procedure followed for
     the release differed in any detail from the previously updated
     instructions in this file.

DONE!  :-)

--- Appendix ---

(A1) GNU Privacy Guard (gpg)
A brief summary of developer relevant gpg commands, see also:
http://dewinter.com/gnupg_howto/english/GPGMiniHowto.html,
man gpg, and http://www.gnupg.org/faq/GnuPG-FAQ.html.

* Configure key-server (if you haven't done that already) by editing
  $HOME/.gnupg/gpg.conf.  Also specify the auto-key-retrieve option
  for convenience.

* List keys on your keyring that have been retrieved or generated so far:

gpg --list-keys irwin

* Search for any previously published keys that you might want to
  revoke.  (Note the search phrase is case insensitive but the search
  is done on the Boolean AND of the terms so the following search would
  miss any key generated in the past by Alan Irwin because of the
  middle initial "W." that is specified for the search).  OTOH, I
  always use my middle initial for publications to reduce name clashes.

gpg --search-keys Alan W. Irwin

* Create a new key:

gpg --gen-key

  With gnupg 1.4.10, I chose the following options when creating a new key:
  
Please select what kind of key you want:
  (1) RSA and RSA (default)

What keysize do you want?
2048 (default)
5-year expiration date.

....

Real name: Alan W. Irwin
Email address: irwin@users.sourceforge.net
Comment: Time Ephemerides key
You selected this USER-ID:
    "Alan W. Irwin (Time Ephemerides key) <irwin@users.sourceforge.net>"


N.B. nameofkey below is the name of the key, usually specified by the
second number after the slash for the first pub line given by
"gpg --list-keys".  For example, the above key gives the following
result:

software@raven> gpg --list-keys irwin
pub   2048R/BB159E92 2011-08-19 [expires: 2016-08-17]
uid                  Alan W. Irwin (Time Ephemerides key) <irwin@users.sourceforge.net>
sub   2048R/C5ECCF77 2011-08-19 [expires: 2016-08-17]

So the name could be BB159E92.  Other possibilities exist as well such
as "irwin", but that might not be unique.

* N.B. Made a mistake in the above.  My SF e-mail address is airwin@....
not irwin@... GRRR.  So fix it.

Under --edit-key command

adduid  (fill in correct e-mail address this time)
uid number (to select uid to work on for further commands
revuid  (revoke bad e-mail one)
primary (to make the new one the primary one, I am not sure that is necessary)
trust  (to make the new one ultimately trusted, again, not sure that is necessary.  N.B. didn't seem to change trust value, but that was just bad output)

save  (to get out again)

When edited the next time showed ultimate trust value for correct id, but
I don't know whether that was the above primary/trust subcommands or
whether those were necessary at all.  It turned out those were not
necessary at all as I later used the above sequence to generate
a libLASi key and a FreeEOS uid key.

* Generate a revocation certificate.  Note this requires the pass phrase
  specified at the time of key generation so keep that pass phrase in
  a safe place or else generate the revocation certificate right after
  generating the key, and keep that certificate in a safe place.  I chose
  the former course (keep the pass phrase safe).  N.B. the options should
  appear below in the order given!

gpg --armor -o nameofkey-revocation.asc --gen-revoke nameofkey

* Publicly revoke old key (from FAQ):

gpg --import old-revocation.asc
gpg --send-keys nameofkey

* Upload your (public) key to GPG key server so that others can obtain it to
verify your signature on the release tarball.
gpg --send-keys nameofkey

gpg --refresh-keys  (to update from the server all keys including your own).

This verified that the bad irwin address was revoked even though
gpg --search-keys Alan W. Irwin

still shows revoked uid as the #1 uid.

(A2) Setting the correct date and time on your computer.

(While it is useful to have the correct time on your computer, this is no 
longer strictly necessary).
Verify that your computer has the right date and time using the command date.
The easiest way to make sure the time and date are correct is to do the 
following:
1. Install the debian ntpdate package.
2. Execute the command "/usr/sbin/ntpdate pool.ntp.org", which you will
   have to do as root.
This will immediately change your system clock. It is not recommended if you
have other apps running on your system that expect time to increase in a
smooth and linear fashion.

If you would like your computer to always have the correct time and date, you 
can install the debian ntp package, which must be properly configured to work.
Some notes about how to do this can be found in the PLplot mailing list 
archive. Look for the thread titled "PLplot 5.7.2 is now available" dated 
Jan 22/23 2007.
