---
title: Development
---

Sisyphus was generated from `linchpin/plugin-scaffold` with `linchpin plugin scaffold`, so it keeps that standard's boot path, gates and build. Namespace `Linchpin\Sisyphus\`, prefix `sisyphus_`, text domain `sisyphus`, PHP 8.4.

## Gates

```bash
composer test     # parallel-lint, PHPCS, php-cs-fixer, PHPStan, then PHPUnit
npm run lint:js
```

The unit suite has no WordPress and no database. The engine takes its store, queue and clock as interfaces, and `tests/Fakes/` has in-memory versions, so every path through a run is tested without a site.

PHPStan reads WP-CLI from `dev/phpstan/wp-cli.php`, a stub of the WP-CLI calls the command makes, because `php-stubs/wp-cli-stubs` conflicts with the WordPress 7 stubs. It reads Action Scheduler's functions from the vendored package.

CI is `php.yml` and `js.yml`, which call `linchpin/actions@v4`. The husky hooks run PHPCS on staged PHP and commitlint on the message.

## Build

```bash
bash scripts/build.sh
```

It builds the admin bundle, installs runtime Composer dependencies only, copies the allow-listed files to `build/sisyphus`, asserts that the plugin, Action Scheduler and the engine are all there, and zips `build/sisyphus.zip`.

Action Scheduler comes from Composer (`woocommerce/action-scheduler`), and an `installer-paths` entry keeps it in `vendor/`: it is a `wordpress-plugin` package, so `composer/installers` would otherwise move it to `wp-content/plugins`. It is loaded from the plugin file and never prefixed.

## Release

release-please owns the version and `CHANGELOG.md`. A merged release PR runs Plugin Check, builds the zip, attaches it to the release, and installs it on Linchpin Packagist, the same route Pushpin and Mantle take. Linchpin Packagist is a SatisPress site that serves the plugins installed on it, so a release reaches `composer require linchpin/sisyphus`, and packagist.linchpin.com runs it, only once it is installed there.

The install copies the release's zip to Pressable over SSH, runs `wp plugin install --force` on it, and fails unless `wp plugin get sisyphus --field=version` then reports the release's version. It needs the `SSH_HOST`, `SSH_USER` and `SSH_PASS` repository secrets. To install a release that already exists, such as one whose install failed, run the **Release** workflow by hand with its tag (`v0.16.0`).

## Documentation

These pages live in `docs/sisyphus` and publish to docs.linchpin.com under WordPress Plugins with DocsPress. `.github/workflows/sync-docs.yml` runs only by hand and starts as a dry run that writes nothing; a write needs `dry-run` unchecked, and the pages stay drafts unless `status` is `publish`. `.docspress/brief.md`, outside the published tree, says what the pages must cover.
