Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Validating a package before publishing

The checks to run on a site package before it goes to the package server, in order, from xmllint and a look inside the archive to ezpm.php validate, the Validate button on the package page and the upload inspector of…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/site-packages/requirements/validating-a-package-before-publishing.md

On this page

Validating a package before publishing

This page is for developers and reviewers who check a site package before it is published. A version on the package server is used by every installation that reads its index, so a broken package fails for everyone at once. Each check below catches something the others miss; run them in this order, from the cheapest to the one that needs a test installation.

Contents

  1. The checks at a glance
  2. Check the definition with xmllint
  3. Look inside the archive
  4. Run ezpm validate
  5. Upload it to a test installation
  6. The Validate button
  7. What no check covers
  8. Related pages

The checks at a glance

CheckNeedsCatches
xmllint --noout package.xmlNothing but the fileXML that is not well formed
tar -tzf and find -type lThe archive and the source folderWrong layout, links, files that should not be there
php ezpm.php validateAn Exponential installation, from the shellThe definition as the kernel reads it, the name, missing documents
Upload on package/uploadA test installation and the package/import policyEverything the upload inspector checks
A fresh installA sandboxDependencies, install scripts, the site itself

Check the definition with xmllint

xmllint --noout packages/example_site/package.xml && echo well-formed

No output from xmllint means the document is well formed. All 16 package.xml files of the two 7x source repositories and the 6.0.15 index.xml pass this check (2026-10-18). It says nothing about the content: an empty <name> is well formed.

Look inside the archive

tar -tzf example_site.ezpkg | head -20
find packages/example_site -type l

What to see, and why:

  • To do: package.xml as the plain entry package.xml, not inside a folder: the import looks for an entry of exactly that name (eZPackage::importUnaudited()). packages/build.sh runs tar from inside each package folder over *, which gives this layout.
  • To do: Only the directories the package uses: documents/, files/, settings/, simplefiles/ and the sub-directories of its install items (ezcontentclass/, ezcontentobject/, ezextension/).
  • To do: No .git, .DS_Store, editor backups or node_modules: build.sh leaves them out with its EXCLUDES list.
  • To do: find -type l prints nothing. A link to a file of the package is imported as a copy of it, but a link out of the package, to a directory or to nothing, a device or a fifo is left out with a notice (link_outside, link_directory, link_missing, special_file), so what the package needs is missing; an entry with .. or an absolute path makes every import refuse the package (unsafe_path).

Warning

Files at the top of a package next to package.xml survive build.sh, which archives the whole folder, but not an export from the administration or ezpm.php export: eZPackage::exportToArchive() copies only the definition, documents/, files/, simplefiles/, settings/ and the install items' sub-directories. cjw_multisite_democontent keeps four files at its top (cjw-class-additions.xml, cjw-explayouts.json, cjw-paths.json, cjw-starter-import.json), so it must be rebuilt from its source folder, never re-exported.

Run ezpm validate

ezpm.php at the project root has a validate command (kernel/private/classes/commands/ezpm.php). It takes an archive, a package directory or the name of an imported package, and imports nothing:

php ezpm.php validate var/tmp/example_site.ezpkg
php ezpm.php validate packages/example_site
php ezpm.php help validate

It runs expPackageJson::validateDirectory() (kernel/classes/exppackagejson.php), which checks:

  • that there is a package.xml or package.json;
  • every document as XML, and in the JSON format against share/package/schema/package-v1.json and the SHA-256 checksums of package.json;
  • the definition as the kernel reads it (eZPackage::parseDOMTree()): a name, plain version and type tokens;
  • the name with eZPackage::isValidName();
  • that every document an install item names (<sub-directory>/<filename>.xml, and the object files of content items) is in the package.

It ends with PASS <name> (xml): N documents, M files, or prints one error line per problem and FAIL <source>: N error(s) with exit code 1, so it can stop a build script. An archive is extracted into a private work directory first, refusing unsafe entries the same way an import does, and the directory is removed afterwards.

Note

validate does not run the upload inspector's checks of the file name, the gzip signature, the size limits or the <ezpublish> and <packaging> elements. The upload below does.

Upload it to a test installation

package/upload in the administration is the strictest door (Packages guide, uploading). Before anything is extracted, eZPackageUploadInspector::inspect() checks, in this order: a file was sent; its name ends in an allowed suffix; it is not larger than MaxArchiveSize; it starts with the gzip signature; every entry is safe and within MaxEntries and MaxUnpackedSize; there is a package.xml or package.json at the top, at most 16 MiB; the definition has a <package> root without DOCTYPE, a valid name, <ezpublish>, <packaging> and a usable vendor. Then it runs the same validateDirectory() as ezpm.php validate and shows the first 20 errors.

The messages are the ones in eZPackageUploadInspector::message(), such as "The package.xml of the archive lacks its version or packaging information". The limits are in settings/package.ini [UploadSettings].

Use a test installation: an upload imports the package for real, and the same name cannot be imported twice. To try again, remove the package on its page first.

The Validate button

An imported package's page (package/view/full/<name>) has a Validate button. It runs validateDirectory() on the package as it lies in the repository and shows the result on the page until the next action on the package. It is the quickest way to check a package that was imported by the setup wizard, which does not validate.

What no check covers

None of the checks above reads the meaning of a package. These are left to a test install and to review:

  • whether every <require> can be found and is new enough (Declaring dependencies);
  • whether every <settings-file> exists (a missing one is skipped silently by the create sites step);
  • whether the install scripts run on the database engines you support;
  • whether the md5sum attributes match their files;
  • whether the license, the changelog and the thumbnail are there and right.

Run a full install in a sandbox before publishing: Testing in a sandbox.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x