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 yamllint
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.
Install yamllint 1.38.0 in the development environment before running composer yamllint. Run the command below after installation.
python -m pip install yamllint==1.38.0
composer yamllint
yamllint checks tracked project YAML for syntax, duplicate keys, indentation and other structural problems. Test fixtures under tests/Fixtures/ are excluded because several deliberately contain malformed YAML for failure-path tests. GitHub Actions workflows are checked separately by actionlint in CI.
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.
DevTools keeps a committed Graphify
code graph at graphify-out/graph.json. It is a navigation aid for understanding
relationships across the loader, virion and build modules. It does not replace
tests, PHPStan, or the release checks.
Install Graphify with the graphifyy package, then rebuild the graph from the
repository root with the command below.
graphify extract . --code-only
Only graphify-out/graph.json is shared. HTML visualizations, reports, caches,
and other generated files remain ignored. After code changes, run
graphify update . and include the refreshed graph with the change.
For graph merge conflicts, configure Graphify's merge driver as described in
the team workflow guide.
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 scheduled and manually dispatched ecosystem-compatibility.yml workflow builds every repository in the ecosystem inventory, once for each declared root role. The current inventory produces 148 plugin or virion builds across 143 repositories, including five dual-role projects.
ecosystem-compatibility.json records each repository's root project path, plugin or virion roles, and whether a plugin build needs locked Composer preparation. Each job checks out the repository's current default branch. The matrix generator checks that its repository set matches the public inventory, and each job checks the current manifests against the recorded profile before building. Refresh the profile when a repository is added to or removed from the inventory, changes its root role manifests, or changes whether it needs Composer preparation.
Runs are weekly and manual, use the DevTools revision that owns the workflow run, and build up to 12 projects at a time. Each job records the resolved source commit and, after a successful build, the PHAR identity and SHA-256 in its Actions summary. The workflow has read-only repository permissions, does not run on pull requests, and does not create issues, upload artifacts, publish releases, or gate releases.
A failed build is evidence to investigate, not an automatic verdict that DevTools caused it. This workflow checks packaging against the current PHP 8.4 build environment. It does not prove runtime behavior on Axolotl-PM. The separate runtime smoke harness remains responsible for that evidence.
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 a GPG-signed annotated version tag pointing to that same candidate commit, only when publication has been explicitly authorized. Verify its signature before publication. 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. Sign
SHA256SUMS.txtlocally and upload its detached armored signature asSHA256SUMS.txt.asc. Keep that signature outside the candidate bundle so the strict candidate asset contract remains unchanged. Verify the signature and every asset hash after downloading the release. Then move the signed major channel (v4for 4.x) andlatestto the verified release commit. Older major channels retain their last stable release.
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 follows the repository or organization policy. 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.