NAME
App::prepare4release - prepare a Perl distribution for release (skeleton)
SYNOPSIS
use App::prepare4release;
App::prepare4release->run(@ARGV);
DESCRIPTION
Run from the distribution root (where prepare4release.json and Makefile.PL live). The tool:
Loads prepare4release.json and resolves
module_name/version/dist_namewhen omitted (from Makefile.PL and the main .pm).Patches Makefile.PL:
META_MERGE(repositoryandbugtrackerURLs), and a markedMY::postambleblock (between# BEGIN PREPARE4RELEASE_POSTAMBLEand# END PREPARE4RELEASE_POSTAMBLE) that runspod2githubwhen--githubor--gitlabwas used (elsepod2markdown), then maint/inject-readme-badges.pl (a standalone Perl script regenerated each run, core modules only) somake README.mdreapplies the same shields without depending onApp::prepare4release. The block is refreshed on each run to match the currentpod2*choice; the script embeds the frozen badge Markdown for the chosen--github/--gitlab/--cpanflags.When
--githubor--gitlabis set, ensures CI workflow files exist (see "Continuous integration").Regenerates README.md from the VERSION_FROM module (
make README.mdwhen Makefile exists, otherwisepod2githuborpod2markdown), then injects Markdown shield lines ([](link)) into README.md after the first title block (runs of#headings) or before# NAMEwhen that is the first heading. The Makefile.PL postamble runs maint/inject-readme-badges.pl afterpod2github/pod2markdownso badges stay in sync without a runtime dependency on this distribution. Strips any legacy badge block from POD after__END__. License and minimum Perl badges are always added; with--cpan, also Repology, CPAN version, and cpants. The GitHub Actions CI badge is added only with--github; the GitLab pipeline badge only with--gitlab(host fromgit.server, else fromgit.repoURL, elsegitlab.com). License shield (always blue) uses the same key as ExtUtils::MakeMaker (Makefile.PLLICENSE), or the type inferred from a root LICENSE file when present; the link is the repository LICENSE blob when that file exists and--githubor--gitlabis set (branch fromgit.default_branch, defaultmain), otherwise the usual canonical license URL. Minimum Perl on the shield comes frommin_perl_version/perl_minin the JSON file, else Makefile.PLMIN_PERL_VERSION, else the stricter of makefile and main module (as for CI).Creates author tests under xt/author/ when missing:
pod.t(Test::Pod),eol.t(Test::EOL),pod-coverage.t(Test::Pod::Coverage), using Test2::V1.With
--cpan, after the steps above: ensures LICENSE exists. The license type is taken from Makefile.PLLICENSE(via the same snippet scan as elsewhere in this tool); if that is missing, perl (same terms as Perl 5) is assumed. The file text is downloaded from official upstream sources (forperl, the Artistic and Copying files from the Perl 5 repository; forapache_2,mit,gpl_3, etc., the canonical license URLs). If a fetch fails, a short built-in fallback is written. If README is missing but README.md exists, writes a short stub README pointing readers to README.md. Creates a default MANIFEST.SKIP when none is present (skipping blib/, cover_db/, nytprof/, tarballs, .git/, etc.); runsperl Makefile.PL, copies MYMETA.* to META.*, andmake manifestso MANIFEST matches the tree for CPAN packaging.Warns when any t/*.t or xt/**/*.t file starts with
use Test::Moreoruse Test::Most(legacy assertion frameworks). Prefer Test2::V1 or Test2::Tools::Spec.
README badge injector (maint/inject-readme-badges.pl)
The MY::postamble fragment cannot hold large, self-contained Perl subs: ExtUtils::MakeMaker expects that section to expand into Makefile rules, and keeping badge logic only in Makefile.PL would either duplicate a lot of text or imply loading this distribution at make README.md time. Instead, prepare4release writes maint/inject-readme-badges.pl, a small, generated program (core modules only) that strips prior shield lines and inserts the frozen Markdown block computed on the last run (same flags as --github / --gitlab / --cpan). Downstream distributions should commit that file with the rest of the tree so make README.md works in a clean clone and the file is included in the CPAN tarball like any other tracked asset. Re-run prepare4release after changing repository URLs, license, or badge-related options so the script and README.md stay consistent. No runtime dependency on App::prepare4release is added to the target module.
CONFIGURATION FILE
File name: prepare4release.json (in the distribution root).
An empty file or whitespace-only file is treated as an empty JSON object {}.
module_name-
Optional. Perl package (e.g.
My::Module). If omitted, taken from theVERSION_FROMmodule'spackageline, fromNAMEin Makefile.PL, or from the firstlib/**/*.pmfile. version-
Optional. If omitted, taken from
$VERSIONin the resolved main module file. dist_name-
Optional. Defaults to
module_namewith::replaced by hyphens. min_perl_version-
Optional. Minimum Perl version string for the README
Perlbadge (e.g.5.026orv5.26.0). If omitted,MIN_PERL_VERSIONfrom Makefile.PL is used, then the combined makefile/module heuristic. perl_min-
Optional alias for
min_perl_version. bugtracker-
Optional bugtracker URL. If omitted, it is built as
<repository web>/issuesfor the selected git host. git-
Object (optional) with:
-
Required for
--githubor--gitlabunlessgit.repois a namespace path (group/project) or a repository URL. Otherwise required to build repository URLs whengit.repois only a short name or omitted. repo-
Repository name,
namespace/projectpath, orhttps://.../git@...URL. If omitted, defaults toperl-plusmodule_namewith::replaced by hyphens. server-
Optional hostname (e.g.
gitlab.example.com) forhttps://links instead ofgithub.com/gitlab.com. default_branch-
Optional branch name for LICENSE blob links in the README badge (default
main).
-
ci-
Optional object:
apt_packages-
Array of Debian package names (e.g.
libssl-dev) appended to the generated GitHub Actions and GitLab CIapt-get installsteps. System libraries are not inferrable reliably from CPAN metadata alone; list them here when XS orAlien::*needs OS packages.
Continuous integration
When --github is set, if .github/workflows/ci.yml does not exist it is created. It runs prove -lr t on an Ubuntu runner using https://github.com/shogo82148/actions-setup-perl|shogo82148/actions-setup-perl, with a matrix of stable Perl releases from the stricter of Makefile.PL MIN_PERL_VERSION and the main module's use v5... / use 5... line, up to the latest stable Perl.
The ceiling is resolved at each run via the MetaCPAN FastAPI GET /v1/release/perl (latest perl distribution release). The previous release/_search sort=version:desc query could return ancient tarballs because Elasticsearch sort is not Perl version order. If the request fails, a fallback (currently 5.40) is used. Override for tests or air-gapped use:
PREPARE4RELEASE_PERL_MAX=5.40 prepare4release ...
Matrix entries use even minor versions only (5.10, 5.12, …) between the computed minimum and maximum.
When --gitlab is set, if .gitlab-ci.yml is missing it is created with a parallel.matrix over PERL_VERSION and the official perl Docker image.
Existing workflow files are never overwritten.
System dependencies (apt)
There is no robust automatic mapping from CPAN modules to Debian packages. The tool scans Makefile.PL, cpanfile, and Build.PL for Alien::... names and, with --verbose, warns so you can add ci.apt_packages manually.
ENVIRONMENT
PREPARE4RELEASE_PERL_MAX-
If set, used as the matrix ceiling instead of querying MetaCPAN (useful for CI of this tool or offline work).
RELEASE_TESTING-
If set to a true value, author tests under xt/ may run (see xt/metacpan-live.t for a live MetaCPAN request that validates
fetch_latest_perl_release_version).
COPYRIGHT AND LICENSE
Copyright (C) by the authors.
Same terms as Perl 5 itself.