<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Release Checklist</title>
</head>
<body>
<h1 id="name">NAME</h1>
<p>Release::Checklist - A QA checklist for CPAN releases</p>
<p>What follows is a list of categories or subjects that touch the
quality - or what an end-user perceives as such - of a distribution end
might need some attention.</p>
<p>This document is aiming at up-river authors that want/need improving
the release status of their distribution.</p>
<p>Work is underway in merging this list with <a
href="https://github.com/Perl-Toolchain-Gang/toolchain-site/blob/master/berlin-consensus.md">The
Berlin Consensus</a> into a toolset and/or service.</p>
<p>Some of those can be (semi-)automated (in tests), others need action
from the maintainer. Not all subjects may apply to your project.</p>
<p>Each subject will mention or list modules that might help in
improving or preserving high standards.</p>
<p>Various guidelines are also available in the <a
href="https://perldoc.perl.org/perlmodstyle.html">perl core
documentation</a> and the basics for preparing a (new) module for
distribution can be found in <a
href="https://perldoc.perl.org/perlnewmod.html">perlnewmod</a>.</p>
<pre class="shell"><code> $ perldoc perlmodstyle</code></pre>
<h1 id="test">Test</h1>
<p>Test, test and test. The more you test, the lower the chance you will
break your code with small changes.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode perl"><code class="sourceCode perl"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a> <span class="fu">use</span> <span class="kw">strict</span>;</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="fu">use</span> <span class="kw">warnings</span>;</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="fu">use</span> <span class="fu">Test::More</span>;</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> :</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> done_testing ();</span></code></pre></div>
<p>Separate your module tests and your author tests. This will lower the
number of dependencies. Check your Pod syntax, documentation coverage,
spelling, and minimum perl version requirements in <code>xt/</code>.
Prevent declaring dependencies that are only used in<code>xt/</code>.
There is no need to check prerequisites when the distribution runs its
tests in user-space.</p>
<pre><code>t/
xt/</code></pre>
<p>If possible, do not use <a
href="https://metacpan.org/search?q=Test%3A%3A&search_type=modules">Test::*</a>
modules that you do not actually require, however fancy they may be. See
the point about dependencies.</p>
<p>If you are still using any additional <code>Test::</code> module, do
not mix your own code with the functionality from a/the module. Be
consistent: use all or use nothing. That is: if the module you (now) use
comes with features you had scripted yourself before using that module,
replace them too.</p>
<p>If adding tests after a bug-fix, add at least two tests: one that
tests that the required (fixed) behavior now passes and that the invalid
behavior fails.</p>
<p>Check to see if your tests support running in parallel</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> prove <span class="at">-vwb</span> <span class="at">-j8</span></span></code></pre></div>
<p>If you have <a
href="https://metacpan.org/pod/Test2::Harness">Test2::Harness</a>
installed, also test with yath</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> yath</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> yath <span class="at">-j8</span></span></code></pre></div>
<p>Add tests cases from issues or tickets to your own tests. Adding
references to the tickets or issues creates a self-documenting
structure, reasoning and history.</p>
<h1 id="dependencies">Dependencies</h1>
<p>Every module you use is a module your release will depend on. If a
new release of such module fails, the likelihood of your release being
unable to install increases. So only use modules that you need. Each
dependency should be well-considered.</p>
<p>Depending on modules that are included in the perl5 CORE distribution
do not have this problem, as you are sure that this module is available
already. However, be careful to ensure that that module is a core module
in the lowest version of perl that you claim to support. Check it with
<a
href="https://metacpan.org/pod/Module::CoreList">Module::CoreList</a></p>
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> corelist File::Temp</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">Data</span> for 2018-04-20</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">File::Temp</span> was first released with perl v5.6.1</span></code></pre></div>
<p>Then there are two types of modules you can depend on: functional
modules, like <a href="https://metacpan.org/pod/DBI">DBI</a> and <a
href="https://metacpan.org/pod/XML::LibXML">XML::LibXML</a>, and
developer convenience modules, like <a
href="https://metacpan.org/pod/Modern::Perl">Modern::Perl</a>.</p>
<p>You cannot get around needing the first type of modules, but the
convenience modules should only be used in (local) perl scripts and not
in CPAN modules, so please do not add additional dependencies on
modules/pragmas like <a
href="https://metacpan.org/pod/sanity">sanity</a>, <a
href="https://metacpan.org/pod/Modern::Perl">Modern::Perl</a>,
common::sense, <a href="https://metacpan.org/pod/exact">exact</a>, or <a
href="https://metacpan.org/pod/nonsense">nonsense</a>.</p>
<p>However useful they might be in your own working environment and
force you into behaving well, adding them as a requirement to a CPAN
module will increase the complexity of the requirements to probably no
good use, as they are unlikely to be found on all your targeted systems
and add a chance to break.</p>
<p>There is no problem with you using those in your own (non-CPAN)
scripts and modules, but please do not add needless dependencies.</p>
<p><a href="https://metacpan.org/pod/Test::Prereq">Test::Prereq</a> is a
fine module to test your dependencies, but please do not ship it in a
test-file on <code>t/</code>.</p>
<p>Finally, make sure all your dependencies are declared in your META
structure, so all CPAN clients know what to do before your module can be
tested. META files are preferably <em>not</em> created manually, but
generated by authoring tools like <a
href="https://metacpan.org/pod/ExtUtils::MakeMaker">ExtUtils::MakeMaker</a>,
<a href="https://metacpan.org/pod/Dist::Zilla">Dist::Zilla</a>, or <a
href="https://metacpan.org/pod/App::ModuleBuildTiny">App::ModuleBuildTiny</a>
etc.</p>
<pre><code> "prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"perl" : "5.006",
"Test::More" : "0.88"
}
}
}</code></pre>
<h1 id="license">License</h1>
<p>Make a clear statement about your license. (or choose a default, but
at least state it).</p>
<p>Some target areas require a license in order to allow a CPAN module
to be installed.</p>
<p>Be very careful in choosing dependencies that have a different
license than your own distribution. However useful a module might be, if
it has a more restrictive license than your distribution, it may be off
limits to some users. That would mean that your distribution cannot be
used either.</p>
<p>The reverse is also true: if your release has a more restrictive
license than most releases on CPAN, it may lead to others avoiding
depending on your code.</p>
<p>Does code (even part of the code from a patch, or a snippet that you
have used) is based on other software, does that software have a
compatible license?</p>
<p>Does code (even part of the code from a patch or snippet that you
have used) is AI-generated, then is it compatible with your license?
(see e.g. <a
href="https://book.servo.org/contributing.html#ai-contributions">AI note
in the Servo project</a>)</p>
<p>The perl/perl_5 license is a reasonable default if you do not have a
preferred license.</p>
<h1 id="legal-issues">Legal issues</h1>
<p>Do not release illegal code, not even in examples: do not release a
webscraper for a site that strictly forbids that. (unless you have a
written stement that your module is allowed to do so).</p>
<p>Remember laws in the US are different than in the EU of Asian
countries. Your module may be legal in Japan, but illegal in the EU,
where <a
href="https://digital-strategy.ec.europa.eu/en/policies/nis2-directive">NIS2</a>,
<a
href="https://digital-strategy.ec.europa.eu/en/policies/cybersecurity-act">CSA</a>,
and <a
href="https://digital-strategy.ec.europa.eu/en/policies/cyber-resilience-act">CRA</a>
might cause you to ensure that the code is easy to update/upgrade and
that there is a full picture of the dependencies and any known issues in
those dependencies.</p>
<h1 id="documentation">Documentation</h1>
<p>Make sure that you have a clear, concise, and short SYNOPSIS section.
This section should show the most important code as simple and clear as
possible. If you have 3500 methods in your class, do not list all of
them there. Just show how to create the object and show the 4 methods
that a beginner would use. Note that the user that reads the manual will
appreciate complete, correct, and up-to-date documentation per method
more than a complete list of available methods in the SYNOPSIS.</p>
<p>Make sure your documentation covers all your methods and/or functions
and all edge cases are documented. If you have private functions,
mentions that in the documentation, so users can read that they might
disappear without warning. A special section about errors, error
messages, and/or exceptions is also a very nice thing to have.</p>
<p>Make sure your pod is correct and can also be parsed by the
pod-modules in the lowest version of perl you support (or mention that
you need at least version whatever to read the pod as intended).</p>
<p>The web is dynamic and some (external) references might cease to
exist not telling you, so checking links used in your documentation once
in a while might hint you to updated sites.</p>
<ul>
<li><a href="https://metacpan.org/pod/Test::Pod">Test::Pod</a></li>
<li><a
href="https://metacpan.org/pod/Test::Pod::Coverage">Test::Pod::Coverage</a></li>
<li><a
href="https://metacpan.org/pod/Test::Pod::Links">Test::Pod::Links</a></li>
</ul>
<h1 id="neutrality">Neutrality</h1>
<p>Do not use offensive or political statements anywhere in your code,
your documentation, or your changelog(s). No one gains from statements
about certain operating system(s), editor(s), president(s) or whatever
are not to your liking. Make neutral claims about not being able to test
your module on system X instead of saying system X should die a horrible
death.</p>
<p>Do not use profane language. Do not promote any deity. A religion to
one might be an insult to others. Stay neutral.</p>
<h1 id="spelling">Spelling</h1>
<p>Not every developer is of native English tongue. And even if, they
also make (spelling) mistakes. There are enough tools available to
prevent public display of mispellings and typos. Use them.</p>
<p>It is a good plan to have someone else proofread your documentation.
If you can, ask three readers: one who knows about what the module is
about, one who can be seen as an end-user of this modules without any
knowledge about the internals, and last someone who has no clue about
programming. You might be surprised of what they will find in the
documentation as weird, unclear, or even plain wrong.</p>
<ul>
<li><p><a href="scripts/pod-spell-check">pod-spell-check</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Pod::Spelling::Aspell">Pod::Spelling::Aspell</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Pod::Escapes">Pod::Escapes</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Pod::Parser">Pod::Parser</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Pod::Spell">Pod::Spell</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Pod::Spell::CommonMistakes">Pod::Spell::CommonMistakes</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Pod::Wordlist">Pod::Wordlist</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Test::Synopsis">Test::Synopsis</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Text::Aspell">Text::Aspell</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Text::Ispell">Text::Ispell</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Text::Wrap">Text::Wrap</a></p></li>
</ul>
<h1 id="examples">Examples</h1>
<p>Have examples of your code. Preferably both in the EXAMPLES section
of the pod, as in a folder named <code>examples</code>.</p>
<p>It is good practice to use your example code/scripts in your
documentation too, as that gives you a two-way check (additional to your
tests). Even better if the test scripts can be used as examples.</p>
<h1 id="test-coverage">Test coverage</h1>
<p>Do not just test what you think would be used. There <em>will</em> be
users that try to bend the rules and invent ways for your module to be
useful that you would never think of.</p>
<p>If every line of your code is tested, not only do you prevent
unexpected breakage, but you also make sure that most corner cases are
tested. Besides that, it will probably confront you with questions like
“What can I possibly do to get into this part of my code?”, Which may
lead to optimizations and other fun.</p>
<ul>
<li><a
href="https://metacpan.org/pod/Devel::Cover">Devel::Cover</a></li>
<li><a
href="https://metacpan.org/pod/Test::TestCoverage">Test::TestCoverage</a></li>
</ul>
<p>Remove dead code. It is in your (git) repository anyway.</p>
<ul>
<li><a
href="https://metacpan.org/pod/Perl::Critic::TooMuchCode">Perl::Critic::TooMuchCode</a></li>
</ul>
<h1 id="version-coverage">Version coverage</h1>
<p>This is a hard one. If your release/dist requires specific versions
of other modules, try to create an environment where you test your
distribution against the required version <em>and</em> a version that
does not meet the minimum version.</p>
<p>If your module requires Foo::Bar 0.123 because it added support for
correct UTF-8 encoding/decoding, and you wrote a test for that, your
release is apt to fail in an environment where Foo::Bar 0.023 is
installed.</p>
<p>This gets really hard to set up if your release has different code
for versions of perl and for versions of required modules, but it pays
off eventually. Note that monitoring <a
href="http://www.cpantesters.org">CPANTESTERS</a> can be a huge
help.</p>
<p>TODO: CI integration. Travis is dead. Please add something about
alternatives. Deprecated documentation: If your code resides on <a
href="https://github.com/">GitHub</a>, you can set up hooks to <a
href="https://travis-ci.org/">Travis CI</a>. Just compose a <a
href="./.travis.yml">.travis.yml</a> and enable the hook. This supports
a variety of perl versions and an environment where you can install
modules for just the tests you need.</p>
<h1 id="minimal-perl-support">Minimal perl support</h1>
<p>Your Makefile.PL (or whatever initial file the build system you use
requires) will have to state a minimal supported perl version that ends
up in <a href="./META.json">META.json</a> and <a
href="./META.yml">META.yml</a></p>
<p>Do not guess. It is easy to check with</p>
<ul>
<li><a
href="https://metacpan.org/pod/Test::MinimumVersion">Test::MinimumVersion</a></li>
<li><a
href="https://metacpan.org/pod/Test::MinimumVersion::Fast">Test::MinimumVersion::Fast</a>.</li>
<li><a
href="https://metacpan.org/release/Perl-MinimumVersion">Perl::MinimumVersion</a>
comes with the <a
href="https://metacpan.org/pod/distribution/Perl-MinimumVersion/script/perlver">perlver</a>
tool:</li>
</ul>
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> perlver <span class="at">--blame</span> test.pl</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">--------------------------------------------------</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">File</span> : test.pl</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">Line</span> : 3</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">Char</span> : 14</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">Rule</span> : _perl_5010_operators</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a> <span class="ex">Version</span> : 5.010</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a> <span class="ex">--------------------------------------------------</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a> <span class="ex">//</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a> <span class="ex">--------------------------------------------------</span></span></code></pre></div>
<h1 id="multiple-perl-versions">Multiple perl versions</h1>
<p>If you host your perl code on github, you can integrate the services
of <a href="https://travis-ci.org">Travis</a>. Read <a
href="https://docs.travis-ci.com/user/languages/perl/">their
instructions</a> on how to set up for multiple perl versions and or
(environment) options.</p>
<p>If you have multiple perls installed on your system, test your module
or release with all of the versions that you claim to support before
doing the release. Best would be to test with a threaded perl and a
non-threaded perl. If you can test with a mixture of
<code>-Duselongdouble</code> and 32bit/64bit perls, that would be even
better.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> perl <span class="at">-wc</span> lib/Foo/Bar.pm</span></code></pre></div>
<ul>
<li><p><a
href="https://metacpan.org/pod/Module::Release">Module::Release</a></p></li>
<li><p><a href="./.releaserc">.releaserc</a></p></li>
</ul>
<p>Repeat this on as many architectures as you can (i586, x64, IA64,
PA-RISC, Sparc, PowerPC, …)</p>
<p>Repeat this on as many Operating Systems as you can (Linux, NetBSD,
OSX, HP-UX, Solaris, Windows, OpenVMS, AIX, …)</p>
<p>Testing against a <code>-Duselongdouble</code> compiled perl will
surface bad tests, e.g. tests that match against NVs like 2.1:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode perl"><code class="sourceCode perl"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a> <span class="fu">use</span> <span class="fu">Test::More</span>;</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a> <span class="kw">my</span> <span class="dt">$i</span> = <span class="dv">21000000000000001</span>;</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a> <span class="dt">$i</span> /= <span class="fl">10e15</span>;</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a> is (<span class="dt">$i</span>, <span class="fl">2.1</span>);</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a> done_testing;</span></code></pre></div>
<p>with <code>-Uuselongdouble</code>:</p>
<pre class="tap"><code> ok 1
1..1</code></pre>
<p>with <code>-Duselongdouble</code>:</p>
<pre class="tap"><code> not ok 1
# Failed test at -e line 1.
# got: '2.1000000000000001'
# expected: '2.1'
1..1
# Looks like you failed 1 test of 1.</code></pre>
<p>will show that 2.25 is probably a better choice that 2.1.</p>
<h1 id="xs">XS</h1>
<p>If you use XS, make sure you (try to) support the widest range of
perl versions. As using XS is quite often using more delicate areas of
perl and perl internals, it is especially important to test for both
threaded and unthreaded perl and - if supported - on operating systems
that have different linking procedures than Linux. AIX and Windows are
known to show deficiencies early.</p>
<ul>
<li><a href="https://metacpan.org/pod/Devel::PPPort">Devel::PPPort</a>
(most recent version)</li>
</ul>
<h1 id="leak-tests">Leak tests</h1>
<p>Your code allocates memory. Not only for the code itself, but also
for all data structures, a stack and other resources (modules you use or
require).</p>
<p>Creating circular references or (in XS) variables that do not get
freed will cause leaks. You might not notice in your tests, but if a
long running process hits leaks and crashes with out-of-memory after 4
days, that is a problem. Tracing memory leaks might be hard, but some
help is available</p>
<ul>
<li><a
href="https://metacpan.org/pod/Test::LeakTrace::Script">Test::LeakTrace::Script</a></li>
<li><a
href="https://metacpan.org/pod/Test::Valgrind">Test::Valgrind</a></li>
<li><a href="http://valgrind.org">valgrind</a></li>
</ul>
<p>If you have a perl available with ASAN (Address Sanitizer) enabled,
your may find corruptions during compilation.</p>
<h1 id="release-tests">Release tests</h1>
<p>Some see <a href="http://cpants.perl.org/">CPANTS</a> as a game, but
many of the tests it puts on your release have a reason. Before you
upload, you can check most of that to prevent unhappy users.</p>
<ul>
<li><a href="....">Test::Package</a> - planned</li>
<li><a
href="https://metacpan.org/pod/Test::Kwalitee">Test::Kwalitee</a></li>
<li><a
href="https://metacpan.org/pod/Module::CPANTS::Analyse">Module::CPANTS::Analyse</a></li>
<li><a
href="https://metacpan.org/pod/distribution/App-CPANTS-Lint/bin/cpants_lint.pl">cpants_lint.pl</a></li>
</ul>
<div class="sourceCode" id="cb13"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> perl Makefile.PL</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> make</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> make test</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> make dist</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> cpants_lint.pl Foo-Bar-0.01.tar.gz</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">Checked</span> dist: Foo-Bar-0.01.tar.gz</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a> <span class="ex">Score:</span> 144.44% <span class="er">(</span><span class="ex">26/18</span><span class="kw">)</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a> <span class="ex">Congratulations</span> for building a <span class="st">'perfect'</span> distribution!</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span></span></code></pre></div>
<p>Other than doing all these tests <em>before</em> you upload to CPAN,
there are some awesome metrics available on <a
href="https://cpants.cpanauthors.org/">cpants</a> that trigger
<em>after</em> you have uploaded to CPAN. <a
href="https://cpants.cpanauthors.org/">This</a> also shows more metrics
and has lots of good <a
href="https://cpants.cpanauthors.org/kwalitee">documentation for the
kwalitee indicators</a>.</p>
<h1 id="clean-dist">Clean dist</h1>
<p>Some problems only surface when you do a <code>make clean</code> or
<code>make distclean</code>. The develop cycle normally only adds and
changes files, and if you forget to add those to the MANIFEST, your
distribution will be incomplete and is likely to fail on other systems,
whereas your tests locally still keep passing.</p>
<p>Check <a href="./MANIFEST">MANIFEST</a> and <a
href="./MANIFEST.skip">MANIFEST.skip</a> are complete.</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> make dist</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> make distclean</span></code></pre></div>
<ul>
<li><a
href="https://metacpan.org/pod/Test::Manifest">Test::Manifest</a></li>
<li><a
href="https://metacpan.org/pod/Test::DistManifest">Test::DistManifest</a></li>
</ul>
<div class="sourceCode" id="cb15"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> perl <span class="at">-MTest::DistManifest</span> <span class="at">-we</span><span class="st">'manifest_ok'</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">1..4</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">ok</span> 1 <span class="at">-</span> Parse MANIFEST or equivalent</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">ok</span> 2 <span class="at">-</span> All files are listed in MANIFEST or skipped</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">ok</span> 3 <span class="at">-</span> All files listed in MANIFEST exist on disk</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">ok</span> 4 <span class="at">-</span> No files are in both MANIFEST and MANIFEST.SKIP</span></code></pre></div>
<h1 id="file-naming">File naming</h1>
<p>Do not make it hard for people and modules to use the files in your
distribution by using spaces and special characters in file names. Also
try to not use overly long names and deep directory structures.</p>
<p>If spaces or weird characters in file or folder names are required by
your module and/or your test cases, consider creating these files from
the test itself and cleaning them up when the test is done.</p>
<ul>
<li><a
href="https://metacpan.org/pod/Test::Portability::Files">Test::Portability::Files</a></li>
</ul>
<div class="sourceCode" id="cb16"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a> <span class="ex">$</span> perl <span class="at">-MTest::More</span> <span class="at">-MTest::Portability::Files</span> <span class="at">-w</span> <span class="dt">\</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a> <span class="at">-e</span> <span class="st">'options (all_tests => 1);'</span> <span class="dt">\</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a> <span class="at">-e</span> <span class="st">'options (test_dos_length => 0);'</span> <span class="dt">\</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-e</span> <span class="st">'run_tests ();'</span></span></code></pre></div>
<h1 id="code-style-consistency">Code style consistency</h1>
<p>Add a <a href="./CONTRIBUTING.md">CONTRIBUTING.md</a> or similar file
to guide others to consistency that will match <a
href="https://tux.nl/style.html"><em>your</em> style</a> (or, in case of
joint effort, the style as agreed upon by the developers).</p>
<p>There are helper modules to enforce a style (given a configuration)
or try to help contributors to come up with a path/change than matches
the project’s style and layout. Again: consistency helps. A lot.</p>
<ul>
<li><p><a
href="https://metacpan.org/pod/Perl::Tidy">Perl::Tidy</a></p></li>
<li><p><a href="https://metacpan.org/pod/Perl::Critic">Perl::Critic</a>
+ <a
href="https://metacpan.org/search?q=Perl%3A%3ACritic%3A%3A&search_type=modules">plugins</a>,
lot of choices</p></li>
<li><p><a
href="https://metacpan.org/pod/Test::Perl::Critic">Test::Perl::Critic</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Test::Perl::Critic::Policy">Test::Perl::Critic::Policy</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Test::TrailingSpace">Test::TrailingSpace</a></p></li>
<li><p><a
href="https://metacpan.org/pod/Perl::Lint">Perl::Lint</a></p></li>
<li><p><a href="./.perltidyrc">.perltidy</a></p></li>
<li><p><a href="./.perlcriticrc">.perlcritic</a></p></li>
</ul>
<p>This document should also describe what type of source is acceptable,
e.g. if AI generated code can be used.</p>
<h1 id="meta">META</h1>
<p>Make sure your meta-data matches the expected requirements. That can
be achieved by using a generator that produces conform the most recent
specifications or by using tools to check handcrafted META-files against
the <a
href="http://module-build.sourceforge.net/META-spec-v1.4.html">META spec
1.4 (2008)</a> or <a
href="http://module-build.sourceforge.net/META-spec-v2.0.html">META spec
2.0 (2011)</a>:</p>
<ul>
<li><a
href="https://metacpan.org/pod/CPAN::Meta::Converter">CPAN::Meta::Converter</a></li>
<li><a
href="https://metacpan.org/pod/CPAN::Meta::Validator">CPAN::Meta::Validator</a></li>
<li><a href="https://metacpan.org/pod/JSON::PP">JSON::PP</a></li>
<li><a
href="https://metacpan.org/pod/Parse::CPAN::Meta">Parse::CPAN::Meta</a></li>
<li><a
href="https://metacpan.org/pod/Test::CPAN::Meta::JSON">Test::CPAN::Meta::JSON</a></li>
<li><a
href="https://metacpan.org/pod/Test::CPAN::Meta::YAML">Test::CPAN::Meta::YAML</a></li>
<li><a
href="https://metacpan.org/pod/Test::CPAN::Meta::YAML::Version">Test::CPAN::Meta::YAML::Version</a></li>
<li><a href="https://metacpan.org/pod/YAML::Syck">YAML::Syck</a></li>
</ul>
<p>It is highly appreciated if you declare <a
href="https://metacpan.org/pod/CPAN::Meta::Spec#resources">resources</a>,
like your public repository URL and the preferred way to communicate in
your <a href="./META.json">META.json</a>:</p>
<pre><code> "resources" : {
"x_IRC" : "irc://irc.perl.org/#toolchain",
"repository" : {
"type" : "git",
"url" : "https://github.com/Tux/Release-Checklist",
"web" : "https://github.com/Tux/Release-Checklist"
},
"bugtracker" : {
"web" : "https://github.com/Tux/Release-Checklist/issues"
}
}</code></pre>
<p>Those are recognized and shown in the top-left section on <a
href="https://metacpan.org/pod/Release::Checklist">meta::cpan</a>.</p>
<h1 id="versions">Versions</h1>
<p>Use a sane versioning system that the rest of the world might
understand. Do not use the MD5 of the current date and time related to
the phase of the moon or versions that include quotes or spaces. Keep it
simple and clear.</p>
<ul>
<li><a
href="https://metacpan.org/pod/Test::Version">Test::Version</a></li>
</ul>
<p>Make sure it is a versioning system that increments</p>
<ul>
<li><a
href="https://metacpan.org/pod/Test::GreaterVersion">Test::GreaterVersion</a></li>
</ul>
<h1 id="readme-readme.md">README / README.md</h1>
<p>Add a <a href="./README.md">file</a> that states the purpose of your
distribution.</p>
<p>The README should state the purpose, the minimal envirenment to test,
build, and run and possible license issue. If there is a need to amend
or create configuration files or set up databases, that should be
mentioned too.</p>
<ul>
<li><a
href="https://metacpan.org/pod/Text::Markdown">Text::Markdown</a></li>
</ul>
<h1 id="changes">Changes</h1>
<p>Make sure your <a href="./Changes">Changes</a> or ChangeLog file is
up-to-date. Your release procedure might check the most recent mentioned
date in that. At least every release should have an entry. Put the most
recent change(s) on top (sort in reverse date order), so people can
easily spot the most recent change(s).</p>
<ul>
<li><a href="https://metacpan.org/pod/Date::Calc">Date::Calc</a></li>
<li><a
href="https://metacpan.org/pod/Test::CPAN::Changes">Test::CPAN::Changes</a></li>
<li><a
href="https://metacpan.org/pod/CPAN::Changes::Spec">CPAN::Changes::Spec</a></li>
</ul>
<h1 id="performance">Performance</h1>
<p>Check if your release matches previous performance (if
appropriate)</p>
<ul>
<li>between different versions of perl</li>
<li>between different versions of the module</li>
<li>between different versions of dependencies</li>
</ul>
<h1 id="tickets">Tickets</h1>
<p>If your module is on <a href="https://github.com">github</a> or
similar, regularly check on submitted issues and deal with them: either
explain why it is not an issue or comment with alternatives or even
better: this has been fixed now. Additionally, you should check on
possible forks of your code and check the commits in that fork. There
are people that make very interesting changes that you could use to
improve your code. If the changes they made are already taken into your
own code, or your code offers a (better) alternative to their change you
could comment on their commits with additional information.</p>
<p>Likewise if you use <a href="https://rt.cpan.org">RT</a> as bug
tracker.</p>
<p>If any ticket is entered as a vulnerability issue, be sure to make
clear in the feedback to that issue that it is indeed a security issue
and how you dealt with it or that you do/did not acknowledge this as a
vulnerability, but as a (plain/simple) bug and deal with at with the
appropriate actions.</p>
<p>Whatever you choose, make it clear in your META information, so the
link to issues on <a href="https://metacpan.org/">metacpan</a> points to
the correct location.</p>
<pre><code> META.yml
---
resources:
bugtracker: https://github.com/Tux/Release-Checklist/issues</code></pre>
<pre><code> META.json
---
"resources" : {
"bugtracker" : {
"web" : "https://github.com/Tux/Release-Checklist/issues"
}
}</code></pre>
<h1 id="cves">CVE’s</h1>
<p>The <a href="https://www.cve.org">Common Vulnerabilities and
Exposures (CVE)</a> Program’s primary purpose is to uniquely identify
vulnerabilities and to associate specific versions of code bases (e.g.,
software and shared libraries) to those vulnerabilities. The use of CVEs
ensures that two or more parties can confidently refer to a CVE
identifier (ID) when discussing or sharing information about a unique
vulnerability. For detailed information regarding CVE please refer to <a
href="https://cve.mitre.org/">CNA</a> <a
href="https://cve.mitre.org/cve/cna/CNA_Rules_v1.1.pdf">CNA CVE Counting
rules</a>.</p>
<p>In order to find a specific CVE that is known for your environment,
you can visit the <a href="https://nvd.nist.gov/vuln">NVD database</a>
and <a href="https://nvd.nist.gov/vuln/search">search for
keywords</a>.</p>
<p>Modules might help you in finding (releated) CVE’s and
vulnerabilities:</p>
<ul>
<li><a href="https://metacpan.org/pod/CPAN::Audit">CPAN::Audit</a></li>
<li><a href="https://metacpan.org/pod/Test::CVE">Test::CVE</a></li>
<li><a
href="https://metacpan.org/pod/App::CveClient">App::CveClient</a></li>
</ul>
<p><a href="http://metacpan.org/">MetaCPAN</a> also provides CVE
information per release in JSON but it is still work in progress,
e.g.:</p>
<p>https://fastapi.metacpan.org/cve/Release-Checklist-0.18</p>
<p>While you are at it, also consider adding F<SECURITY.md> where
you declare how vulnerabilities in your own release are to be
reported.</p>
<ul>
<li><a
href="https://metacpan.org/pod/Software::Security::Policy::Individual">Software::Security::Policy::Individual</a></li>
</ul>
<h1 id="downriver">Downriver</h1>
<p>Please read <a
href="https://neilb.org/2015/04/20/river-of-cpan.html">The River of
CPAN</a> to understand the concept of upstream and downstream vs upriver
and downriver.</p>
<p>You have had reasons to make the changes leading up to a new
distribution. If you really care about the users of your module, you
should check if your new release would break any of the CPAN modules
that (indirectly) depend on your module by testing with your previous
release and your upcoming release and see if the new release would cause
the other module(s) to break. Have good tests for your API (the stable
parts) to prevent yourself from pushing unsuspected changes.</p>
<p><a href="./scripts/used-by.pl">used_by.pl</a> will check the
depending modules with the upcoming version.</p>
<p>Of course it is impossible to cover every possible situation here.
The DarkPAN (uses of your module beyond what is registered on CPAN) is
huge.</p>
<h1 id="license-1">LICENSE</h1>
<p>Copyright (C) 2015-2026 H.Merijn Brand. All rights reserved.</p>
<p>This library is free software; you can redistribute and/or modify it
under the same terms as Perl itself.</p>
</body></html>