This section describes what has to be done to create a pcb Launchpad Personal Package Archives (PPA).

## Introduction

As you may have noticed already, Launchpad and Ubuntu are tightly connected, so this howto assumes you run Ubuntu or an Ubuntu derivate.
It may work similar on Debian, but no guarantees.

This howto also assumes you build for Ubuntu release 'vivid'.
In case you build for another release, simply replace each occurence of 'vivid' with that other release name.

## Web references, prerequisites

What a PPA, a Personal Package Archive, is can be read here: https://help.launchpad.net/Packaging/PPA

Packaging for a PPA happens the same way as packaging for Debian or Ubuntu itself.
Ubuntu wiki pages about packaging start here: http://packaging.ubuntu.com/html/

About the few differences between PPAs and regular packages (e.g. version number): https://help.launchpad.net/Packaging

Required packages, next to the environment to build pcb itself:

      sudo apt-get install packaging-dev ubuntu-dev-tools

Other than that you also have to have signed the Ubuntu Code of Conduct and uploaded the public part of your SSH key.

## Getting started

If you want to upload the packages later, you need your personal GPG key.
On how to create such a key, see https://help.ubuntu.com/community/GnuPrivacyGuardHowto

To use this key it has to be added to your personal Launchpad account.
Visit https://launchpad.net/people/+me/+editpgpkeys and follow the instructions:

     'gpg --fingerprint'

lists your keys with fingerprints.

After the fingerprint is imported, Launchpad will send you an encrypted email and being able to decrypt it (your emailer should do this) means this part works fine.
Click the activation link in the email and be done.
Without the key you can still build the package, e.g. to find out whether packaging works or to install it locally.
The build process will abort a moment before completion, but after creating the packages.

We want to build straight from the pcb git repo.
However, Debian packaging builds much on the assumption that developers ("upstream") and packagers are two different entities.
Some packaging tools assume source code tarballs in specific places, which we don't have, unless we create them just for building the package.

Luckily, the existence of Git has come to the attention of Debianers these days, so they start to use repository clones for packaging ... which is very similar to packaging from the original repo.
See https://wiki.debian.org/PackagingWithGit

Note: the debian/ directory is no longer part of the pcb git repository.

Central tool is 'git-buildpackage'.
It creates a temporary "upstream" tarball straight from a git stored object (usually a branch), not from the currently checked out files of this repository.
This temporary tarball is then passed to the usual packaging tools, which in turn unpack it again.

To deal with the upstream-less situation 'git-buildpackage' needs a few parameters.
This is how it's run:

      git-buildpackage --git-ignore-new --git-force-create \
                       --git-upstream-branch=master --git-upstream-tree=BRANCH \
                       --git-export-dir=packagebuild

Explanation:

--git-ignore-new
  Ignores that there are uncommitted files when fetching the temporary build tarball from git.
  Without this flag, such files cause an abort.
--git-force-create
  Overwrites an eventually already existing result tarball.
--git-upstream-branch=master
  .
--git-upstream-tree=BRANCH
  Tells which branch to fetch the temporary build tarball from and that 'master' is a branch.
--git-export-dir=packagebuild
  Unpacks the temporary build tarball in 'packagebuild'.
  Without this flag, this happens in the main directory and then dpkg-buildpackage complains about files existing, but not being part of the build tarball.

## Doing a (weekly) PPA upload

First you have to update the ChangeLog.
Debian packaging insists on this and also uses the signature of the top ChangeLog entry to look for the signature GPG key.

      # For simplicity, take the first available signature.
      MY_SIGNATURE=$(gpg --list-secret-keys | \
                     awk '/^uid/ { $1 = ""; sub(/^[ ]+/, ""); print; }' | \
                     head -1)
      echo "My signature is ${MY_SIGNATURE}."
      TODAY=$(date +%Y%m%d)
      TIMESTAMP=$(date -R)
      REL=vivid
      mv debian/changelog temp
      echo "pcb (${TODAY}-weekly) ${REL};" \
           "urgency=low"                                    > debian/changelog
      echo                                                 >> debian/changelog
      echo "  * Weekly build."                             >> debian/changelog
      echo                                                 >> debian/changelog
      echo "  For changes see" \
           "http://git.geda-project.org/pcb/log/"          >> debian/changelog
      echo                                                 >> debian/changelog
      echo " -- ${MY_SIGNATURE}  ${TIMESTAMP}"             >> debian/changelog
      echo                                                 >> debian/changelog
      cat temp >>debian/changelog
      rm temp
      sed -i "s/^Uploaders:.*/Uploaders: ${MY_SIGNATURE}/" debian/control
      unset MY_SIGNATURE TODAY TIMESTAMP REL
      # git-buildpackage picks up comitted stuff, only, so commit the above.
      git commit debian/changelog debian/control -m "weekly build"

Then build as explained above:

      # We want to build from our current branch, which is not always 'master'.
      THIS=$(git symbolic-ref --short HEAD)
      rm -rf packagebuild
      git-buildpackage --git-ignore-new --git-force-create \
                       --git-upstream-branch=${THIS} --git-upstream-tree=BRANCH \
                       --git-export-dir=packagebuild
      unset THIS

Launchpad PPAs accept only sources, Launchpad builds the binaries.
Trying to upload binaries results in a rejection of the whole package, so let's see the above as a preparation and build test and rebuild for source-only packages.
It takes only a few seconds.

      THIS=$(git symbolic-ref --short HEAD)
      rm -rf packagebuild
      git-buildpackage --git-ignore-new --git-force-create \
                       --git-upstream-branch=${THIS} --git-upstream-tree=BRANCH \
                       --git-export-dir=packagebuild --git-builder='debuild -S'
      unset THIS

Last build step is to upload the package to the pcb PPA:

      dput ppa:pcb/weekly_packagebuild/pcb_*-weekly_source.changes

To round up, remove this committed changelog entry and the build:

      git reset --hard HEAD^
      rm -rf packagebuild

## Building with pbuilder

If you want to modify the packaging system, e.g. for testing dependencies, it's a good idea to build in a chroot'ed environment.
There are many tools out there to make this easy ... and almost as many which I (Traumflug) found to not work as described.
If you think that's me, well, have a look at https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779255.
The tool which was found to actually work is 'pbuilder'.
It's very similar to the tool used by these build farm machines (sbuild).

We have build dependencies in 'universe', so let's pbuilder know this:

      echo "COMPONENTS=\"main restricted universe multiverse\"" > ${HOME}/.pbuilderrc

Then build a base chroot image:

      # To build for 32-bit on a 64-bit machine, add --architecture i386
      # To build for a different distribution, add --distribution vivid
      sudo pbuilder create --debootstrapopts --variant=buildd

It's recommended to update this chroot image once daily:

      sudo pbuilder update

The above has to be done only once.
To actually build the package, prepare the source package as shown in the previous section, but don't upload to Launchpad and also don't remove packagebuild/.
Then it's as simple as this:

      (cd packagebuild && sudo pbuilder build *.dsc)

Built packages end up in /var/cache/pbuilder/result/.

Cleaning up:

      sudo rm -r /var/cache/pbuilder  # remove chroot image and apt cache

... and don't forget to remove the stuff made in the previous section.

## TODO:

The pcb version isn't set, after packaging the application itself still reports "pcb-1.99z" or similar.
The --git-prebuild=COMMAND parameter for git-buildpackage might come in handy here for setting this on the fly.
The following citation comes from its man page:

> execute COMMAND from the build directory before calling debuild or the application specified via --git-builder. Exported environment variables are: GBP_GIT_DIR (the repository the package is being built from), GBP_BUILD_DIR (the build dir).

Put all this into a script, perhaps a Makefile target.

Review each dependency.
Like removing it from the build machine, then trying to build and run the binary.
Likely this dependency list is a decade old, so it well might contain obsolete entries.

There are tools to create a package changelog from git history.
Might be better than putting a link to the public git repository: https://marquiz.github.io/git-buildpackage-rpm/man.gbp.dch.html