PHPackages                             publishpress/dev-workspace - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. publishpress/dev-workspace

ActiveComposer-plugin[Utility &amp; Helpers](/categories/utility)

publishpress/dev-workspace
==========================

Shared Composer scripts for PublishPress plugins

1.4.2(1mo ago)11.0k↑186%[1 issues](https://github.com/publishpress/library-dev-workspace/issues)1GPL-2.0-or-laterShellPHP &gt;=7.4CI failing

Since Apr 1Pushed 2w agoCompare

[ Source](https://github.com/publishpress/library-dev-workspace)[ Packagist](https://packagist.org/packages/publishpress/dev-workspace)[ RSS](/packages/publishpress-dev-workspace/feed)WikiDiscussions development Synced 4w ago

READMEChangelog (10)Dependencies (34)Versions (41)Used By (1)

PublishPress Dev Workspace
==========================

[](#publishpress-dev-workspace)

Shared development tooling for PublishPress WordPress plugins. This Composer package exposes scripts for building, testing, translating, syncing, and quality checks — all managed through standard `composer` commands.

What it provides
----------------

[](#what-it-provides)

- **Docker** — Compose setup for local development and automated tests
- **Build &amp; pack** — JavaScript (webpack), zip/dir packaging, version helpers
- **Quality** — PHP compatibility, PHPCS, phplint, PHPStan, PHP-CS-Fixer
- **Tests** — Codeception workflows and Docker test stack helpers
- **i18n** — POT/MO/JSON/PHP translation pipelines and PublishPress Translate hooks (JSON uses Jed `locale_data` via `@connectedcars/po2json` bundled in this package; plugins do not need their own `package.json`)
- **Sync** — Optional rsync to local or remote WordPress installs

Installing in a plugin
----------------------

[](#installing-in-a-plugin)

This package is a [Composer plugin](https://getcomposer.org/doc/articles/plugins.md), so it must be explicitly allowed in `config.allow-plugins` before Composer will activate it.

Add the following to the plugin's `composer.json` first, then run `composer update`:

```
{
    "require-dev": {
        "publishpress/dev-workspace": "^1.0"
    },
    "config": {
        "allow-plugins": {
            "publishpress/dev-workspace": true,
            "php-http/discovery": true,
            "dealerdirect/phpcodesniffer-composer-installer": true,
            "phpstan/extension-installer": true
        }
    }
}
```

Once installed, all shared scripts become available through `composer`. For example:

```
composer build
composer test:up
composer check:all
```

If the plugin already defined those commands under `scripts` in its own `composer.json`, remove them. Names such as `build`, `check:php`, `check:all`, `test:up`, and the other shared workflows are registered by this package; keeping copies in the plugin would shadow or duplicate what the workspace provides.

If the project root still has a `dev-workspace` file delete it entirely. Tooling is installed under `vendor/publishpress/dev-workspace`; leaving the old path in place can confuse editors, scripts, or sync rules that treat `dev-workspace` as a separate tree.

### GitHub authentication

[](#github-authentication)

Composer fetches package metadata from GitHub's API. The unauthenticated rate limit (60 requests/hour) is exhausted quickly, and **Pro plugins require a token anyway because they reference private GitHub repositories**.

Without a token you will see an error like:

```
GitHub API limit (60 calls/hr) is exhausted, could not fetch https://api.github.com/repos/...
You need to provide a GitHub access token.

```

**Create a token**

1. Go to [github.com/settings/tokens](https://github.com/settings/tokens) and generate a **classic** personal access token (or a fine-grained token scoped to the relevant repositories).
2. Grant it the **`repo`** scope so it can read private repositories.
3. Use short expiration times and only the minimum permissions necessary.

**Configure Composer to use the token**

The auth file location depends on where you are running `composer`:

- **On your host machine** — `~/.composer/auth.json`
- **Inside the dev container** (`composer dev:shell`) — `${CACHE_PATH}/.composer/auth.json`, where `CACHE_PATH` is the value set in your `.env` file (defaults to `dev-workspace-cache` at the project root)

In both cases the file must contain:

```
{
    "github-oauth": {
        "github.com": "ghp_YourPersonalAccessTokenHere"
    }
}
```

The `CACHE_PATH` directory is mounted into the container, so a token saved there persists across container restarts without needing to be re-added.

After saving the file, re-run `composer update` and the rate-limit error should be gone.

### Remove duplicate Composer dependencies

[](#remove-duplicate-composer-dependencies)

This package already **requires** the shared QA and test stack. After adding `publishpress/dev-workspace`, drop the same packages from the plugin’s own `require-dev` (and from `require` if they were only there for tooling) so you do not pin conflicting versions or install duplicates. Typical overlaps include:

- **PHPCS ecosystem** — `squizlabs/php_codesniffer`, `dealerdirect/phpcodesniffer-composer-installer`, `wp-coding-standards/wpcs`, `automattic/vipwpcs`, `phpcompatibility/php-compatibility`, `publishpress/publishpress-phpcs-standards`
- **Static analysis and fixes** — `phpstan/phpstan`, `phpstan/extension-installer`, `szepeviktor/phpstan-wordpress`, `friendsofphp/php-cs-fixer`, `overtrue/phplint`, `phpmd/phpmd`, `phpmetrics/phpmetrics`
- **Tests** — Codeception modules, `lucatume/wp-browser`, `behat/behat`, `phpunit/phpunit`, and related packages pulled in for acceptance tests
- **CLI and i18n** — `wp-cli/wp-cli-bundle`, `wp-cli/i18n-command`
- **Other dev tools** — e.g. `publishpress/translations`, `knplabs/github-api` with PSR-7 HTTP, `spatie/ray`, `symfony/process`

The complete and current list is the `require` section of this repository’s `composer.json`:

[github.com/publishpress/dev-workspace/blob/development/composer.json](https://github.com/publishpress/dev-workspace/blob/development/composer.json)

Keep any dependency the plugin needs **at runtime** or that is **not** provided by `dev-workspace`. After edits, run `composer update` and fix anything that still expects binaries under the plugin’s direct `vendor/bin` paths (prefer `composer` script names or `vendor/bin/...` as resolved from the root install).

### Configuring the plugin metadata

[](#configuring-the-plugin-metadata)

Set the following keys in the plugin's `composer.json` `extra` section so the workspace can expose the right environment variables to scripts:

```
{
    "extra": {
        "plugin-slug": "post-expirator",
        "plugin-name": "publishpress-future",
        "plugin-folder": "post-expirator",
        "version-constant": "PUBLISHPRESS_FUTURE_VERSION",
        "plugin-lang-domain": "post-expirator",
        "plugin-github-repo": "publishpress/publishpress-future",
        "plugin-composer-package": "publishpress/publishpress-future"
    }
}
```

Each plugin root must have two environment files:

- **`.env.example`** — committed template with placeholder or default values; keep it in the repository so contributors know what variables are required.
- **`.env`** — your local copy with real values; never commit it (add `.env` to `.gitignore`).

The canonical reference for all keys and their expected format is the fake-plugin template in this repository:

[github.com/publishpress/dev-workspace/blob/development/test/fake-plugin/.env.example](https://github.com/publishpress/dev-workspace/blob/development/test/fake-plugin/.env.example)

Copy that file into the plugin root, rename it to `.env.example`, and fill in the values for your plugin. At minimum, set:

```
PLUGIN_NAME="PublishPress Future"
PLUGIN_TYPE="FREE"
PLUGIN_COMPOSER_PACKAGE="publishpress/publishpress-future"

TERMINAL_IMAGE_NAME="publishpress/dev-workspace-terminal:node-25"
WP_IMAGE_NAME="publishpress/dev-workspace-wordpress:wordpress-6.9-php-8.5"
WPCLI_IMAGE_NAME="publishpress/dev-workspace-wpcli:wpcli-2-php-8.5"
```

`PLUGIN_TYPE` is typically `FREE` or `PRO`. `PLUGIN_COMPOSER_PACKAGE` must match the package name in the plugin’s `composer.json` (and the `plugin-composer-package` value under `extra` when you set it). Adjust `PLUGIN_NAME` to the human-readable product name.

Set `GENERATE_TRANSLATION_JSON=1` in `.env` to enable `composer translate:json`. Output files are WordPress-compatible Jed JSON: top-level `domain` and `locale_data[][] = ["translation", ...]`, using `extra.plugin-lang-domain` as the text domain (for example `advanced-gutenberg`, not necessarily the plugin slug).

Use the **same** `TERMINAL_IMAGE_NAME`, `WP_IMAGE_NAME`, and `WPCLI_IMAGE_NAME` values in every plugin; do not use per-plugin image tags. When these images are updated in `dev-workspace`, bump the tags here in `.env.example` (and your local `.env`) together with any release notes from this package.

After editing `.env.example`, copy it to `.env`.

Both `.env` and `.env.example` must be excluded from the built/distributed package. They are already listed in `.rsync-filters-pre-build.default` and `.rsync-filters-post-build.default` (the rsync filter files used during packaging), so no extra action is required as long as the plugin uses the standard build pipeline from this package.

### `dev-workspace-cache` directory

[](#dev-workspace-cache-directory)

Tools from this package create a `dev-workspace-cache` folder at the project root (or the path set by `CACHE_PATH` in `.env`). It holds local-only data: Docker volume data (for example WordPress and MySQL test instances), npm and shell caches inside containers, deploy debug logs, and similar artifacts. It is regenerated as needed and must not be committed.

Add it to the plugin repository’s `.gitignore`:

```
dev-workspace-cache/

```

It is also excluded from the built/distributed package — it is listed in both `.rsync-filters-pre-build.default` and `.rsync-filters-post-build.default`, so no extra action is required when using the standard build pipeline.

### Docker image cleanup

[](#docker-image-cleanup)

Older setups used **per-plugin image tags** (for example `publishpress/dev-workspace-terminal:publishpress-revisions`). All PublishPress plugins are expected to use the **same shared images** set via `TERMINAL_IMAGE_NAME`, `WP_IMAGE_NAME`, and `WPCLI_IMAGE_NAME` in `.env` (see the environment files section above).

You can reclaim disk space by listing and removing obsolete images that are named or tagged after a single plugin:

```
docker image ls 'publishpress/dev-workspace*'
docker rmi publishpress/dev-workspace-terminal:publishpress-revisions   # example; use your actual unused tags
```

Use `docker image prune` or `docker system prune` if you want a broader cleanup; only remove images you no longer need.

Entering the development shell
------------------------------

[](#entering-the-development-shell)

To open an interactive terminal inside the development container, run:

```
composer dev:shell
```

This replaces the legacy `dev-workspace/run` script. If you still have that file in your project root, delete it — the command above is the only supported entry point.

Requirements
------------

[](#requirements)

- Composer 2.x
- PHP with the following extensions enabled (Composer and tooling expect them to be available):
    - **ext-dom** — XML/HTML DOM (used by tooling that parses or generates markup)
    - **ext-curl** — HTTP client support (used by packages and scripts that perform outbound requests)
- Docker (for container-based scripts and tests)

License
-------

[](#license)

GPL-2.0-or-later (see `LICENSE`).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance74

Regular maintenance activity

Popularity22

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 99.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

33

Last Release

41d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/407131?v=4)[Anderson Grüdtner Martins](/maintainers/andergmartins)[@andergmartins](https://github.com/andergmartins)

---

Top Contributors

[![andergmartins](https://avatars.githubusercontent.com/u/407131?v=4)](https://github.com/andergmartins "andergmartins (209 commits)")[![ojopaul](https://avatars.githubusercontent.com/u/92122385?v=4)](https://github.com/ojopaul "ojopaul (1 commits)")

### Embed Badge

![Health badge](/badges/publishpress-dev-workspace/health.svg)

```
[![Health](https://phpackages.com/badges/publishpress-dev-workspace/health.svg)](https://phpackages.com/packages/publishpress-dev-workspace)
```

###  Alternatives

[wp-cli/wp-cli-tests

WP-CLI testing framework

423.1M139](/packages/wp-cli-wp-cli-tests)[humanmade/coding-standards

Human Made Coding Standards

160443.1k58](/packages/humanmade-coding-standards)[lucatume/wp-browser

A set of Codeception modules to test WordPress projects.

6424.1M176](/packages/lucatume-wp-browser)[ec-europa/toolkit

Toolkit packaged for Drupal projects based on Robo.

40252.8k34](/packages/ec-europa-toolkit)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.6M552](/packages/shopware-core)[drupal/core-dev

require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.

2022.6M335](/packages/drupal-core-dev)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
