How to upload a perl module on CPAN using Dist::Zilla?

Today, I released my second CPAN module. While writing my first CPAN module, I used Dist::Zilla for uploading my module to CPAN, but when I looked into it today, I had to go through some dzil plugins again. So, I thought that I should write a blog post about this.

Basic directory structured of the module:

Assuming, my module name is X::Y::Z, I need to create a directory with name X-Y-Z. Output of find command should look like this:

lib                 # all code goes in lib/
lib/X              # code for X will go here
lib/X/Y           # code for Y will go here
lib/X/Y/  # code for Z will go here
t/                   # all tests will go here
dist.ini           # explained below

For example : see this module.

Writing dist.ini:

Following is my dist.ini. I've pasted it below with comments for explaination.

name = Plack-Middleware-FixMissingBodyInRedirect
version = 0.01
author = Upasana <>
license = Perl_5
copyright_holder = Upasana

; this plugin gathers all files in a dist,
; if root is not given it defaults to where dist.ini is located

; this plugin will add META.yml file to the dist
; META.yml contains information related to dist like abstract, author,
; which modules are required for building & testing the dist,
; which modules are required during runtime,
; pre-requisites etc.

; for removing unwanted files, e.g. files starting a '.'

; This plugin builds Makefile.PL, that uses ExtUtils::MakeMaker
; ExtUtils::MakeMaker create a module Makefile.
; (I found this thing very lengthy & very complicated,
; I've myself not understood it well).

; will create a META.json, for replacing old style META.yml
; META.json contains same information as META.yml, but in JSON format

; adds a LICENSE file containing the full text of dist's license

; adds a README file to the dist,
; citing the dist's name, version, abstract % license

; This plugin rip apart your kind of POD & reconstructs it as old real POD
; (I really don't know the difference between the two kinds of PODs though)
; By default, it'll modify the files under:
; :InstallModules - .pm/.pod files under lib/ directory
; :ExecFiles - executable files in the distribution

; This plugin will read MANIFEST.SKIP file &
; skip all the files decalred in it, while building the dist
; My MANIFEST.SKIP contains this text:
; ^.*~$
; because I want to skip backup files, which starts with any character,
; but ends with '~'

; This plugin checks POD coverage of all subs,
; to indicate that some subs should be treated as covered,
; even if no documentation can be found, you can add:
; =for Pod::Coverage sub_name other_sub this_one_too.
; It generates xt/release/pod-coverage.t file

; for checking POD syntax

; This plugin runs before a release happens,
; It'll extract to-be-released archive into a temporary directory,
; run all the tests, if tests fail then it'll abort the release,
; else it'll release the dist to CPAN & clean-up the temporary directory

; This plugin checks for correct line endings in the dist
; It generates xt/release/eol.t file

; This plugin allows the "dzil release" command to upload the dist
; to CPAN. It'll look for PAUSE account configuration in dist.ini
; (I would suggest to use the latter options for saving PAUSE configuration)
; or in ~/.dzil/config.ini in the following format:
; [%PAUSE]
; username = YOUR-PAUSE-ID
; If above configuration doesn't exist, then it'll look into ~/.pause
; in the following format:
; If none of the above exists, then it'll prompt you for PAUSE credentials

; This plugin prompts the author whether or not to continue before
; releasing the distribution to CPAN. It gives authors
; a chance to abort before they upload.
; The default is "no", but you can set the environment variable
; DZIL_CONFIRMRELEASE_DEFAULT to "yes" if you just want to hit enter to release.

; This plugin will automatically extracts pre-requisties from your modules
; You can manually add pre-requisites by using Prereqs plugin

Releasing dist to CPAN:

After writing dist.ini, you should test & build your dist & see if everything is fine in resulted tarball. For testing & building your dist, do

dzil test --all
dzil build

If everything goes well with the above commands, you can release your dist to CPAN, by doing

dzil release


I've taken most of the explanation from PODs of various Dist::Zilla::Plugin::* modules.


Actually, you need to use a semicolon as comment character ;-)

Leave a comment

About Upasana

user-pic I blog about Perl. I'm still in the early phase of learning perl, so please do let me know if you find any flaws in my posts, I'll appreciate it.