#          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 "Bug 25013: Add torbutton as a tor-browser submodule" 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.
   # 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
   # Enable networking
   networksetup -setsecurewebproxystate Ethernet on
   # Sign the bundles.
   ../gatekeeper-signing.sh $TORBROWSER_VERSION
   # notarize and staple
   ../notarization.sh $TORBROWSER_VERSION
   ../stapler.sh $TORBROWSER_VERSION
   # Check that it worked.
   unzip -d test tb-$TORBROWSER_VERSION-osx_zh-CN-stapled.zip
   pushd test
   # Both should be "Tor Browser.app: Accepted" with "source=Notarized Developer ID"
   spctl -vvvv --assess --type=exec --context context:primary-signature Tor\ Browser.app/
   spctl -vvvv --assess --type=open --context context:primary-signature Tor\ Browser.app/
   popd
   rm -rf test
   # Disable networking
   networksetup -setsocksfirewallproxystate Ethernet off
   exit
   torsocks rsync -avP mac-signer:$TORBROWSER_VERSION/tb-*-stapled.zip /path/to/builddir/$TORBROWSER_VERSION/

   cp -rT tor-browser-build/projects/tor-browser/Bundle-Data/mac-applications.dmg dmg

#. Regenerate macOS MAR files from code signed dmg files.
   # XXX Go to your directory prepared for recreating the .dmg files and containing
   # the uploaded .zip files.
   ./gatekeeper-bundling.sh $TORBROWSER_VERSION
   rsync -avP ../$TORBROWSER_VERSION-signed/*.dmg $TORBROWSER_BUILDDIR/
   cd tor-browser-build
   mv $TORBROWSER_BUILDDIR/ release/signed/ (or alpha)
   # 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
   # Fetch signatures on unsigned sha256sums from other builds

#. 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

#. 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 hosts: web-fsn-02.torproject.org, web-cymru-01.torproject.org,
#  web-fsn-01.torproject.org, and cdn-backend-sunet-01.torproject.org

#. Remove the oldest *.mar files from cdn.tpo to save space
   rm -rf /srv/cdn-master.torproject.org/htdocs/aus1/torbrowser/$TORBROWSER_VERSION_OLDEST
   static-update-component cdn.torproject.org

#. Sync files to dist.tpo and cdn.tpo mirrored web servers
   # Obtain publish_version.sh from the tor-browser-build repo under tools/update/.
   # $PREV_TORBROWSER_VERSION is one of the previously published versions remaining
   # on staticiforme from where the .htaccess is copied.
   ./publish_version.sh $TORBROWSER_VERSION $PREV_TORBROWSER_VERSION release # or alpha

#. Make sure we really built from the proper Mozilla build tag by consulting
   # the respective ESR release branch (for a good overview for ESR78 see
   # https://hg.mozilla.org/releases/mozilla-esr78/graph/). For the platforms following
   # rapid release (only Android, currently), consult the beta repo
   # (https://hg.mozilla.org/releases/mozilla-beta/graph/) or the release repo
   # (https://hg.mozilla.org/releases/mozilla-release/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.
   vim databags/versions.ini
   git commit databags/versions.ini -m "Add new Tor Browser version"
   torsocks git push origin master:master
   cd ..
   # Check build success/failure:
   # https://jenkins.torproject.org/job/lektor-website-tpo-translation/
   # https://jenkins.torproject.org/job/lektor-website-tpo-translation-install/

#. 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.

#. Check whether the .exe files got properly signed and timestamped
   # Point OSSLSIGNCODE to your osslsigncode binary
   pushd tor-browser-build/${channel}/signed/$TORBROWSER_VERSION
   OSSLSIGNCODE=/path/to/osslsigncode
   ../../../tools/authenticode_check.sh
   popd

#. Check whether the MAR files got properly signed
   # Point NSSDB to your nssdb containing the mar signing certificate
   # Point SIGNMAR to your signmar binary
   # Point LD_LIBRARY_PATH to your mar-tools directory
   pushd tor-browser-build/${channel}/signed/$TORBROWSER_VERSION
   NSSDB=/path/to/nssdb
   SIGNMAR=/path/to/mar-tools/signmar
   LD_LIBRARY_PATH=/path/to/mar-tools/
   ../../../tools/marsigning_check.sh
   popd

#. 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}/
   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"
   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
  Publication on F-Droid via the Guardian Project's repository should be
  automatic. Hans is responsible for maintaining this automation.

# Update rollout percentage
   After 24 hours, check the Release Daskboard:
     - "Release"->"Production" and select the "Release Dashboard" tab
   If the Release Dashboard does not show any concerning trends (significant
   increase in crashes or ANRs (Application Not Responding)), then continue on
   to the next paragraph and increase rollout from 25% to 100%. Otherwise
   consider halting rollout as described in the `RollingBackUpdate` process.

   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.
