|

Uploading cmatrix to a PPA (PPA Upload Tutorial)

← Previous Linux PPA Packaging (3/4) Next →

Example Values Used in This Tutorial

This tutorial uses the following fake example values throughout. Replace them with your own real details when following along.

FieldExample Value
Full NameRex Bytes
Email[email protected]
Launchpad Usernamerexbytes
GPG Key IDAABB1122CCDD3344
GPG Fingerprint1A2B3C4D5E6F7890AABB1122CCDD3344EEFF5566
PPAppa:rexbytes/example-ppa
Packagecmatrix 2.0
PPA Version2.0-1~ppa1~rexbytes
Target Distributionnoble
Working Directory~/packaging/cmatrix-ppa

Prerequisites: You should complete 02-local-packaging.md and be familiar with 01-key-management.md before continuing.


In tutorial 02, you built and installed a .deb package locally. This tutorial takes the next step: signing, uploading, and publishing that package to a Launchpad PPA so anyone can install it with apt.

You’ll learn how to:

  • Set up your GPG key and Launchpad PPA
  • Use dch to create a PPA-versioned changelog
  • Build a signed source package for Launchpad
  • Upload it to your PPA with dput
  • Install and test the package from your PPA

This tutorial assumes you already have:

  • A working ~/packaging/cmatrix-ppa/cmatrix-2.0 source tree with debian/ packaging
  • A successful local build from dpkg-buildpackage -us -uc
  • The upstream tarball cmatrix_2.0.orig.tar.gz in ~/packaging/cmatrix-ppa/

If not, go back and complete 02-local-packaging.md first.


0. Install additional tools for PPA uploads

Tutorial 02 installed the core packaging tools. Confirm you also have gnupg (for GPG signing):

sudo apt install gnupg


Note: gnupg is usually pre-installed on Ubuntu. If you followed tutorial 02 exactly, it’s already installed.


1. Set your packaging identity for dch

Tell dch (and other Debian tools) who you are. This controls the name/email in debian/changelog:

export DEBFULLNAME="Rex Bytes"
export DEBEMAIL="[email protected]"


Code language: JavaScript (javascript)

To make this permanent, add it to your shell config:

echo 'export DEBFULLNAME="Rex Bytes"' >> ~/.bashrc
echo 'export DEBEMAIL="[email protected]"' >> ~/.bashrc
source ~/.bashrc


Code language: PHP (php)

dch will now generate changelog trailer lines like:

 -- Rex Bytes <[email protected]>  Fri, 05 Dec 2025 12:34:56 +0000


Code language: HTML, XML (xml)

2. One-time PPA prep: GPG key + Launchpad PPA

See 01-key-management.md for full details on key management, backup, and rotation.

You only need to do this once per account.

2.1 Generate a GPG key

Create a new GPG key for signing packages:

gpg --full-generate-key


Choose:

  • Kind: RSA and RSA (default is fine)
  • Key size: 4096 (recommended)
  • Expiry: e.g. 1–2 years, or “does not expire”
  • Name and email: must match your Launchpad account

Confirm the secret key was created and note the fingerprint:

gpg --list-secret-keys --keyid-format LONG


Code language: PHP (php)

Why --list-secret-keys? For package signing, what matters is that the secret (private) key exists on your machine. --list-keys only shows public keys, which isn’t enough to confirm you can sign. This is especially important after restoring keys from a backup — you might have the public key but not the private one.

2.2 Upload your GPG key to the Ubuntu keyserver

Launchpad doesn’t accept key uploads directly — it fetches your public key from a keyserver. You must publish your key there first:

gpg --keyserver keyserver.ubuntu.com --send-keys AABB1122CCDD3344


Code language: CSS (css)

Verify the upload worked:

gpg --keyserver keyserver.ubuntu.com --recv-keys AABB1122CCDD3344


Code language: CSS (css)

Note: Keyserver propagation can take a few minutes. If Launchpad can’t find your key immediately, wait and try again.

2.3 Add your GPG key to Launchpad and create a PPA

  1. Go to https://launchpad.net/, log in (or create an account).
  2. Navigate to your profile → OpenPGP keys → paste your full key fingerprint (e.g. 1A2B 3C4D 5E6F 7890 AABB 1122 CCDD 3344 EEFF 5566).
  3. Launchpad will send an encrypted email to the address in your key’s uid. Decrypt it, click the confirmation link inside, and your key is registered.
  4. Create a PPA: go to your profile → Create a new PPA → name it (e.g. example-ppa), giving you ppa:rexbytes/example-ppa.

Important: The email address in your GPG key uid must match a verified email on your Launchpad account, and the fingerprint must match what Launchpad fetched from the keyserver. If either doesn’t match, uploads will be rejected.


3. Update debian/changelog for a PPA build (using dch)

In tutorial 02 you wrote debian/changelog by hand. For PPA builds, we’ll use dch to regenerate it with a PPA-style version.

From inside the source tree:

cd ~/packaging/cmatrix-ppa/cmatrix-2.0


Code language: JavaScript (javascript)

Create a new changelog (this overwrites the hand-written one from tutorial 02):

dch --create -v 2.0-1~ppa1~rexbytes --package cmatrix -D noble


Code language: CSS (css)

Important: Without -D noble, dch defaults the distribution to UNRELEASED. Launchpad rejects uploads with UNRELEASED — you must set it to an active Ubuntu series like noble.

dch will open an editor. Write a description:

cmatrix (2.0-1~ppa1~rexbytes) noble; urgency=medium

  * Initial PPA build with custom Debian packaging.

 -- Rex Bytes <[email protected]>  Wed, 26 Nov 2025 12:00:00 +0000


Code language: HTML, XML (xml)
  • 2.0-1~ppa1~rexbytes is the package version (see tutorial 02, section 13 for the full version breakdown).
  • noble is the target distribution.
  • The last line is automatically filled by dch, using your DEBFULLNAME/DEBEMAIL.

Save and exit.

For later uploads (e.g. 2.0-1~ppa2~rexbytes), you can bump the version with:

dch -v 2.0-1~ppa2~rexbytes -D noble "Second PPA build: tweak packaging."


Code language: JavaScript (javascript)

4. Build a signed source package for your PPA

For PPAs, you upload a signed source package, not a .deb. Launchpad builds the binary packages for you.

Make sure your packaging identity matches your GPG key and Launchpad account:

export DEBFULLNAME="Rex Bytes"
export DEBEMAIL="[email protected]"


Code language: JavaScript (javascript)

Your GPG key should use the same name and email. Verify with:

gpg --list-secret-keys --keyid-format LONG


Code language: PHP (php)

Example output:

sec   rsa4096/AABB1122CCDD3344 2024-01-15 [SC]
      1A2B3C4D5E6F7890AABB1122CCDD3344EEFF5566
uid           [ultimate] Rex Bytes <[email protected]>
ssb   rsa4096/9988776655443322 2024-01-15 [E]


Code language: HTML, XML (xml)
  • Long key ID: AABB1122CCDD3344
  • Fingerprint (recommended for -k): 1A2B3C4D5E6F7890AABB1122CCDD3344EEFF5566

Replace the fingerprint in the commands below with your own.

First, unapply any quilt patches (if still applied from tutorial 02). With 3.0 (quilt) format, dpkg-source will re-apply patches during the build:

quilt pop -a


Note: If you get No patch removed that’s fine — it means patches are already unapplied.

4.1 First upload of this upstream version

Include the full orig tarball and sign the source package:

debuild -S -sa -k<YOUR-FINGERPRINT>


Code language: HTML, XML (xml)

For example:

debuild -S -sa -k1A2B3C4D5E6F7890AABB1122CCDD3344EEFF5566


Explanation:

  • -S → build source only (no binary .deb).
  • -sa → include the upstream orig.tar.gz in this upload.
  • -k… → tell debuild which GPG key to sign with (by fingerprint or long key ID).

On a correctly configured system, this:

  1. Builds the source package
  2. Runs lintian (a Debian package checker)
  3. Signs the .dsc, .buildinfo, and _source.changes files with your key

Note: debuild runs lintian automatically. You may see warnings about missing man pages or other minor policy issues — these don’t block the build and are normal for tutorial packages. To see detailed explanations, run lintian --info <package>_source.changes.

If you accidentally ran debuild without -k… and got unsigned files, you can sign them afterwards with:

cd ~/packaging/cmatrix-ppa
debsign -k<YOUR-FINGERPRINT> cmatrix_2.0-1~ppa1~rexbytes_source.changes


Code language: HTML, XML (xml)

After a successful debuild, go up one directory:

cd ..
ls


You should see files like:

cmatrix_2.0-1~ppa1~rexbytes.dsc
cmatrix_2.0.orig.tar.gz
cmatrix_2.0-1~ppa1~rexbytes.debian.tar.xz
cmatrix_2.0-1~ppa1~rexbytes_source.buildinfo
cmatrix_2.0-1~ppa1~rexbytes_source.changes


Code language: CSS (css)

4.2 Subsequent uploads of the same upstream version

If you later tweak the packaging (e.g. 2.0-1~ppa2~rexbytes) but the upstream version (2.0) is unchanged, you don’t need to re-upload the orig.tar.gz. Use:

debuild -S -sd -k<YOUR-FINGERPRINT>


Code language: HTML, XML (xml)
  • -sd → do not re-upload the orig tarball (saves time and bandwidth).

Troubleshooting signing and build failures

SymptomLikely causeFix
gpg: skipped "...": No secret keyThe fingerprint in -k doesn’t match any secret key on your systemRun gpg --list-secret-keys --keyid-format LONG and use the correct fingerprint
gpg: signing failed: No pinentryGPG can’t prompt for your passphrase (common in SSH sessions)Install pinentry-tty and set pinentry-program in ~/.gnupg/gpg-agent.conf, then gpgconf --kill gpg-agent
debsign: gpg error occurred! Aborting.GPG passphrase wrong or agent timed outRe-run debuild or debsign and enter the correct passphrase
orig.tar.gz not foundMissing or misnamed upstream tarballEnsure cmatrix_2.0.orig.tar.gz is in the parent directory (~/packaging/cmatrix-ppa/)
distribution UNRELEASED is not allowedChangelog still says UNRELEASEDRe-run dch -D noble or edit debian/changelog to set the distribution to noble

5. Upload to your PPA with dput

Now use dput to send the signed source package to your PPA.

From ~/packaging/cmatrix-ppa:

dput ppa:rexbytes/example-ppa cmatrix_2.0-1~ppa1~rexbytes_source.changes


Adjust ppa:rexbytes/example-ppa to match the PPA you created on Launchpad.

Troubleshooting: Network unreachable errors

Very rarely you might get a “Network is unreachable” or “Cannot assign requested address” error:

[Errno 101] Network is unreachable
[Errno 99] Cannot assign requested address


Code language: CSS (css)

This can happen due to IPv6, NAT, router, or firewall quirks.

If this happens, the most reliable workaround is to use SFTP instead of the default FTP method. SFTP requires an SSH key registered on your Launchpad account (see 01-key-management.md).

Create a custom dput config in ~/.dput.cf:

[my-ppa]
fqdn = ppa.launchpad.net
method = sftp
incoming = ~rexbytes/ubuntu/example-ppa/
login = rexbytes


Note: The incoming path follows the pattern ~<launchpad-user>/ubuntu/<ppa-name>/. Replace rexbytes with your Launchpad username and example-ppa with your PPA name.

Then upload using the [my-ppa] config section name instead of ppa:...:

dput my-ppa cmatrix_2.0-1~ppa1~rexbytes_source.changes


Code language: CSS (css)

Note: The system-wide /etc/dput.cf contains a [ppa] section that uses FTP with anonymous login — the ppa:user/ppa-name shorthand uses this system config. Your ~/.dput.cf overrides let you use SFTP as an alternative.

dput will:

  1. Check the signatures on _source.changes and .dsc
  2. Upload the referenced files (.dsc, .orig.tar.gz, .debian.tar.xz, .buildinfo, etc.) to Launchpad

On Launchpad:

  • Open your PPA page.
  • You should see cmatrix 2.0-1~ppa1~rexbytes in the build queue.
  • When the build completes for your target series (e.g. noble amd64) and the status changes to Published, the binary packages become available in your PPA.

6. Install from your PPA and test

Once Launchpad has built and published your package, you can install it like any other PPA package.

On an Ubuntu (or Mint Noble-based) system:

sudo add-apt-repository ppa:rexbytes/example-ppa
sudo apt update


Before installing, check which versions APT sees. Because the PPA version uses ~ (tilde) in its version string, it will sort lower than the archive version — this is expected and intentional, not a sign that something went wrong:

apt-cache policy cmatrix


Expected output (example):

cmatrix:
  Installed: (none)
  Candidate: 2.0-6
  Version table:
     2.0-6 500
        500 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages
     2.0-1~ppa1~rexbytes 500
        500 https://ppa.launchpadcontent.net/rexbytes/example-ppa/ubuntu noble/main amd64 Packages


Code language: JavaScript (javascript)

Note on version sorting: Because of the ~ in 2.0-1~ppa1~rexbytes, this version sorts lower than the archive’s 2.0-6. This is by design — if Ubuntu publishes an official update, apt upgrade will replace your PPA version automatically. It also means sudo apt install cmatrix will install the archive version, not your PPA version. To install the PPA version explicitly:

sudo apt install cmatrix=2.0-1~ppa1~rexbytes


Verify it installed:

apt-cache policy cmatrix


cmatrix:
  Installed: 2.0-1~ppa1~rexbytes
  Candidate: 2.0-6
  Version table:
 *** 2.0-1~ppa1~rexbytes 100
        100 /var/lib/dpkg/status
     2.0-6 500
        500 http://archive.ubuntu.com/ubuntu noble/universe amd64 Packages
     2.0-1~ppa1~rexbytes 500
        500 https://ppa.launchpadcontent.net/rexbytes/example-ppa/ubuntu noble/main amd64 Packages


Code language: JavaScript (javascript)

Now test the version output:

cmatrix -V


Expected output (similar to):

CMatrix version 2.0 (compiled 16:47:43, Dec 07 2025)
Email: abishekvashok@gmail.com
Web: https://github.com/abishekvashok/cmatrix
 Packaged By: Rex Bytes - As part of a packaging tutorial.


Code language: CSS (css)

That confirms you’re running the cmatrix build from your PPA, with your quilt patch applied and your PPA-style version string.


7. Understanding the version: 2.0-1~ppa1~rexbytes

This was covered in detail in tutorial 02, section 13. Here’s a quick recap:

[epoch:]upstream-version[-debian-revision]


Code language: CSS (css)
PartMeaning
2.0The upstream project version (cmatrix 2.0).
-1The first Debian packaging revision for this upstream version.
~ppa1First PPA build. The ~ makes this sort older than 2.0-1, so an official 2.0-1 package will automatically replace it.
~rexbytesLabels which PPA this build is from.

2.0-1~ppa1~rexbytes = cmatrix 2.0, first Debian packaging revision, first PPA build, from “rexbytes”, always considered older than an official 2.0-1 package.

Similar Posts

Leave a Reply