diff --git a/.agents/skills/prepare-providers-documentation/SKILL.md b/.agents/skills/prepare-providers-documentation/SKILL.md index 688160d3a2a38..fb5602f894a62 100644 --- a/.agents/skills/prepare-providers-documentation/SKILL.md +++ b/.agents/skills/prepare-providers-documentation/SKILL.md @@ -108,49 +108,73 @@ date — running breeze the first time below will recreate and fetch it. The skill runs in five phases. Mark tasks with `TaskCreate` for each phase and tick them off as you go — the release manager wants to see progress. -### Phase 1 — Discover providers with pending changes +### Phase 1 — Discover and pre-classify pending changes (deterministic) -For each provider, the source of truth for "what changed since last release" -is the same git query breeze uses internally: commits between the latest -release tag for that provider (`providers-/`) and -`apache-https-for-providers/`, restricted to the provider's own -folders. +The source of truth for "what changed since last release" is the same git +query breeze uses internally: commits between the latest release tag for that +provider (`providers-/`) and `apache-https-for-providers/`, +restricted to the provider's own folders. -Discover in batch by running: +Run the **deterministic classifier** — it discovers every provider with pending +changes **and** pre-classifies each commit with hard-coded, high-confidence +rules, flagging only the genuinely ambiguous ones as `needs_llm`. No random +answers, nothing to discard: ```bash -breeze release-management prepare-provider-documentation \ - --non-interactive \ - --skip-changelog \ - --skip-readme \ - --release-date "$RELEASE_DATE" +breeze release-management classify-provider-changes \ + --base-branch main \ + --output-file /tmp/provider-changes.json +# scope to a subset by appending provider ids, e.g. ... amazon cncf.kubernetes ``` -> [!WARNING] -> Do **not** commit the result of that command. `--non-interactive` answers -> the classification prompts with random values — Claude will overwrite the -> changelog and version bumps in Phase 4 with real classifications. The only -> reason to run breeze first is to refresh the apache remote, regenerate -> build files, and confirm which providers have pending changes (read the -> "Summary of prepared documentation" block at the end). +The JSON it writes: + +```json +{ + "base_branch": "main", + "providers": { + "amazon": { + "current_version": "9.29.0", + "commits": [ + {"hash": "c2dbd7a75a", "pr": "67987", "subject": "Fix IDC domain S3 path resolution", + "classification": "needs_llm", "reason": "no high-confidence deterministic rule matched"}, + {"hash": "abc123", "pr": "68087", "subject": "Bump the edge-ui-package-updates group ...", + "classification": "misc", "reason": "dependency bump (subject starts with 'Bump')"} + ] + } + } +} +``` -Record from the summary: +How to read it: -- **Success** — providers that had real changes (these need classification). -- **Docs only** — providers with only documentation changes (already handled - by breeze; skip in Phase 2). -- **Skipped on no changes** — nothing to do. +- Providers under `providers` have pending changes (these need attention). +- `classification ∈ {documentation, skip, misc}` are **decided by rules — take + them as-is**, no sub-agent needed (doc-only → `documentation`, test/example + only → `skip`, `Bump …` dependency bump → `misc`). +- `classification == needs_llm` → **Phase 3 decides** with a sub-agent. These are + the only commits that need LLM analysis. +- A provider with a `note`/`error` (e.g. a brand-new provider with no prior + release tag) → treat as an **initial release** and classify by hand. -Reset the per-provider files that breeze touched but you'll be rewriting -yourself before continuing: +> [!NOTE] +> The classifier is deliberately conservative: `Fix …`/`Add …` subjects are +> **not** auto-classified (an "Add …" can be a breaking change), so they come +> back as `needs_llm`. The rules live in `classify_change_deterministically` +> (`dev/breeze/src/airflow_breeze/prepare_providers/provider_documentation.py`). + +Then regenerate the auto-generated build files (this does **no** classification, +so nothing random is produced): ```bash +breeze release-management prepare-provider-documentation \ + --reapply-templates-only --release-date "$RELEASE_DATE" git checkout -- $(git diff --name-only -- '**/provider.yaml' '**/changelog.rst') ``` This leaves the regenerated build files (`__init__.py`, `README.rst`, -`pyproject.toml`, `conf.py`, `get_provider_info.py`, `index.rst`) in place -and discards only the stuff Claude is about to rewrite. +`pyproject.toml`, `conf.py`, `get_provider_info.py`, `index.rst`) in place and +discards only the changelog/version files Claude is about to rewrite itself. ### Phase 2 — Per-provider commit list @@ -205,32 +229,35 @@ For each commit, classify it into one of: | `s` | Skip (test/CI/example only — no user impact) | none | | `v` | Min Airflow version bump | minor (treated as misc + bump) | -#### Auto-classify cheap cases first +#### Take the deterministic classifications from Phase 1 -Before spawning a sub-agent, apply the same fast heuristics breeze uses -(see `classify_provider_pr_files` in -`dev/breeze/src/airflow_breeze/prepare_providers/provider_documentation.py`): +`classify-provider-changes` (Phase 1) already classified every commit it could +with hard-coded rules. Read `/tmp/provider-changes.json` and: -- All changed files match `providers//docs/**/*.rst` → **`d`** (docs). -- All changed files match `providers//tests/**` or - `providers//src/airflow/providers//example_dags/**` → **`s`** (skip). -- Subject contains `Bump minimum Airflow version` and only `__init__.py` / - `provider.yaml` changed → **`v`**. +- Use any commit whose `classification` is `documentation`, `skip`, or `misc` + **as-is** — these map to `d`, `s`, `m` respectively; no sub-agent needed. +- Only commits with `classification: needs_llm` go to a sub-agent (below). -Note these classifications and move on — no sub-agent needed. +The deterministic rules (doc-only → `d`, test/example-only → `s`, `Bump …` +dependency bump → `m`) are exactly the cheap cases — now computed once by +breeze (`classify_change_deterministically`) instead of re-derived here. If you +ever need the min-Airflow-bump case (`v`), that one is still a `needs_llm` +judgement: a sub-agent should flag it when a PR bumps the provider's minimum +Airflow version. -#### Classify the rest — batched per provider, not one agent per PR +#### Classify the `needs_llm` commits — batched per provider, not one agent per PR +Only the commits the classifier returned as `needs_llm` still need a sub-agent. Classification is the token-heavy part of this skill, so spend sub-agents sparingly. Do **not** spawn one sub-agent per PR — that is one agent per commit and balloons to hundreds of agents on a normal release wave. Pick the smallest fan-out that fits the volume: -- **Few commits remain (≲ 15 across all providers) → classify inline.** Read - each PR and its provider-scoped diff yourself, in this context. Spawn no +- **Few `needs_llm` commits remain (≲ 15 across all providers) → classify inline.** + Read each PR and its provider-scoped diff yourself, in this context. Spawn no sub-agents at all. - **More than that → one sub-agent per provider.** Each agent classifies that - provider's *entire* remaining commit list in a single pass. This is the + provider's *entire* remaining `needs_llm` list in a single pass. This is the natural unit: multi-provider PRs are classified independently per provider anyway (see Cross-Cutting Rules), and one provider-scoped agent amortizes the breaking-change checklist across all of that provider's commits instead diff --git a/dev/breeze/doc/09_release_management_tasks.rst b/dev/breeze/doc/09_release_management_tasks.rst index 6a4d1a86b2109..63d691950875a 100644 --- a/dev/breeze/doc/09_release_management_tasks.rst +++ b/dev/breeze/doc/09_release_management_tasks.rst @@ -447,6 +447,25 @@ You can also add ``--answer yes`` to perform non-interactive build. :width: 100% :alt: Breeze prepare-provider-documentation +Classifying provider changes +"""""""""""""""""""""""""""" + +You can use Breeze to classify each provider's unreleased changes using hard-coded, +high-confidence rules, flagging ambiguous commits as ``needs_llm`` for an agent or skill +to assess. The result is emitted as JSON, providing a deterministic alternative to the +``--non-interactive`` documentation run used purely for change discovery. + +The below example classifies the pending changes for all providers. + +.. code-block:: bash + + breeze release-management classify-provider-changes + +.. image:: ./images/output_release-management_classify-provider-changes.svg + :target: https://raw.githubusercontent.com/apache/airflow/main/dev/breeze/doc/images/output_release-management_classify-provider-changes.svg + :width: 100% + :alt: Breeze classify-provider-changes + Updating provider next version """""""""""""""""""""""""""""" diff --git a/dev/breeze/doc/images/output_release-management.svg b/dev/breeze/doc/images/output_release-management.svg index 2613a5159f574..309ebac51d6d4 100644 --- a/dev/breeze/doc/images/output_release-management.svg +++ b/dev/breeze/doc/images/output_release-management.svg @@ -1,4 +1,4 @@ - +