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 ea9f13c70dd Prepare airflow-ctl 0.1.4rc1 release (#65468)
ea9f13c70dd is described below
commit ea9f13c70dd665b63d92972c2c05c48d1839d648
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sun Apr 19 13:20:46 2026 +0200
Prepare airflow-ctl 0.1.4rc1 release (#65468)
* Prepare airflow-ctl 0.1.4rc1 release
* Fix spellcheck: quote 'uvx' and 'datamodels' in RELEASE_NOTES.rst
---
airflow-ctl/RELEASE_NOTES.rst | 38 +++++++++++
airflow-ctl/newsfragments/59850.significant.rst | 30 ---------
airflow-ctl/src/airflowctl/__init__.py | 2 +-
dev/README_RELEASE_AIRFLOWCTL.md | 84 ++++++++++++++++++++++---
4 files changed, 116 insertions(+), 38 deletions(-)
diff --git a/airflow-ctl/RELEASE_NOTES.rst b/airflow-ctl/RELEASE_NOTES.rst
index 3e4ac4427de..fe76a09d33b 100644
--- a/airflow-ctl/RELEASE_NOTES.rst
+++ b/airflow-ctl/RELEASE_NOTES.rst
@@ -15,6 +15,44 @@
specific language governing permissions and limitations
under the License.
+airflowctl 0.1.4 (2026-04-18)
+-----------------------------
+
+Significant Changes
+^^^^^^^^^^^^^^^^^^^
+
+- Add YAML-based help texts for auto-generated airflowctl commands (#65073)
+- Added plugins command to airflowctl (#64935)
+- Allow direct execution from airflowctl via ``uvx`` (#64406)
+- Python 3.14 support (#63520)
+
+Bug Fixes
+^^^^^^^^^
+
+- Prevent path traversal via AIRFLOW_CLI_ENVIRONMENT in airflowctl (#64618)
+- Fix ``is_alive`` default in ``airflowctl jobs list`` to show all jobs
(#65065)
+- Fix CLI error handling and exit codes for failed commands (#65052)
+- Fix list-envs auth status for env names containing ``.json`` (#64677)
+- Fix infinite loop for ``limit<0`` in airflowctl list operations (#64582)
+- Fix ``airflowctl dagrun list`` limit handling (#64071)
+- Fix incorrect fallback logic in airflowctl API client (#64586)
+- Fix ``airflowctl connections import`` to return non-zero exit code on
failure (#64416)
+- Fix ``airflowctl variables import`` to correctly handle falsy values (#64362)
+- Fix ``airflowctl version`` command prompting for keyring credentials (#63772)
+- Fix ``airflowctl`` boolean flags on Python 3.14 (#63587)
+
+Improvements
+^^^^^^^^^^^^
+
+- Support cursor-based pagination for ``get_task_instances`` in airflowctl
``datamodels`` (#64845)
+- Expose ``is_backfillable`` property on DAG responses in airflowctl
``datamodels`` (#64644)
+- Add ``operator`` value to ``DagRunType`` in airflowctl ``datamodels``
(#63733)
+- Support clear / mark success / mark fail / delete for multiple task
instances (#64141)
+- Use DAG form when materializing assets in airflowctl (#64211)
+- Allow ``null`` ``dag_run_conf`` in ``BackfillResponse`` serialization
(#63259)
+- Mention Python 3.14 support in docs (#63950)
+
+
airflowctl 0.1.3 (2026-03-09)
-----------------------------
diff --git a/airflow-ctl/newsfragments/59850.significant.rst
b/airflow-ctl/newsfragments/59850.significant.rst
deleted file mode 100644
index dfb10ae852c..00000000000
--- a/airflow-ctl/newsfragments/59850.significant.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-Remove ``airflowctl variables export`` command
-
-The ``airflowctl variables export`` command has been removed from the remote
CLI. Variable export functionality is only available through the local Airflow
CLI.
-
-**What changed:**
-
-- Removed ``airflowctl variables export`` command
-
-**Migration:**
-
-Use the local Airflow CLI command for exporting variables:
-
-.. code-block:: bash
-
- # Old (no longer available)
- airflowctl variables export variables.json
-
- # New (use local CLI)
- airflow variables export variables.json
-
-* Types of change
-
- * [ ] Dag changes
- * [ ] Config changes
- * [ ] API changes
- * [x] CLI changes
- * [ ] Behaviour changes
- * [ ] Plugin changes
- * [ ] Dependency changes
- * [ ] Code interface changes
diff --git a/airflow-ctl/src/airflowctl/__init__.py
b/airflow-ctl/src/airflowctl/__init__.py
index 974222d4f46..d2dd19e81e2 100644
--- a/airflow-ctl/src/airflowctl/__init__.py
+++ b/airflow-ctl/src/airflowctl/__init__.py
@@ -19,4 +19,4 @@ from __future__ import annotations
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
-__version__ = "0.1.3"
+__version__ = "0.1.4"
diff --git a/dev/README_RELEASE_AIRFLOWCTL.md b/dev/README_RELEASE_AIRFLOWCTL.md
index b760e283c93..fbe593e90b0 100644
--- a/dev/README_RELEASE_AIRFLOWCTL.md
+++ b/dev/README_RELEASE_AIRFLOWCTL.md
@@ -26,7 +26,8 @@
- [Decide when to release](#decide-when-to-release)
- [Airflow-ctl versioning](#airflow-ctl-versioning)
- [Prepare Regular airflow-ctl distributions
(RC)](#prepare-regular-airflow-ctl-distributions-rc)
- - [Generate release notes](#generate-release-notes)
+ - [Bump the version and generate release
notes](#bump-the-version-and-generate-release-notes)
+ - [Commit the version bump and release notes via a merged
PR](#commit-the-version-bump-and-release-notes-via-a-merged-pr)
- [Build airflow-ctl distributions for SVN apache
upload](#build-airflow-ctl-distributions-for-svn-apache-upload)
- [Build and sign the source and convenience
packages](#build-and-sign-the-source-and-convenience-packages)
- [Add tags in git](#add-tags-in-git)
@@ -122,17 +123,31 @@ echo "Previous: ${PREVIOUS_VERSION} Current: ${VERSION}
RC: ${VERSION_RC}"
# Prepare Regular airflow-ctl distributions (RC)
-## Generate release notes
+## Bump the version and generate release notes
-Generate the RST changelog for the new release by running:
+The `apache-airflow-ctl` version is read by `hatch` from
+`airflow-ctl/src/airflowctl/__init__.py` (`[tool.hatch.version].path` in
+`airflow-ctl/pyproject.toml`). Before anything else, bump it to the version you
+are releasing:
```shell script
-breeze release-management generate-airflowctl-changelog --previous-release
"airflow-ctl/${PREVIOUS_VERSION}" --version "${VERSION}"
+sed -i.bak -E "s/^__version__ = \".*\"/__version__ = \"${VERSION}\"/" \
+ ${AIRFLOW_REPO_ROOT:-$(pwd -P)}/airflow-ctl/src/airflowctl/__init__.py
+rm ${AIRFLOW_REPO_ROOT:-$(pwd -P)}/airflow-ctl/src/airflowctl/__init__.py.bak
+```
+
+Then generate the RST changelog for the new release by running:
+
+```shell script
+GITHUB_TOKEN=$(gh auth token) \
+ breeze release-management generate-airflowctl-changelog \
+ --previous-release "airflow-ctl/${PREVIOUS_VERSION}" \
+ --version "${VERSION}"
```
`--current-release` defaults to `HEAD` so you do not need to tag first.
-The command fetches PR metadata from GitHub (using `gh auth token` or
`GITHUB_TOKEN`) and
-categorises each merged PR into one of:
+The command fetches PR metadata from GitHub (using `GITHUB_TOKEN` or
+`gh auth token`) and categorises each merged PR into one of:
- **Significant Changes** — PRs whose title starts with `feat`, `add`, or
`allow`
- **Bug Fixes** — PRs whose title starts with `fix`
@@ -143,7 +158,57 @@ By default, the new section is **prepended** to
`airflow-ctl/RELEASE_NOTES.rst`
previous version entry. Pass `--output-file -` to print to stdout instead, or
`--output-file <path>` to write to a different file.
-Review the changes to `airflow-ctl/RELEASE_NOTES.rst` and commit before
proceeding.
+The auto-categorisation is a best-effort keyword match, so **manual review of
+the generated section is required**. Typical cleanups:
+
+- Move CI / build / dependency-bump entries out of *Significant Changes* or
+ *Improvements* and into *Miscellaneous* — or drop the *Miscellaneous* section
+ entirely, since its items have no user impact.
+- Strip leaked branch prefixes (`[main]`, `[v3-X-test]`) from PR titles.
+- Security fixes sometimes land in *Improvements*; move them to *Bug Fixes*.
+- API-server-only changes that touched only `airflowctl` datamodels can be
+ re-worded to make the "datamodels only" scope clear, or dropped if they are
+ not user-observable through the CLI.
+- Also clean up any stale files in `airflow-ctl/newsfragments/` that describe
+ changes already released in a previous version. The changelog generator does
+ **not** consume newsfragments — it works off `git log` — so stale fragments
+ will not appear in the generated output, but they mislead readers.
+
+## Commit the version bump and release notes via a merged PR
+
+The release tag must point at a commit on `main` (or the maintenance branch
+you are releasing from) that contains both the bumped `__version__` and the
+new `RELEASE_NOTES.rst` section. This means the release-prep changes MUST be
+merged to the target branch before tagging:
+
+```shell script
+cd ${AIRFLOW_REPO_ROOT:-$(pwd -P)}
+git checkout -b "prepare-airflow-ctl-${VERSION_RC}"
+git add airflow-ctl/src/airflowctl/__init__.py airflow-ctl/RELEASE_NOTES.rst
+# Also `git rm` any stale newsfragments you cleaned up
+git commit -m "Prepare airflow-ctl ${VERSION_RC} release"
+
+# Push to your fork (NOT to apache)
+git push -u origin "prepare-airflow-ctl-${VERSION_RC}"
+
+# Open the PR in the browser, pre-filled
+gh pr create --web \
+ --title "Prepare airflow-ctl ${VERSION_RC} release" \
+ --body "Bump \`__version__\` to ${VERSION} and regenerate
\`RELEASE_NOTES.rst\`."
+```
+
+Wait for CI to pass and for the PR to be merged to the target branch (`main`
+for a regular release, or the maintenance branch for a backport release).
+**Do not tag until the PR is merged** — the tag must point at the merge
+commit.
+
+After the PR merges, pull the target branch before continuing so that your
+local `HEAD` matches the commit you are about to tag:
+
+```shell script
+git checkout main # or v3-X-test for maintenance releases
+git pull apache main
+```
## Build airflow-ctl distributions for SVN apache upload
@@ -182,6 +247,11 @@ rm -rf ${AIRFLOW_REPO_ROOT}/dist/*
Assume that your remote for apache repository is called `apache` you should now
set tags for the airflow-ctl in the repo.
+**Prerequisite:** the version-bump + release-notes PR from "Commit the version
+bump and release notes via a merged PR" must already be merged, and your local
+target branch must be fast-forwarded to that merge commit. The tag should
+point at that commit.
+
Sometimes in cases when there is a connectivity issue to GitHub, it might be
possible that local tags get created
and lead to annoying errors. The default behaviour would be to clean such
local tags up.