Use Launchpad to distribute Debian packages

In this article, we are going to review the steps to create and upload sources to Launchpad where it will be built and distributed from a Personal Package Archive (PPA), which is a repository that allows developers and enthusiasts to deliver their software to all Ubuntu users using the apt-get command.

Foreword

Launchpad is bit complicated, and getting your local development environment setup to upload your packages can be challenging. Depending of your needs and requirements you may want to consider other options to distribute your software in a repository, such as JFrog Bintray, GitHub Releases, or your own server managed by yourself running debuild and reprepo.

Additionally, it is important to note that Launchpad only accept sources packages, not binaries packages, as the software is compiled and built by the Launchpad servers themselves. Another constraints is that Debian users can benefit of the packages as well as long as the sources weren’t compiled on libraries specific to Ubuntu.

However, Launchpad is a really good solution if you want to distribute your open-source software primarily for the Ubuntu platform, targeting multiple processor architectures, Launchpad provides the well-known PPA repository, which is a robust solution for small pet projects to very large software (such as MySQL, MariaDB, MongoDB, Inkscape and many more). It allows collaboration of users and support for bug tracking.

Overview

The steps required to use upload sources to Launchpad, and then use it to build it as Debian package to distribute via PPA are:

  • Create a Launchpad account and project
  • Upload a SSH key
  • Upload GPG key
  • Sign code of conduct
  • Prepare sources
  • Create Debian source package
  • Upload Sourcesto Launchpad to distribute as a PPA

Prepare a Launchpad account

The first step required before progressing is to create an user account on the Launchpad service. This step is really similar to every other online services, however, it is followed by added complexity with the need of a SSH key (to store code), a GPG key (to sign the packages before upload to ensure authenticity), and the requirement to sign the Code Of Conduct (COC) using the GPG key, before being able to progress further.

To proceed, login to Launchpad and create an account by following the steps. You will be redirected to Ubuntu One, another service from Canonical, to manage your user credentials. Once completed, you will have access to your account by pointing to the slug, such as https://launchpad.net/~<username>, and from there you can create projects and upload your Debian sources packages.

As explained in the documentation, go to the Overview page of your user account, click on SSH keys and enter yours that will be used to upload the sources if you plan to use the version control features.

Next, click on the OpenGPG keys button in the Overview page, and import your GPG key that will be used to sign your source and Code Of Conduct. This step can be really off-putting for new comers, so please review fully the information from this page before progressing further. If you want to create a GPG key, execute the following commands and enter the required information such as name, email, passphrase, etc.:

# Execute GPG in expert mode (let you enter empty passphrase, for automation)
$ gpg --expert --gen-key

# If necessary, to generate entropy, open a separate Terminal and execute these commands to generate some random activity
$ find /dev/disk/by-uuid/ -type l | xargs md5sum
$ rngd -r /dev/urandom

To confirm the GPG key was successfully created on your system, execute the following command which should list the same ID as the previous command (e.g. 2048R/99D93242), and take note of the ID as GPG_KEY_ID:

$ ​gpg --list-secret-keys
/home/username/.gnupg/secring.gpg
-------------------------------
sec   2048R/B37CF5E2 2018-04-15
uid                  someone <someone@example.com>
ssb   2048R/3E6C7C93 2018-04-15

You can now export this key to local file before uploading to Launchpad, or for offsite backup if working on an important project:

# Export Public Key
gpg --armor --export <GPG_KEY_ID> > my-public-key.asc

# Export Private Key
gpg --armor --export-secret-keys <GPG_KEY_ID> > my-private-key.asc

If you import the private GPG key on another server or workstation, the following steps will allow you to do so:

# Import gpg key
gpg --import --allow-secret-key-import <exported_gpg_private_key>.asc
# List all local GPG keys
gpg --list-keys
# Test GPG signing to confirm key correctly imported
gpg -s -a --batch --passphrase "<password>" test.txt # test GPG signing

You can now import the local Public GPG key in the OpenGPG keys section of the Overview page, and press Import Key.

You will receive an email that will contain a PGP message that you will need to decrypt to have access to a URL which will activate the GPG key of your account when opened. Copy the email contents in a text file, such as message.gpg, and run the following commands to decrypt it:

gpg --output message.txt --decrypt message.gpg

This will prompt you for a passphrase if any, and will generate a decrypted file named message.txt on your workstation:

$ message.txt

Here are the instructions for confirming the OpenPGP key registration that we
received for use in Launchpad.

Requester details:

    User name    : someone
    Email address: someone@example.com

Key details:

    Key type    : 2048R
    Fingerprint : 3CB52183BE1EBB764C825AFCEA3E6BAEB37CF3C4

UIDs:
    someone@example.com

Please go here to finish adding the key to your Launchpad account:

    https://launchpad.net/token/1c2RmBfr2RDp2tH5VsGE

You can now (finally) sign the Launchpad Code Of Conduct. In the Overview page, click on Signed Ubuntu Code of Conduct, and follow the instructions. You will be required to download the latest version of a document, and sign it using GPG to certify you have it was read by yourself and yourself only, and the signing will be recognised using the public key already imported in your account. The command to sign the document is and generate a .asc ready to upload is:

# Sign the document
$ gpg --clearsign UbuntuCodeofConduct-2.0.txt

# Sign the document using a specified key if have multiple ones in your key ring
gpg -u <GPG_KEY_ID> --clearsign UbuntuCodeofConduct-2.0.txt

Create a project

Once all the prerequisite steps are completed and you account is fully configured, you are ready to continue and create a project identified by a meaningful name.

When opening the project page, you can edit the PPA settings to enable multiple architectures. It will get Launchpad to build the PPA for any of the following architectures automatically: x86 (i386), x86-64 (amd64), Raspberry Pi (armhf) …etc. Log in and select “Change details” in the upper right corner of your PPA page, and at the bottom of the page that follows, you’ll see the options for architectures that can be enabled.

To provide the sources packages for multiple releases (xenial, trusty and others), you will need to upload different specific version for each, differentiated by the release in the debian/changelog file, or by using Launchpad web interface to copy the package(s).

Upload sources

You can only upload source packages to a PPA, for security and licensing (open-source) reasons; Launchpad will then build it into binary packages for you. There’s 3 different ways to upload the sources to Launchpad: using the version control Git or Bazaar, upload a Debian sources package, import using Travis CI after a successful build. We are going to look only at the 2 last options in this article.

Upload sources from Travis CI

The process to upload your sources to Launchpad after a successful build in Travis, including running unit tests, is very well documented. It consists of entering the correct properties in the deploy section of  the project .travis.yml. A good example would look like the following:

deploy:
  provider: launchpad
  slug: "https://launchpad.net/~username/+archive/projectname/ppa"
  oauth_token: $OAUTH_TOKEN
  oauth_token_secret: $OAUTH_TOKEN_SECRET

Upload sources from a Debian package

Packaging

A Debian package is a tar archive consisting of multiple files, typically located in a DEBIAN directory, which control how and where a package is installed. There’s multiple files required and the structure can appear complex. The below commands will lay the files and directories structure of a Debian package to allow copy your sources and create an archive:

# create structure with mandatory and optional files
mkdir <package>-<version>
cd <package>-<version>
dh_make --createorig

After this, edit the files in debian/ folder (control, changelog, etc.) to match your project name, the author name and other information. The changelog file needs to include the same author as GPG key owner that will be used to sign the package.

You should be now be ready to create the Debian source package for your project. The options for debuild tool are:

# create and sign package
debuild / debuild -S (not -us -uc)
  -us Do not sign the source package.
  -uc Do not sign the .changes file.
  -sa Upload sources
  -S  Specifies a source-only build, no binary packages need to be made. Passed to dpkg-genchanges.

Depending if you have a passphrase in you GPG key, or need to run the packaging from a script, the following sets of commands will to create and sign the archive and its .changes file (which is the delta of changes that will be uploaded):

# Enter secret passphrase on a local file
vim /home/username/passphrase.txt

# Build and sign Debian source package without prompting for passphrase
debuild -S -sa -us -uc
debsign -p'gpg --passphrase-file /home/username/passphrase.txt --batch --no-use-agent' -S -k<GPG_KEY_ID> ../<package>-<version>_<arch>.changes

Otherwise, if your GPG key doesn’t have a passphrase, simply remove the -us and -uc option from the command:

# Build and sign Debian source package directly
debuild -S -sa -k<GPG_KEY_ID>

If you encounter build failures, you may need to overrides dh_ targets by editing you debian/rules file. In general manner if you have a problem with a specific target, you just override it by adding override_{target} in your debian/rules, either by adding different instructions or by leaving the target blank to void it.

Uploading

The last step on your side consist to upload the .changes file, which is the difference of changes before and after, by using the dput command:

# Upload to own PPA
dput ppa:<username>/ppa <package>_<version>_<arch>.changes

Packages take a while to process, and you may need to wait to see them appearing in Launchpad (up to 3-4 hours). You will receive an email saying that your package was accepted (or rejected) then the packages will build, which will take some time. You should see the build progress on the right of your PPA page. Once the packages have built (or failed to build), you will be emailed again.

Launchpad Buildd System Failures

You may encounter vnumerous and various failures in the Launchpad system that will require you to investigate the build logs. However, you can reproduce the build system locally to ease debugging by building on a host Ubuntu desktop system, but this system may already have thousands of dependencies and packages installed, while Launchpad builds packages in a clean chroot environment containing just the package’s necessary to build dependencies. To match a Launchpad system and resolve potential dependency issues early, try building the package with pbuilder locally on a clean environment, and which may be able to reproduce the failure and identify the issue.

Using PPA to install software

Once your sources are upload and built correctly on Launchpad, you will be able to provide your software to anyone anywhere around the world.

All they will require to do to use your PPA and yours software is:

# Add and accept PP repository
sudo add-apt-repository ppa:<username>/ppa
# Update list of packages available on all repository, including your PPA
sudo apt-get update
# Install you package
sudo apt-get install <packagename>

Resources