Tooling releases
Changes to the tooling commands go into .eddy/tooling/, where the scaffold's own tests and builds use them straight away. Generated projects get them through releases of the drevops/eddy-tooling package. This page covers how the package is published and how to release it.
How the package is published
On every push to main, .github/workflows/eddy-publish-tooling.yml mirrors the .eddy/tooling/ directory to the main branch of drevops/eddy-tooling, which Packagist serves. The workflow pushes with the EDDY_TOOLING_DEPLOY_KEY secret, a deploy key with write access to the mirror. It runs only in drevops/eddy, so a push to a fork publishes nothing.
The workflow also publishes each drevops/eddy branch whose name contains eddy-tooling, such as feature/123-eddy-tooling-fix, to the mirror branch of the same name. A change on either kind of branch reaches generated projects only with the next release, because their ~ constraint matches release tags only.
To try a published branch in a generated project before it merges:
-
In the project's
composer.dev.json, set thedrevops/eddy-toolingconstraint inrequire-devto the branch name with Composer'sdev-prefix:"drevops/eddy-tooling": "dev-feature/123-eddy-tooling-fix" -
Run
scripts/eddy-tooling, or any command that runs it, such asahoy build. The changed constraint makes it install the branch (see Tooling package).
To switch back, restore the ~ constraint you replaced and run scripts/eddy-tooling again.
Each run of the workflow adds 1 commit to the mirror branch, with the subject of the pushed commit. The runs follow these rules:
- Every push to a published branch runs the workflow. A push that leaves
.eddy/tooling/unchanged adds an empty commit. - A branch that's new to the mirror starts without history.
- Runs of 1 branch queue one after another, and a newer push cancels a run that's still waiting. In a quick burst of pushes, some pushes get no commit of their own, and the mirror still ends on the latest state.
- A published branch stays on the mirror until you delete it there.
Release the package
You create each release on the mirror by hand, and the create-eddy-tooling-release-notes skill writes its notes. The skill needs git and an authenticated GitHub CLI (gh).
To release the package:
- Create a release on
drevops/eddy-toolingin the GitHub UI, with a new tag on the mirror'smain, such as1.0.1. Leave out thevprefix: the tags have none. Save the release as a draft, or publish it straight away. - From a clone of Eddy, run
/create-eddy-tooling-release-notesin Claude Code, or ask Claude Code for the tooling release notes. The skill writes the notes to.artifacts/release-notes-tooling-<version>.md. - Paste the notes into the release description.
- If the release is still a draft, publish it.
- If the release is a new minor or major version, or Eddy relies on what it ships, raise the constraint to it.
The skill takes the version from the newest release on the mirror while that release has no notes. The previous release is the highest published release lower than it. The skill lists the commits that changed .eddy/tooling/ between the 2. It describes each commit from its subject, or from its pull request, its issue or its diff when the subject isn't enough.
When the newest release on the mirror already has notes, the skill prepares the notes of a release you haven't created yet. It suggests a version from the changes and asks you to confirm it.
Generated projects accept every patch release within their ~ constraint. A project picks up a patch release when it installs the tooling from scratch, such as after vendor/ is removed.
Raise the constraint
Eddy's own composer.dev.json holds the drevops/eddy-tooling constraint that generated projects get. Raise it to a new release, such as ~1.1.0, in any of these cases:
- The release is a new minor or major version.
- The command wrappers, the workflows or the docs of a generated project call a command or an
eddy-infofield that the release ships. - A step moves from the command wrappers into a command of the release.
Then update the examples on the Tooling package page and in the package's README.md to match.
Publish the release before you raise the constraint. ~1.1.0 matches release tags only, so a project with it can't install the tooling until 1.1.0 is out. Generated projects receive the new constraint with their next scaffold update. The changed constraint makes scripts/eddy-tooling install the release on its next run. Without the raise, a project's checkout keeps the release it installed, even one that lacks what the new scaffold calls.
2 scaffold tests guard the constraint:
ToolingConstraintTestlists the first release that ships each command andeddy-infofield the scaffold calls. It fails while the constraint allows an older release, so add each new call to that list with its release. The test can't detect a step that moves into a command, so raise the constraint for that case yourself.DocumentationTestfails until both examples show the constraint.