Earlier this year, I attended MiniDebcamp Kochi 2026 at Bolgatty, Kochi. During this 4-day event, I had the opportunity to interact and learn from long-time debian contributors. I ended up attempting to package an emacs-lisp package. This blog post is a description of the stuff that I did or came across during this packaging.
Objective
The immediate goal in packaging a piece of software for use in debian is the generation of source and binary distributions.
But, how do they look like?
- Source package: Consists of
- Upstream source tarball:
.orig.tar.gz - Debian directory tarball:
.debian.tar.gz - Metadata:
.dscfile
- Upstream source tarball:
- Binary distribution:
.debfile
Binary distribution is the one we are more likely to be familiar
with: the .deb file. This is what is being used when we
install packages via apt. The .deb file
targeting specific architectures are built from a source distribution,
which is a tar ball.
How do we produce these files? Let's find out.
(Outputs shown are sometimes truncated or edited for clarity.)
ITP
Once you decide on a piece of software that you want to package, you
should first make an 'Intent to Package' (ITP) mail to bugs.debian.org. This is to let others know that
you are gonna start working on this package and thereby help others
avoid duplicating that effort. ITP also helps to figure out if someone
has already started working on that project.
It is good to make the ITP a bit detailed without being wordy. Bullet points would be nice, I guess. Points like the following could be addressed:
- What does the package do
- What are its dependencies
- Are there similar packages available?
- Are any of them already in debian?
- How does this package compare to other similar packages?
- Who will maintain the package? Is there a team doing similar work?
- Does the package need a sponsor?
Fun fact: I actually went on quite a bit with a package before thinking of filing an ITP, only to realize that the package was already available in debian stable. So, better raise an ITP first, so that the risk of your work being wasted is lesser.
I chose to package speed-type, a emacs package that lets us practice touch typing within emacs.
We should receive an acknowledgement mail with the bug number for the ITP some time after submitting the ITP. If you haven't received a bug number even after a few hours, it would be good to ask in IRC or something.
reportbug
In addition to sending mail directly, we can file an ITP using the
reportbug tool as well.
$ reportbug --email famubu@domain.tld wnpp
Warning: no reportbug configuration found. Proceeding in novice mode.
Detected character set: UTF-8
Please change your locale if this is incorrect.
Using 'Julin Shaji <famubu@domain.tld>' as your from address.
Will send report to Debian (per lsb_release).
What sort of request is this? (If none of these things mean anything to you, or you are trying to report a bug in an existing package, please press Enter to exit reportbug.)
1 ITP This is an `Intent To Package'. Please submit a package description along with copyright and URL in such a report.
2 O The package has been `Orphaned'. It needs a new maintainer as soon as possible.
3 RFA This is a `Request for Adoption'. Due to lack of time, resources, interest or something similar, the current maintainer is asking for someone else to maintain this package. They will
maintain it in the meantime, but perhaps not in the best possible way. In short: the package needs a new maintainer.
4 RFH This is a `Request For Help'. The current maintainer wants to continue to maintain this package, but they need some help to do this because their time is limited or the package is
quite big and needs several maintainers.
5 RFP This is a `Request For Package'. You have found an interesting piece of software and would like someone else to maintain it for Debian. Please submit a package description along with
copyright and URL in such a report.
Choose the request type: 1
Please enter the proposed package name: speed-type
Checking package information...
Please briefly describe this package; this should be an appropriate short description for the eventual package: Practice touch and speed typing within emacs
Your report will be carbon-copied to debian-devel, per Debian policy.
Querying Debian BTS for reports on wnpp...
7609 bug reports found:
Bugs with severity normal: 1406 remain
1) #140577 RFA: knews -- Graphical threaded news reader
2) #332498 RFH: openssl -- Secure Socket Layer (SSL) binary and related cryptographic tools
3) #354174 RFA: nas -- Network Audio System - local server
4) #374643 O: htdig -- web search and indexing system
5) #375733 O: htdig -- web search and indexing system
....
....
....
2723) #808427 RFP: kaldi -- Kaldi speech recognition toolkit
2724) #808428 RFP: mage-numediart -- toolkit for speech and singing synthesis
2725) #808434 RFP: libkgeomap -- Libkgeomap is a wrapper around different world-map components, to browse and arrange photos over a map.
2726) #808895 RFP: lofreq -- sensitive variant calling from sequencing data
(2704-2726/7592) Is the bug you found listed above [y|N|b|m|r|q|s|f|e|?]? ?
y - Problem already reported; optionally add extra information.
N - (default) Problem not listed above; possibly check more (skip to Next page).
b - Open the complete bugs list in a web browser.
m - Get more information about a bug (you can also enter a number without selecting "m" first).
r - Redisplay the last bugs shown.
q - I'm bored; quit please.
s - Skip remaining problems; file a new report immediately.
f - Filter bug list using a pattern.
e - Open the report using an e-mail client.
? - Display this help.
(2704-2726/7592) Is the bug you found listed above [y|N|b|m|r|q|s|f|e|?]? s
Spawning sensible-editor...
Report will be sent to Debian Bug Tracking System <submit@bugs.debian.org>
Submit this report on wnpp (e to edit) [Y|n|a|c|e|i|l|m|p|q|d|t|?]? Y
Sending message via /usr/sbin/sendmail...
Bug report submitted to: Debian Bug Tracking System <submit@bugs.debian.org>
Copies sent to:
Debian Bug Tracking System <submit@bugs.debian.org>
Julin Shaji <famubu@domain.tld>
If you want to provide additional information, please wait to receive the bug tracking number via email; you may then send any extra information to n@bugs.debian.org (e.g.
nnnnnn@bugs.debian.org), where n is the bug number. Normally you will receive an acknowledgement via email including the bug report number within an hour; if you haven't received a
confirmation, then the bug reporting process failed at some point (reportbug or MTA failure, BTS maintenance, etc.).
Thank you for using reportbug
Caveat: I couldn't make reportbug work as expected. The
report seemed to have gone off successfully, as the tool showed no
error. But the ITP never reached bugs.debian.org. I had to manually send a mail
afterwards. I think this may be because of a configuration of some tool
that actually sends out the mail from my computer.
Packaging
Once obtaining the bug number for the ITP, we can start the packaging. Broadly speaking, debian packaging involves the following steps:
- Get a copy of the upstream source code
- Adapt it for debian
- Build the source and binary distributions
Let us examine each step, one by one.
Get upstream code
First, we set a couple of variables with the name and email id of the person doing the packaging. Value of these variables will be used by the tools that we will be using:
export DEBFULLNAME="My name"
export DEBEMAIL=my@email.comNow, we get the source of the software that we are going to package:
git clone -o upstream https://github.com/dakra/speed-typeThe -o upstream instructs git to name the
remote as upstream instead of the origin. This is the debian recommended name
while packaging.
Before proceeding further, following git config commands can be helpful too. Ignore them if not needed.
# Set name used in commits
git config user.name "My name"
# Set email used in commits
git config user.email "my@email.com"
# Set pgp key used to sign commits
git config user.signingkey 5C3B9F1EF93CB7A6A5C66769DDF7D61086BA8EED
# Sign all commits by default
git config commit.gpgsign trueWith that out of the way, we enter the cloned repo and adjust branch names to suit DEP-14.
cd speed-type
# Rename default branch from master or main to upstream/latest
# This makes upstream/latest to point to the latest commit in the
# development branch of source repo
git branch -m upstream/latest
# Remove upstream tracking information from repo
git branch --unset-upstream
# Check out tag latest release
git checkout 1.7
# Duplicate latest release branch with the name debian/latest
# This branch points to the last commit in the debianized source
git checkout -b debian/latestInitial 'debianization'
Now, we need to make few files that will adapt the source to work
well with debian. These files should be within a directory named
debian/. In most cases, the original source of software
being packaged is not changed. There are tools to generate a boilerplate
for the debian/ files, by examining files in the source and
values of shell variables.
Since, speed-type is already available on MELPA, so we can use
dh-make-elpa. This tool can do most of the work in
'debianizing' an ELPA package. Similar tools like
dh-make-perl, dh-make-golang exist to generate
template files for other languages in this manner.
I am not sure how the case of a software having source written in multiple languages is handled. But I am guessing it will be complicated.
We can generate the debian/ directory
along with most of the required contents using the following
command:
dh-make-elpa --pkg-emacsen
Debian has the Debian Emacsen
team which collectively maintain many emacs packages.
The --pkg-emacsen flag will instruct
dh-make-elpa to mention this team in the files under debian/.
The above command will make a debian/
directory that roughly looks like this:
debian/
├── changelog
├── control
├── copyright
├── docs
├── elpa
├── gbp.conf
├── rules
├── source
│ └── format
└── watch
control: specifies package name, maintainer and author names, pre-requisite packages, etccopyright: clearly mentions the license and copyright holders of the files in the packagedocs: lists files that are only for documentationgbp.conf: info used by thegbpcommandrules: kind of like aMakefilesource/format: determines the format of source packagewatch: Used byuscanto see if there are newer releases
Among these files, control and copyright
are probably the ones that requires the most attention.
I just mentioned a couple of tools like gbp and
uscan. Debian comes with a bunch of packages that people
have created over time to help with packaging. Some of them are very
commonly used. gbp and uscan are two of them.
You can read more about it if you find them interesting.
gbp: Git build package- git integration for debian build system
- Among other things, can import a debian package into git
uscan: upstream scan- check upstream for changes to help maintainer figure out if it's time for a new release
Anyway, at this point, we could make a commit.
git add debian
git commit -S -m "initial Debianisation"Fine-tuning debianization
The files generated by dh-make-elpa inside the debian/ directory serves as a starting point. We
need to modify these files to suit our package. Let's look at few of the
files and directories within debian/.
Patches
Sometimes, the upstream source of the target software cannot be used
in debian as is. In such cases, we patch the original source to apply
appropriate modifications. Such patches will be stored in debian/patches/. We can create patches using the
quilt tool.
I needed to first set the QUILT_PATCHES variable to make
quilt generate the patches in the correct directory. Just
to be safe, we first apply all existing patches, in case there are
pre-existing patches.
QUILT_PATCHES=debian/patches
quilt push -aSuppose the upstream source has a file named random.txt that we don't wish to include in the
source distribution. We can make a new patch named
remove-random like:
# Make a new patch named 'remove-random'
quilt new remove-random
# Indicate that the file to be patched
quilt add random.txt
# Make the edits for the patch
# We could also simply use and editor for this.
quilt edit random.txt
# Include the edit to the 'remove-random' patch
quilt refresh
# At this point, we can see the changes if we want
quilt diff
# Remove all patches, restoring the source to its original state
quilt pop -aNote: gbp pq can also be used to set up patches.
changelog
As the name implies, the debian/changelog file records the history of
changes to the debian package. This file mentions many things, including
the version and target debian distribution. We also indicate that the
acceptance of this package will close the bug number associated with the
ITP that we made for it. I think eventually, the corresponding RFS bug
number will also get included, but that will be for the sponsor to
include.
See: https://www.debian.org/doc/manuals/debmake-doc/ch06.en.html#changelog
The changelog for the first debian revision of our package looked like:
emacs-speed-type (1.7-1) UNRELEASED; urgency=medium
* Initial release (Closes: #1139675)
-- Julin Shaji <famubu@domain.tld> Thu, 11 Jun 2026 09:06:35 +0530
The most important part of the changelog is probably the version
number. This is the only place where the version of the package is
mentioned. There are some
conventions in determining the version number of the package. For
example, in our package, the version number is 1.7-1. The upstream release version is 1.7, the -1
indicates that this is the first revision for debian.
Few examples:
1.0~alpha: an alpha pre-release+dfsg: non-free parts removed~dfsg1: debian release before upstream release1.2~git20260101.abcdef: package from git snapshot2.3+really2.2-1: a newer upstreamv2.3rolled back to an older versionv2.2-11.4-5+deb10u2: second stable update tov1.4-5in debian 101.4-5+deb10u1~bpo9u1: a package in debian 10 backported in debian 9- Version without a hyphen to indicate debian revision means that the package is debian native
See:
- https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version
- https://www.debian.org/doc/debian-policy/ch-binary.html#the-version-of-a-package
Lintian is going to get annoyed with the UNRELEASED in this file, but you should not
change it till the package is ready for final upload to the actual
debian FTP server (not mentors.debian.net, I guess). I think changing
the UNRELEASED part also comes under
purview of the sponsor. It could get changed to unstable.
The dch -i command (debian change) may be used to bump
the version number of the package. It will trigger the opening up of a
modified debian/changelog for us to add
notes.
control file
The debian/control file contains
information about the source and binary packages being created. Among
other things, it specifies their dependencies.
In our case, most of the file is as generated by
dh-make-elpa. I only needed to change the package names and
description. This is the control file that I ended up with:
Source: emacs-speed-type
Section: editors
Maintainer: Debian Emacsen team <debian-emacsen@lists.debian.org>
Uploaders: Julin Shaji <famubu@domain.tld>
Build-Depends: debhelper-compat (= 13),
dh-elpa
Standards-Version: 4.7.4
Vcs-Browser: https://salsa.debian.org/emacsen-team/speed-type
Vcs-Git: https://salsa.debian.org/emacsen-team/speed-type.git
Homepage: https://github.com/dakra/speed-type
Testsuite: autopkgtest-pkg-elpa
Package: elpa-speed-type
Architecture: all
Depends: ${elpa:Depends}, ${misc:Depends}
Recommends: emacs
Enhances: emacs
Description: Practice touch and speed typing
Speed-type allows you to practice your touch typing skills. You can
test yourself by typing snippets from online books or use any piece
of text or code you have in Emacs. Speed-type keeps track of your
stats (WPM, CPM, accuracy) while you are typing.
As per the Debian emacsen team policy, the source and binary
distribution for my target package must have different names (emacs-speed-type and elpa-speed-type respectively).
The names like ${elpa:Depends} are substvars
(substitution variables). In this case, it's a substvar defined by
dh_elpa which is implicitly invoked by dh
while building the package. We can also define substvars of our own if
needed inside debian/substvars.
See:
copyright file
The debian/copyright file specifies the
copyright holders and license of the files associated with package.
Debian is quite attentive towards the license, since it categorizes
packages into components like main, contrib
and non-free.
Note that the entire license text of all mentioned licenses need to
be included here. Depending on the licenses used, this can make the
copyright file quite long. For example, I
needed to include the complete CC-BY-SA-4.0 license text which much
lengthier than GPL-3+.
A part of the copyright file that I ended up using is shown below:
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: speed-type
Upstream-Contact: Daniel Kraus <daniel@kraus.my>
Source: https://github.com/dakra/speed-type
Files: *
Copyright: (C) 2015 Gunther Hagleitner
License: GPL-3+
Files: debian/*
Copyright: (C) 2026 Julin Shaji <famubu@domain.tld>
License: GPL-3+
License: GPL-3+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in `/usr/share/common-licenses/GPL-3'
Note that blank lines are not allowed for multi-paragraph texts, a dot is placed instead, as seen in the license text above.
See: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
There are also extensions to the format version 1.0 of the copyright
fellow that are not uncommon. Like Files-Excludes that can
be used to exclude a file present in the upstream source from the
package. But support for such extensions varies among tools.
The copyright file may be checked to ensure that the licenses are DFSG-compliant
(Debian Free Software Guidelines). A package can be included into main component of debian
only if all its files are DFSG-compliant.
Info: Repackaging is done in situations like when a package can still be DFSG-compliant after making changes like excluding a file.
There are two tools that can help us assign the copyright correctly:
licensecheck: try to figure out the copyright that should be assignedlrc(licenserecon): check if the license assigned and the one given bylicensecheckare same
For example, I had initially assigned a GPL to a file which was
CC-BY-SA. lrc caught that.
$ lrc
en: Versions: licenserecon '6.0' licensecheck '3.3.9-1'
Parsing Source Tree ....
Reading d/copyright ....
Running licensecheck ....
d/copyright | licensecheck
GPL-3 | GPL-3+ debian/emacs-speed-type/usr/share/emacs/site-lisp/elpa-src/speed-type-1.7/speed-type.el
GPL-3 | GPL-3+ .github/workflows/test.yml
GPL-3 | GPL-3+ makem.sh
GPL-3 | GPL-3+ speed-type.el
GPL-3 | CC-BY-SA-4.0 test/https-en-wikipedia-org-wiki-Haskell-002f156.txt
GPL-3 | GPL-3+ test/speed-type-test.el
gbp
The debian/gbp.conf file has
information that can be used when gbp needs to be invoked.
For my package, I modified the template made by
dh-make-elpa and got it to look like this:
[DEFAULT]
upstream-branch = upstream/latest
debian-branch = debian/latest
upstream-tag = %(version)s
debian-tag = debian/%(version)s
sign-tags = True
pristine-tar = False
pristine-tar-commit = False
For example, this makes
gbp use upstream/latest as
the value for its --git-upstream-branch option.
Remember how we named/re-named branches after cloning source repo in the beginning? The resultant names are in line with DEP-14, and are the names mentioned in here.
upstream/latest: latest commit in the development branch of upstreamdebian/latest: latest commit in debianized version of the source code
At first, I wasn't sure if upstream/latest and debian/latest were meant to be branches or just
tags. But I later realized that those two are branches, but names like
upstream/<version> are to be
tags.
See:
- https://wiki.debian.org/PackagingWithGit
- https://manpages.debian.org/testing/git-buildpackage/gbp.conf.5.en.html
Pristine tar: We can have the original source tar ball from upstream
(if any) in a separate branch named pristine-tar. I didn't include a pristine tar
ball, since my upstream doesn't provide an explicit tarball. But since
the source is hosted on github, it does have git tags corresponding to
latest release, which means github auto-generates a tarball. But I still
didn't use it since the other emacs packages doesn't seem to be having
them either.
See: https://wiki.debian.org/DebianPackaging--pristine-tar-option-explained
watch file
uscan uses the watch file at debian/watch to figure out where to look to see
if there are new releases for the package. The watch file for the
package that I had been trying ended being like this:
Version: 5
Template: Github
Owner: dakra
Project: speed-type
dh-make-elpa generated a watch file with version 4,
which looked more complex.
For comparison, the version 4 one made by dh-make-elpa
looked like this:
version=4
opts="filenamemangle=s/(?:.*?)?v?(@ANY_VERSION@@ARCHIVE_EXT@)/@PACKAGE@-$1/" \
https://github.com/dakra/speed-type/tags \
(?:.*?/)?@ANY_VERSION@@ARCHIVE_EXT@ debian uupdate
These specify values for various options of uscan.
Values like @ARCHIVE_EXT@ are
special strings that will automatically get substituted with
appropriate values by uscan.
See:
source/format
If I understand correctly, this file specifies how the source package
distribution is built. 3.0 (quilt) seems
to be the usual choice, although others choices are also available. Like
3.0 (native) for native packages. As per
a
page on wiki.debian.org, 'Less than 5
% of Debian's source packages are not in 3.0 (quilt) format' This format
has the advantage of letting us keep the patches distinct from the
source.
In my case, the source/format generated
by dh-make-elpa was sufficient uncharged:
3.0 (quilt)
See:
upstream/metadata
debian/upstream/metadata is a yml file
contains metadata related to the upstream in machine readable form. I
don't think I saw any lintian errors nudging me to include this file,
but many emacs packages that recently got accepted to unstable had this
file, so I thought I would add one too. I got it like:
---
Bug-Database: https://github.com/dakra/speed-type/issues
Bug-Submit: https://github.com/dakra/speed-type/issues/new
Repository: https://github.com/dakra/speed-type.git
Repository-Browse: https://github.com/dakra/speed-type
This information will be useful for uscan.
I am not sure, but I think this file is especially relevant if we are using a watch file with version 5 onwards.
rules
The debian/rules is the build script of the
package. It is an executable Makefile that specifies how to build the
package. In our case, we delegate the whole thing to debhelper commands
so there is not much left to do. I didn't have to change the debian/rules generated by
dh-make-elpa, which looked like:
#!/usr/bin/make -f
%:
dh $@ --with elpaUsing the rules Makefile, we should be able to do stuff like:
- Clean build environment:
debian/rules clean - Build package:
/debian/rules build - And others like
binary,binary-arch,build-arch, etc.
An example:
$ debian/rules clean
dh clean --with elpa
dh_clean
Building
We got all the files needed for building the package ready, so let us get on with building the package.
For a package, we need the following:
- Source distribution
- Binary distribution
We can make a tar ball of the original source with:
git deborig
This creates a speed-type_1.7.orig.tar.xz file
containing the source from upstream as is. deborig is not a
part of a standard git installation and is from the devscripts package of debian.
Note: Somehow deborig will also create a file named
test.bin. I needed to delete it before building the
package.
By this point, we are all set to build the package. The package can be built with:
dpkg-buildpackageThis created a few extra files.
elpa-speed-type_1.7-1_all.deb: binary distributionspeed-type_1.7-1.debian.tar.xz: contents of thedebian/directoryspeed-type_1.7-1.dsc: metadata, with info like files involvedspeed-type_1.7-1_amd64.buildinfo: for reproducible builds. Has info on the environment used to build the packagespeed-type_1.7-1_amd64.changes: contains information used while uploading the package
Thus, we have obtained the source and binary distributions. These can
now be uploaded to the FTP servers. But before that, we should push all
the files that we got to the repo mentioned under Vcs-git in the debian/control file. I did it like this:
git push https://salsa.debian.org/emacsen-team/emacs-speed-type --all
git push https://salsa.debian.org/emacsen-team/emacs-speed-type --tags
Uploading
Before uploading, the built package needs to be signed by the
packager. This can be done via debsign:
$ debsign -k 5C3B9F1EF93CB7A6A5C66769DDF7D61086BA8EED emacs-speed-type_1.7-1_amd64.changes
signfile dsc emacs-speed-type_1.7-1.dsc 5C3B9F1EF93CB7A6A5C66769DDF7D61086BA8EED
fixup_buildinfo emacs-speed-type_1.7-1.dsc emacs-speed-type_1.7-1_amd64.buildinfo
signfile buildinfo emacs-speed-type_1.7-1_amd64.buildinfo 5C3B9F1EF93CB7A6A5C66769DDF7D61086BA8EED
fixup_changes dsc emacs-speed-type_1.7-1.dsc emacs-speed-type_1.7-1_amd64.changes
fixup_changes buildinfo emacs-speed-type_1.7-1_amd64.buildinfo emacs-speed-type_1.7-1_amd64.changes
signfile changes emacs-speed-type_1.7-1_amd64.changes 5C3B9F1EF93CB7A6A5C66769DDF7D61086BA8EED
Successfully signed dsc, buildinfo, changes files
Our package needs to reviewed before it can be considered for
inclusion to debian repos. We can upload it to mentors.debian.net for this. mentors.debian.net is a platform facilitating
review of packages. We can upload our source packages there and other
people, including non-DDs, can make comments to provide feedback. It is
like a staging area for debian packages.
Our package can be uploaded
to mentors.debian.net with:
$ # Can use `dput --force` if re-uploading without version change
$ dput mentors emacs-speed-type_1.7-1_amd64.changes
Checking signature on .changes
gpg: /home/user/speed-type/emacs-speed-type_1.7-1_amd64.changes: Valid signature from 26AF96E2D752882F
Checking signature on .dsc
gpg: /home/user/speed-type/emacs-speed-type_1.7-1.dsc: Valid signature from 26AF96E2D752882F
Uploading to mentors (via https to mentors.debian.net):
Uploading emacs-speed-type_1.7-1.dsc: done.
Uploading emacs-speed-type_1.7.orig.tar.xz: done.
Uploading emacs-speed-type_1.7-1.debian.tar.xz: done.
Uploading elpa-speed-type_1.7-1_all.deb: done.
Uploading emacs-speed-type_1.7-1_amd64.buildinfo: done.
Uploading emacs-speed-type_1.7-1_amd64.changes: done.
Successfully uploaded packages.
You should get an acknowledgement mail from mentors.debian.net after a few minutes, and the
package should show up in their webpage.
Fun fact: dput is used upload package to FTP server.
Similarly dget can be used to download a package.
RFS
Once the package is ready and uploaded to mentors.debian.net, we need it reviewed and need
a sponsor to upload it to debian repos. Only a debian developer (DD) can
sponsor packages. We try to get the attention of potential sponsors with
a 'Request For Sponsors' (RFS). This can be done with a mail to
submit@bugs.debian.org. Template for such a mail can be
found at mentors.debian.net. The system
will generate a bug number for the RFS.
Note that sending out RFS by no means signify that your package is guaranteed to get sponsored or even reviewed. As I understand, it is generally difficult to find a sponsor (I haven't found one yet for my package). Because the sponsor would need to go through your package (and probably get vexed at mistakes/omissions that you made) and suggest changes, involving a lot of back-forth mails in the process. Bottom line is, sponsor would need to put some work in too, so you might need to be patient (and persistent) before you finally get a sponsor.
Updating RFS
We can reply to the bug number associated with our RFS if we need to mention anything more with regard to that RFS.
I, for one, needed to change the title of the package specified in
RFS. So sent this mail to my-rfs-bug-no@bugs.debian.org get it fixed:
Control: retitle -1 RFS: emacs-speed-type/1.7-1 [ITP] -- Practice touch and speed typing
thanks
As I understand it, similar messages can be used to update any bug at bugs.debian.org. And that includes ITPs too. Control mailserver commands are documented here.
Testing
Building the package was the first part of the packaging process. Next thing to do is to check whether software installed via that package works as expected in the latest debian unstable. If the upstream comes with tests, we can use that. Otherwise, not much we can do, I guess. Thankfully, my upstream did have tests.
lintian
Lintian is a tool that acts like linter for debian packages. It is quite good at flagging errors and potential errors We can run lintian on a package like:
$ lintian
W: elpa-speed-type: copyright-contains-automatically-extracted-boilerplate
W: elpa-speed-type: initial-upload-closes-no-bugs [usr/share/doc/elpa-speed-type/changelog.Debian.gz:1]
W: speed-type source: unknown-paragraph-in-dep5-copyright [debian/copyright:30]
Lintian expects the .changes file as
argument, but can use the one in current directory if available.
Errors/warning produced by lintian are associated with tags. We can
ask lintian to explain the meaning of that tag with
lintian-explain-tags. For example:
$ lintian-explain-tags missing-license-paragraph-in-dep5-copyright
N:
W: missing-license-paragraph-in-dep5-copyright
N:
N: The Files paragraph in the machine readable copyright file references a license for which no stand-alone License paragraph exists.
N:
N: Sometimes this tag appears because of incorrect ordering. Stand-alone License paragraphs must appear *after* all Files paragraphs.
N:
N: Please refer to https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ and Bug#959067 for details.
N:
N: Visibility: warning
N: Show-Always: no
N: Check: debian/copyright/dep5
N:
Also, flags can be used to make lintian 'stricter':
lintian -EviIL +pedantic ../emacs-speed-type_1.7-1_amd64.changes
Caveat: The lintian used at mentors.debian.org was outdated when I tried. So some of the errors/warnings that it showed were not relevant. I felt that using the latest lintian version locally would be more instructive.
sbuild
sbuild can build our package in clean, isolated
environment. It works on top of a tool named mmdebstrap
(usually with unshare backend), if I understand
correctly.
The full output of sbuild is too long to include here,
but parts of it looks pretty much like how we install packages with
apt, because that's exactly what's happening.
Before using sbuild, I did the following to allow my
user to use sbuild:
sudo sbuild-adduser famubuThis adds the user named famubu to the group named
sbuild. Only members of the sbuild group can
invoke sbuild.
$ groups famubu
famubu : famubu audio video users ....... sbuild
Then, invoking sbuild is as simple as:
sbuildAmong other things, sbuild does the following:
- Make a complete debian sid chroot
- Install packages that are prerequisite for our package
- Build the package
- Run the tests present in the source package
- Including lintian checks if
--run-lintianoption is used
- Including lintian checks if
Finally, sbuild produces a summary like the one
below.
+------------------------------------------------------------------------------+
| Summary Sat, 23 May 2026 06:36:39 +0000 |
+------------------------------------------------------------------------------+
Build Architecture: amd64
Build Type: binary
Build-Space: 1384
Build-Time: 2
Distribution: unstable
Host Architecture: amd64
Install-Time: 28
Job: /home/famubu/speed-type/emacs-speed-type_0.7.0-1.dsc
Lintian: warn
Machine Architecture: amd64
Package: emacs-speed-type
Package-Time: 80
Source-Version: 0.7.0-1
Space: 1384
Status: successful
Version: 0.7.0-1
--------------------------------------------------------------------------------
Finished at 2026-05-23T06:36:17Z
Build needed 00:01:20, 1384k disk space
Looks like sbuild sets up the chroot at:
/home/username/.cache/sbuild/unstable-amd64.tar.
autopkgtest
Warning: This section is all guesses. I haven't completely tried them yet.
autopkgtest
is used to test the package after installing it from its binary
distribution. Its working is described in the current
draft of DEP-8. Unlike sbuild which runs tests from the
source, autopkgtests are run against the package installed from its
binary in a debian environment.
The tests to be run, along with their necessary parameters, are
specified in the test control file at debian/tests/control.
- A test is considered to have passed if it returns
0and doesn't print anything tostderr - The tests are like scripts inside
debian/tests/ - The tests would run with root of the source package as the working directory, but the tests would be testing the installed version of the package.
- Also see:
/usr/share/docs/autopkgtest/README.package-tests.rst.gz/usr/share/docs/autopkgtest/README.running-tests.rst.gz
For example, with the following test control file,
Tests: verbose
Depends: @, build-essential
Restrictions: needs-root
Architecture: amd64 arm64 i386
the debian/tests/verbose test itself
could be
!/bin/bash
foo --verbose
and autopkgtest should be able to run the test.
See:
- https://wiki.debian.org/ContinuousIntegration/AutopkgtestBestPractices
- https://manpages.debian.org/trixie/autopkgtest/autopkgtest.1.en.html
autodep8
The test control is meant to be written in a way that is compliant
with DEP-8. The autodep8
tool is helpful to generate the test control file template specific to
the target package. The output of autodep8 is meant to be
the contents of debian/tests/control.
For example, for the emacs elpa package that I had been using, it gave this:
$ autodep8
Test-Command: dh_elpa_test --autopkgtest
Depends: @, @builddeps@,
Restrictions: rw-build-tree,
Features: test-name=dh-elpa-test-autopkgtestautopkgtest can automatically use autodep8
by looking at the value of Testsuite in
debian/control. This value should be like
autopkgtest-pkg-TYPE where TYPE is a package type supported by autodep8. In
our case, TYPE is elpa, which is indeed supported, thereby making
things easier for us.
salsa tests
Warning: This section is all guesses. I haven't completely tried them yet.
Debian salsa has CI/CD that can run before a package is admitted into
unstable. Looks like it runs only basic checks like lintian By default,
but we can request it to run the tests meant for
autopkgtest as well by making a debian/salsa-ci.yml file like below:
---
include:
- https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml
'Manual testing' with containers
Tests like those run by from sbuild and autopkgtest are kind of automatic. Once the configuration has been done, we need not be involved further. But what if you want to play around with the installed package to see if it actually feels all right? Sometimes hiccups can creep in even when all the tests pass. Though it is an ad-hoc way, a way to enter into an environment where the package and its dependencies are installed would be nice. It would let us tinker around and see things from the usability point of view. A full blown VM is unnecessary for this, a container would be sufficient. I went with podman, since it seemed lighter than docker.
Podman is like docker except that it doesn't need a daemon to run.
Dockerfiles meant for docker can usually be used with
podman without any modification, except that the file name
is Containerfile instead of Dockerfile.
snapshot.debian.org provides snapshots that can be used as a basis to build our own pods.
I used this Containerfile:
FROM debian:sid
# Use snapshot
RUN echo "deb http://snapshot.debian.org/archive/debian/20260611T082845Z sid main" \
> /etc/apt/sources.list
WORKDIR /root
# Install dependencies
RUN apt-get update
RUN apt-get install -y \
lintian \
devscripts \
debhelper \
dh-elpa \
git \
gnupg
# Download source distribution from mentors.debian.net
RUN mkdir ~/.gnupg && \
chmod 700 ~/.gnupg && \
gpg --keyserver keyserver.ubuntu.com --recv-keys D752882F && \
dget -x -u https://mentors.debian.net/debian/pool/main/e/emacs-speed-type/emacs-speed-type_1.7-1.dsc
WORKDIR /root/emacs-speed-type-1.7
# Build package
RUN dpkg-buildpackage -us -uc && \
lintian -EviIL +pedantic ../emacs-speed-type_1.7-1_amd64.changes
CMD ["bash"]PWD is location of the Containerfile:
# Build image.
podman build -t sid:20260611T082845Z .
# Start the pod
podman run -it sid:20260611T082845Z
This will create a sid snapshot, install our package and run the tests. Once that is done, it will enter bash shell where we can examine the leftover files or take out our installed package for a spin.
I can't help feel that someone in debian must have made a tool to
sort of automate this when using podman. Especially since it looks as if
there are tools for testing via docker like debdocker and
debocker are already there.
Useful tools
As mentioned earlier, there is a whole host of tools that debian packagers have developed over the years. Let me mention something about a couple of them.
piuparts: stands for 'package installation, upgrading and removal testing suite'- Does a form of regression testing
- Checks whether everything is fine when this package is installed, upgraded and removed.
- I suppose the upgrade check cannot be done for fresh packages
- Debian runs this tool on all packages in its repo, with the results being made available at https://piuparts.debian.org/
sbuildgave some error when I tried using its--run-piupartsflag. When I asked a DD about it, they said it's a problem with the tool. Maybe mysbuildversion was too old.
gbpcan do stuff like:gbp import-orig --uscan: check if there are newer commits in upstream. If yes, import it
Many of these tools are implicitly used by other tools.
Conclusion
So, in conclusion, I figure the flow for a new-comer to submit a package for inclusion into debian is like this:
- Find a package
- File ITP
- Package the sofware
- File RFS
- Get package reviewed
- Sponsor found
Acknowledgements: Thanks to,
- Everyone involved with MiniDebCamp Kochi 2026!
- Abraham Raji, for his blog post on packaging (nodejs)
- Folks at
#debian-emacs,#debian-mentors