// file : doc/release.cli // license : MIT; see accompanying LICENSE file "\title=Release Process" // NOTES // // - Maximum
 line is 70 characters.
//

"\h1|Table of Contents|"
"\$TOC$"

"
\h0#process|Process|

Review the state and services list (currently on paper) for any new additions.
Consider how/when they are updated/tested during the release process.

@@ We have switched to a single configuration for the entire toolchain
   (plus -libs).

@@ We currently have an issue in that \c{queue} builds \c{public} using
\c{public} \c{buildtabs} (since it's querying \c{public} brep) which means
existing packages are not tested with new build configurations. But maybe
that's correct, conceptually. We also have the inverse problem: stage bots
may no longer have the machines to build public.

\h1#stage|Stage|

The staging repository is completely independent which means it must contain
all the \c{build2} dependencies (plus a few extra packages for testing; see
the \c{etc/stage} script for the complete list). This in turn means that if
any of these dependencies are in the unreleased state, then they should go
through the applicable steps in this section (e.g., updating of \c{NEWS}, etc)
and then be queued and published (effectively released) as part of the
\c{build2} release. Generally, however, we should strive to not unnecessarily
bundle the release of dependencies with the release of \c{build2} to keep the
process as streamlined as possible. In fact, we now have \c{queue.stage} (see
\c{etc/stage-queue}) which is the place for such \"extra packages for
testing (or that require the staged toolchain)\".

\N|When unbundling the release of a dependency we need to remove its
distribution from \c{etc/stage} and add the pre-distributed packages
(for example, from \c{public}) to \c{staging/repository/1/}.|

\b{Pre-Conditions:}

\ul|

\li|Current \c{stage} build is clean.||

\h#stage-public|Build public with stage toolchain|

  Before starting the release process we rebuild all the packages in the
  public repository with the stage toolchain in order to detect any
  regressions.

  \ol|

  \li|Review \c{brep} commit log for any potential issues and upgrade \c{brep}
      on public to latest staged version. See the detailed instructions in
      \c{private}.|

  \li|Compare stage and public \c{buildtabs} and identify public machines that
      are no longer present on stage. We aim to at least have a build machine
      for the primary compiler for each operating system.|

  \li|Temporarily add missing machines to stage build bots.|

  \li|Uncomment controller URL for public repository in \c{devel-config} and
      \c{stage-config} build bot configuratons. Regenerate and reboot.|

  \li|Confirm all the primary configurations are being built.|

  \li|Wait for the builds to complete (note that there may be unbuilt
      entries for secondary configurations) and compare public toolchain
      build results to stage for regressions. See the detailed instructions
      in \c{private}.||

\h#copy|Update copyright if new year|

  Use the \c{git/copyright} script. See the script header for instructions.

  Note that most of (all?) our project have been converted to the automatic
  copyright update notification via a pre-commit hook. So perhaps this step
  can be removed.

\h#install-times|Update install script times.|

  See \c{private/install/build2-times.txt} for instructions.

\h#etc|Update \c{etc/git/modules}|

  Review for any new modules. Remove \c{etc/} and \c{private/} from
  \c{modules} to reduce noise during stat.

\h#review|Review \c{@@}|

  Review \c{etc/review} for new modules. Then review \c{@@} notes:

  \
  etc/review | less -R
  \

  At least look for \c{@@\ TMP}

  \
  etc/review | grep TMP
  \

\h#review-db|Review database schema changes|

  Review database schema changelog differences in \c{bpkg}, \c{bdep}, and
  \c{brep} compared to the previous release (tag) for any schema/data
  migration that may be required (if something is missing, then it would also
  have to be tested).

\h#news|Update \c{NEWS} files|

  Update in all projects (including dependencies) that will have a release
  version.

  See \c{etc/stage} for the complete list.


\h#packaging|Release \c{packaging/} dependencies|

  Release dependencies mentioned in \c{etc/stage} that have the snapshot
  version as described in
  \l{https://github.com/build2-packaging/README#version-and-release-management
  Version and Release Management}.

  Also, consider upgrading the \c{curl/ca-certificates-curl}.

  \N|Maybe this should be done during queuing? Why do we release (but not
     publish) these now and other dependencies later? Maybe so that we can
     stage them one more time?|

  Note: may want to update dependencies bundled as \c{git} submodules after
  that.

\h#dependencies|Finalize all other dependencies|

  Make sure all other unreleased dependencies listed in \c{etc/stage} are
  ready to be released (\c{NEWS}, etc). Effectively, the only remaining step
  should be to change the version.

  Do this in the dependency order and finish each off with:

  \
  git pull
  bdep sync -fura && bdep test -ar
  \

  For some it may make sense to go straight to release; see
  \l{#version-release Change to release version}.


\h#upgrade-dep|Upgrade dependencies|

  Upgrade all dependencies in the \c{build2} toolchain build:

  \
  etc/upgrade
  \

  If released ODB on the previous step:

  \
  # Step 0: make sure b, bpkg, bdep are runnable.

  # Step 1a: update odb submodule in libbutl (see README-DEV)
  # Step 1b: run odb.sh in bpkg, bdep.
  # Step 1c: update b, bpkg, bdep.
  # Step 1d: copy *-odb.?xx for bpkg and bdep to build2-toolchain.

  # Step 2a: update ODB version in etc/version
  # Step 2b: run etc/version (should only change brep)
  # Step 2c: commit the changes to brep
  # Step 2d: run bdep sync -f (should upgrade libodb*)
  # Step 2e: manually update version.hxx in libodb, libodb-pgsql,
  #          and libbrep by running b .../hxx{version}
  # Step 2f: run odb.sh ib brep/libbrep
  # Step 2g: update brep
  \

  Then push \c{build2} repositories.


\h#hello|Update \c{hello/} projects|

  These projects should closely track the output of \c{bdep-new(1)}. The
  recommended procedure is to generate a new project with the same name and
  then review/resolve the differences with \c{diff\ -ru}.

  Every change in these projects must be accompanied by a revision increment
  and a re-tag. This should be managed with \c{bdep-release(1)}:

  \
  # make changes
  git add .
  bdep release --revision --show-push
  # review commit
  git push ...
  \

  Once done, make sure the latest \c{libhello} revision is on stage, run the
  \c{intro} scripts, and review any changes in the output (this information
  will be helpful on the next step):

  \
  cd etc

  script -qc ./intro2-tldr intro2-tldr.out && sed -i -e 's/\r//g' intro2-tldr.out
  diff -u intro2-tldr.orig intro2-tldr.out  # Or use gitk.
  mv intro2-tldr.out intro2-tldr.orig

  # NOTE: comment out !config.import.libbuild2_hello in ~/.build2/b.options

  script -qc ./intro2-tour intro2-tour.out && sed -i -e 's/\r//g' intro2-tour.out
  diff -u intro2-tour.orig intro2-tour.out  # Or use gitk.
  mv intro2-tour.out intro2-tour.orig

  # NOTE: uncomment !config.import.libbuild2_hello in ~/.build2/b.options
  \

\h#doc|Review documentation|

  Review the following documentation for (1) sample output changes and (2)
  still being relevant/making sense. Also (3) check the \c{NEWS} files for
  anything new worth mentioning.

  \N|Ideally this should be done during development but it's easy to forget.
     Also, check if there is any new documentation that has been added that is
     not on the below list.|

  \ul|

    \li|Install guide: 1 & 2 (also review \c{build2-toolchain} commit log).|

    \li|Toolchain introduction: 1, 2 & 3 (use \c{intro} script output for 2).|

    \li|Packaging gude: 2 & 3 (also \c{bdep-new}-generated buildfiles).|

    \li|Introduction in the build system manual: 1 (uses \c{bdep-new(1)}
        output).|

    \li|Testscript manual: 1.||


\h#submod|Update all submodules|

  Make sure all working trees are clean. Review \c{sub_modules} in
  \c{etc/git/modules} for any missing new modules, then:

  \N|\c{etc/} and \c{private/} need to be committed manually.|

  \
  ./modup.sh
  ./commit.sh # If changes.
  ./push.sh

  cd build2-toolchain

  git submodule update --remote --checkout
  git submodule foreach git submodule update --init --recursive

  git status  # There should only be 'new commits'; see README-GIT

  git commit -a -m \"Update submodules\"
  git push
  \

\h#stage-machines|Update \c{stage} \c{buildtab}s and build machines|

  NOTE: may want to keep old machines around for public testing (since we use
  existing public buildtabs, none of the new machines will be used).

  Note: normally, we try to do all of this as part of normal development
  (e.g., when adding new machines, etc).

  Review \c{stage} \c{buildtab} for any configurations to drop (for example,
  an intermediate version of a compiler), classes to adjust (\c{legacy},
  \c{default}, \c{latest}, etc).

  Based on these changes update \c{stage} CI \c{buildtab}, which is a subset
  of the \c{stage} configurations (and is a base for the \c{queue}/\c{public}
  configurations).

  Review deployed machines against the updated \c{stage} \c{buildtab} and
  remove those that are no longer used:

  \
  cd private/buildos/

  grep '.*' .../brep-buildtab | cut -d' ' -f1 | sort -u
  ./ls-machines -c stage -c devel

  ~/work/buildos/remove-machine  
  \

  Also review deployed machines against the latest available versions and
  upgrade those that are not the latest:

  \
  cd private/buildos/

  ./ls-machines -l \"/btrfs/$(whoami)/machines/default/\" | sort
  ./ls-machines -c stage -c devel

  ~/work/build2/buildos/upload-machine  .../new-ver .../old-ver
  \


\h#restage|Restage|

  Confirm \c{stage} and \c{devel} \c{buildos} images, hardware-specific
  configurations are the same.

  Review \c{staging/0/} and \c{staging/repository/1/} for anything stray.

  If no upgrade is possible from the previous version, uncomment errors in
  install scripts (and add a note to restore after the release).

  Enable extra packages for testing in \c{etc/stage} script.

  Restage and upgrade \c{brep} by performing the following steps:

  \ol|

  \li|Disable building of all repositories on \c{stage} by adding the
      \c{buildable:no} field at the end of each line in \c{loadtab}.|

  \li|Restage with \c{baseutils}/\c{mingw} regeneration:

      \
      etc/stage -b
      \

      Consider restaging queue for good measure.

      \
      etc/stage-queue
      \

  |

  \li|While build machines are bootstrapping, upgrade \c{brep} on \c{stage},
      sync latest \c{buildtab}s but do not restart the web server.|

  \li|Once all build machines have bootstrapped, enabling build of all
      repositories and restart the web server. To check bootstrap progress:

     \
     ./ls-machines -b stage -c stage -c devel
     \

  ||

  Verify \c{stage} build is clean, nothing is unbuilt.


\h#test-extra|Perform extra testing|

  CI: (check for any new repositories in \c{github.com/build2/})\n
  \n
  \c{libauto-symexport}\n
  \c{hello-thrift}\n
  \c{assembler-with-cpp}\n

  Test \c{cxx20-modules-examples} (see \c{test} script) and \c{async_simple}.

  Test any third-party/demos (\c{build2-dynamic-module-demo},
  \c{cherimcu}, \c{cherio-rtos}, \c{boost-dependency}).

  Test on ARM Mac (run tests for \c{libbutl/build2/bpkg/bdep}).

  Test build system modules (especially standard pre-installed).

  Test old toolchain version (can fetch and build old packages from
  \c{queue.stage}; add dummy package if all require to be released toolchain).


\h#install-stage|Test install scripts|

  Test \l{https://stage.build2.org/0/ \c{stage} install scripts}, including
  upgrading, as described in \c{private/install/testing.txt}.

  Perform necessary upgrades, if any, and test on ad hoc test machines
  (\c{test-*}).

  Also test \c{bootstrap-mingw.bat} and \c{bootstrap.sh} (preferably on
  something less mainstream like FreeBSD) since not exercised as part of
  install.

\h1#queue|Queue|

\b{Pre-Conditions:}

\ul|

\li|Final \c{stage} build is clean.|

\li|Build with the \c{queue} toolchain is inactive.||


\h#queue-repo|Review \c{queue} repository|

  Pull, review, and clean the \c{queue} \c{git} repository for any stale
  packages or anything (ownership, etc) that may conflict with packages being
  released.

  Also clean toolchain distribution:

  \
  rm -rf cppget.org/queue/0/*
  \

\h#version-release|Change to release version|

  Change to the release version in all the packages being released and tag
  (see \c{etc/stage} for the list). Use \c{bdep-release(1)} unless a custom
  versioning/tagging scripts are used:

  \
  git pull
  bdep release --no-open --show-push [--alpha|--beta]
  # review commit, run update (in case anything comitted is pre-generated)
  git push ...
  \

  Do this in the dependency order and finish each off with:

  \
  bdep sync -fura && bdep update
  \

  For the \c{build2} packages (commit but don't push after each step if
  required):

  \ul|

    \li|Close schema versions in \c{bpkg}, \c{bdep}, and \c{brep}.|

    \li|Change \c{LIBBUILD2_STAGE} in \c{build2/libbuild2/config.hxx.in} to \c{false}.|

    \li|If necessary, update minimum \c{build2} and \c{bpkg} version
        requirements in projects generated by \c{bdep-new}. \b{This must be
        done if created projects use new features.}

        \N|Why shouldn't we always do this for simplicity? Maybe because then
        we cannot run tests using \c{public} services?

        Also if we change this in toolchain packages, the below upgrade steps
        will break since there is no continuity. Perhaps do it in two stages:
        first change version to final, upgrade, then change toolchain
        dependencies to final, upgrade again? But then nobody involed in
        development will be able to pull and upgrade. Maybe KISS and keep
        it pre-release.||

    \li|Change version by updating \c{etc/version} (including with new modules
        and/or new dependencies, but keep pre-release in minimum toolchain
        version requirements) and then executing:

        \
        etc/version
        ./commit.sh                            # \"Release version X.Y.Z\"
        git -C build2-toolchain commit --amend # \"Change version to X.Y.Z\"
        \

        Note that \c{libbuild2-*} modules (e.g., \c{libbuild2-hello}) are
        independently versioned but may still need to update minimum toolchain
        version requirements (see below).|

    \li|Tag by executing \c{tag.sh\ }.|


    \li|Release all standard pre-installed build system modules. Update
        minimum toolchain version requirements.

        \
        bdep release --no-open --show-push
        \

        Also release \c{libbuild2-hello} (it's not standard pre-installed
        but it gets published).

        |

    \li|Regenerate documentation in each package (including standard
        pre-installed build system modules, use \c{BDEP_SYNC=0}).|

    \li|Upgrade all dependencies in configure-only mode by executing
        \c{etc/upgrade\ -c} (don't skip this step even if all the dependencies
        were released during staging).

        Avoid this (see above): If the \c{build2}/\c{bpkg} requirements in the
        manifests have been bumped to the version being released, then first
        bootstrap the build system and update \c{bpkg}/\c{bdep} (might have to
        hack their generated \c{version.hxx} to disable constraint checking;
        also if you forget \c{BDEP_SYNC=0} it will most likely hose the build
        configuration).

        \
        BDEP_SYNC=0 b-boot build2/build2/
        BDEP_SYNC=0 b bpkg/ bdep/
        \

    |

    \li|Trigger regeneration of version files (might require several runs
        to \"close off\"):

        \
        BDEP_SYNC=0 b --match-only ~/work/build2/builds/gcc/
        \

        If using GCC prior to 8 then might also need explicit version target
        upgrades:

        \
        BDEP_SYNC=0 b ~/work/build2/builds/gcc/.../hxx{version}
        \

    |

    \li|Regenerate ODB in relevant packages passing upgraded configuration
        path explicitly (\c{bdep} is not runnable; can skip if ODB was
        released during staging):

       \
       ./odb.sh ~/work/build2/builds/gcc/
       \

    |

    \li|Finish upgrading all dependencies by executing in the upgraded
    configuration:

       \
       BDEP_SYNC=0 b ~/work/build2/builds/gcc/

       b build2/ bpkg/ bdep/

       # Update standard pre-installed build system modules.
       \

    |


    \li|Update other \c{libbuild2-*} modules if required.||

  Verify key tests pass (in particular, the \c{bdep} tests will now be running
  against \c{public} services):

  \
  b test: build2/ bpkg/ bdep/
  b test: bpkg/ config.bpkg.test.remote=true
  b test: libbuild2-hello/libbuild2-hello-tests/

  # Test standard pre-installed build system modules.
  \

  \N|We could have queued after this step before preparing
     \c{build2-toolchain}. However, splitting this seems to only increase
     complexity without any major benefits (it's not hard to update submodules
     and regenerated \c{build2-toolchain} if there are any issues with
     packages). Plus we can start testing install scripts, etc.|

  Next push the above changes and update all submodules in
  \c{build2-toolchain}:

  \
  ./push.sh

  # Push (with tags) standard pre-installed build system modules.

  cd build2-toolchain

  git submodule update --remote --checkout

  git status  # There should only be 'new commits'; see README-GIT

  git commit -a -m \"Update submodules\"
  \

  As well as (commit after each step if required):

  \ul|

    \li|Regenerate documentation in each package inside as well as in
        \c{build2-toolchain} itself. Note: for \c{libbuild-kconfig}
        it gets updated automatically during dist.|

    \li|Update ODB by copying relevant files from the previous step (trust me,
        this is the easy way for now). Make sure all \c{*-odb.*} are copied!|

    \li|Change \c{build2_repo} in \c{build2-toolchain} \c{buildfile} to
    \c{queue}.||

  Finally, push the changes:

  \
  git push
  \

\h#queuing|Queue|

   Prepare packages and the toolchain distribution (disable extra packages
   first if any were enabled in the \c{etc/stage} script):

   \
   etc/stage -q -b
   \

   Sort non-alpha packages from \c{cppget.org/queue/1/alpha/} into appropriate
   sections (we could probably automate this similar to \c{bdep-release(1)}).
   Also check if any of them are already in \c{public}. Note that some
   build system modules may already in \c{public}. If standard pre-installed,
   then need to copy archives from \c{public} (so that checksums match).

   Note also that we assume all the packages already have the corresponding
   ownership information either in \c{queue} or \c{public}. However, if any
   new packages were added, then that will have to be added as well.

   Commit and push queue repository:

   \
   cd cppget.org/queue/
   git add .
   git ci -m \"Queue build2 toolchain X.Y.Z\"
   git push
   \

   If queued package manifests contain new values, then the
   \c{bpkg-rep-publish} script will fail to create repository due to unknown
   manifest values. To resolve this we temporarily add (to \c{crontab})
   \c{--ignore-unknown} and make a note to restore.

   Also change \c{--min-bpkg-version} from previous to current release
   (not the one being released).

\h#build-public|Verify queued packages build with \c{public}|

   This makes sure that the new version can be built with the old toolchain.

   While all the packages should build (except perhaps \c{libhello} which,
   being based on the latest \c{bdep-new(1)} output, may use new features),
   some tests may fail. In particular, we will be running \c{bpkg} tests using
   a previous version of the build system and \c{bdep} tests also using a
   previous version of \c{bpkg}. None of that is or will be supported. So
   for now we manually review all the failed builds for anything suspicious
   and in the future we may skip tests if the tool versions mismatch.


\h#install-queue|Test install scripts|

  Test \l{https://download.build2.org/queue/ \c{queue} install scripts}. Here
  we just smoke-test each script on its \"primary\" platform and make sure
  \c{queue} URLs/repositories are used.


\h#upgrade-brep-bpub|Upgrade \c{brep} and \c{bpub} on \c{cppget.org}|

  Upgrade \c{brep} and \c{bpub} using the queued toolchain according
  to \c{private/brep-bpub-upgrade.txt}.

  After upgrade, drop all package builds for \c{public} and \c{queue} and
  verify there are no regressions. This makes sure that the \c{brep} services
  in the new version are usable with the old toolchain. If there are issues,
  they have to be fixed by publishing/queuing revisions. Note that if
  \c{public} was tested with staged toolchain (and thus \c{brep} was already
  upgraded), perhaps this can be skipped (since it will take days to
  completely rebuild \c{public}).

  \N|The \c{bdep} tests that exercise CI and publishing services do it in the
  simulation mode. To properly test that these services are compatible with
  the old version of the toolchain we would need to CI/publish a real test
  package manually.|


\h#start-queue|Start \c{queue} builds|

  Update \c{queue} \c{buildtab} based on the \c{stage} CI \c{buildtab}
  (normally just a copy sans the sanitized toolchain configurations).

  \N|Note that the \c{queue} \c{buildtab} is shared between \c{public} and
     \c{queue} builds. As a result, after this update, \c{public} build hosts
     may not have some of the new (or renamed) build machines.

     This also means that if the \c{buildtab} contains anything new (options,
     etc) that are incompatible with \c{public}, then they should only be
     enabled later, when upgrading \c{public} \c{buildtab} (make a note if
     that's the case).|

  Adjust \c{stage} and \c{devel} build host configurations (both \c{*-config}
  and hardware classes) to enable the \c{queue} toolchain. Shift most
  instances from \c{stage} to \c{queue} in the hardware class-specific
  configurations. Regenerate affected configurations and reboot build hosts:

  \
  cd private/buildos/

  ./regen
  ./po-hosts -r -c stage -c devel
  \

  Verify both \c{queue} and \c{public} builds with the queued toolchain,
  fixing any breakages with revisions, moving to legacy, and/or queuing
  replacements. We can only proceed further once we have a \"resolution\"
  for every (newly) broken package.

  \N|If public has been built with the staged toolchain, rebuilding of the
     public repository (which takes days) can be omitted.|

\h#stop-queue|Stop \c{queue} builds|

  Adjust \c{stage} and \c{devel} build host configurations to disable the
  \c{queue} toolchain (comment out). Regenerate affected configurations and
  reboot build hosts as on the previous step (or poweroff until stage
  reopening).

\h1#public|Public|

\b{Pre-Conditions:}

\ul|

\li|A \"resolution\" is queued or published for every (newly) broken package.||

\h#public-machines|Update \c{public} \c{buildtab}s and build machines|

  Stop \c{public} build hosts:

  \
  ./po-hosts -s public -c public
  \

  Update \c{public} \c{buildtab}s based on the \c{queue} \c{buildtab}
  (normally just a copy).

  Adjust \c{public} build host configurations (hardware classes, etc) and
  add/remove new/old build hosts.

  Use new sync scripts to update \c{public} build hosts with new VMs.

  Power off \c{public} build hosts:

  \
  ./po-hosts -c public
  \

  Replace the \c{public} \c{buildos} image on \c{build-cache} with the
  one for \c{stage} (note: this will cause build hosts to reboot, thus
  power off above).

  The only remaining step is to boot \c{public} build hosts (not yet).

\h#pub-dist|Publish distribution|

  Change \c{build2_repo} in \c{build2-toolchain} \c{buildfile} to \c{public},
  commit, and publish the distribution (this also cleans/disables the
  \c{queue} toolchain):

  \
  etc/stage -p
  \

\h#pub-pkg|Publish packages|

  @@ Need to add --min-bpkg-version 0.13.0

  Move packages (manually for now) from the \c{queue} to \c{public} \c{git}
  repository, including ownership information. Move old/replaced/FTB
  packages either to legacy or delete.

  Commit everything (see the commit log for procedure @@ this needs
  automation) and push (which should trigger auto-publish). Note: commit and
  push both \c{queue} and \c{public} \c{git} repositories.

  Note that once published, the existing install instructions/download
  links are no longer usable, so do not linger (in fact, may make sense
  to update Download and Install pages before publishing packages and
  only sync them immediately after).

\h#start-public|Start \c{public} builds|

  Reboot \c{public} build hosts. They should next bootstrap and proceed
  with building all packages.

  Once all the machines have bootstrapped, submit a test CI task.

\h#install-public|Test install scripts|

  Test \l{https://download.build2.org/ \c{public} install scripts}. Here
  we just smoke-test each script on its \"primary\" platform and make sure
  \c{public} URLs/repositories are used.

  Also test building an old package with the previous version of the
  toolchain.

\h#web|Update web|

  \ul|

  \li|Write release notes, use placeholder for announcement URL (or guess).
      Add link from the \c{doc.cli}. Add blog entry.|

  \li|Add any new FAQ entries or any other updates (main page, etc). Any new
      documentation to link from the Doc page?|

  \li|Update the Download page.

      \
      cat `ls -1 cppget.org/public/0/X.Y.Z/*.sha256`
      \

  |

  \li|Update the Install page.

      \
      cat cppget.org/public/0/toolchain.sha256
      \

  |

  \li|Regenerate documentation in \c{private/} for all hosts:

      \
      cd private/

      cd /www/
      ./cli.sh
      \

  |

  \li|Test locally, publish, and test remote:

      \
      cd private/
      ./publish --dry-run
      ./publish
      \

  ||


\h#ann|Announce|

  \ul|

  \li|Write and send the announcement to the mailing lists.

      \
      cat `ls -1 cppget.org/public/0/X.Y.Z/*.sha256`
      \

      Add \c{reply-to:} header for \c{users@} announcement.|

  \li|Patch (or verify) the announcement URL in release notes, re-publish.|

  \li|Announce on reddit, slack, and other relevant places.|

  \li|Add links to reddit discussions to release notes.||

\h#tag|Commit, tag, and push the rest.|

   Tag \c{build2-toolchain}:

   \
   cd build2-toolchain
   git tag -a vX.Y.Z -m \"Tag version X.Y.Z\"
   git push --follow-tags
   \

   Add \c{etc/} and \c{private/} back to \c{modules} in \c{etc/git/modules}
   (essentially reverse \l{#etc Update \c{etc/git/modules}}).

   Finalize changes, commit, tag, and push \c{style/}, \c{etc/}, and
   \c{private/}.

   Snapshot \c{buildos} subvolumes (including on \c{aarch64}):

   \
   btrfs subvolume snapshot buildos-3 buildos-3-X.Y.Z
   btrfs subvolume snapshot buildos-6 buildos-6-X.Y.Z
   \

\h1#reopen|Reopen|

\h#version-snapshot|Change to snapshot version|

  Change to the snapshot version in all the released packages. Use
  \c{bdep-release(1)} unless a custom versioning script is used:

  \
  bdep release --open --show-push [--open-*]
  # review commit
  git push ...
  \

  Essentially, the same steps as in \l{#version-release Change to
  release version} (but no tagging).

  Revert changes to install scripts if upgrade was disabled.

\h#stage-machines-reopen|Update \c{stage} \c{buildtab}s and build machines|

  Essentially, the same steps as in \l{#public-machines Update \c{public}
  \c{buildtab}s and build machines} but for stage. Some differences:

  Clean \c{buildtab}s (both \c{stage} and CI) by removing no longer relevant
  configurations, moving some to \c{legacy}, etc. NOTE: we now keep the
  same set of machines as public until next release so that we can build
  public with stage for testing.

  More generally, this is the time to do sweeping changes such as renaming
  machines/configurations, adjusting classes, etc. This is also the time to
  rebalance machines across available hosts.

\h#restage-reopen|Restage|

  Make symlinks for the new version in \c{private/baseutils} (for both
  \c{baseutils} and \c{mingw}; the idea is that we will start with those and
  maybe upgrade later).

  Review \c{etc/stage} for any packages to enabled/disable.

  Then cleanup and restage:

  \
  rm -r staging/0/*
  rm -r staging/repository/1/*/

  etc/stage -b
  \

\h#start-stage|Start \c{stage} builds|

  Reboot \c{stage} build hosts. They should next bootstrap and proceed with
  building all the staged packages. Make sure all the builds of the new
  development snapshot are successful and there is nothing unbuilt.

  Upgrade \c{brep} on \c{stage}.

  Review \c{etc/stage-queue} and restage queue.stage:

  \
  rm -r staging/repository/1/*/

  etc/stage-queue
  \

\h#commit-reopen|Commit and push \c{etc/} and \c{private/}.|

  Commit and push changes to \c{etc/} and \c{private/}.


\h1#upgrade|Upgrade|

\h#upgrade-baseutils|Upgrade \c{baseutils}|

  Check for abnormalities in new package sizes. Restage:

  \
  rm -r staging/0/*

  etc/stage -b
  \

  Remember to update the GCC version in the stage \c{buildtab}s for the
  configuration that uses \c{mingw} package.

\h#upgrade-db-migration|Cleanup database migrations|

  Drop old database migration code. Keep migration entries for two previous
  versions for \c{bpkg} and \c{bdep} and for one previous version for
   \c{brep}.

\h#upgrade-buildos|Upgrade \c{buildos}|

  See \c{bootstrap.txt} for the procedure. Start with the \c{devel}
  configuration and upgrade \c{stage} after testing.

\h#upgrade-build-machines|Upgrade build machines|

  Check every major compiler and OS if a new version is available.

\h#upgrade-packages|Upgrade third-party packages|

  Consider upgrading to new upstream versions in \c{packaging/}.

  Also, bundled \c{libodb}, \c{libsqlite3}, and \c{libpkg-config} in
  \c{libbutl}.

\h#upgrade-projects|Upgrade own projects|

  Adjust own projects to use any newly available features.

\h#upgrade-bdep-new|Upgrade \c{bdep-new}|

  Adjust \c{bdep-new}-generated projects to use any newly available features.


\h1#re-review|Re-review \c{@@}|

  Review \c{@@} notes (in case some should be fixed after the release):

  \
  etc/review | less -R
  \

  At least look for \c{@@\ TMP}

  \
  etc/review | grep TMP
  \

\h1#plan|Plan|

Plan the next release and update the project roadmap.
"