Read PROJECT_MAP.md and AGENTS.md before changing code. Keep work inside folder loading, shared development virions, standalone builds and extraction, or the quality and release support for those workflows.
composer install
composer syntax
composer lint
composer phpstan
composer test
composer build
composer artifact
composer check
Focused suites are composer test:loader, composer test:virion, and composer test:build. composer analyse, composer qa, and composer build:self remain compatibility aliases.
For the CLI use php -d phar.readonly=0 vendor/bin/phpunit --testsuite cli. Action and release handoff behavior uses node --test .github/scripts/*.test.mjs. The pinned real-server harness is documented under runtime validation. It runs separately from ordinary builds.
composer check is the release-equivalent local gate. It runs strict Composer validation, all-project PHP syntax, style, PHPStan level max, all tests, self-build, and PHAR content, signature and secret validation. It returns nonzero on any failed stage.
- Loader and validation tests cover discovery, manifests, namespace, letter case, paths and actionable diagnostics.
- Virion tests cover source and PHAR discovery, single registration, async-visible loader use, semantic constraints, selection, missing or conflicting packages, compatibility and duplicate classes.
- Build tests inspect real PHAR contents, resources and licenses, AST rewrites, standalone guards, output protection, and safe extraction.
examples/is an integration fixture as well as user documentation.- A release candidate should receive a live compatible-server smoke test with the built DevTools PHAR, folder example, shared virion, and produced standalone plugin when practical.
The candidate and publication steps are separate. A tag push does not build or publish anything. Existing published releases are never overwritten.
- Choose the final version before preparing a publication candidate. Synchronize
plugin.yml,composer.json(extra.devtools.release-version),CHANGELOG.md, andRELEASE_NOTES.md. The current source version is not automatically bumped by these workflows. - Run
composer check,composer audit, andnode --test .github/scripts/*.test.mjs. Review any audit findings under the dependency policy. Commit the intended source and push it to the selected dispatch branch or tag. Wait for its CI checks. - Explicitly dispatch Build DevTools release candidate (
release-candidate.yml) on the intended source branch or tag and setcandidate-committo that exact full commit SHA. GitHub's dispatch ref selects a branch or tag. The workflow fails if itsGITHUB_SHAdiffers from the explicit commit, then checks out that commit directly. It does not choose or update a source branch for you. - The candidate workflow verifies version synchronization, runs the complete quality gate, builds and validates the PHAR once, packages the examples and exact release notes, and writes
candidate.jsonplusSHA256SUMS.txt. It uploads one immutable artifact with commit, run and attempt in its name. Record the run ID, attempt, artifact ID and archive digest from the run summary. Download and inspect that candidate and perform the clean Axolotl-PM runtime checks required for release approval. Candidate metadata records runtime asnot_run. It does not substitute for those checks. - After reviewing the candidate, create and push the version tag pointing to that same candidate commit, only when publication has been explicitly authorized. This is a separate maintainer action. Neither workflow creates or moves the version tag. A candidate must retain the version recorded in its source. A version change requires a new candidate.
- Explicitly dispatch Promote verified DevTools release candidate (
release.yml) from the repository default branch, supplyingcandidate-run-id,artifact-id, and the existingtag. Promotion resolves lightweight and annotated tags, requires that the tag commit equals the successful manual candidate run's head commit, verifies repository, workflow, run, attempt and artifact identity and expiry, and compares the archive digest with GitHub's immutable artifact digest. It then checks every candidate asset hash and exact version tag. - Promotion publishes the already verified PHAR and examples ZIP, candidate provenance and checksums, using the candidate's exact release notes. No Composer installation, build, recompression, version rewrite or plugin or runtime code execution occurs in that publication step. Download the published assets and verify them against the reviewed candidate.
The candidate has read-only repository permissions. Promotion alone receives contents: write. A failed, incomplete, expired, wrong-commit, wrong-run, wrong-workflow, or modified candidate fails closed. Rerunning the candidate workflow increments its attempt. Review and select the new attempt's artifact rather than assuming an older artifact is still the selected candidate. GitHub artifact retention is 90 days. Expired artifacts cannot be promoted.
Local contract tests cover source identity, annotated tag resolution, wrong run, artifact and version, failed checks, archive digest and asset tampering. Local tests and workflow linting do not count as a hosted candidate run, tag push, or real publication. These external actions require explicit authorization and are not part of ordinary development validation.