[[!meta title="Releasing tails-installer"]]

[[!toc levels=3]]

The big picture
===============

Upstream
--------

For this package, "upstream" means, from a Debian packaging
point-of-view, the state of our upstream branches. Let's not pretend we
have not forked liveusb-creator, and admit we are now upstream for our
own version. Thus, from version 4.x on, our fork has been renamed to
tails-installer.

The `master` branch must always be the one that targets current Tails.
That's what we have always done, and right
now `master` is indeed targeting Jessie.

But that's not enough, since we also need to put releases out with code
that works on current Debian testing/sid. Thus, we maintain several upstream
release branches in parallel, each with their own major version number:

 * for releases that target Wheezy:
   * version = `3.*`
   * tag = `tails-installer_3.*`
 * for work and releases that target Jessie (and, as long as compatible,
   that target testing/sid as well):
   * branch = feature/jessie (that's what we've been doing so far)
   * version = `4.*`
   * tag = `tails-installer_4.*`

Once we can't support both Jessie and testing/sid with the same
codebase anymore, we'll fork a new upstream release branch that targets Stretch,
it'll be called feature/stretch, use version `5.*`, etc.

Packaging
---------

We're using [DEP-14 conventions](http://dep.debian.net/deps/dep14/),
except for our `master` branch which is used for upstream development
targeted at current Tails, as said above. More specifically:

* The `pristine-tar` branch contains the binary delta between DFSG-freed
  tarballs and the corresponding tag. It's automatically maintained by
  `gbp import-orig`.
* The `debian/sid` branch is used to build the package that we upload to
  Debian unstable. The tags on this branch are called `debian/$package_version`,
  which is the default when creating them with
  `gbp buildpackage --git-sign-tags --git-tag-only`;
  in practice this is something like `debian/4.0+dfsg-1`.
* The `debian/$codename-backports` branch is used to prepare packages
  that we upload to the official backports repository for Debian `$codename`.
  E.g. here we want to have `debian/jessie-backports` soon after the initially
  uploaded package reaches Debian testing. The tags on this branch are also called
  `debian/$package_version`. In practice this is something like
  `debian/4.0+dfsg-1~bpo8+1`.
* The `tails/$codename` branch is used to prepare packages that we upload
  to the Tails APT repo, but not to Debian -- e.g. `4.*` as currently used on
  Tails/Jessie will never be uploaded to Debian.
* Additionally, we use `tails/$feature` branches for other Tails-specific packaging branches.
* The `upstream/3.x+dfsg`, `upstream/4.x+dfsg`, etc. branches are what we tell `gbp`
  to use as its "upstream" branch. Make sure to check them out when setting up the repository
  for the first time.
* For Ubuntu, we want to support the current Ubuntu version (currently `yakkety`), the
  upcoming version (currently `zesty`), and the current LTS (currently
  `xenial`).
  We do not maintain any Git branches related to Ubuntu releases, as simply the changelog
  entries are modified.

Topic branches
--------------

In practice, it's expected that Tails contributors submit bugfix and
feature branches forked off master, because they want them part of next
Tails release. Hence, it will happen that code lands into master first,
and in turn into a new `4.*` upstream release, before it lands into
`feature/stretch` and in turn into a new `5.*` upstream release.

For how to package topic branches (`bugfix/*` and `feature/*`), see
[[the dedicated page|topic_branch]].

Workflow
========

Release a new upstream version
------------------------------

<a id="upstream-prepare"></a>

### Prepare the environment

The new upstream version should be something like `4.14`, based on the
upstream branch you are building the Debian package for. Adjust and
export:

    export NEW_UPSTREAM_VERSION=4.replace_me
    export UPSTREAM_DEV_BRANCH=master
    export PKG_NAME=tails-installer

<a id="upstream-tag"></a>

### Tag the new version

    git checkout "$UPSTREAM_DEV_BRANCH" && \
    ./setup.py build && \
       (cd po && \
           for po in *.po ; do msgmerge --update "$po" \
           "$PKG_NAME.pot" ; done \
       ) && \
       git commit po -m 'Update POT and PO files.' && \
    git tag \
       -s "${PKG_NAME}_${NEW_UPSTREAM_VERSION}" \
       -m "Releasing Tails Installer $NEW_UPSTREAM_VERSION" && \
    git push --tags origin "$UPSTREAM_DEV_BRANCH"

<a id="upstream-tarball"></a>

### Generate a new upstream tarball

    mkdir -p ../tarballs && \
    git archive \
       --prefix="${PKG_NAME}-${NEW_UPSTREAM_VERSION}/" \
       --output="../tarballs/${PKG_NAME}_${NEW_UPSTREAM_VERSION}.tar.gz" \
       "$UPSTREAM_DEV_BRANCH"

<a id="tails-package"></a>

Update the Debian package for Tails
-----------------------------------

Checkout the packaging branch:

	export PKG_NAME=tails-installer
	export PACKAGING_BRANCH=tails/jessie
	git checkout "$PACKAGING_BRANCH"

Verify that `debian/gbp.conf` references the correct upstream and Debian (packaging) branches,
and that `pristine-tar` usage is enabled, e.g.:

	[DEFAULT]
	upstream-branch = upstream/4.x+dfsg
	debian-branch = tails/jessie
	pristine-tar = True

Extract the upstream and packaging branch from gbp.conf:

	export UPSTREAM_BRANCH=`gbp config buildpackage.upstream-branch | sed -r -e 's,.*=,,'`

Create a DFSG-compatible tarball from the previously created Git
archive and reimport it into the source tree. This merges, into the
`debian-branch` specified in `gbp.conf`, not only the commit that
imported the current DFSG-free upstream tarball into the
`upstream-branch`, but also the corresponding upstream Git history:

	mk-origtargz \
	   -C ../tarballs \
	   --version "$NEW_UPSTREAM_VERSION+dfsg" \
	   --copy \
	   ../tarballs/${PKG_NAME}_${NEW_UPSTREAM_VERSION}.tar.gz && \
	gbp import-orig \
	   --upstream-vcs-tag="${PKG_NAME}_$NEW_UPSTREAM_VERSION" \
	   ../tarballs/${PKG_NAME}_${NEW_UPSTREAM_VERSION}+dfsg.orig.tar.gz

Update `debian/changelog`:

    gbp dch && dch -e

In there, set the appropriate:

* version number, such as `4.3+dfsg-0tails1`; in particular, note that
  the Debian revision starts with `-0` for any package meant for the
  Tails APT repository, while the first package that will be uploaded
  to Debian will have `-1`;
* target release name.

Commit the changelog:

    git commit debian/changelog -m "$(head -n 1 debian/changelog | sed -e 's,).*,),')

Git-Dch: Ignore
"

Make sure that the working environment is clean:

    git clean -fdx

Build a new Tails package (use a i386 chroot that matches the target distribution):

    gbp buildpackage

Add a signed tag to the Git repository and push the changes:

    gbp buildpackage --git-tag-only --git-sign-tags && \
    git push --tags origin "$UPSTREAM_BRANCH" \
                    "$PACKAGING_BRANCH" \
                    pristine-tar

Add the Debian package to Tails
-------------------------------

Sign the package:

    debsign $CHANGES_FILE

Upload:

    dupload --to tails $CHANGES_FILE

Update the Debian package
-------------------------

This assumes that the latest upstream release has been imported into
a Tails packaging branch (e.g. `tails/jessie`) already.

And then, a maintainer of `tails-installer` in Debian updates the
package in sid accordingly, for example:

* check out the `debian/sid` branch
* merge the `tails/jessie` branch
* bump version to `4.3+dfsg-1`
* build, test and upload to sid
* have gbp create a `debian/4.3+dfsg-1` tag
* push the Debian packaging branch (`debian/sid`) and the new tag

Example for a backport to Jessie:

* check out the `debian/jessie-backports` branch
* merge the `debian/sid` branch
* `dch --bpo` to bump version to `4.3+dfsg-1~bpo8+1`
* build, test and upload to jessie-backports
* have gbp create a `debian/4.3+dfsg-1_bpo8+1` tag
* push the Debian packaging branch (`debian/jessie-backports`) and the new tag

Upload a package to our Ubuntu PPA
----------------------------------

Team members are allowed to upload a package to our Ubuntu PPA:
<https://launchpad.net/~tails-team/+archive/ubuntu/tails-installer>

You'll need to configure the dput tool to upload to the PPA and put into
`$HOME/.dput.cf` (adjust to use your Launchpad ID):

    [ppa-tails-installer]
    fqdn = ppa.launchpad.net
    method = ftp
    incoming = ~tails-team/ubuntu/tails-installer/
    login = your_launchpad_id
    allow_unsigned_uploads = 0

* checkout the `debian/sid` branch
  to build a package for the next Ubuntu release or checkout the
  `debian/jessie-backports` branch to build a package for the
  current Ubuntu version or current LTS.
* bump version to `4.3+dfsg-0ubuntu1~$codename` using `dch -i`
  where `$codename` is the name of the target Ubuntu distribution.
* if it does not exist, rebuild the .orig.tar.gz of the latest version
  from pristine-tar (use the latest git log entry to find the version):
  `pristine-tar checkout ../tails-installer_4.4.6+dfsg.orig.tar.gz`
* build a source only package using `debuild -i -uc -us -sa -S`
  Once the package has been built, a `.changes` file will be created in
  pbuilder's configured destination directory.
* test the package (piuparts, Lintian, etc.)
* sign the corresponding source.changes file
  `debsign ../tails-installer_$NEW_UPSTREAM_RELEASE-xxx_source.changes`
  Replace "xxx" with the correct version information.
  The signature should be made with a key which is registered
  at Launchpad as being part of the Tails team.
* Upload to the PPA:
  `dput ppa-tails-installer ../tails-installer_$NEW_UPSTREAM_RELEASE+xxx_source.changes`

You will receive an email informing you if the upload was really successful
or if it contained any errors. On success, you should now revert your changes on the
Debian branch using `git reset HEAD --hard`.

Quality assurance for Debian and Ubuntu packages
------------------------------------------------

    Scenario: Installing Tails to a pristine USB drive
      Given I have started Debian
      And I have a Tails ISO image
      When I install the tails-installer package
      And I plug USB drive "install"
      And I ask Tails Installer to install my Tails ISO image to USB drive "install"
      Then my Tails ISO image is installed on USB drive "install"

    Scenario: Upgrading an old Tails USB installation from an ISO image
      Given I have started Debian
      And I have a Tails ISO image
      When I install the tails-installer package
      And I plug USB drive "upgrade" that has an old Tails installed
      And I ask Tails installer to upgrade USB drive "upgrade" with my Tails ISO image
      Then my Tails ISO image is installed on USB drive "upgrade"
