From 0596027bdd6ce17ac4b500dc6165a088b7d88d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20Say=C3=A3o=20Lobato=20Abreu?= Date: Sat, 17 Oct 2026 17:07:40 -0300 Subject: [PATCH] ci(release): adopt Fast Forward Changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Felipe Sayão Lobato Abreu --- .changelog/fast-forward-release-workflow.md | 8 + .changeset/README.md | 229 -------- .changeset/config.json | 17 - .gitattributes | 5 +- .github/dependabot.yml | 9 - .github/workflows/changelog.yml | 32 ++ .github/workflows/changesets.yml | 259 --------- .gitignore | 1 - AGENTS.md | 6 +- CHANGELOG.md | 6 +- CONTRIBUTING.md | 6 +- README.md | 8 +- docs/api.md | 6 +- docs/index.html | 5 +- docs/releases.md | 90 +++ package-lock.json | 586 -------------------- package.json | 19 - 17 files changed, 151 insertions(+), 1141 deletions(-) create mode 100644 .changelog/fast-forward-release-workflow.md delete mode 100644 .changeset/README.md delete mode 100644 .changeset/config.json create mode 100644 .github/workflows/changelog.yml delete mode 100644 .github/workflows/changesets.yml create mode 100644 docs/releases.md delete mode 100644 package-lock.json delete mode 100644 package.json diff --git a/.changelog/fast-forward-release-workflow.md b/.changelog/fast-forward-release-workflow.md new file mode 100644 index 0000000..503fed5 --- /dev/null +++ b/.changelog/fast-forward-release-workflow.md @@ -0,0 +1,8 @@ +--- +category: changed +type: patch +--- + +Replace Changesets with the Fast Forward Changelog lifecycle for independent +release notes, PR validation and comments, Dependabot notes and reviewed version +PRs. Preserve Git-tag-based Composer releases without Node release tooling. diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index a588eb7..0000000 --- a/.changeset/README.md +++ /dev/null @@ -1,229 +0,0 @@ -# Release notes and version PRs - -Changesets is development tooling for the Composer package `coisa/error-handler`. -The private npm manifest starts at the published `2.0.0` baseline and tracks the -next version. It is never published to npm. Composer continues to derive its -version from Git tags; do not add a `version` field to `composer.json`. - -Installing or using the PHP library does not require Node.js. The tooling, -lockfile and workflows are excluded from Composer distribution archives. - -## Add a release note - -Use Node.js 24 and npm 10.9 or newer for maintenance: - -```sh -npm ci --ignore-scripts - -git fetch origin - -npm run changeset - -npm run changeset:status -``` - -Select `@coisa/error-handler`, choose the appropriate bump, and describe the -consumer-visible change in English. Commit the generated `.changeset/*.md` file -with the change. Use `patch` for compatible fixes or maintenance and `minor` for -compatible additions. Changes to public contracts or supported PHP versions need -separate major-release planning. This setup includes only a maintenance patch. - -Keep `package-lock.json` committed to make development dependencies reproducible. -Do not run the version command as part of an ordinary feature PR. -Local status compares runtime files (`src/` and `composer.json`) against the -configured base (`origin/master` in this repository). CI selects the repository's -default branch automatically. -Version PRs can therefore validate after consuming their notes. Tooling-only or -documentation-only PRs may omit a note when no version bump is intended. - -The **Changesets** workflow's status and comment jobs follow the official -[non-blocking status example](https://changesets.dev/guide/automating#non-blocking). -It uses `changesets/action/pr-status` and `changesets/action/pr-comment` to create -or update one informational comment, skipping `changeset-release/` branches. -No Changeset bot installation is needed. A read-only job checks out the trusted -base and reads PR files without executing them; a separate job can only post the -comment. It never installs dependencies or runs PHP or npm scripts from the PR. - -## Dependabot updates and their release notes - -Dependabot checks Composer, the private npm tooling and GitHub Actions weekly, -with at most three open version-update PRs per ecosystem. Each update remains a -separate PR; there is no automatic approval or merge. Composer major updates are -excluded from these maintenance proposals and need an explicit compatibility -decision. npm and action majors are reviewable development-tooling proposals; -they do not automatically mean a major release of this PHP library. - -Composer uses `versioning-strategy: widen` to retain already supported dependency -versions rather than raising their minimum. This works with a manifest-only -library: the automation detects `composer.json` updates without requiring a -tracked `composer.lock`. Releases already allowed by a constraint do not need a -new manifest-only PR. Without a committed Composer lockfile, this setup does not -track a fixed transitive dependency graph or promise transitive security-update -PRs. Consumer applications resolve and audit their own installations. See -[Dependabot versioning strategies](https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#versioning-strategy). - -The same **Changesets** workflow's Dependabot job writes -`.changeset/dependabot-.md` directly with `printf`. It reads the package -name from the default branch's `package.json` and uses the PR title as the summary -with a default `patch` classification. This job does not install Node/npm or run -the Changesets CLI. Each run replaces the same file; identical contents produce -no new commit. Manual edits to that note, including its release classification, -are overwritten on the next run. Other note files are left alone. - -A small `gh` check skips stale/closed PRs. The job identifies these PRs by the -`dependabot/` head-branch prefix, without checking the author's login or ID. It -writes only to branches in this repository. - -[`stefanzweifel/git-auto-commit-action@v7`](https://github.com/stefanzweifel/git-auto-commit-action) -commits only that PR's generated note after the workflow switches to the checked -PR commit. No PR code or tooling runs after that switch. Checkout retains the -built-in token only in this job so the action can push; no additional secret is -required. A rebase that removes the note gets it back at the same path on its next -event. Review dependencies and make final release adjustments after the last -dependency update. - -The generated commit has a bot DCO sign-off and `[dependabot skip]`, allowing -[later rebases](https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/manage-your-dependency-security/manage-dependabot-prs#allowing-dependabot-to-rebase-and-force-push-over-extra-commits). -The job uses the existing `pull_request_target` event, following -[Dependabot's write-access guidance](https://github.com/dependabot/fetch-metadata#enabling-auto-merge), -and executes only trusted default-branch code. Informational status and comment -jobs skip `dependabot/` branches because the writer already creates the note; they -do not depend on the writer. The general Changesets validation remains independent. -No PR code is executed by the writer. - -This activates after merge. Observe the first real bot PR and rebase then; local -checks do not establish hosted write permissions. `GITHUB_TOKEN` commits -[do not trigger ordinary PR workflows](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/trigger-a-workflow#triggering-a-workflow-from-a-workflow), -so the generated commit does not automatically get another validation run. The -existing `workflow_dispatch` trigger can validate the updated branch manually. -The initial run belongs to its original SHA. General dependency/PHP CI remains -separate from this minimal release-note job. - -## Review the version PR - -After changes reach the default branch and validation passes, the version job -creates or updates `changeset-release/`. Changesets consumes pending notes, updates -`package.json`, and generates `CHANGELOG.md`. The version script also updates -`package-lock.json` so both manifests have the same version. - -The title includes the repository and recalculated version, for example -`chore(release): release coisa/error-handler 2.0.1`. The action locates the open -PR by its head and base branches, not its title. Further merged changes update -that same PR and its title, even when they change the planned release version. -The `chore(release)` commit records release preparation without classifying it -as another runtime feature or bug fix. - -Changelog entries use the official -[`@changesets/changelog-github`](https://changesets.dev/packages/changelog-github) -formatter with links to PRs and commits. Author acknowledgements are disabled -with `disableThanks: true`. It reads the -repository from `GITHUB_REPOSITORY`, which Actions provides automatically, and -uses `GITHUB_TOKEN` for read-only GitHub queries. The validation rehearsal passes -the built-in token; the version action passes its token to the version command. -No personal token, custom template or repository name in the config is needed. - -Review the version, changelog and consumed notes before merging that PR. The -workflow needs the repository setting **Settings → Actions → General → Workflow -permissions → Allow GitHub Actions to create and approve pull requests** enabled. -It uses the built-in `GITHUB_TOKEN`; no personal token or npm credential is needed. - -The validation job installs the locked tooling, validates pending notes -and uses `changesets/action/select-mode` to rehearse only pending releases. -The version job also dispatches validation on the generated branch, without relying -on automatic `pull_request` events from `GITHUB_TOKEN` or on a separate PHP CI. -The validation job has read-only repository access. The version job can write -version metadata, manage its PR and dispatch validation; the publication job -can create tags and GitHub releases. -All six jobs live in `.github/workflows/changesets.yml`. PR checks run on -`pull_request`; the status jobs use `pull_request_target` without executing PR -code. Only pushes to the default branch can prepare a version PR. Dispatched runs validate -the generated branch without starting another version job. - -The workflow follows the official [Git tags only recipe](https://changesets.dev/guide/automating#publish-git-tags-only): -Node.js 24, a private package, `privatePackages.tag: true`, and the official -`select-mode`, `version` and `publish` actions. Permissions start empty and are -granted per job; jobs that write to GitHub disable package-manager caching. -This Composer library needs no npm build or publishing credentials. -The explicit validation dispatch avoids requiring an additional GitHub App token. -Actions use the publishers' major references (`@v7` and `@v2`) so compatible action -updates do not require a dependency-update PR for every patch or minor release. -The version PR title, commit message and description use `github.repository` -instead of a hardcoded repository name. The workflow uses -`github.event.repository.default_branch` for event selection, status comparisons, -the stale-run guard and the generated validation branch. - -## Merge to release - -Merging the generated version PR is the release decision. When no pending notes -remain and the private package has an unpublished tag, the official -`select-mode` action selects `publish`. The publication job checks out the -event's commit and calls the official `changesets/action/publish` action. -There is no custom release script. - -Concurrency uses `queue: max` with cancellation disabled, retaining up to 100 -pending runs per group. Another push therefore does not replace a pending -release run. Publication uses that run's validated commit even if the default -branch has advanced; version-PR preparation still skips outdated commits. -See GitHub's [concurrency queue documentation](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency#example-queueing-multiple-pending-runs). - -The official publisher creates `v2.0.1`-style tags and a GitHub release from the -matching changelog entry. Existing `1.0.0` and `2.0.0` tags remain unchanged; -Composer accepts the `v` prefix on new versions. Review version changes through -the generated PR; GitHub records who merged it in the PR timeline and its -`merged_by` API field. - -`create-github-releases: true` is explicit. `push-git-tags` is omitted because -the action already defaults it to `true`. No package is sent to npm. Packagist -discovers the Composer version from the Git tag through the repository's -existing integration; this workflow does not configure or force a Packagist sync. - -Version commits use the default GitHub API transport, which signs them with -GitHub's key and attributes them to the token owner. `push-with-git-cli` changes -that transport; it does not identify who merges the PR. See the official -[version action inputs](https://github.com/changesets/action/tree/v2/version). - -Existing tags are excluded from the official publication plan. If a run stops -after creating a tag but before creating its GitHub release, inspect that tag -and finish the missing release with the matching changelog entry; this minimal -workflow does not add a separate recovery implementation. - -The first live version PR and release must still be observed after an -owner-authorized merge. Review prerelease needs separately before adding a -prerelease policy to this stable 2.x flow. - -## Maintain the changelog introduction and history - -Keep the changelog title, introduction and historical backfills on the default -branch. The generator preserves that introduction and inserts new entries before -the first version heading. Use plain headings such as `## 2.0.0`, with release -links or other metadata below them. - -Edits made only to a generated version PR can be overwritten when it is rebuilt -from the default branch. Backfill only published versions; pending versions -belong to their Changesets. A documentation-only backfill does not need a new -Changeset when no additional version bump is intended. - -## Rehearse locally - -In a disposable checkout with the tooling installed, provide -`GITHUB_REPOSITORY=coisa/error-handler` and a read-capable `GITHUB_TOKEN` through -your environment, then run: - -```sh -npm run changeset:status - -npm run version:packages - -git diff -- package.json package-lock.json CHANGELOG.md .changeset -``` - -Never commit the token. Adding notes and running `changeset:status` do not need -a GitHub token. - -With only the initial maintenance note, expect `2.0.1` in both manifests, a patch -changelog entry, and removal of that note. `composer.json` and `src/` must remain -unchanged; any ignored local `composer.lock` is outside release preparation. -A second run with no pending notes must not bump -the version again; Changesets 3 exits with code 1 for that no-op. The validation -job skips this command when the release plan is empty. Do not commit a local -rehearsal into a feature PR. diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index ad0ad70..0000000 --- a/.changeset/config.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config/schema.json", - "changelog": ["@changesets/changelog-github", { "disableThanks": true }], - "commit": false, - "fixed": [], - "linked": [], - "access": "restricted", - "baseBranch": "origin/master", - "changedFilePatterns": ["src/**", "composer.json"], - "updateInternalDependencies": "patch", - "ignore": [], - "format": false, - "privatePackages": { - "version": true, - "tag": true - } -} diff --git a/.gitattributes b/.gitattributes index c5ebc0b..29c1981 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,11 +4,8 @@ AGENTS.md export-ignore /examples/ export-ignore docs/index.html export-ignore docs/.nojekyll export-ignore -.changeset/ export-ignore +.changelog/ export-ignore .github/ export-ignore -node_modules/ export-ignore -package.json export-ignore -package-lock.json export-ignore CONTRIBUTING.md export-ignore tests/ export-ignore .editorconfig export-ignore diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 890ad48..2da9962 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,15 +15,6 @@ updates: prefix: chore include: scope - - package-ecosystem: npm - directory: / - schedule: - interval: weekly - open-pull-requests-limit: 3 - commit-message: - prefix: chore - include: scope - - package-ecosystem: github-actions directory: / schedule: diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml new file mode 100644 index 0000000..17dd88a --- /dev/null +++ b/.github/workflows/changelog.yml @@ -0,0 +1,32 @@ +name: Changelog + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled, closed] + + push: + + workflow_dispatch: + +permissions: {} + +jobs: + changelog: + permissions: + contents: write + pull-requests: write + issues: read + statuses: write + + # The upstream release line currently has no major tag; pin its reviewed runtime. + uses: php-fast-forward/changelog/.github/workflows/changelog.yml@ddcbe0fab5009d8c5c5e504a6a7b9a20682e6d32 + + with: + source: tags + comment-mode: always + version-pr-title: 'chore(release): prepare {next_version} for publication' + prepare-release: true + publish: true diff --git a/.github/workflows/changesets.yml b/.github/workflows/changesets.yml deleted file mode 100644 index 83d9600..0000000 --- a/.github/workflows/changesets.yml +++ /dev/null @@ -1,259 +0,0 @@ -name: Changesets - -on: - pull_request: - pull_request_target: - push: - workflow_dispatch: - -permissions: {} - -env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - -concurrency: - group: changesets-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} - queue: max - cancel-in-progress: false - -jobs: - dependabot: - name: Add Dependabot Changeset - if: >- - github.event_name == 'pull_request_target' && - github.event.pull_request.head.repo.full_name == github.repository && - startsWith(github.head_ref, 'dependabot/') - runs-on: ubuntu-latest - timeout-minutes: 5 - - permissions: - contents: write - pull-requests: read - - steps: - # Use default-branch code and tooling; only PR metadata is read by API. - - uses: actions/checkout@v7 - with: - ref: ${{ github.event.repository.default_branch }} - persist-credentials: true - - - name: Write the release note from the PR title - id: note - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - PR_TITLE: ${{ github.event.pull_request.title }} - PR_HEAD: ${{ github.event.pull_request.head.sha }} - PR_BRANCH: ${{ github.head_ref }} - run: | - package=$(jq -r '.name' package.json) - note="dependabot-$PR_NUMBER.md" - printf -- '---\n"%s": patch\n---\n\n%s\n' "$package" "$PR_TITLE" > "$RUNNER_TEMP/$note" - - current=$(gh pr view "$PR_NUMBER" --json state,headRefOid --jq 'select(.state == "OPEN") | .headRefOid') - if [ "$current" = "$PR_HEAD" ]; then - git fetch --no-tags origin "$PR_HEAD" - git checkout -b "$PR_BRANCH" FETCH_HEAD - mv "$RUNNER_TEMP/$note" ".changeset/$note" - echo 'created=true' >> "$GITHUB_OUTPUT" - fi - - # Only this PR's generated note is committed; no PR code or tooling runs. - - uses: stefanzweifel/git-auto-commit-action@v7 - if: steps.note.outputs.created == 'true' - with: - branch: ${{ github.head_ref }} - skip_fetch: true - file_pattern: '.changeset/dependabot-${{ github.event.pull_request.number }}.md' - commit_message: 'chore(release): add Dependabot Changeset [dependabot skip]' - commit_options: --signoff - commit_author: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>' - - validate: - name: Validate Changesets - if: >- - github.event_name == 'workflow_dispatch' || - (github.event_name == 'push' && github.ref_name == github.event.repository.default_branch) || - (github.event_name == 'pull_request' && github.base_ref == github.event.repository.default_branch) - runs-on: ubuntu-latest - timeout-minutes: 5 - - permissions: - contents: read - - outputs: - mode: ${{ steps.mode.outputs.mode }} - - steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 0 - persist-credentials: false - - - uses: actions/setup-node@v7 - with: - node-version: '24' - cache: npm - - - run: npm ci --ignore-scripts - - - run: npm run changeset -- status --since="origin/$DEFAULT_BRANCH" - - - name: Select Changesets mode - id: mode - uses: changesets/action/select-mode@v2 - - - name: Rehearse versioning in the disposable checkout - if: steps.mode.outputs.mode == 'version' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npm run version:packages - - status: - name: Read PR Changesets - if: >- - github.event_name == 'pull_request_target' && - github.base_ref == github.event.repository.default_branch && - !startsWith(github.head_ref, 'dependabot/') && - !startsWith(github.head_ref, 'changeset-release/') - runs-on: ubuntu-latest - timeout-minutes: 5 - - permissions: - contents: read - - outputs: - comment-body: ${{ steps.status.outputs.comment-body }} - - steps: - # Check out the trusted base; the action only reads PR files. - - uses: actions/checkout@v7 - with: - persist-credentials: false - - - name: Generate Changeset status - id: status - uses: changesets/action/pr-status@v2 - - comment: - name: Comment PR Changesets - needs: status - runs-on: ubuntu-latest - timeout-minutes: 5 - - permissions: - pull-requests: write - - steps: - - name: Create or update the Changeset comment - uses: changesets/action/pr-comment@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - body: ${{ needs.status.outputs.comment-body }} - - version: - name: Prepare version PR - needs: validate - if: >- - github.event_name == 'push' && - github.ref_name == github.event.repository.default_branch && - needs.validate.outputs.mode == 'version' - runs-on: ubuntu-latest - timeout-minutes: 10 - - permissions: - contents: write - pull-requests: write - actions: write - - steps: - - uses: actions/checkout@v7 - with: - persist-credentials: false - - - uses: actions/setup-node@v7 - with: - node-version: '24' - package-manager-cache: false - - - run: npm ci --ignore-scripts - - - name: Check the current default-branch tip - id: tip - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - current=$(gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/$DEFAULT_BRANCH" --jq .object.sha) - if [ "$current" = "$GITHUB_SHA" ]; then - echo "current=true" >> "$GITHUB_OUTPUT" - fi - - - name: Create or update the version PR - id: version - if: steps.tip.outputs.current == 'true' - uses: changesets/action/version@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: npm run version:packages - pr-title: 'chore(release): prepare next release of ${{ github.repository }}' - commit-message: 'chore(release): prepare next version of ${{ github.repository }}' - - - name: Describe the version PR - if: steps.version.outputs.pr-number != '' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ steps.version.outputs.pr-number }} - REPOSITORY: ${{ github.repository }} - run: | - version=$(node -p "require('./package.json').version") - - printf 'Prepare %s %s for release.\n\n' "$REPOSITORY" "$version" > "$RUNNER_TEMP/version-pr.md" - - cat >> "$RUNNER_TEMP/version-pr.md" <<'MARKDOWN' - Review the generated `CHANGELOG.md`, the versions in `package.json` and - `package-lock.json`, and the consumed `.changeset/*.md` notes. - - Merging this PR starts validated Git tag and GitHub release publication. - Review it as the release decision. The private npm package is never published. - MARKDOWN - - gh pr edit "$PR_NUMBER" \ - --title "chore(release): release $REPOSITORY $version" \ - --body-file "$RUNNER_TEMP/version-pr.md" - - - name: Validate the generated version branch - if: steps.version.outputs.pr-number != '' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run changesets.yml --ref "changeset-release/$DEFAULT_BRANCH" - - publish: - name: Publish reviewed release - needs: validate - if: >- - github.event_name == 'push' && - github.ref_name == github.event.repository.default_branch && - needs.validate.outputs.mode == 'publish' - runs-on: ubuntu-latest - timeout-minutes: 10 - - permissions: - contents: write - - steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 0 - persist-credentials: false - - - uses: actions/setup-node@v7 - with: - node-version: '24' - package-manager-cache: false - - - run: npm ci --ignore-scripts - - - name: Publish the Composer tag and GitHub release - uses: changesets/action/publish@v2 - with: - create-github-releases: true diff --git a/.gitignore b/.gitignore index f2c8d28..1891fc2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ /composer.lock .idea/ vendor/ -node_modules/ tests/html/ tests/clover.xml tests/cobertura.xml diff --git a/AGENTS.md b/AGENTS.md index 0d5023c..302a361 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ Maintain `coisa/error-handler` under `CoiSA\ErrorHandler` as a small PHP library ## Compatibility and ownership - Preserve the declared PHP `^7.4 || ^8.0` range and existing 2.x public classes, interfaces, factories, ConfigProvider and Laminas discovery metadata. Keep executable example syntax compatible with PHP 7.4. -- Use the actual selected source and Composer version as authority. The proposed major has different container, middleware, rendering and exit contracts; do not present that proposal or a pending Changeset as a published release. +- Use the actual selected source and Composer version as authority. The proposed major has different container, middleware, rendering and exit contracts; do not present that proposal or a pending release note as a published release. - Applications own reporters, PSR-14 dispatchers, PSR-17 factories, HTTP emission and when native PHP callbacks are installed. Resolving a service must not install callbacks. - Preserve the existing container integration. FastForward adoption, removal of legacy classes and API changes require their own explicitly reviewed scope. - Callbacks are process-wide. Use distinct handlers for nested scopes and restore in reverse order. Direct reporting, registered uncaught exceptions and fatal shutdown reporting are different paths; do not promise recovery or an automatic nonzero exit. @@ -18,7 +18,7 @@ Inspect branch/HEAD, tracked/untracked/ignored state, applicable contracts and r Use Composer 2 dependency installs with `--no-plugins --no-scripts`, then run `composer --no-plugins check`. Development integrations may need a newer PHP than the library minimum: verify minimum runtime separately through a clean no-dev consumer. Report actual PHP/Composer/dependency versions, the tested SHA and existing failures honestly. -Keep source, meaningful regression coverage, affected examples/guides, the source-linked `coisa-error-handler` consumer skill and a pending Changeset aligned. Never install the skill globally as part of maintenance. +Keep source, meaningful regression coverage, affected examples/guides, the source-linked `coisa-error-handler` consumer skill and an independent `.changelog/*.md` fragment aligned. Never install the skill globally as part of maintenance. The Fast Forward Changelog workflow prepares the reviewed version PR; do not consolidate history or consume pending notes in ordinary contributions. Run `php examples/verify.php` with the documented application dependencies after example or documented-contract changes. The verifier owns bounded child processes, including fatal experiments. Do not run fatal fixtures in an agent, application, real server or parent test process. Use synthetic records and disposable consumer dependencies; never application credentials or production logs. @@ -48,7 +48,7 @@ and verification continue to follow this AGENTS.md. - [examples/verify.md](examples/verify.md): bounded verifier inputs, outputs, child-process effects and recovery. - [docs/testing.md](docs/testing.md): direct PHPUnit contracts, isolated native process cases, installed-package checks and honest coverage limits; no custom test runner. - [CONTRIBUTING.md](CONTRIBUTING.md): library dependency resolution and clean production-container checks. -- [.changeset/README.md](.changeset/README.md): pending notes, reviewed version PRs and separate publication authority. +- [docs/releases.md](docs/releases.md): independent fragments, reviewed version PRs, Git-tag version authority and publication boundaries. - [docs/agent-skill.md](docs/agent-skill.md): optional project/global skill distribution, trust and lifecycle; copying does not establish host activation. - [resources/skills/coisa-error-handler/SKILL.md](resources/skills/coisa-error-handler/SKILL.md): portable consumer integration procedure, bundled examples and supported API contract; keeps its own package entrypoint and source identity. diff --git a/CHANGELOG.md b/CHANGELOG.md index f03e5c0..54eea4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,11 @@ Notable changes to `coisa/error-handler`, with the newest release first. This file is inspired by [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -New entries are generated from [Changesets](https://changesets.dev/) using its -GitHub changelog formatter and change categories. +New entries are collected from independent Markdown fragments by +[Fast Forward Changelog](https://github.com/php-fast-forward/changelog). The entries for 1.0.0 and 2.0.0 were reconstructed from their published Git tags. -Pending changes live in `.changeset/` until a version PR is prepared. +Pending changes live in `.changelog/` until a version PR is prepared. ## 2.5.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a67f27c..155eec6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,8 +89,10 @@ Dependency installation in a fresh checkout resolves a local lockfile; subsequen installs can reuse it. CI must record the actual resolution for its runner, and cache keys must not require a committed Composer lockfile. -`package-lock.json` remains tracked for the independent Node release tooling. -Node.js is not a runtime dependency of the Composer library. +Add one independent `.changelog/*.md` fragment for observable changes, including +dependencies and workflows. The [release process](docs/releases.md) describes the +format, PR checks and reviewed version PR. Release automation supplies its own +runtime; it adds no PHP or Node dependency to this library. ## Native development environment diff --git a/README.md b/README.md index 6404266..0eea219 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,7 @@ Requires PHP `^7.4 || ^8.0` and Composer 2. Applications supply their logger, event dispatcher, HTTP factories and response emitter as needed. This README describes the 2.x API. Check `composer show coisa/error-handler` -and the [release history](CHANGELOG.md) for your installed version; a pending -Changeset is not a published Composer release. +and the [release history](CHANGELOG.md) for your installed version. ## 🛠️ Quick start @@ -121,8 +120,9 @@ status-code mapping, reason validation and output-buffer cleanup limits. Follow the [contributor guide](CONTRIBUTING.md) for dependency setup and `composer --no-plugins check`. See [testing](docs/testing.md) for process fixtures -and platform evidence, and [Changesets](.changeset/README.md) for release notes. -Node.js is used only by development release tooling. +and platform evidence, and the [release process](docs/releases.md) for independent +release notes and reviewed version PRs. Release automation uses the Fast Forward +Changelog reusable workflow without adding a runtime or Node dependency. ## License diff --git a/docs/api.md b/docs/api.md index 25f2bc0..1059ea6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # Core API and lifecycle in 2.x -These guides describe the existing 2.x API, including compatible maintenance on `master`. Confirm the installed version with `composer show coisa/error-handler` and consult its matching source. A pending Changeset is not a published Composer version. The PSR-11 metadata and PHP 7.4 alias corrections are tracked in [#13](https://github.com/coisa/error-handler/issues/13) and [#40](https://github.com/coisa/error-handler/issues/40); container recipes on PHP 7.4 need a checkout or release containing both. +These guides describe the 2.x API. Confirm the installed version with `composer show coisa/error-handler` and consult its matching source. The PSR-11 metadata and PHP 7.4 alias corrections are tracked in [#13](https://github.com/coisa/error-handler/issues/13) and [#40](https://github.com/coisa/error-handler/issues/40); container recipes on PHP 7.4 need a checkout or release containing both. The declared runtime is PHP `^7.4 || ^8.0`. This is a dependency contract, not evidence that every PHP/dependency combination has been tested. Application integrations can impose narrower requirements. @@ -57,11 +57,11 @@ The [complete logging example](https://github.com/coisa/error-handler/blob/maste The predicate must return a boolean: truthy/false-like non-booleans raise `TypeError`. Predicate and delegate failures propagate unchanged, without retry. To invert a condition, supply a predicate that returns its boolean negation. A skipped branch does not recover an operation, change PHP suppression or imply a successful HTTP response; a failure still stops later aggregate reporters. -The [filtering example](https://github.com/coisa/error-handler/blob/master/examples/filtering.php) routes synthetic PHP deprecations to a selected branch while keeping the general branch. Inspect `ErrorException::getSeverity()` for PHP severity; arbitrary exception codes do not carry that meaning. Use a callable directly for one-off application logic, and the decorator when wrapping an existing reporter or aggregate. This is an additive, opt-in 2.x API: use a source version containing it; a pending minor Changeset is not a published release. +The [filtering example](https://github.com/coisa/error-handler/blob/master/examples/filtering.php) routes synthetic PHP deprecations to a selected branch while keeping the general branch. Inspect `ErrorException::getSeverity()` for PHP severity; arbitrary exception codes do not carry that meaning. Use a callable directly for one-off application logic, and the decorator when wrapping an existing reporter or aggregate. ## Best-effort reporting -`new Handler\BestEffortThrowableHandlerAggregate($first, $second, ...)` is an explicit alternative to the existing fail-fast `ThrowableHandlerAggregate`. It takes a fixed constructor list of `ThrowableHandlerInterface` reporters. Construction invokes nothing and installs no callbacks. Use a checkout/release containing these new classes; a pending minor Changeset does not make them available in older 2.x installations. +`new Handler\BestEffortThrowableHandlerAggregate($first, $second, ...)` is an explicit alternative to the existing fail-fast `ThrowableHandlerAggregate`. It takes a fixed constructor list of `ThrowableHandlerInterface` reporters. Construction invokes nothing and installs no callbacks. Each `handleThrowable($original)` invocation attempts every constructor slot once, in order, with the identical original object. A reporter's `Throwable` failure is retained while later slots run. Duplicate slots remain deliberate separate attempts. Zero reporters and all-success passes return normally. If any reporter fails, including partial success, one `Exception\AggregateReportingException` escapes after all attempts. diff --git a/docs/index.html b/docs/index.html index ec6e2ab..93ddc32 100644 --- a/docs/index.html +++ b/docs/index.html @@ -113,7 +113,7 @@

Error Handler 2.x

Compose diagnostic reporting, native PHP callbacks and HTTP responses with explicit application boundaries.

The library supplies handlers and PSR adapters. Your application chooses reporters, PSR implementations, callback installation and HTTP emission.

-
This guide describes the existing 2.x API and compatible maintenance on master. Check your installed version and matching source. A pending Changeset is not a published release.
+
This guide describes the 2.x API. Check your installed version and matching source.

New to the library? Follow installation, run direct reporting, then choose process callbacks or an explicit HTTP response policy. Add container integration when the application needs service lookup.

@@ -223,7 +223,7 @@

Select diagnostic branches explicitly

Severity selection from examples/filtering.php · the example also retains a general diagnostic branch
    static fn(Throwable $error): bool => $error instanceof ErrorException && E_USER_DEPRECATED === $error->getSeverity(),
-

This opt-in adapter requires a source version containing the additive API; a pending Changeset is not a published release. It adds no discovery, output, callback registration, recursion guard or response policy. A nonmatch is not recovery or redaction: built-in empty capture still falls back to diagnostic text. See the API guide and HTTP composition.

+

This opt-in adapter adds no discovery, output, callback registration, recursion guard or response policy. A nonmatch is not recovery or redaction: built-in empty capture still falls back to diagnostic text. See the API guide and HTTP composition.

@@ -362,6 +362,7 @@

Continue in the source guides

  • Native checks, bounded probes and evidence limits
  • Portable consumer skill and optional installation
  • Published release history
  • +
  • Release fragments, reviewed version PRs and publication
  • diff --git a/docs/releases.md b/docs/releases.md new file mode 100644 index 0000000..94960b0 --- /dev/null +++ b/docs/releases.md @@ -0,0 +1,90 @@ +# Release notes and reviewed releases + +The [Changelog workflow](https://github.com/coisa/error-handler/blob/master/.github/workflows/changelog.yml) +uses [Fast Forward Changelog](https://github.com/php-fast-forward/changelog) for +independent release notes, PR checks and a reviewed version PR. Git tags are the +version authority for `coisa/error-handler`; there is no separate npm manifest +or Composer `version` field to maintain. + +## Add a release note + +Create a unique lowercase dash-separated file in `.changelog/`, for example +`.changelog/preserve-reporting-order.md`: + +```markdown +--- +category: fixed +type: patch +--- + +Preserve reporter order when handling an application exception. +``` + +Describe the observable change in English. Commit the fragment with the change; +keep meaningful Markdown indentation, code fences and hard line breaks. Prefer +a backslash at the end of a line for an explicit Markdown break: Git's unchanged +whitespace check rejects trailing spaces, even when intended as a hard break. Ordinary +contributions leave existing fragments and `CHANGELOG.md` intact. + +Categories are `added`, `changed`, `deprecated`, `removed`, `fixed` and `security`. +Always specify `type`: `patch` for compatible fixes or maintenance, `minor` for +compatible additions, and `major` for breaking changes. A tooling change or an +upstream dependency's major version does not itself require a library major. +The 2.x maintenance line preserves its public API and PHP requirements. + +Optional `issue` and `pull_request` fields contain positive integers. Omit +`author`: this repository does not add contributor thanks to new entries. +The folder contains only valid fragments; contribution instructions live here. + +No local changelog installation is required. The workflow supplies its trusted +Docker runtime on Linux. If you already use the compatible upstream CLI, its +`check` and `status --json --source=tags` commands validate and preview the plan; +local CLI requirements belong to that tool, not the library's PHP support. +With no pending fragments, the version command succeeds without changing files. + +## Contribution checks and feedback + +One caller handles the lifecycle on the repository's default branch: + +- `pull_request` checks committed contributions with read-only permissions. +- `pull_request_target` uses the pinned runtime for one updated PR comment and + commit status, without executing consumer PHP, Composer scripts or templates + from the PR with write credentials. +- Dependabot PRs receive a fragment from verified dependency metadata. Existing + notes are preserved; review the generated summary and release impact. +- Default-branch pushes and manual dispatch prepare or update `changelog/version`. + +The caller has no repository name or default-branch literal. The reusable +workflow selects those from the event. Its implementation is pinned to a +reviewed commit because upstream has no major-version tag at the selected +revision; update the pin deliberately to another integrated revision. + +PHP CI, coverage and formatting remain independent checks. The generated-head +changelog status verifies release inputs; it does not run the PHP suite. +With `GITHUB_TOKEN`, GitHub can require owner approval before workflows on a +generated PR run. Approve those runs and verify their exact head before merging. +An optional GitHub App is an application-level authentication choice, described +in the [upstream guide](https://github.com/php-fast-forward/changelog/blob/main/docs/github-app.md). +This workflow configures no App, secret, repository setting or branch rule. + +## Review and publication + +The version PR consolidates validated fragments into `CHANGELOG.md` and removes +only the consumed notes. Review its next version, text, diff and actual PHP CI +results. New contributions update the same managed PR; its title is not its +identity. Preserve published historical entries and the introductory header. +New sections use Keep a Changelog categories; older Changesets headings remain +part of the historical record. + +The workflow retains automatic publication after the owner merges the managed +version PR. `publish: true` routes that approved merge to the upstream publisher, +which validates the exact merge SHA and consolidation evidence before creating +its `v`-prefixed Git tag and GitHub Release. It does not publish an npm package, +merge PRs or bypass review. Composer consumers receive versions through Git tags +and the existing package registry integration. + +Preparing this integration or passing CI does not authorize an agent to merge a +PR or publish a release. Test consolidation only in a disposable copy. For a +failed publication, inspect the run and its exact SHA; upstream can complete a +matching partial publication without moving an existing tag. Never move or +delete published tags to repair a prepared version. diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 5e4e2da..0000000 --- a/package-lock.json +++ /dev/null @@ -1,586 +0,0 @@ -{ - "name": "@coisa/error-handler", - "version": "2.5.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@coisa/error-handler", - "version": "2.5.1", - "devDependencies": { - "@changesets/changelog-github": "1.0.1", - "@changesets/cli": "3.0.3" - }, - "engines": { - "node": "^22.11 || ^24 || >=26", - "npm": ">=10.9.0" - } - }, - "node_modules/@changesets/apply-release-plan": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-8.1.1.tgz", - "integrity": "sha512-nk2Hbq3M9NeHMdaIRBDvawKrQJzXB9sGyBUE5yWnIKtvdcNCPj75zBekJYr0gTT2ecJH3eFeTrc8eisPImcv0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/config": "^4.0.1", - "@changesets/format": "^0.1.2", - "@changesets/git": "^4.0.1", - "@changesets/should-skip-package": "^1.0.0", - "@changesets/types": "^7.0.0", - "import-meta-resolve": "^4.2.0", - "jsonc-parser": "^3.3.1", - "semver": "^7.8.1" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/assemble-release-plan": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-7.0.0.tgz", - "integrity": "sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^1.0.0", - "@changesets/get-dependents-graph": "^3.0.0", - "@changesets/should-skip-package": "^1.0.0", - "@changesets/types": "^7.0.0", - "semver": "^7.8.1" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/changelog-git": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-1.0.0.tgz", - "integrity": "sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^7.0.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/changelog-github": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-1.0.1.tgz", - "integrity": "sha512-QUcrV7878yHlWPXXPA6gqSxNKwtVHCd1K22L7ZAoJw2yGy8K4QvjwOStD75+1Q9KD9ZSUgGS94HuYdd7HOVtpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/get-github-info": "^1.0.1", - "@changesets/types": "^7.0.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/cli": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-3.0.3.tgz", - "integrity": "sha512-L1i67bMfkK6iC/kDejuNO4pFgTRcWIObsD6Qof2woP1I4M8tj17DGlcpRaTzTv1DYSP5EMwWdEtR8X0Pj5Jg3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/apply-release-plan": "^8.1.1", - "@changesets/assemble-release-plan": "^7.0.0", - "@changesets/changelog-git": "^1.0.0", - "@changesets/config": "^4.0.1", - "@changesets/errors": "^1.0.0", - "@changesets/get-dependents-graph": "^3.0.0", - "@changesets/git": "^4.0.1", - "@changesets/pre": "^3.0.0", - "@changesets/read": "^1.0.1", - "@changesets/should-skip-package": "^1.0.0", - "@changesets/types": "^7.0.0", - "@changesets/write": "^1.0.1", - "@clack/prompts": "^1.7.0", - "@manypkg/get-packages": "^3.1.0", - "@pnpm/deps.graph-sequencer": "^1100.0.1", - "cac": "^7.0.0", - "import-meta-resolve": "^4.2.0", - "launch-editor": "^2.14.1", - "package-manager-detector": "^1.6.0", - "semver": "^7.8.1", - "tinyexec": "^1.3.1" - }, - "bin": { - "changeset": "bin.js" - }, - "engines": { - "node": "^22.11 || ^24 || >=26", - "npm": ">=10.9.0", - "pnpm": ">=10.0.0", - "yarn": ">=4.5.2" - } - }, - "node_modules/@changesets/config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@changesets/config/-/config-4.0.1.tgz", - "integrity": "sha512-PxpxSQLQSLDjceAgRq+4FWlU+HflDIw03mmPVipxoQx9xrXFUjmqTy3SE+n/2t+DqPdpPiLWVr5NRiLZvjyLwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/get-dependents-graph": "^3.0.0", - "@changesets/should-skip-package": "^1.0.0", - "@changesets/types": "^7.0.0", - "@manypkg/get-packages": "^3.1.0", - "picomatch": "^4.0.7" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/errors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-1.0.0.tgz", - "integrity": "sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/format": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@changesets/format/-/format-0.1.2.tgz", - "integrity": "sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "package-manager-detector": "^1.8.0", - "tinyexec": "^1.3.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/get-dependents-graph": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-3.0.0.tgz", - "integrity": "sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^7.0.0", - "semver": "^7.8.1" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/get-github-info": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-1.0.1.tgz", - "integrity": "sha512-ifLQCky/ZtDgZ4xCiUMjnLZSJ8xk52iIzMJbBBPlZWjr2CiTNTaTDddIVWKicrUAdWuLWL7PUw2fNa1yPwLpIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "dataloader": "^2.2.3" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/git": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-4.0.1.tgz", - "integrity": "sha512-6vWpIAC4LkpmlqaIu37ViT5enyd9+uBwAiGqCGhASvkSHBgx4PrtTGXWTMFYpDmZbjgyonyVgMciPrW4MqtJsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^1.0.0", - "@changesets/types": "^7.0.0", - "@manypkg/get-packages": "^3.1.0", - "picomatch": "^4.0.4", - "tinyexec": "^1.3.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-1.0.0.tgz", - "integrity": "sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^7.0.0", - "yaml": "^2.9.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/pre": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-3.0.0.tgz", - "integrity": "sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/errors": "^1.0.0", - "@changesets/types": "^7.0.0", - "@manypkg/get-packages": "^3.1.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/read": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-1.0.1.tgz", - "integrity": "sha512-nzvSC6RcTiWf/dsuwZFXpLzGGsRHYCL68U3uHV7srsulU93aVWY7u2GEJiDZ+4GIIElfaW5EqtKC0UHroY+LTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/git": "^4.0.1", - "@changesets/parse": "^1.0.0", - "@changesets/types": "^7.0.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/should-skip-package": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-1.0.0.tgz", - "integrity": "sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/types": "^7.0.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/types": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-7.0.0.tgz", - "integrity": "sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@changesets/write": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@changesets/write/-/write-1.0.1.tgz", - "integrity": "sha512-q/ThtP9gcnEP6xlv7LrY26C2mHqdGBti/MmOVngt/M/oIGYkssmQGxPK9WzBNt2juVcH/vml2WQ+ra8LXYOTaA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@changesets/format": "^0.1.1", - "@changesets/types": "^7.0.0", - "human-id": "^4.2.0" - }, - "engines": { - "node": "^22.11 || ^24 || >=26" - } - }, - "node_modules/@clack/core": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.1.tgz", - "integrity": "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-wrap-ansi": "^0.2.0", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 20.12.0" - } - }, - "node_modules/@clack/prompts": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.1.tgz", - "integrity": "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@clack/core": "1.5.1", - "fast-string-width": "^3.0.2", - "fast-wrap-ansi": "^0.2.0", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 20.12.0" - } - }, - "node_modules/@manypkg/find-root": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-3.1.0.tgz", - "integrity": "sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@manypkg/tools": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@manypkg/get-packages": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-3.1.0.tgz", - "integrity": "sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@manypkg/find-root": "^3.1.0", - "@manypkg/tools": "^2.1.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@manypkg/tools": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@manypkg/tools/-/tools-2.1.2.tgz", - "integrity": "sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jju": "^1.4.0", - "tinyglobby": "^0.2.13", - "yaml": "^2.9.0" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/@pnpm/deps.graph-sequencer": { - "version": "1100.0.1", - "resolved": "https://registry.npmjs.org/@pnpm/deps.graph-sequencer/-/deps.graph-sequencer-1100.0.1.tgz", - "integrity": "sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=22.13" - }, - "funding": { - "url": "https://opencollective.com/pnpm" - } - }, - "node_modules/cac": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cac/-/cac-7.1.0.tgz", - "integrity": "sha512-LMDU/U2yA4IPIY8KT0NsNPWEYZvAMkbgyspxJ6btJaYV+WMDOHAZCmB0lsTObiHaRS1V/ztKAl7+TSkTqXyeoA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20.19.0" - } - }, - "node_modules/dataloader": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.3.tgz", - "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-string-truncated-width": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", - "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-string-width": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", - "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-string-truncated-width": "^3.0.2" - } - }, - "node_modules/fast-wrap-ansi": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", - "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-string-width": "^3.0.2" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/human-id": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.2.tgz", - "integrity": "sha512-Z+8unD6em/MJwyrkWQ2M3wygRGI1+MztbutiNwk1DCuEPXOZRWGjtcMPZYP1exY9iNZMhd7ZOSMQSo9WYtiQRw==", - "dev": true, - "license": "MIT", - "bin": { - "human-id": "dist/cli.js" - } - }, - "node_modules/import-meta-resolve": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/launch-editor": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.2.tgz", - "integrity": "sha512-NHJEb30MGBCkmZXLZwz25t37QR4aY03ZzPYUJXOJaOa92uWwExI9SBQUuIznBYc1xkD7cJNGX7oc3Nl3sq2kQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.1.1", - "shell-quote": "^1.10.0" - } - }, - "node_modules/package-manager-detector": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.9.0.tgz", - "integrity": "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shell-quote": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.12.0.tgz", - "integrity": "sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", - "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/yaml": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", - "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index ac54919..0000000 --- a/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "@coisa/error-handler", - "version": "2.5.1", - "private": true, - "description": "Development-only release tooling for the coisa/error-handler Composer package", - "scripts": { - "changeset": "changeset", - "changeset:status": "changeset status --since=origin/master", - "version:packages": "changeset version && npm install --package-lock-only --ignore-scripts && git diff --check" - }, - "engines": { - "node": "^22.11 || ^24 || >=26", - "npm": ">=10.9.0" - }, - "devDependencies": { - "@changesets/changelog-github": "1.0.1", - "@changesets/cli": "3.0.3" - } -}