This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 391578af620 Add a command to take a prepared provider back out of a
release (#71836)
391578af620 is described below
commit 391578af62027fe8939ad4bd6188eabcc6707f92
Author: Jarek Potiuk <[email protected]>
AuthorDate: Tue Sep 8 18:51:17 2026 +0200
Add a command to take a prepared provider back out of a release (#71836)
* Document dropping a prepared provider back to doc-only
Release managers hit this when review concludes a prepared provider's
changes
are internal after all: the changelog entry can be corrected, but the
version
bump and changelog section stay behind and the provider is still built and
uploaded. The sequence that actually removes it from the wave - and the
marker
file that records it - was described nowhere outside the breeze sources.
The pre-merge sweep only ever looked for providers missing from a wave, so
the
opposite direction had nothing watching it in either the manual or the
agentic
flow.
* Add a command to take a prepared provider back out of a release
When review concludes that an already-prepared provider has no user-facing
changes, correcting its changelog entry leaves the version bump and the
changelog section behind, so the provider is still built and uploaded.
Undoing
that by hand is a restore-rerun-answer-N sequence that release managers
repeatedly get wrong, and it is unavailable during an incremental update at
all:
that mode answers every question with yes, so the prompt that reclassifies a
provider as doc-only never appears.
* Say why a never-released provider cannot be dropped to doc-only
Review pointed out that such a provider gets no doc-only marker. Writing one
would not help: the marker is only read once the current version is tagged,
so
for a first release it is inert, and read literally it would suppress that
release for good. What was wrong is the message, which claimed there were no
changes when the real reason is that there is no earlier release to diff
against.
Marking the two functions that always raise as NoReturn also lets the
compiler,
rather than the reader, establish that the loop cannot continue past the
doc-only branch.
* Refresh the breeze command hash for prepare-provider-documentation
The committed hash was computed against a stale cached breeze build, so CI's
static checks regenerated it and failed the run.
Generated-by: Claude Code (Opus 5)
Claude-Session: https://claude.ai/code/session_01XS3bodTDYYGrPmorhtLsjP
---
.../prepare-providers-documentation/SKILL.md | 22 ++++++
dev/README_RELEASE_PROVIDERS.md | 58 +++++++++++++++
...e-management_prepare-provider-documentation.svg | 78 ++++++++++++--------
...e-management_prepare-provider-documentation.txt | 2 +-
.../commands/release_management_commands.py | 23 +++++-
.../commands/release_management_commands_config.py | 1 +
.../prepare_providers/provider_documentation.py | 45 +++++++++++-
dev/breeze/tests/test_provider_documentation.py | 83 +++++++++++++++++++++-
8 files changed, 276 insertions(+), 36 deletions(-)
diff --git a/.agents/skills/prepare-providers-documentation/SKILL.md
b/.agents/skills/prepare-providers-documentation/SKILL.md
index d5d5fe84998..cfcfda85817 100644
--- a/.agents/skills/prepare-providers-documentation/SKILL.md
+++ b/.agents/skills/prepare-providers-documentation/SKILL.md
@@ -901,6 +901,28 @@ git diff --name-only <base-branch>..HEAD --
'**/provider.yaml' \
- **Bucket B — not in the wave.** The provider has unrecorded commits but no
new version section, so it is a candidate to *join*. Classify it
(Incremental Phase 3), then take it to **Incremental Phase 3.6**.
+- **Bucket C — in the wave but no longer warranting a release.** The sweep
+ above only finds commits *missing* from a wave; this bucket is the opposite
+ direction, and nothing else in the flow looks for it. A provider that review
+ has since concluded is internal-only or documentation-only still carries the
+ version bump and changelog section written by the initial run, so it would
+ still be built and uploaded to PyPI. Find these by re-reading the entries of
+ each in-wave provider's newest changelog section: if every entry is
+ `Doc-only`, or review reclassified the last remaining non-doc entry as
+ documentation, the provider should leave the wave.
+
+ Drop it back with the dedicated command rather than editing the files by
+ hand — it restores `provider.yaml` and `changelog.rst` to their released
+ state and writes the marker in one step:
+
+ ```bash
+ breeze release-management prepare-provider-documentation --mark-doc-only
<provider-id>
+ ```
+
+ Then commit `providers/<provider-path>/docs/.latest-doc-only-change.txt`.
+ **Ask the release manager before doing it** — taking a provider out of a wave
+ is their decision, and a `Misc` entry that merely *looks* internal may still
+ be something they want released.
Most Bucket B rows are ordinary noise — repo-wide tooling and test commits
that correctly keep a provider out of the release. A Bucket B provider whose
diff --git a/dev/README_RELEASE_PROVIDERS.md b/dev/README_RELEASE_PROVIDERS.md
index 34c2132bf0f..eedaa88cbd8 100644
--- a/dev/README_RELEASE_PROVIDERS.md
+++ b/dev/README_RELEASE_PROVIDERS.md
@@ -378,6 +378,56 @@ In case you want to also release a pre-installed provider
that is in ``not-ready
you want to release it before you switch their state to ``ready``), pass
``--include-not-ready-providers``.
+### Dropping a prepared provider back to doc-only (no PyPI artifact)
+
+Two different outcomes are both called "doc-only", and the difference decides
whether the provider
+gets a PyPI release at all:
+
+| | What it means | PyPI artifact |
+|---|---|---|
+| A `doc-only` entry in the changelog | The provider *is* released; one of the
entries in the release happens to be documentation | **Yes** |
+| The `.latest-doc-only-change.txt` marker | The provider is *not* released at
all; only its documentation is republished | **No** |
+
+The second case comes up when a provider was already prepared with, say, a
`Misc` entry, and review
+then concludes the change is internal or documentation only, so there is
nothing for users to install.
+Changing the changelog entry is not enough — the version bump and the
changelog stay prepared, and the
+provider would still be built and uploaded. Drop the provider back to doc-only
with:
+
+```shell script
+breeze release-management prepare-provider-documentation --mark-doc-only
PROVIDER [MORE PROVIDERS]
+```
+
+This restores the provider's `provider.yaml` and `changelog.rst` to their
released state, then writes
+`providers/PROVIDER/docs/.latest-doc-only-change.txt`. No version bump, no
changelog section, no
+distribution. It needs an explicit list of providers — it takes them out of
the release, so it will
+not default to every provider.
+
+Commit the marker file afterwards. It is the only artifact of the whole
sequence, and it must be
+committed or the next release will prepare the provider again:
+
+```shell script
+git add providers/PROVIDER/docs/.latest-doc-only-change.txt
+```
+
+Doing it by hand is the same three steps: restore those two files, re-run
+`prepare-provider-documentation PROVIDER`, and answer **`N`** to
+`Does the provider: PROVIDER have any changes apart from 'doc-only'?`. Note
that the interactive
+prompt is not reachable during `--incremental-update`, which answers every
question with "yes" —
+that is what `--mark-doc-only` is for.
+
+The marker holds the full commit hash of the latest change that was declared
doc-only. On the next
+release, the tooling counts commits since that hash rather than since the last
release tag, so:
+
+* if nothing landed since the marker, the provider is skipped with
+ `The provider has doc-only changes since the last release. Skipping`;
+* if something did land, only the commits after the marker are classified, so
the changes already
+ declared doc-only are not offered for classification a second time.
+
+> [!NOTE]
+> The same applies when using the `prepare-providers-documentation` skill — it
classifies commits,
+> but the decision that a prepared provider should not be released at all is
still made by the
+> release manager, and is still recorded by this marker file.
+
## Update versions of dependent providers to the next version
Sometimes when contributors want to use next version of a dependent provider,
instead of
@@ -458,6 +508,14 @@ following labels to the PR (if they aren't already set
from the original PR):
* `skip common compat check`
* `allow provider dependency bump`
+The rebase before merging is also the point to check the wave in the other
direction. The incremental
+flow looks for commits that are *missing* from the release; it does not look
for providers that are in
+the release but should no longer be there. If review concluded that a prepared
provider's only changes
+are internal or documentation, that provider still carries its version bump
and changelog section, and
+it would still be built and uploaded. Drop it back with [Dropping a prepared
provider back to
+doc-only](#dropping-a-prepared-provider-back-to-doc-only-no-pypi-artifact)
before merging, so the
+decision made in review is actually reflected in what gets released.
+
Once approved, merge it - be careful to do it quickly so that no new PRs are
merged for
providers in the meantime; if they are, you'd miss them in the changelog.
diff --git
a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
index 4a2a8e8c474..f300add9c2c 100644
---
a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
+++
b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg
@@ -1,4 +1,4 @@
-<svg class="rich-terminal" viewBox="0 0 1482 1294.3999999999999"
xmlns="http://www.w3.org/2000/svg">
+<svg class="rich-terminal" viewBox="0 0 1482 1392.0"
xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@@ -43,7 +43,7 @@
<defs>
<clipPath
id="breeze-release-management-prepare-provider-documentation-clip-terminal">
- <rect x="0" y="0" width="1463.0" height="1243.3999999999999" />
+ <rect x="0" y="0" width="1463.0" height="1341.0" />
</clipPath>
<clipPath
id="breeze-release-management-prepare-provider-documentation-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
@@ -195,9 +195,21 @@
<clipPath
id="breeze-release-management-prepare-provider-documentation-line-49">
<rect x="0" y="1197.1" width="1464" height="24.65"/>
</clipPath>
+<clipPath
id="breeze-release-management-prepare-provider-documentation-line-50">
+ <rect x="0" y="1221.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath
id="breeze-release-management-prepare-provider-documentation-line-51">
+ <rect x="0" y="1245.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath
id="breeze-release-management-prepare-provider-documentation-line-52">
+ <rect x="0" y="1270.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath
id="breeze-release-management-prepare-provider-documentation-line-53">
+ <rect x="0" y="1294.7" width="1464" height="24.65"/>
+ </clipPath>
</defs>
- <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="1292.4" rx="8"/><text
class="breeze-release-management-prepare-provider-documentation-title"
fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: release-management prepare-provider-documentation</text>
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1"
x="1" y="1" width="1480" height="1390" rx="8"/><text
class="breeze-release-management-prepare-provider-documentation-title"
fill="#c5c8c6" text-anchor="middle" x="740"
y="27">Command: release-management prepare-provider-documentation</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
@@ -229,35 +241,39 @@
</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="483.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="483.6" textLength="366"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-19)">2025-11-16 or 2025-11-16_01). </text><text
class="breeze-release-management-p [...]
</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="508" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="508" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-20)">--incremental-update     </text><text
class="breeze-release-management-p [...]
</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="532.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="532.4" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-21)">changes.             
[...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="556.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="556.8" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">--only-min-version-update</text><text
class="breeze-release-management-prepare-provider-docum [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="581.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="581.2" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">documentation            
[...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="605.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="605.6" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">--reapply-templates-only </text><text
class="breeze-release-management-prepare-provider- [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="630" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="630" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">to regenerate documentation.         &
[...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="654.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="654.4" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">--non-interactive        </text><text
class="breeze-r [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="678.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="678.8" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">releasefor providers prepared for release - useful to&
[...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="703.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="703.2" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">mode in CI.           &#
[...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="727.6" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="727.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provid [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="752" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="752" textLength="366"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)"> Select non-regular providers </text><text
class="breeze-release-management- [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="776.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="776.4" textLength="353.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">--include-not-ready-providers</text><text
class="breeze-release-management-prepare-provider [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="800.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="800.8" textLength="353.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">--include-removed-providers  </text><text
class="breeze-release-management-prepar [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="556.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="556.8" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-22)">--mark-doc-only          </text><text
class [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="581.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="581.2" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-23)">the released state and record the doc-only marker 
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="605.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="605.6" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-24)">that an already-prepared provider has no user-facing c
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="630" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="630" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-25)">of providers.            
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="654.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="654.4" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-26)">--only-min-version-update</text><text
class="breeze-release-management-prepare-provider-docum [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="678.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="678.8" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-27)">documentation            
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="703.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="703.2" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-28)">--reapply-templates-only </text><text
class="breeze-release-management-prepare-provider- [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="727.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="727.6" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-29)">to regenerate documentation.        
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="752" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="752" textLength="305"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-30)">--non-interactive        </text><text
class="breeze-relea [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="776.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="776.4" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-31)">releasefor providers prepared for release - useful to&
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="800.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="353.8"
y="800.8" textLength="1085.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-32)">mode in CI.           &#
[...]
</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="825.2" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-33)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="825.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provid [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="849.6" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="849.6" textLength="146.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)"> Skip steps </text><text
class="breeze-release-management-prepare-provider- [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="874" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="874" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">--skip-git-fetch</text><text
class="breeze-release-management-prepare-provider-documentation-r1 [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="898.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="244"
y="898.4" textLength="1195.6"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">is recreated and fetched to make sure that it'
[...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="922.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="922.8" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">--skip-changelog</text><text
class="breeze-release-management-prepare-provider-documentatio [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="947.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="947.2" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">--skip-readme   </text><text
class="breeze-release-management-prepare-provid [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="971.6" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="971.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provid [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="996" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="996" textLength="219.6"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)"> Advanced options </text><text
class="breeze-release-management-prepare-provide [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1020.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1020.4" textLength="231.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">--base-branch      </text><text
class="breeze-release-manag [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1044.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-42)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="329.4"
y="1044.8" textLength="97.6"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-42)">branch) </text><text
class="breeze-release-management-prepare-provider-documentation [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1069.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-43)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1069.2" textLength="231.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-43)">--github-repository</text><text
class="breeze-release-management-prepare-provider-documen [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1093.6" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-44)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="1093.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-prov [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1118" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-45)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="1118" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-45)"> Common options </text><text
class="breeze-release-management-prepare-provide [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1142.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-46)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1142.4" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-46)">--verbose</text><text
class="breeze-release-management-prepare-provider-documentation-r7" [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1166.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-47)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1166.8" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-47)">--answer </text><text
class="breeze-release-management-prepare-provider-documentatio [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1191.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-48)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1191.2" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-48)">--dry-run</text><text
class="breeze-release-management-prepare-provider-documentation-r7" [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1215.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-49)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1215.6" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-49)">--help   </text><text
class="breeze-release-management-prepare-provider-do [...]
-</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1240" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-50)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="1240" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="849.6" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="849.6" textLength="366"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-34)"> Select non-regular providers </text><text
class="breeze-release-managem [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="874" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="874" textLength="353.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-35)">--include-not-ready-providers</text><text
class="breeze-release-management-prepare-provider-doc [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="898.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="898.4" textLength="353.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-36)">--include-removed-providers  </text><text
class="breeze-release-management-prepar [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="922.8" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-37)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="922.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provid [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="947.2" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="947.2" textLength="146.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-38)"> Skip steps </text><text
class="breeze-release-management-prepare-provider- [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="971.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="971.6" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-39)">--skip-git-fetch</text><text
class="breeze-release-management-prepare-provider-documentatio [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="996" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="244"
y="996" textLength="1195.6"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-40)">is recreated and fetched to make sure that it's
[...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1020.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1020.4" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-41)">--skip-changelog</text><text
class="breeze-release-management-prepare-provider-documentat [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1044.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-42)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1044.8" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-42)">--skip-readme   </text><text
class="breeze-release-management-prepare-prov [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1069.2" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-43)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="1069.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-prov [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1093.6" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-44)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="1093.6" textLength="219.6"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-44)"> Advanced options </text><text
class="breeze-release-management-prepare-p [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1118" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-45)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1118" textLength="231.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-45)">--base-branch      </text><text
class="breeze-release-managemen [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1142.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-46)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="329.4"
y="1142.4" textLength="97.6"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-46)">branch) </text><text
class="breeze-release-management-prepare-provider-documentation [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1166.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-47)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1166.8" textLength="231.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-47)">--github-repository</text><text
class="breeze-release-management-prepare-provider-documen [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1191.2" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-48)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="1191.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-prov [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1215.6" textLength="24.4"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-49)">╭─</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="24.4"
y="1215.6" textLength="195.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-49)"> Common options </text><text
class="breeze-release-management-prepare-pro [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1240" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-50)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1240" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-50)">--verbose</text><text
class="breeze-release-management-prepare-provider-documentation-r7" x=" [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1264.4" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-51)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1264.4" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-51)">--answer </text><text
class="breeze-release-management-prepare-provider-documentatio [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1288.8" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-52)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1288.8" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-52)">--dry-run</text><text
class="breeze-release-management-prepare-provider-documentation-r7" [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1313.2" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-53)">│</text><text
class="breeze-release-management-prepare-provider-documentation-r4" x="24.4"
y="1313.2" textLength="109.8"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-53)">--help   </text><text
class="breeze-release-management-prepare-provider-do [...]
+</text><text
class="breeze-release-management-prepare-provider-documentation-r5" x="0"
y="1337.6" textLength="1464"
clip-path="url(#breeze-release-management-prepare-provider-documentation-line-54)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯</text><text
class="breeze-release-management-prepare-provider-documentation-r1" x="1464"
y="1337.6" textLength="12.2"
clip-path="url(#breeze-release-management-prepare-prov [...]
</text>
</g>
</g>
diff --git
a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
index e7ca97a104b..8b5412434a2 100644
---
a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
+++
b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt
@@ -1 +1 @@
-a94ab59178e740921f451bdc68bfb445
+2abadb69d28b092ff196d4c4830046fe
diff --git
a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
index f0eb946b1c5..c876d17d654 100644
--- a/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
+++ b/dev/breeze/src/airflow_breeze/commands/release_management_commands.py
@@ -981,6 +981,13 @@ def classify_provider_changes(
is_flag=True,
help="Runs incremental update only after rebase of earlier branch to check
if there are no changes.",
)
[email protected](
+ "--mark-doc-only",
+ is_flag=True,
+ help="Take the named providers back out of the release: restore their
version and changelog to the "
+ "released state and record the doc-only marker to commit. Use when review
concludes that an "
+ "already-prepared provider has no user-facing changes. Requires an
explicit list of providers.",
+)
@click.option(
"--skip-readme",
is_flag=True,
@@ -1011,6 +1018,7 @@ def prepare_provider_documentation(
skip_changelog: bool,
skip_readme: bool,
incremental_update: bool,
+ mark_doc_only: bool,
release_date: str | None,
):
from airflow_breeze.prepare_providers.provider_documentation import (
@@ -1019,6 +1027,7 @@ def prepare_provider_documentation(
PrepareReleaseDocsNoChangesException,
PrepareReleaseDocsUserQuitException,
PrepareReleaseDocsUserSkippedException,
+ drop_provider_to_doc_only,
update_changelog,
update_index_rst,
update_min_airflow_version_and_build_files,
@@ -1029,10 +1038,19 @@ def prepare_provider_documentation(
console_print("[error]Release date is required unless
--only-min-version-update is used![/]")
sys.exit(1)
+ if mark_doc_only and not provider_distributions:
+ console_print(
+ "[error]--mark-doc-only takes the named providers out of the
release, so it needs an "
+ "explicit list of providers rather than defaulting to all of
them![/]"
+ )
+ sys.exit(1)
+
perform_environment_checks()
fix_ownership_using_docker()
cleanup_python_generated_files()
- if incremental_update:
+ # Forcing "yes" keeps the incremental pass from re-asking about every
provider, which also puts
+ # the reclassify-to-doc-only prompt out of reach - --mark-doc-only is how
that decision is applied.
+ if incremental_update and not mark_doc_only:
set_forced_answer("yes")
if not provider_distributions:
provider_distributions = get_available_distributions(
@@ -1052,6 +1070,9 @@ def prepare_provider_documentation(
for provider_id in provider_distributions:
try:
provider_metadata = basic_provider_checks(provider_id)
+ if mark_doc_only:
+ with ci_group(f"Marking '{provider_id}' as doc-only"):
+ drop_provider_to_doc_only(provider_id,
base_branch=base_branch)
if os.environ.get("GITHUB_ACTIONS", "false") != "true":
if not only_min_version_update:
console_print("-" * get_console().width)
diff --git
a/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
b/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
index fdca9db46e6..4c6175d5949 100644
---
a/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
+++
b/dev/breeze/src/airflow_breeze/commands/release_management_commands_config.py
@@ -293,6 +293,7 @@ RELEASE_MANAGEMENT_PARAMETERS: dict[str, list[dict[str, str
| list[str]]]] = {
"options": [
"--release-date",
"--incremental-update",
+ "--mark-doc-only",
"--only-min-version-update",
"--reapply-templates-only",
"--non-interactive",
diff --git
a/dev/breeze/src/airflow_breeze/prepare_providers/provider_documentation.py
b/dev/breeze/src/airflow_breeze/prepare_providers/provider_documentation.py
index 4fcd4dd34c9..6de99e295e0 100644
--- a/dev/breeze/src/airflow_breeze/prepare_providers/provider_documentation.py
+++ b/dev/breeze/src/airflow_breeze/prepare_providers/provider_documentation.py
@@ -30,7 +30,7 @@ from enum import Enum
from pathlib import Path
from shutil import copyfile
from time import time
-from typing import Any, NamedTuple
+from typing import Any, NamedTuple, NoReturn
from packaging.version import Version, parse
from rich.syntax import Syntax
@@ -588,7 +588,7 @@ def _ask_the_user_for_the_type_of_changes(non_interactive:
bool) -> TypeOfChange
def _mark_latest_changes_as_documentation_only(
provider_id: str, list_of_list_of_latest_changes: list[list[Change]]
-):
+) -> NoReturn:
latest_change = list_of_list_of_latest_changes[0][0]
provider_details = get_provider_details(provider_id=provider_id)
console_print(
@@ -601,6 +601,47 @@ def _mark_latest_changes_as_documentation_only(
raise PrepareReleaseDocsChangesOnlyException()
+def drop_provider_to_doc_only(provider_id: str, base_branch: str) -> NoReturn:
+ """Take a provider that is already prepared for release back out of the
wave.
+
+ Review can conclude that a prepared provider's changes are internal after
all. Correcting the
+ changelog entry is not enough: the version bump and the changelog section
are already written,
+ so the provider would still be built and uploaded. Restoring both files to
their released state
+ and recording the doc-only marker is what actually removes it from the
release.
+ """
+ provider_details = get_provider_details(provider_id=provider_id)
+ provider_yaml_path = get_provider_yaml(provider_id)
+ changelog_path = provider_details.root_provider_path / "docs" /
"changelog.rst"
+ restore_paths = [str(path) for path in (provider_yaml_path,
changelog_path) if path.exists()]
+ console_print(f"[info]Restoring {provider_id} to its released state before
marking it doc-only.[/]")
+ run_command(
+ ["git", "checkout", f"{HTTPS_REMOTE}/{base_branch}", "--",
*restore_paths],
+ cwd=AIRFLOW_ROOT_PATH,
+ check=True,
+ )
+ clear_cache_for_provider_metadata(provider_yaml_path=provider_yaml_path)
+ marked_for_release, list_of_list_of_changes, _ =
_get_all_changes_for_package(
+ provider_id=provider_id,
+ base_branch=base_branch,
+ reapply_templates_only=False,
+ only_min_version_update=False,
+ )
+ if not list_of_list_of_changes or not list_of_list_of_changes[0]:
+ if marked_for_release:
+ # Restored to the released state and still up for release with no
earlier version to diff
+ # against: the provider has never been released. The marker means
"everything after this
+ # commit is documentation" and is only read once the current
version is tagged, so writing
+ # one here would be inert - and taken literally, would suppress
the first release for good.
+ console_print(
+ f"[warning]{provider_id} has never been released, so there is
no release to take it "
+ f"out of. Its prepared files were restored - drop it from the
wave instead.[/]"
+ )
+ else:
+ console_print(f"[warning]No changes found for {provider_id} -
nothing to mark as doc-only.[/]")
+ raise PrepareReleaseDocsNoChangesException()
+ _mark_latest_changes_as_documentation_only(provider_id,
list_of_list_of_changes)
+
+
VERSION_MAJOR_INDEX = 0
VERSION_MINOR_INDEX = 1
VERSION_PATCHLEVEL_INDEX = 2
diff --git a/dev/breeze/tests/test_provider_documentation.py
b/dev/breeze/tests/test_provider_documentation.py
index 9deb9b225cb..25d7b493291 100644
--- a/dev/breeze/tests/test_provider_documentation.py
+++ b/dev/breeze/tests/test_provider_documentation.py
@@ -30,6 +30,7 @@ from airflow_breeze.prepare_providers.provider_documentation
import (
VERSION_PATCHLEVEL_INDEX,
Change,
PrepareReleaseDocsChangesOnlyException,
+ PrepareReleaseDocsNoChangesException,
TypeOfChange,
_convert_git_changes_to_table,
_find_insertion_index_for_version,
@@ -38,12 +39,13 @@ from
airflow_breeze.prepare_providers.provider_documentation import (
_get_git_log_command,
classification_result,
classify_change_deterministically,
+ drop_provider_to_doc_only,
get_most_impactful_change,
get_version_tag,
update_release_notes,
)
from airflow_breeze.utils.confirm import Answer
-from airflow_breeze.utils.packages import ProviderPackageDetails
+from airflow_breeze.utils.packages import HTTPS_REMOTE, ProviderPackageDetails
PROVIDER_DOCUMENTATION =
"airflow_breeze.prepare_providers.provider_documentation"
@@ -601,3 +603,82 @@ def
test_doc_only_marker_written_when_classification_overrides_user_answer(
)
assert marker_file.read_text().strip() == change.full_hash
+
+
+def _make_doc_only_change(full_hash: str = "a" * 40) -> Change:
+ return Change(
+ full_hash=full_hash,
+ short_hash=full_hash[:7],
+ date="2026-06-08",
+ version="1.0.0",
+ message="Fix a typo",
+ message_without_backticks="Fix a typo",
+ pr="123",
+ )
+
+
[email protected]("airflow_breeze.prepare_providers.provider_documentation.run_command")
[email protected]("airflow_breeze.prepare_providers.provider_documentation._get_all_changes_for_package")
[email protected]("airflow_breeze.prepare_providers.provider_documentation.clear_cache_for_provider_metadata")
[email protected]("airflow_breeze.prepare_providers.provider_documentation.get_provider_yaml")
[email protected]("airflow_breeze.prepare_providers.provider_documentation.get_provider_details")
+def
test_drop_provider_to_doc_only_restores_the_release_state_and_records_the_marker(
+ mock_details, mock_yaml, mock_clear_cache, mock_changes, mock_run, tmp_path
+):
+ """Correcting the changelog is not enough - the prepared bump would still
be released."""
+ docs = tmp_path / "docs"
+ docs.mkdir()
+ changelog = docs / "changelog.rst"
+ changelog.write_text("changelog")
+ provider_yaml = tmp_path / "provider.yaml"
+ provider_yaml.write_text("versions: [1.0.0]")
+ mock_details.return_value = mock.MagicMock(root_provider_path=tmp_path)
+ mock_yaml.return_value = provider_yaml
+ mock_changes.return_value = (True, [[_make_doc_only_change()]], "table")
+
+ with pytest.raises(PrepareReleaseDocsChangesOnlyException):
+ drop_provider_to_doc_only("amazon", base_branch="main")
+
+ restored = mock_run.call_args.args[0]
+ assert restored[:4] == ["git", "checkout", f"{HTTPS_REMOTE}/main", "--"]
+ assert str(provider_yaml) in restored
+ assert str(changelog) in restored
+ assert (docs / ".latest-doc-only-change.txt").read_text() == "a" * 40 +
"\n"
+
+
[email protected](
+ ("marked_for_release", "expected_reason"),
+ [
+ pytest.param(True, "has never been released", id="never-released"),
+ pytest.param(False, "No changes found",
id="nothing-since-last-release"),
+ ],
+)
[email protected]("airflow_breeze.prepare_providers.provider_documentation.run_command")
[email protected]("airflow_breeze.prepare_providers.provider_documentation._get_all_changes_for_package")
[email protected]("airflow_breeze.prepare_providers.provider_documentation.clear_cache_for_provider_metadata")
[email protected]("airflow_breeze.prepare_providers.provider_documentation.get_provider_yaml")
[email protected]("airflow_breeze.prepare_providers.provider_documentation.get_provider_details")
+def
test_drop_provider_to_doc_only_writes_no_marker_when_there_is_nothing_to_mark(
+ mock_details,
+ mock_yaml,
+ mock_clear_cache,
+ mock_changes,
+ mock_run,
+ tmp_path,
+ capsys,
+ marked_for_release,
+ expected_reason,
+):
+ """An empty marker would silence the provider's next release entirely, and
a provider without a
+ release has nothing for the marker to point at."""
+ docs = tmp_path / "docs"
+ docs.mkdir()
+ mock_details.return_value = mock.MagicMock(root_provider_path=tmp_path)
+ mock_yaml.return_value = tmp_path / "provider.yaml"
+ mock_changes.return_value = (marked_for_release, [], "")
+
+ with pytest.raises(PrepareReleaseDocsNoChangesException):
+ drop_provider_to_doc_only("amazon", base_branch="main")
+
+ assert not (docs / ".latest-doc-only-change.txt").exists()
+ assert expected_reason in capsys.readouterr().out