Distribution Guide

Build and distribute production-ready plugins with WPZylos.

Build Pipeline

WPZylos plugins use PHP-Scoper for namespace isolation in production.

Install PHP-Scoper

composer require --dev humbug/php-scoper

Configure Scoper

<?php
// scoper.inc.php

declare(strict_types=1);

use Isolated\Symfony\Component\Finder\Finder;

$polyfillsBootstraps = array_map(
    static fn (SplFileInfo $fileInfo) => $fileInfo->getPathname(),
    iterator_to_array(
        Finder::create()
            ->files()
            ->in(__DIR__ . '/vendor/symfony/polyfill-*')
            ->name('bootstrap*.php'),
        false
    )
);

return [
    'prefix' => 'VendorPrefix',

    'finders' => [
        Finder::create()->files()->in('src'),
        Finder::create()
            ->files()
            ->ignoreVCS(true)
            ->notName('/LICENSE|.*\\.md|.*\\.dist|Makefile|composer\\.json|composer\\.lock/')
            ->in('vendor'),
    ],

    'exclude-namespaces' => [
        'WPZylos',
        'Psr',
        'Symfony\Polyfill',
    ],

    'exclude-files' => [
        ...$polyfillsBootstraps,
    ],

    'expose-global-constants' => true,
    'expose-global-classes' => true,
    'expose-global-functions' => true,
];

Build Script

#!/bin/bash
# build.sh

set -e

VERSION=${1:-"1.0.0"}
PLUGIN_SLUG="my-plugin"

echo "Building ${PLUGIN_SLUG} v${VERSION}..."

# Clean
rm -rf dist build

# Install production dependencies
composer install --no-dev --optimize-autoloader

# Run PHP-Scoper
vendor/bin/php-scoper add-prefix --output-dir=build --force

# Dump optimized autoloader for scoped build
cd build
composer dump-autoload --classmap-authoritative --no-dev
cd ..

# Create distribution directory
mkdir -p dist/${PLUGIN_SLUG}

# Copy required files
cp -r build/src dist/${PLUGIN_SLUG}/
cp -r build/vendor dist/${PLUGIN_SLUG}/
cp -r config dist/${PLUGIN_SLUG}/
cp -r resources dist/${PLUGIN_SLUG}/
cp -r languages dist/${PLUGIN_SLUG}/
cp ${PLUGIN_SLUG}.php dist/${PLUGIN_SLUG}/
cp README.txt dist/${PLUGIN_SLUG}/
cp LICENSE dist/${PLUGIN_SLUG}/

# Create ZIP
cd dist
zip -r ${PLUGIN_SLUG}-${VERSION}.zip ${PLUGIN_SLUG}
cd ..

echo "Build complete: dist/${PLUGIN_SLUG}-${VERSION}.zip"

CI Build

# .github/workflows/build.yml
build:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4

    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: "8.0"

    - name: Install dependencies
      run: composer install

    - name: Build
      run: bash build.sh ${{ github.ref_name }}

    - name: Upload artifact
      uses: actions/upload-artifact@v3
      with:
        name: plugin-zip
        path: dist/*.zip

WordPress.org Submission

Prepare readme.txt

=== My Plugin ===
Contributors: yourname
Tags: plugin, wordpress
Requires at least: 6.0
Tested up to: 6.4
Stable tag: 1.0.0
Requires PHP: 8.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Short description here (150 characters max).

== Description ==

Full description of what your plugin does.

== Installation ==

1. Upload the plugin files to `/wp-content/plugins/my-plugin/`
2. Activate the plugin through the 'Plugins' screen in WordPress
3. Configure at Settings → My Plugin

== Changelog ==

= 1.0.0 =
* Initial release

Submission Checklist

  • No PHP-Scoper prefix conflicts with WordPress core
  • All text is properly internationalized
  • No hardcoded URLs (use WordPress functions)
  • Assets load from plugin directory
  • readme.txt follows WordPress.org format
  • Screenshot images under 1MB
  • GPL-compatible license
  • No external service calls without disclosure

CodeCanyon / ThemeForest Submission

Additional Requirements

  • Envato licensing integration
  • Documentation (PDF or online)
  • Demo content/import
  • Support ticket system reference

Package Structure

upload/
+-- my-plugin/
|   +-- ... (plugin files)
+-- documentation/
|   +-- index.html
|   +-- assets/
+-- licensing-guide.pdf

Version Management

Semantic Versioning

MAJOR.MINOR.PATCH
  • MAJOR: Breaking API changes
  • MINOR: New features, backward compatible
  • PATCH: Bug fixes, backward compatible

Update Version

Update in multiple locations:

  1. my-plugin.php (Plugin header)
  2. composer.json
  3. PluginContext constructor
  4. readme.txt (Stable tag)
  5. CHANGELOG.md

Changelog

Maintain a CHANGELOG.md:

# Changelog

## [1.1.0] - 2024-02-15

### Added

- New feature X
- Support for Y

### Fixed

- Bug in Z component

### Changed

- Improved performance of W

## [1.0.0] - 2024-01-01

### Added

- Initial release