Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions .claude/skills/upgrade-plan/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
name: upgrade-plan
description: >
Use when asked to plan, prepare or draft a new upgrade page for the Dotkernel documentation — for
example "plan the 7.1 to 7.2 upgrade page", "what changed between releases", or "list the pull
requests for the next upgrade guide". Produces a plan file in .claude/ that lists the pull
requests of a release, split into important and optional updates, based on the release notes,
commits and code of the source repository. Planning only: it does not create the page.
---

# Upgrade page plan

Produce `.claude/PLAN-UPGRADE-<to>.md` for a new `docs/book/v<major>/upgrading/UPGRADE-<to>.md` page.
This skill only plans.
Do not create the page, edit `mkdocs.yml` or edit any other file until the user approves the plan and asks for it.

## Inputs

- `from` and `to`: the release tags, for example `7.0.0` and `7.1.0`. Ask if either is missing.
- `repo`: defaults to `dotkernel/api`. Other Dotkernel repositories work the same way.
- Check the tag exists with `gh release list -R <repo>` before going further.

## Steps

1. **Gather.** Run `bash .claude/skills/upgrade-plan/gather.sh <from> <to> [repo] > <scratchpad>/upgrade-<to>.md` and read the output.
It prints the release notes, commit and file counts, the `composer.json` diff, the files touched by each pull request, and the commits on the release branch after the tag.
2. **Read the code.** Never classify from titles.
For every pull request that touches `src/`, `config/`, `bin/`, `composer.json`, migrations or entities, read its diff with `gh pr diff <n> -R <repo>`.
With many pull requests, hand this step to a subagent and keep only its conclusions.
3. **Classify** each pull request as important or optional using the rules below.
4. **Cross-check** and record the findings in the plan:
- pull requests that must be read together, for example one removes a file and a later one recreates it elsewhere
- titles that disagree with the code, such as a class named differently in the title and the diff
- release-note oddities: a changelog entry missing most pull requests, or dated differently from the release
- which branch the release comes from, since a minor release may come from the previous branch
5. **Scope.** List commits on the release branch after the tag as out of scope and unreleased.
6. **Write the plan** to `.claude/PLAN-UPGRADE-<to>.md`, using the layout below.
7. **Lint and report.**
Run `npx --yes markdownlint-cli2 --config ~/.claude/markdownlint.jsonc ".claude/PLAN-UPGRADE-<to>.md"` and fix every issue.
Tell the user the counts, the headline items, and anything from step 4 that needs a decision.

## Classification rules

Important: the change affects a project that has copied the skeleton.

- PHP version constraint, or any change to `require` or `conflict` in `composer.json` that reaches runtime
- major version bumps of runtime dependencies
- configuration files added, removed, renamed or with changed keys
- database schema: entity columns, enums, DBAL types, migrations
- entity, repository, service or interface signature changes
- new or changed middleware, pipeline or routes, and any change of response, header or error behavior
- security fixes and security headers
- changes to Composer scripts or the post-install script

Optional: skipping it does not change how the application runs.

- CI workflows and GitHub Action bumps, Renovate, Qodana, code coverage
- README, changelog and other documentation, API collections
- dev-only dependencies with no effect on project code, and comment or type-only cleanups
- config `.dist` clarifications

When unsure, classify as important and say why in the description.
State the condition where a change only matters sometimes, for example "only when using PostgreSQL".

## Plan layout

Follow `.claude/PLAN-UPGRADE-7.1.md` if it exists, otherwise this order:

1. Goal, including the target file path and the page used as the template.
2. Sources checked: release dates, target branch, commit and file counts.
3. Findings that shape the page: the headline changes and the step 4 cross-checks.
4. Pull requests: an important table and an optional table with `PR | Description`, each PR as a full URL, most impactful first.
Escape `|` inside table cells as `\|`.
5. Out of scope: unreleased commits.
6. Page outline: the newest existing `UPGRADE-*.md` is the template, with the same headings, one sentence per line and the same bullet marker.
Details has `### Important updates` and `### Optional updates`, and the FAQ covers PHP versions, migrations, moved config, and whether optional updates are required.
7. Files to change on execution: the new page, the nav entry in `mkdocs.yml` (newest first), and `upgrading.md` only if it links the other version pages.
8. Verification: markdownlint, a check that every PR URL from the release notes appears exactly once, `mkdocs build --strict` if available, and a check of versions against `composer.json` at the tag.

## Rules

- Every claim in the plan and in later FAQ answers must come from a diff or the release notes, not from memory.
- Link pull requests by full URL, as the existing upgrade pages do.
- Major releases (for example 6.x to 7.0) need migration guidance in the FAQ and not just a pull request list; say so in the plan.
- Never publish or share the plan outside the repository.
44 changes: 44 additions & 0 deletions .claude/skills/upgrade-plan/gather.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Collect the raw facts for an upgrade plan between two releases of a Dotkernel repository.
# Usage: gather.sh <from-tag> <to-tag> [owner/repo] (default repo: dotkernel/api)
# Output: Markdown on stdout. Needs gh (authenticated) and jq.
set -euo pipefail

FROM="${1:?usage: gather.sh <from-tag> <to-tag> [owner/repo]}"
TO="${2:?usage: gather.sh <from-tag> <to-tag> [owner/repo]}"
REPO="${3:-dotkernel/api}"

for tool in gh jq; do
command -v "$tool" >/dev/null || { echo "missing required tool: $tool" >&2; exit 1; }
done

echo "# Raw data: $REPO $FROM -> $TO"
echo

echo "## Release $TO"
gh release view "$TO" -R "$REPO" --json tagName,publishedAt,targetCommitish,body \
-q '"- published: \(.publishedAt)\n- target branch: \(.targetCommitish)\n\n\(.body)"'
BRANCH="$(gh release view "$TO" -R "$REPO" --json targetCommitish -q .targetCommitish)"
echo

echo "## Compare $FROM...$TO"
gh api "repos/$REPO/compare/$FROM...$TO" --jq '"- commits: \(.ahead_by)\n- changed files: \(.files | length)"'
echo

echo "## composer.json diff"
echo '```diff'
gh api "repos/$REPO/compare/$FROM...$TO" --jq '.files[] | select(.filename == "composer.json") | .patch' || true
echo '```'
echo

echo "## Files per pull request in the $TO release notes"
gh release view "$TO" -R "$REPO" --json body -q .body | grep -o 'pull/[0-9]*' | sort -t/ -k2 -n -u | cut -d/ -f2 |
while read -r pr; do
gh pr view "$pr" -R "$REPO" --json number,title,mergedAt,files \
-q '"### #\(.number) \(.title)\n- merged: \(.mergedAt)\n- files: \([.files[].path] | join(", "))\n"'
done

echo "## Commits on branch $BRANCH after tag $TO (unreleased)"
gh api "repos/$REPO/compare/$TO...$BRANCH" \
--jq '"- ahead: \(.ahead_by)", (.commits[] | "- \(.sha[0:7]) \(.commit.message | split("\n")[0])")' 2>/dev/null ||
echo "- (branch $BRANCH not comparable)"
85 changes: 85 additions & 0 deletions docs/book/v7/upgrading/UPGRADE-7.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Upgrading from 7.0 to 7.1

## Summary

The changes you need to port into your project when moving from Dotkernel API 7.0 to 7.1, each linked to the pull request that introduced it.
The headline items are the new PHP 8.3 minimum, the upgrade to `mezzio-authentication-oauth2` 3.x, and the schema change to the admin login log.

## Details

> You can find the release notes in [7.1.0](https://github.com/dotkernel/api/releases/tag/7.1.0) and a complete list in [Changelog](https://github.com/dotkernel/api/blob/7.0/CHANGELOG.md)

### Important updates

These changes affect your PHP version, dependencies, configuration, database schema, entities or runtime behavior.

* Upgrade `mezzio/mezzio-authentication-oauth2` to `^3.0.1`: the OAuth entities and repositories are adapted, `Admin` and `NumericIdentifierTrait` types are tightened, and the post-install script now generates `config/autoload/mail.local.php` [https://github.com/dotkernel/api/pull/511](https://github.com/dotkernel/api/pull/511)
* Bump PHPUnit to `^12.5.23` and drop PHP 8.2 support: `composer.json` now requires PHP `~8.3.0 || ~8.4.0 || ~8.5.0` and tests use stubs instead of mocks [https://github.com/dotkernel/api/pull/510](https://github.com/dotkernel/api/pull/510)
* Implement browscap in `AdminLogin`: the columns `deviceBrand`, `deviceModel`, `osPlatform`, `clientEngine` and `clientVersion` are removed and `isCrawler` is added, so a schema migration is required [https://github.com/dotkernel/api/pull/513](https://github.com/dotkernel/api/pull/513)
* Remove `config/autoload/mail.global.php`: mail settings now live in `mail.local.php` [https://github.com/dotkernel/api/pull/499](https://github.com/dotkernel/api/pull/499)
* OAuth2 token invalidated on Composer install/update: adds `bin/generate-oauth2-keys.php`, which skips existing keys, and points `post-update-cmd` to it [https://github.com/dotkernel/api/pull/506](https://github.com/dotkernel/api/pull/506)
* Add security headers in `config/autoload/response-header.global.php`: `X-Content-Type-Options` and `Referrer-Policy` on all responses, `Cache-Control: no-store` and `Pragma: no-cache` on the token endpoints [https://github.com/dotkernel/api/pull/490](https://github.com/dotkernel/api/pull/490)
* Add `MalformedRequestBodyMiddleware`, piped in `config/pipeline.php`: a malformed request body now results in a `BadRequestException` [https://github.com/dotkernel/api/pull/476](https://github.com/dotkernel/api/pull/476)
* Require `symfony/var-exporter` to keep LazyGhost support [https://github.com/dotkernel/api/pull/485](https://github.com/dotkernel/api/pull/485)
* Core sync: `created` becomes nullable in `TimestampsTrait` and `EntityInterface`, and the Admin, User and role entities are updated [https://github.com/dotkernel/api/pull/486](https://github.com/dotkernel/api/pull/486)
* Bump `zircote/swagger-php` to `^6.0.0` [https://github.com/dotkernel/api/pull/522](https://github.com/dotkernel/api/pull/522)

### Optional updates

These changes cover development tooling, CI and documentation.
Skipping them does not affect how the API runs.

* Bump `dotkernel/dot-maker` to `^2.0.0` and add a Composer `conflict` on versions below `2.0` [https://github.com/dotkernel/api/pull/494](https://github.com/dotkernel/api/pull/494)
* Update PostgreSQL host configuration in `config/autoload/local.php.dist` to `127.0.0.1` [https://github.com/dotkernel/api/pull/465](https://github.com/dotkernel/api/pull/465)
* Add Bruno collection, update readme [https://github.com/dotkernel/api/pull/516](https://github.com/dotkernel/api/pull/516)
* Update API version in README example [https://github.com/dotkernel/api/pull/473](https://github.com/dotkernel/api/pull/473)
* Configure Renovate [https://github.com/dotkernel/api/pull/515](https://github.com/dotkernel/api/pull/515)
* Update branch for Qodana workflow to 7.0 [https://github.com/dotkernel/api/pull/491](https://github.com/dotkernel/api/pull/491)
* Update Qodana action version to v2025.3 [https://github.com/dotkernel/api/pull/500](https://github.com/dotkernel/api/pull/500)
* Update `JetBrains/qodana-action` to v2026 [https://github.com/dotkernel/api/pull/523](https://github.com/dotkernel/api/pull/523)
* Update `JetBrains/qodana-action` to v2026.1.3 [https://github.com/dotkernel/api/pull/527](https://github.com/dotkernel/api/pull/527)
* Update `actions/checkout` to v6 [https://github.com/dotkernel/api/pull/518](https://github.com/dotkernel/api/pull/518)
* Update `actions/checkout` to v7 [https://github.com/dotkernel/api/pull/528](https://github.com/dotkernel/api/pull/528)
* Update `actions/cache` to v5 [https://github.com/dotkernel/api/pull/517](https://github.com/dotkernel/api/pull/517)
* Update `actions/cache` to v6 [https://github.com/dotkernel/api/pull/530](https://github.com/dotkernel/api/pull/530)
* Update `codecov/codecov-action` to v6 [https://github.com/dotkernel/api/pull/520](https://github.com/dotkernel/api/pull/520)
* Update `codecov/codecov-action` to v7 [https://github.com/dotkernel/api/pull/526](https://github.com/dotkernel/api/pull/526)

## FAQ

**Q: Is there an automated upgrade from 7.0 to 7.1?**

A: No.
You implement each listed change manually in your own project.
See [Upgrades](upgrading.md) for the recommended procedure.

**Q: Which PHP versions does 7.1 support?**

A: PHP 8.3, 8.4 and 8.5.
PHP 8.2 is no longer supported; raise the `php` constraint in your `composer.json` before updating.

**Q: Do I need a database migration?**

A: Yes, if your project has the `AdminLogin` entity from 7.0.
Pull request 513 removes five columns and adds `isCrawler`.
Review it and generate a migration before touching production data.

**Q: Where did `mail.global.php` go?**

A: Pull request 499 removes it, and pull request 511 makes the post-install script copy the `dot-mail` distribution file to `config/autoload/mail.local.php` (and `mail.local.php.dist`).
The script skips files that already exist, so move your mail settings into `mail.local.php` yourself.

**Q: Do I have to regenerate my OAuth2 keys?**

A: No.
The new `bin/generate-oauth2-keys.php` from pull request 506 only generates keys when `data/oauth/encryption.key`, `private.key` or `public.key` is missing.
Test your authentication flow after upgrading to `mezzio-authentication-oauth2` 3.x (pull request 511).

**Q: Do I have to apply the optional updates?**

A: No.
They only concern tooling, CI and documentation.

**Q: Where do I find the complete list of changes?**

A: In the [7.1.0 release notes](https://github.com/dotkernel/api/releases/tag/7.1.0) and the project [CHANGELOG.md](https://github.com/dotkernel/api/blob/7.0/CHANGELOG.md).
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ nav:
- "FAQ": v7/installation/faq.md
- Upgrading:
- "Upgrade procedure": v7/upgrading/upgrading.md
- "Upgrading 7.0 to 7.1": v7/upgrading/UPGRADE-7.1.md
- "Upgrading 6.x to 7.0": v7/upgrading/UPGRADE-7.0.md
- "Upgrading 5.x to 6.0": v7/upgrading/UPGRADE-6.0.md
- Flow:
Expand Down
Loading