npm2deb is an automatic tool which permits to fast deploy debian/* files starting from a module downloaded via npm.

Following commands for lxc container creation:

# apt-get install lxc
# lxc-create -n deb-sid -t debian -- -r sid

See LXC for more. For docker, see PackagingWithDocker.

Add the following variables in your ~/.bashrc file. DEBEMAIL and DEBFULLNAME variables are used by debian tools to set your name and email.

export DEBEMAIL=your@email.domain
export DEBFULLNAME='Your Name'
alias lintian='lintian -iIEcv --pedantic --color auto'
alias git-import-dsc='git-import-dsc --author-is-committer --pristine-tar'
alias clean='fakeroot debian/rules clean'

Note: You can also use debclean command instead of setting alias for clean.

and update your current environment by running

source ~/.bashrc

sudo apt-get install npm2deb

If you want help in developing:

git clone https://github.com/LeoIannacone/npm2deb

For usage information, please refer to npm2deb man page. There is a also a more detailed tutorial.

Step 1. Check dependencies

A simple workflow is check if a node_module has all dependencies already satisfied in Debian, you can use npm2deb depends to get this info.

In this example we will check jade module which at the moment is not packaged for Debian:

$ npm2deb depends -b -r jade
Dependencies:
NPM                                               Debian
jade (1.3.1)                                      None
├─ monocle (1.1.51)                               None
│  └─ readdirp (~0.2.3)                           node-readdirp (0.2.4-2)
├─ transformers (2.1.0)                           None
│  ├─ uglify-js (~2.2.5)                          uglifyjs (1.3.5-1)
│  ├─ promise (~2.0)                              None
│  │  └─ asap (~1.0.0)                            None
│  └─ css (~1.0.8)                                None
│     ├─ css-stringify (1.4.1)                    None
│     │  └─ source-map (~0.1.31)                  None
│     │     └─ amdefine (>=0.0.4)                 None
│     └─ css-parse (1.7.0)                        None
├─ character-parser (1.2.0)                       None
├─ mkdirp (~0.3.5)                                node-mkdirp (0.3.5-1)
├─ commander (2.1.0)                              node-commander (2.0.0-1)
├─ constantinople (~2.0.0)                        None
│  └─ uglify-js (~2.4.0)                          uglifyjs (1.3.5-1)
└─ with (~3.0.0)                                  None
   └─ uglify-js (~2.4.12)                         uglifyjs (1.3.5-1)

As you can see, there are many modules not packaged for debian. npm2deb was written to reach this goal, have a tool to fast and easy package new nodejs module.

In this example we will take care about monocle module.

Step 2. Search for existing work

First of all, use npm2deb search to know if someone else has already started working on this module:

$ npm2deb search monocle
Looking for similiar package:
  None
Looking for existing repositories:
  None
Looking for wnpp bugs:
  None

As you can see, there no info about monocle in Debian. So you can start to work on.

Step 3. Preview more information

Use npm2deb view command to get a preview information about module:

$ npm2deb view monocle
Name:                                   monocle
Version:                                1.1.51
Description:                            a tool for watching directories for file changes
Homepage:                               https://github.com/samccone/monocle
License:                                BSD
Debian:                                 None

License is automatically recognize as BSD, if this does not happen, please pass --upstream-license option during creation to set a correct license.

Step 4. Create packaging files

Next step, make the debianization:

$ npm2deb create monocle

This is not a crystal ball, so please take a look at auto-generated files.
You may want fix first these issues:
monocle/node-monocle/debian/control: FIX_ME long description

This command creates <module_name>/node-<module_name>/debian directory which contains the basic information about the module.

You have to fix every occurrence of FIX_ME in those files.

By default npm2deb set Vcs-* fields to git in pkg-javascript. For more information about git, please read GitPackaging.

Note: If the module is using any complex build tools like grunt, gulp, babel, webpack, browserify or rollup (look in the devDependencies section of package.json), follow ?this guide.

Manually download upstream sources (if required)

Where uscan does not work because the upstream repo is missing tags. The node module we use is 'require-directory'. Follow these steps if you got this warning

*** Warning ***
Using fakeupstream to download npm dist tarballs, because upstream
git repo is missing tags. Its better to ask upstream to tag their releases
instead of using npm dist tarballs as dist tarballs may contain pre built files
and may not include tests.

Usually this can be done by uscan --verbose --download-current-version but some projects does not create git tags for their releases so we have to visit their home page (given in 'debian/control') and find out the commit for the release (from their 'commits' page) or download the tarball from npmjs.org.

Note: Current version of npm2deb already download orig tarballs from github if tag matching npm release is present or npm dist tarball if matching tag is missing in github. But if you need to include tests, you may follow Option 2 below to download github tarballs.

Option 1: Download via npmjs.org (npm2deb does this by default)

This is the easier method but you may not get tests in these tarballs. Also if it includes pre-built files (output of uglifyjs, babel, browserify, webpack etc), you may want to follow Option 2 below. You can skip this step if you already have the source tarball (downloaded by npm2deb create).

$ cd require-directory
$ npm view require-directory dist.tarball
https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz
$ wget https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz

Option 2: Download via github.com commit snapshot

Note: You may also request the upstream to add the corresponding tag and wait a few days before choosing this option.

Homepage: https://github.com/troygoode/node-require-directory
Commits page: https://github.com/troygoode/node-require-directory/commits/master

In this case 'bump to v2.1.1' commit is what we want Click on '<>' button on the right of this commit to browse repository on this commit.

'bump to v2.1.1 commit page: https://github.com/troygoode/node-require-directory/tree/cc71c23dd0c16cefd26855303c16ca1b9b50a36d

Click on the 'Clone or download' button Right click on 'Download ZIP' and copy its url

ZIP download url: https://github.com/troygoode/node-require-directory/archive/cc71c23dd0c16cefd26855303c16ca1b9b50a36d.zip

Paste the link on the terminal and change .zip to .tar.gz and use wget command to download this file and give -O option to set a different name for the downloaded file

$ cd require-directory/
$ wget -O node-require-directory-2.1.1.tgz https://github.com/troygoode/node-require-directory/archive/cc71c23dd0c16cefd26855303c16ca1b9b50a36d.tar.gz

Step 5. Create debian source package/.dsc file (if required)

Now combine the 'debian' directory we created earlier to the tar.gz file we downloaded (if ../node-require-directory-2.1.1-1.dsc is not present).

.dsc file (file with .dsc extension) is debian source package and is normally created by npm2deb create command.

Note: If you already imported dsc file to git, you can use gbp import-orig --pristine-tar ../node-require-directory-2.1.1.tgz to import the tarball, after removing the upstream/2.1.1 tag (git tag -d upstream/2.1.1) instead of uupdate.

$ cd node-require-directory
$ uupdate -b ../node-require-directory-2.1.1.tgz

Switch to package directory and remove the extra line "* New upstream release" from debian/changelog in case you did uupdate.

$ cd ../node-require-directory-2.1.1
$ dch -e
$ dpkg-source -b .

Step 6. Build the binary package

dpkg-buildpackage (if required)

$ dpkg-buildpackage

Import your package to git

It is highly recommended you import your debian source package (.dsc file) to git version control system at this point and commit your changes in git repo. This is useful to track all changes you make to the package. See the commands given below.

$ cd ..
$ rm -rf node-require-directory
$ gbp import-dsc --pristine-tar node-require-directory_2.1.1-1.dsc
$ cd node-require-directory
$ git tag -d debian/2.1.1-1

# apt-get install git-buildpackage

It would be a good idea to add --pristine-tar option to gbp command as default in ~/.gbp.conf

[DEFAULT]
pristine-tar = True

Make your package lintian clean

$ lintian ../node-require-directory_2.1.1-1_amd64.changes

Make sure you fix all the errors and warnings (lines starting with E: or W:) shown by lintian. Every time you make a change to any file inside debian directory. Run dpkg-buildpackage and lintian commands to make sure the warning/error is actually fixed.

$ licensecheck --deb-machine -r -l0 *

Update debian/copyright with any missing information.

You can also use libconfig-model-dpkg-perl (# apt-get install libconfig-model-dpkg-perl) to update debian/copyright.

$ cme update dpkg-copyright

Run tests if available

Use this example commit as reference.

  "scripts": {
    "test": "tap test"
  },

override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
      tap test
endif

Tests: require
Depends: node-qw

Test-Command: tap test
Depends: @, node-tap

Note: Some of the test dependencies like xo, nyc, standard, eslint, jshint can be ignored. Some test frameworks like ava is not packaged, which you can skip.

ITP (Intend to Package bug)

Clean build with sbuild

$ sudo apt-get install sbuild
$ sudo sbuild-adduser $LOGNAME
     ... *logout* and *re-login* or use `newgrp sbuild` in your current shell
$ sudo sbuild-createchroot --include=eatmydata,ccache,gnupg unstable /srv/chroot/unstable-amd64-sbuild http://deb.debian.org/debian
$ sudo sbuild -A -d unstable

See sbuild for more options.

# chroot /srv/chroot/unstable-amd64-sbuild
# echo 'Acquire::http { Proxy "http://127.0.0.1:3142"; }' >> /etc/apt/apt.conf.d/proxy

# apt-get install autopkgtest
# dpkg -i ../node-require-directory_2.1.1-1_all.deb
$ sudo autopkgtest ./ --- null

For more information about Javascript Team Infrastracture please read the Javascript page.

Step 7. Push your repo to salsa

$ git remote add origin git@salsa.debian.org:js-team/node-promzard.git
$ git push -u --all --follow-tags

Step 8. Request sponsorship

RFS Checklist

Please make sure you have taken care of these common issues before sending an RFS mail.

  1. You MUST check if the module is already packaged. Run npm2deb search before you file an ITP. Check carefully for existing package, previous work or warnings.

  2. Description should be good for debian standards, both in ITP and debian/control. Mention it is a dependency of ava or browserify as the case may be. Description line should be split less than 80 characters but not too small like 30 or 40. Please manually verify no FIX_ME is remaining in control, copyright or changelog.
  3. Make sure --pristine-tar option is given when gbp import-dsc is run
  4. You MUST delete the debian tag
  5. You MUST push all branches (master, upstream and pristine-tar)
  6. You MUST make your package lintian clean every time you make changes to your package
  7. You MUST make it build in a clean chroot using tools like sbuild every time you make a change
  8. If tests are present and test framework is packaged, tests should be enabled in rules and tests/control. Check package.json for how to run the tests.
  9. You should check email for the comments you receive for ITP or RFS or ftp master rejection and fix them.
  10. If you don't get a reply to your RFS, please wait for at least a week before sending a reminder. If you have to send a reminder please reply to the previous RFS mail instead of writing a new mail.
  11. You should cc/copy your ITP when you send RFS
  12. You MUST import your package to js-team repo on salsa if you are a member of js-team group

Updating a package to new upstream release

  1. Clone the current repo gbp clone --pristine-tar gbp clone --pristine-tar  git+ssh://git.debian.org/git/pkg-javascript/node-require-directory

  2. Download new upstream release tarball using uscan --verbose or use "Step 2, Option 2" above to manually download the new upstream release tarball.

  3. Import the orig.tar.gz using gbp import-orig --pristine-tar --uscan or gbp import-orig --pristine-tar ../<upstream-version.tar.gz>.

  4. Add a new section to changelog by running dch -i or dch --team. Mention "New upstream release" as an item.

  5. Build the package using dpkg-buildpackage

  6. Make it lintian clean
  7. Build in clean chroot (using tools like sbuild)

Embedding some modules

When we have modules that are unlikely to be needed by other modules we can include it inside another module. Later if other modules also need the embedded module, it can be packaged separately. See node-clone-deep for an example.

  1. Download the module from npmjs.com as given in Javascript/Nodejs/Npm2Deb#Option_1:_Download_via_npmjs.org_.28npm2deb_does_this_by_default.29

  2. Extract and copy it to debian/node_modules
  3. Add debian/.gitignore with this line: !node_modules

  4. export NODE_PATH=debian/node_modules in debian/rules and debian/tests
  5. Install the modules if it is a runtime dependency using debian/install file