#          Magical Tor Browser Release Process Incantations
#
#  "May this part of our job one day be replaced by a small shell script"
#

#. Tag any relevant component versions.
#  In particular: before tagging the tor-browser tag, the final code from
#  Torbutton needs to get included and in order to avoid unnecessary commit
#  inflation the commit for bumping the git submodule should be a fixup commit
#  to the one with "Pick up latest Torbutton code" in its commit message.

#. Update changelog and relevant config files in tor-browser-build.
   cd tor-browser-build
   vim projects/firefox/config
   vim ChangeLog.txt
   vim rbm.conf

#. Tag a build tag in tor-browser-build.
   make signtag-release # or `make signtag-alpha` for an alpha build

#. Push tag and version to tor-browser-build.git. In case of doing a stable
#  release with a maintenance branch use that one instead of `master`.
   torsocks git push origin master:master
   torsocks git push origin --tags

#. Build and generate incremental MAR files.
   make && make incrementals-release # `make alpha && make incrementals-alpha`

#. Compare the SHA256 sums of the bundles and MAR files with an independent
#  builder.
   sha256sum tor-browser-build/release/unsigned/$TORBROWSER_BUILDDIR/sha256sums-unsigned-build.txt
   sha256sum tor-browser-build/release/unsigned/$TORBROWSER_BUILDDIR/sha256sums-unsigned-build.incrementals.txt

#. If the sums match (download and) upload the bundles to your build dir on
#  people.torproject.org. Fix permissions.
   chmod 755 $TORBROWSER_BUILDDIR
   chmod 644 $TORBROWSER_BUILDDIR/*
   chmod 644 $TORBROWSER_BUILDDIR/.htaccess
   torsocks ssh people.torproject.org "mkdir ~/public_html/builds/${TORBROWSER_BUILDDIR}"
   torsocks rsync -avP $TORBROWSER_BUILDDIR/ people.torproject.org:public_html/builds/$TORBROWSER_BUILDDIR

#. (Optional): Upload your binaries to people using partial rsync over old version
   torsocks ssh people.torproject.org "mv ~/public_html/builds/${TORBROWSER_VERSION}-build1 ~/public_html/builds/$TORBROWSER_BUILDDIR"
   torsocks rsync -avP $TORBROWSER_BUILDDIR/ people.torproject.org:public_html/builds/$TORBROWSER_BUILDDIR

#. Distribute build to tor-qa@lists.torproject.org
   # XXX: Currently manual email with link to candidate build, important changes,
   # and changelog.
   # For stable releases put tails-dev@boum.org into Cc.

#. Codesign the macOS dmg files.
   # XXX: Update with Notarization bits once they are included in our signing
   # setup
   torsocks ssh mac-signer "mkdir $TORBROWSER_VERSION"
   torsocks rsync -avP $TORBROWSER_BUILDDIR/*.dmg mac-signer:$TORBROWSER_VERSION/
   torsocks ssh mac-signer
   # Unlock the keychain and then...
   cd $TORBROWSER_VERSION
   # Sign the bundles.
   ../gatekeeper-signing.sh $TORBROWSER_VERSION
   # Check that it worked.
   tar xf torbrowser-$TORBROWSER_VERSION-osx_zh-CN-signed.tar.bz2
   spctl -a -t exec -vv TorBrowser.app/
   rm -rf TorBrowser.app
   exit
   torsocks rsync -avP mac-signer:$TORBROWSER_VERSION/*.bz2 .

#. Regenerate macOS MAR files from code signed dmg files.
   # XXX Go to your directory prepared for recreating the .dmg files and containing
   # the uploaded .bz2 files.
   ./gatekeeper-bundling.sh $TORBROWSER_VERSION
   rsync -avP *.dmg $TORBROWSER_BUILDDIR/
   cd tor-browser-build
   # The code signed dmg files should be in the $TORBROWSER_VERSION directory
   # Install a recent p7zip version (see ../tools/dmg2mar for instructions)
   make dmg2mar-release # or `make dmg2mar-alpha`

#. Sign the MAR files
   # First, copy the tor-browser-bundle tree to the signing machine. XXX: This
   # still uses part of the old Gitian related infrastructure.
   torsocks rsync -avP $TORBROWSER_BUILDDIR/../../../ signing-machine
   torsocks ssh signing-machine "mkdir tor-browser-bundle/gitian/$TORBROWSER_VERSION"
   torsocks rsync -avP $TORBROWSER_BUILDDIR/*.mar signing-machine:tor-browser-bundle/gitian/$TORBROWSER_VERSION/
   torsocks ssh signing-machine
   cd tor-browser-bundle/gitian
   # XXX Modify the signmars.sh script to comment out the eval call.
   export TORBROWSER_VERSION=$TORBROWSER_VERSION
   export NSS_DB_DIR=/path/to/nssdb
   # Only needed if you are not owner of the marsigner cert
   export NSS_CERTNAME=your_certname
   make signmars
   exit
   torsocks rsync -avP signing-machine:tor-browser-bundle/gitian/$TORBROWSER_VERSION/*.mar $TORBROWSER_BUILDDIR/

#. Sign individual bundle files.
   # Authenticode signing first
   torsocks ssh windows-signing-machine "mkdir tor-browser-bundle/gitian/$TORBROWSER_VERSION"
   torsocks rsync -avP $TORBROWSER_BUILDDIR/*.exe windows-signing-machine:tor-browser-bundle/gitian/$TORBROWSER_VERSION/
   torsocks ssh windows-signing-machine
   cd tor-browser-bundle/gitian/$TORBROWSER_VERSION
   /path/to/authenticode-signing.sh
   exit
   torsocks rsync -avP window-signing-machine:tor-browser-bundle/gitian/$TORBROWSER_VERSION/*.exe $TORBROWSER_BUILDDIR/
   # Authenticode timestamping next
   cd $TORBROWSER_BUILDDIR
   export OSSLSIGNCODE=/path/to/osslsigncode
   /path/to/authenticode-timestamping.sh
   # Hashes of the signed bundles
   ../tools/hash_signed_bundles.sh
   # All the GPG signatures at last
   torsocks rsync -avP $TORBROWSER_BUILDDIR/* signing-machine:tor-browser-bundle/gitian/$TORBROWSER_VERSION/
   cd tor-browser-bundle/gitian/$TORBROWSER_VERSION
   /path/to/tbb-signing.sh
   exit
   torsocks rsync -avP signing-machine:tor-browser-bundle/gitian/$TORBROWSER_VERSION/ $TORBROWSER_BUILDDIR

#. Sync to people.torproject.org
   torsocks rsync -avP $TORBROWSER_BUILDDIR/ people.torproject.org:public_html/builds/$TORBROWSER_BUILDDIR
   torsocks ssh people.torproject.org "mv public_html/$TORBROWSER_BUILDDIR public_html/$TORBROWSER_VERSION"

#. Transfer builds to staticiforme
   # IMPORTANT: Remove the oldest version in a series in case there is more
   # than 1 available on dist.torproject.org before proceeding
   # XXX: TORBROWSER_VERSION_OLDEST needs to be set
   rm -rf /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION_OLDEST
   static-update-component dist.torproject.org
   # We must use $TORBROWSER_VERSION here because signed result dirs should omit the build number suffix
   wget -nH --cut-dirs=2 -r -l 1 https://people.torproject.org/~gk/builds/$TORBROWSER_VERSION
   rm $TORBROWSER_VERSION/index.html*
   mv $TORBROWSER_VERSION /srv/dist-master.torproject.org/htdocs/torbrowser/
   chmod 775 /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION
   chmod 664 /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION/*
   # XXX: Need to manually get .htaccess :(
   chmod 664 /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION/.htaccess
   chown -R :torwww /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION
   # Verify everything was downloaded/copied correctly
   cd /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION
   for i in *.asc; do echo $i ; gpg -q $i || break; done
   static-update-component dist.torproject.org

#. Check diskspace available on cdn.tpo
#  We currently have enough disk space to host two alpha and stable
#  releases. However with the size of each Tor Browser release increasing,
#  it may become necessary to increase disk space. The server hosting
#  the files for cdn.tpo is savii.tpo and its disk usage can be monitored
#  by going to https://grafana.torproject.org/d/Z7T7Cfemz/node-exporter-full
#  and selecting the host savii.torproject.org.

#. Upload the *.mar files to cdn.tpo
#. Local to staticiforme:
   mkdir /srv/cdn-master.torproject.org/htdocs/aus1/torbrowser/$TORBROWSER_VERSION
   chmod 775 /srv/cdn-master.torproject.org/htdocs/aus1/torbrowser/$TORBROWSER_VERSION
   cd /srv/cdn-master.torproject.org/htdocs/aus1/torbrowser/$TORBROWSER_VERSION
   for marfile in /srv/dist-master.torproject.org/htdocs/torbrowser/$TORBROWSER_VERSION/*.mar; do ln $marfile; done
   static-update-component cdn.torproject.org

#. Make sure we really built from the proper Mozilla build tag by consulting
   # the respective ESR release branch (for a good overview for ESR60 see
   # https://hg.mozilla.org/releases/mozilla-esr60/graph/).

#. Update website's torbrowser versions file in the website git
   cd tpo
   torsocks git pull origin
   # Update `win32` in the `torbrowser-stable` section as well if we
   # include a new stable tor version (called the Windows Expert Bundle
   # on the website). See: #14152.
   # In the RecommendedTBBVersions file, only add the new version. Don't
   # remove the old one yet. That comes later.
   vim databags/versions.ini content/projects/torbrowser/RecommendedTBBVersions/contents.lr
   git commit databags/versions.ini content/projects/torbrowser/RecommendedTBBVersions/contents.lr -m "Add new Tor Browser version"
   torsocks git push origin master:master
   cd ..

#. Add new locales to the download page
   # If this release is introducing new locales, add them to the
   # databags/download-alternatives.ini file (for a stable release) or
   # the databags/download-alternatives-alpha.ini file (for an alpha
   # release).
   cd tpo
   torsocks git pull origin
   vim databags/download-alternatives.ini # or databags/download-alternatives-alpha.ini
   git commit databags/download-alternatives.ini -m "Add new Tor Browser locales"
   torsocks git push origin master:master
   cd ..

#. Create blog post from changelog
   # See https://blog.torproject.org/blog/tor-browser-352-released for now
   # Don't forget to link to Mozilla's security advisories if this is a security
   # update, or Nadim will yell at you.

#. Check whether the MAR files got properly signed
   # Point SIGNMAR to your signmar binary
   # Point LD_LIBRARY_PATH to your mar-tools directory
   cd tor-browser-build/$TORBROWSER_VERSION
   ../tools/marsigning_check.sh
   cd ..

#. Update and upload new update responses for the updater
   # IMPORTANT: Copy the signed MAR files back before creating the update
   # responses!
   export TORBROWSER_UPDATE_CHANNEL=release # or alpha / nightly
   make update_responses-$TORBROWSER_UPDATE_CHANNEL
   cd $TORBROWSER_UPDATE_CHANNEL/update-responses
   tar -xf update-responses-$TORBROWSER_UPDATE_CHANNEL-$TORBROWSER_VERSION.tar
   chmod 664 ${TORBROWSER_UPDATE_CHANNEL}/*
   chmod 664 ${TORBROWSER_UPDATE_CHANNEL}/.htaccess
   chmod 775 ${TORBROWSER_UPDATE_CHANNEL}/
   # Rename the update responses directory to .old to make it easier to
   # revert in case of problem (see the file RollingBackUpdate for more
   # details about this)
   torsocks ssh staticiforme.torproject.org "rm -rf /srv/aus1-master.torproject.org/htdocs/torbrowser/update_3/${TORBROWSER_UPDATE_CHANNEL}.old"
   torsocks ssh staticiforme.torproject.org "mv -v /srv/aus1-master.torproject.org/htdocs/torbrowser/update_3/${TORBROWSER_UPDATE_CHANNEL} /srv/aus1-master.torproject.org/htdocs/torbrowser/update_3/${TORBROWSER_UPDATE_CHANNEL}.old"
   torsocks rsync -avP $TORBROWSER_UPDATE_CHANNEL staticiforme.torproject.org:/srv/aus1-master.torproject.org/htdocs/torbrowser/update_3/
   torsocks ssh staticiforme.torproject.org "chown -R :torwww /srv/aus1-master.torproject.org/htdocs/torbrowser/update_3/${TORBROWSER_UPDATE_CHANNEL}/*"
   torsocks ssh staticiforme.torproject.org "static-update-component aus1.torproject.org"

#  Upload APKs to Google Play
   Log into https://play.google.com/apps/publish
   Select correct app (Tor Browser or Tor Browser Alpha)
   Under left-side navigation bar, select "Production" under "Release"->"Launch"
   Select "Create new release" button at upper right-side
   Under "App bundles and APKs" section, "Upload" each signed APK
   After uploading APKs:
     - The "Release Name" should be automatically filled with the Firefox version
     - Next to "Release notes" click "Copy from a previous release"
     - Select the previous release and adjust the blog post url for this release
     - Save, review, and configure rollout percentage at the bottom
       - Use 25% rollout when publishing a scheduled update (without a security driver)
       - Use 100% rollout when publishing an unscheduled update or security-driven release
   Roll out.

   Note, you may receive three warning messages about:
     1) app is larger than it is necessary (android app bundle),
     2) missing deobfuscation file for better crash analysis
     3) missing debug symbol file

   These warnings are expected and should be accepted.

   See below for updating the rollout percentage.

# Release on F-Droid
  Send an email Hans asking him to upload the new version on F-Droid

# Update rollout percentage
   After 24 hours, increase rollout from 25% to 100% if the Release Dashboard
   ("Release"->"Launch"->"Production" and select the "Release Dashboard" tab)
   does not show any concerning trends (significant increase in crashes or ANRs
   (Application Not Responding)).

   Select the "Releases" tab on the "Production" page. The current released
   version should indicate 25% rollout: "Available to 25% of users on Google Play"
   On the right-side of the "View release details" button of the release there
   should be a button labeled "Manage rollout" with a down-arrow. Clicking on
   that button should show two options:
     - Update rollout
     - Halt rollout

   Select "Update rollout" and increase to 100% and click "Update". The change
   should be immediately implemented and the "Manage rollout" button disappears.

#. Write an email to tor-announce in case this release is concerned with getting
#  a stable version out. Using the contents of the blog entry should do it.

#. Update website's torbrowser versions file to remove old versions
#  NOTE: You probably want to wait some hours (12-24?) after pushing the
#  update responses before doing this, so that people have a chance to see
#  the Firefox notification first before their browser starts weirdly blinking
#  at them.
   cd tpo
   torsocks git pull origin
   # Now it's time to remove the obsolete version(s)
   vim content/projects/torbrowser/RecommendedTBBVersions/contents.lr
   git commit content/projects/torbrowser/RecommendedTBBVersions/contents.lr -m "Deprecate old Tor Browser version"
   torsocks git push origin master:master
   cd ..
