Checklists for PuTTY administrative procedures
==============================================

Going into pre-release stabilisation
------------------------------------

When we begin to work towards a release and want to enable
pre-releases on the website:

 - Make a branch whose tip will be the current state of the
   pre-release. Regardless of whether the branch is from main or
   from a prior release branch, the name of the branch must now be in
   the form 'pre-X.YZ', or else the website will fail to link to it
   properly in gitweb and the build script will check out the wrong
   thing.

 - Edit ~/adm/puttysnap.sh on my build machine to set $prerelver correctly.

 - Edit ~/adm/puttysnap.sh on the master machine to enable pre-release
   builds, by changing the 'if false' to 'if true'.

 - Put the website into pre-release mode, by defining prerel_version()
   in components/Base.mc to return the upcoming version number. Also
   add a news announcement in components/news. (Previous naming
   convention has been to name it in the form 'X.YZ-pre.mi'.)

Things to do during the branch-stabilisation period:

 - Go through the source (including the documentation), and the
   website, and review anything tagged with a comment containing the
   word XXX-REVIEW-BEFORE-RELEASE. (Any such comments should state
   clearly what needs to be done.)

 - Do some testing of the Windows version with Minefield (you can
   build a Minefield version using 'bob . XFLAGS=-DMINEFIELD'), and of
   the Unix version with valgrind and/or Address Sanitiser. In
   particular, any headline features for the release should get a
   workout with memory checking enabled!

 - Test the CMake build scripts with the oldest CMake they claim to
   support, on both Unix and Windows.

Making a release candidate build
--------------------------------

 - Make a directory to hold all the release paraphernalia. I usually
   call it ~/src/putty/X.YZ (where X.YZ will stand throughout for the
   version number).

 - Inside that directory, clone the PuTTY git repository to a
   subdirectory ~/src/putty/X.YZ/putty. Here you can make release-
   related commits and tags tentatively, and keep them out of the way
   of any 'git push' you might still be doing in other checkouts.

 - Double-check that we have removed anything tagged with a comment
   containing the words XXX-REMOVE-BEFORE-RELEASE or
   XXX-REVIEW-BEFORE-RELEASE. ('git grep XXX-RE' should only show up
   hits in this file itself.)

 - Now update the version numbers and the transcripts in the docs, by
   checking out the release branch in the release-specific checkout
   and running

      ./release.pl --version=X.YZ --setver

   Then check that the resulting automated git commit has updated the
   version number in the following places:

    * putty/LATEST.VER
    * putty/doc/plink.but
    * putty/doc/pscp.but

   and also check that it has reset the definition of 'Epoch' in
   Buildscr.

 - Make the release tag, pointing at the version-update commit we just
   generated.

 - If the release is on a branch (which I expect it generally will
   be), merge that branch to main.

 - Make a release-candidate build from the release tag, and put the
   build.out and build.log files somewhere safe. Normally I store
   these inside the ~/src/putty/X.YZ directory, alongside the git
   checkout at ~/src/putty/X.YZ/putty, so I'll sit in that checkout
   directory and run a command like

     bob -o ../build-X.YZ-rcN.out -l ../build-X.YZ-rcN.log -c X.YZ . RELEASE=X.YZ

   This should generate a basically valid release directory as
   `build-X.YZ-rcN.out/putty', and provide link maps and sign.sh
   alongside that.

 - Double-check in build-X.YZ-rcN.log that the release was built from
   the right git commit.

 - Make a preliminary gpg signature, but don't run the full release-
   signing procedure. (We use the presence of a full set of GPG
   signatures to distinguish _abandoned_ release candidates from the
   one that ended up being the release.) In the 'build.X.YZ-rcN.out'
   directory, run
     sh sign.sh -r -p putty
   which will generate a clearsigned file called
   sha512sums-preliminary.gpg _outside_ the 'putty' subdirectory.

 - For my own safety, make the release candidate build read-only.
     chmod -R a-w build-X.YZ-rcN.{out,log}

 - Now do some checking of the release binaries, and pass them to the
   rest of the team to do some as well. Do at least these things:
    * make sure they basically work
    * check they report the right version number
    * if there's any easily observable behaviour difference between
      the release branch and main, arrange to observe it
    * test that the Windows installer installs successfully
       + on x86 and Arm, and test that putty.exe runs in both cases
    * test that the Unix source tarball unpacks and builds
       + on at least a reasonably current stable Linux distro, and
         also try Debian sid
       + test-build with all of GTK 1, 2 and 3
       + test-build with -DNOT_X_WINDOWS
    * feed the release-candidate source to Coverity and make sure it
      didn't turn up any last-minute problems
    * make sure we have a clean run of testsc
    * do some testing on a system with a completely clean slate (no
      prior saved session data)

Preparing to make the release
-----------------------------

 - Write a release announcement (basically a summary of the changes
   since the last release). Check the draft version into the putty-aux
   repository, so the whole team can help wordsmith it if they want to.

 - Update the website, in a local checkout:
    * Write a release file in components/releases which identifies the
      new version, a section for the Changes page, and a news
      announcement for the front page.
       + The one thing this can't yet contain is the release date;
         that has to be put in at the last minute, when the release
         goes live. Fill in 'FIXME', for the moment.
    * Disable the pre-release sections of the website (if previously
      enabled), by editing prerel_version() in components/Base.mc to
      return undef.

 - Update the wishlist, in a local checkout:
    * If there are any last-minute wishlist entries (e.g. security
      vulnerabilities fixed in the new release), write entries for
      them.
    * If any other bug fixes have been cherry-picked to the release
      branch (so that the wishlist mechanism can't automatically mark
      them as fixed in the new release), add appropriate Fixed-in
      headers for those.

 - Sign the release in full. In the `build-X.YZ-rcN.out' directory,
   re-verify that the preliminary signed checksums file has a correct
   signature on it and also matches the files you're about to sign for real:

     gpg -d sha512sums-preliminary.gpg | (cd putty; grep -vF ' (installer version)' | grep . | sha512sum -c)

   If the combined output of that pipeline reports both a good
   signature (from the release key) and a successful verification of
   all the sha512sums, then all is well and you can do the full
   signing (not forgetting that the directory will have been readonly
   during the last-minute testing period):

     chmod -R u+w putty
     sh sign.sh -r putty     # and enter the release key passphrase
     chmod -R a-w putty

The actual release procedure
----------------------------

Once all the above preparation is done and the release has been built
locally, this is the procedure for putting it up on the web.

 - Make a final adjustment to your local website changes, filling in
   the release date in components/releases/X.YZ.mi.

 - Upload the release itself and its link maps to everywhere it needs
   to be, by running this in the build-X.YZ-rcN.out directory:
      ../putty/release.pl --version=X.YZ --upload

 - Check that downloads via version-numbered URLs all work:
      ../putty/release.pl --version=X.YZ --precheck
   If this has trouble accessing chiark's ftp server, that is
   unfortunately normal; add --no-ftp and try again.

 - Switch the 'latest' links over to the new release:
    * Update the HTTP redirect at the:www/putty/htaccess .
    * Update the FTP symlink at chiark:ftp/putty-latest .

 - Now verify that downloads via the 'latest' URLs are all redirected
   correctly and work:
      ../putty/release.pl --version=X.YZ --postcheck

 - Push all the git repositories:
    * run 'git push' in the website checkout
    * run 'git push' in the wishlist checkout
    * push from the main PuTTY checkout. Typically this one will be
      pushing both the release tag and an update to the main branch,
      plus removing the pre-release branch, so you'll want some
      commands along these lines:
        git push origin main          # update the main branch
        git push origin --tags        # should push the new release tag
        git push origin :pre-X.YZ     # delete the pre-release branch

 - Run ~/adm/puttyweb.sh on thyestes to update the website after all
   those git pushes.

 - Check that the unpublished website on thyestes looks sensible.

 - Run webupdate, so that all the changes on thyestes propagate to
   chiark. Important to do this _before_ announcing that the release
   is available.

 - After running webupdate, run update-rsync on chiark and verify that
   the rsync mirror package (~/ftp/putty-website-mirror) contains a
   subdirectory for the new version and that the links from its
   latest.html point into that subdirectory.

 - Announce the release!
    + Construct a release announcement email whose message body is the
      announcement written above, and which includes the following
      headers:
       * Reply-To: <putty@projects.tartarus.org>
       * Subject: PuTTY X.YZ is released
    + Mail that release announcement to
      <putty-announce@lists.tartarus.org>.
    + Post it to comp.security.ssh.
    + Mention it in <TDHTT> on mono.

 - Edit the master ~/adm/puttysnap.sh to disable pre-release builds,
   if they were previously enabled.

 - Relax (slightly).
