Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package ansible-documentation for
openSUSE:Factory checked in at 2026-08-11 17:16:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ansible-documentation (Old)
and /work/SRC/openSUSE:Factory/.ansible-documentation.new.17972 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ansible-documentation"
Tue Aug 11 17:16:57 2026 rev:41 rq:1370640 version:2.21.3
Changes:
--------
---
/work/SRC/openSUSE:Factory/ansible-documentation/ansible-documentation.changes
2026-07-14 13:52:03.019352101 +0200
+++
/work/SRC/openSUSE:Factory/.ansible-documentation.new.17972/ansible-documentation.changes
2026-08-11 17:18:07.076543366 +0200
@@ -1,0 +2,30 @@
+Tue Aug 11 07:23:06 UTC 2026 - Johannes Kastl
<[email protected]>
+
+- Update to version 2.21.3:
+ * ci: refresh dev dependencies (#3882)
+ * vault_guide: Update vault example script (#3753) (#3878)
+ * [stable-2.21] ci: refresh dev dependencies (#3836)
+ * Pin the alls-green action to hash (#3869) (#3873)
+ * fix(ruff.toml): specify the correct target python version
+ (#3870)
+ * [stable 2.21]: Bump actions and pin to hash (#3848)
+ * Add basic ruff config to disable problematic rules (#3862)
+ (#3868)
+ * chore: ignore ruff warnings about blind exception handlers in
+ yamllint checker (#3857) (#3865)
+ * chore: update pr_labeler to use type keyword (#3858)
+ * chore: remove porting guide workflow from stable (#3849)
+ * Document soft deprecation of rc failure inference (#3605)
+ (#3854)
+ * Document register projections (#3752) (#3853)
+ * chore: fix ruff checks in docs/bin/ (#3841) (#3845)
+ * update Galaxy token URL (#3825) (#3835)
+ * Fix duplicate word in cli_parsing docs (#3820) (#3832)
+ * Fix duplicate word in testing_running_locally docs (#3817)
+ (#3830)
+ * Remove outdated UTF-8 encoding comment recommendation (#3821)
+ (#3822)
+ * ci: refresh dev dependencies (#3815)
+ * Add the Ansible community 14.2.0 porting guide (#3811) (#3812)
+
+-------------------------------------------------------------------
Old:
----
ansible-documentation-2.21.2.obscpio
New:
----
ansible-documentation-2.21.3.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ansible-documentation.spec ++++++
--- /var/tmp/diff_new_pack.AyOt2p/_old 2026-08-11 17:18:07.892577946 +0200
+++ /var/tmp/diff_new_pack.AyOt2p/_new 2026-08-11 17:18:07.896578116 +0200
@@ -17,7 +17,7 @@
Name: ansible-documentation
-Version: 2.21.2
+Version: 2.21.3
Release: 0
Summary: Ansible community documentation and example files
License: GPL-3.0-only
++++++ _service ++++++
--- /var/tmp/diff_new_pack.AyOt2p/_old 2026-08-11 17:18:07.940579980 +0200
+++ /var/tmp/diff_new_pack.AyOt2p/_new 2026-08-11 17:18:07.944580150 +0200
@@ -3,7 +3,7 @@
<param
name="url">https://github.com/ansible/ansible-documentation.git</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
- <param name="revision">refs/tags/v2.21.2</param>
+ <param name="revision">refs/tags/v2.21.3</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">v(.*)</param>
<param name="changesgenerate">enable</param>
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.AyOt2p/_old 2026-08-11 17:18:07.976581505 +0200
+++ /var/tmp/diff_new_pack.AyOt2p/_new 2026-08-11 17:18:07.980581675 +0200
@@ -3,6 +3,6 @@
<param
name="url">https://github.com/ansible/ansible-documentation</param>
<param
name="changesrevision">24dc86db4bb88b47a8f4f12e35f32508510ce69d</param></service><service
name="tar_scm">
<param
name="url">https://github.com/ansible/ansible-documentation.git</param>
- <param
name="changesrevision">9c065609c8e15db88b41cff07462f8ef25c6795a</param></service></servicedata>
+ <param
name="changesrevision">57de24c1d19ab232b49d12a2f0a0bace15c40318</param></service></servicedata>
(No newline at EOF)
++++++ ansible-documentation-2.21.2.obscpio ->
ansible-documentation-2.21.3.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-documentation-2.21.2/docs/bin/clone-core.py
new/ansible-documentation-2.21.3/docs/bin/clone-core.py
--- old/ansible-documentation-2.21.2/docs/bin/clone-core.py 2026-07-13
11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/docs/bin/clone-core.py 2026-08-10
09:18:09.000000000 +0200
@@ -82,7 +82,7 @@
return Args(**vars(parser.parse_args(args)))
-def remove_files(directory: pathlib.Path = pathlib.Path.cwd()) ->
list[pathlib.Path]:
+def remove_files(directory: pathlib.Path) -> list[pathlib.Path]:
removed: list[pathlib.Path] = []
for file in REMOVE_FILES:
path = directory / file
@@ -95,7 +95,7 @@
def main(args: Args) -> None:
# Start by removing extra files
- removed_files = remove_files()
+ removed_files = remove_files(pathlib.Path.cwd())
if (
# Check is enabled
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/bin/find-plugin-refs.py
new/ansible-documentation-2.21.3/docs/bin/find-plugin-refs.py
--- old/ansible-documentation-2.21.2/docs/bin/find-plugin-refs.py
2026-07-13 11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/docs/bin/find-plugin-refs.py
2026-08-10 09:18:09.000000000 +0200
@@ -60,11 +60,7 @@
# the file contains an unported ref
if label in plugin_names:
print(
- ":ref:`{0}` matching plugin {1} was found in
{2}".format(
- ref_match.group(1),
- label,
- os.path.join(dirpath, filename),
- )
+ f":ref:`{ref_match.group(1)}` matching plugin
{label} was found in {os.path.join(dirpath, filename)}"
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/dev_guide/developing_modules_documenting.rst
2026-08-10 09:18:09.000000000 +0200
@@ -35,8 +35,8 @@
.. _shebang:
-Python shebang & UTF-8 coding
-=============================
+Python shebang
+==============
1. Begin your Ansible module with the ``#!/usr/bin/python`` shebang so that
``ansible_python_interpreter`` works.
@@ -45,20 +45,19 @@
* Do NOT use ``#!/usr/bin/env`` because it makes ``env`` the interpreter and
bypasses ``ansible_<interpreter>_interpreter`` logic.
* Passing arguments to the interpreter in the shebang does not work; for
example, ``#!/usr/bin/env python``.
-2. Follow the shebang immediately with ``# -*- coding: utf-8 -*-`` to clarify
that the file is UTF-8 encoded.
+2. Do not add an encoding comment such as ``# -*- coding: utf-8 -*-``. It was
required for Python 2 but is unnecessary in Python 3, which treats source files
as UTF-8 by default. Since ansible-core 2.17 dropped Python 2 support, existing
encoding comments can be removed.
.. _copyright:
Copyright and license
=====================
-* After the shebang and UTF-8 encoding lines, add a `copyright line
<https://www.linuxfoundation.org/blog/copyright-notices-in-open-source-software-projects/>`_
with the original copyright holder and a license declaration.
+* After the shebang, add a `copyright line
<https://www.linuxfoundation.org/blog/copyright-notices-in-open-source-software-projects/>`_
with the original copyright holder and a license declaration.
* The license declaration should be one line ONLY, not the full GPL prefix, as
follows:
.. code-block:: python
#!/usr/bin/python
- # -*- coding: utf-8 -*-
# Copyright: Contributors to the Ansible project
# GNU General Public License v3.0+ (see COPYING or
https://www.gnu.org/licenses/gpl-3.0.txt)
@@ -83,7 +82,7 @@
Before committing your module documentation, please test it at the
:ref:`command line and as HTML <dev_testing_module_documentation>`.
-After the shebang, the UTF-8 encoding, the copyright line, and the license
section comes the ``DOCUMENTATION`` block. Ansible's online module
documentation is generated from the ``DOCUMENTATION`` blocks in the source code
of each module.
+After the shebang, the copyright line, and the license section comes the
``DOCUMENTATION`` block. Ansible's online module documentation is generated
from the ``DOCUMENTATION`` blocks in the source code of each module.
The ``DOCUMENTATION`` block must be valid YAML. To make it easier:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/dev_guide/testing_running_locally.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/dev_guide/testing_running_locally.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/dev_guide/testing_running_locally.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/dev_guide/testing_running_locally.rst
2026-08-10 09:18:09.000000000 +0200
@@ -187,7 +187,7 @@
""""""""""""""""""""""""""
1. Open Docker Desktop and go to the **Settings** screen.
-2. On the the **General** tab:
+2. On the **General** tab:
a. Uncheck the **Start Docker Desktop when you log in** checkbox.
b. Check the **Use the WSL 2 based engine** checkbox.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/network/user_guide/cli_parsing.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/network/user_guide/cli_parsing.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/network/user_guide/cli_parsing.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/network/user_guide/cli_parsing.rst
2026-08-10 09:18:09.000000000 +0200
@@ -334,7 +334,7 @@
Red Hat Ansible Automation Platform subscription support is limited to
the use of the ``ntc_templates`` public APIs as documented.
-This task and and the predefined template sets the following fact as the
``interfaces`` fact for the host:
+This task and the predefined template sets the following fact as the
``interfaces`` fact for the host:
.. code-block:: yaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_conditionals.rst
2026-08-10 09:18:09.000000000 +0200
@@ -194,6 +194,33 @@
.. note:: Older versions of Ansible used ``success`` and ``fail``, but
``succeeded`` and ``failed`` use the correct tense. All of these options are
now valid.
+In loops, you can use the implicit ``_task`` variable to access the previous
iteration's result in ``when`` conditionals.
+Since conditionals are evaluated during iteration, you must provide a default
value for the first iteration:
+
+.. code-block:: yaml
+
+ - name: Run each step only if the previous one ran and succeeded
+ ansible.builtin.command: "/opt/scripts/{{ item }}.sh"
+ loop:
+ - initialize
+ - validate
+ - deploy
+ when: _task.result | default({}) is not failed and _task.result |
default({}) is not skipped
+
+You can also use ``_task.loop_result`` to access all accumulated results
during iteration:
+
+.. code-block:: yaml
+
+ - name: Stop after processing two items
+ ansible.builtin.shell: /usr/bin/process {{ item }}
+ loop: [1, 2, 3, 4, 5, 6]
+ when: (_task.loop_result.results | default([]) | length) < 2
+
+.. note::
+
+ The ``default`` filter is required in conditionals because they are
evaluated during each iteration.
+ In contrast, register projections are evaluated after the task completes,
so ``default`` is not needed there.
+ See :ref:`playbooks_loops` for examples of using ``_task.loop_result`` in
register projections.
Conditionals based on variables
-------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_error_handling.rst
2026-08-10 09:18:09.000000000 +0200
@@ -144,6 +144,18 @@
(ret.stderr != '') or
(ret.rc == 10)
+You may also access task results without registering a variable via the
``result`` property of the implicit variable ``_task``.
+
+.. code-block:: yaml
+
+ - name: Fail task when either condition is met
+ ansible.builtin.command: /usr/bin/example-command
+ failed_when: _task.result.rc != 0 or 'ERROR' in _task.result.stdout
+
+.. note::
+
+ The ``_task`` implicit variable can be used in all conditional keywords,
including ``when``, ``until``, ``failed_when``, ``changed_when``, and
``break_when``.
+
.. _override_the_changed_result:
Defining "changed"
@@ -180,6 +192,16 @@
- '"ERROR" in result.stderr'
- result.rc == 2
+As with ``failed_when``, you may use the implicit variable ``_task`` to avoid
registering a variable:
+
+.. code-block:: yaml
+
+ - name: Combine multiple conditions to override 'changed' result
+ ansible.builtin.command: /bin/fake_command
+ changed_when:
+ - some_msg in _task.result.stdout
+ - some_warning not in _task.result.stderr
+
You can reference simple variables in conditionals to avoid repeating certain
terms, as in the following example:
.. code-block:: yaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_loops.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_loops.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_loops.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_loops.rst
2026-08-10 09:18:09.000000000 +0200
@@ -155,7 +155,7 @@
ip_address: "10.1.1.100"
role: "backend_db"
-Here, we are iterating over `server_configs` and printing the key and selected
nested fields.
+This example iterates over `server_configs` and prints the key and selected
nested fields.
If the values in the dictionary are themselves dictionaries (for example, each
group maps
to a dict containing a ``gid``), remember that after applying ``dict2items``
each loop item
@@ -239,6 +239,71 @@
register: echo
changed_when: echo.stdout != "one"
+.. versionadded:: 2.21
+
+You can also use register projections to access task results without
registering a variable, or to register multiple variables at once. See
:ref:`registered_variables` for details.
+
+The result of the current item during iteration is also accessible in the
``result`` property of the implicit variable ``_task``. This allows for
accessing loop item results without registering a variable.
+
+.. code-block:: yaml+jinja
+
+ - name: Place the result of the current item in the variable
+ ansible.builtin.shell: echo "{{ item }}"
+ loop:
+ - one
+ - two
+ changed_when: _task.result.stdout != "one"
+
+For more details on register projections and the ``_task`` variable, see
:ref:`registered_variables`.
+
+To access the full, accumulated loop result list during iteration, the
``loop_result`` property of the ``_task`` implicit variable may be used.
+
+.. code-block:: yaml+jinja
+
+ - name: Run a loop and access individual item output
+ ansible.builtin.shell: "{{ item }}"
+ register:
+ foo_output: _task.loop_result.results[0].stdout
+ bar_output: _task.loop_result.results[1].stdout
+ loop:
+ - /usr/bin/foo
+ - /usr/bin/bar
+
+.. note::
+
+ Register projection expressions are evaluated after the task completes, so
``default`` is not needed when accessing ``_task.loop_result`` if the
registered variables are only used after the task.
+ However, if a registered projection variable will be used in a conditional
during iteration, ``default`` must be used in the register expression itself
because the variable does not exist on the first iteration.
+
+ .. code-block:: yaml
+
+ - name: Using registered projection in conditional during iteration
+ ansible.builtin.shell: "{{ item }}"
+ register:
+ first_output: _task.loop_result.results[0].stdout | default('') #
default needed to use first_output during iteration
+ loop: [1, 2, 3]
+ when: first_output != 'skip'
+
+ See :ref:`playbooks_conditionals` for examples of using ``_task`` directly
in conditionals.
+
+To access the same functionality as name-only variable registration when
registering multiple variables, the ``polymorphic_result`` property of the
``_task`` implicit variable can be used. During iteration, it will contain the
result of the most recent loop iteration, and afterwards it will contain the
full task result. This makes these two tasks equivalent:
+
+.. code-block:: yaml
+
+ - name: Run a loop and register a single variable
+ ansible.builtin.shell: "{{ item }}"
+ register: foo_bar_result
+ loop:
+ - /usr/bin/foo
+ - /usr/bin/bar
+
+ - name: Register the same variable in the multi-variable register format
+ ansible.builtin.shell: "{{ item }}"
+ register:
+ foo_bar_result: _task.polymorphic_result
+ loop:
+ - /usr/bin/foo
+ - /usr/bin/bar
+
.. _do_until_loops:
Retrying a task until a condition is met
@@ -287,6 +352,25 @@
When you use the ``timeout`` keyword in a loop, it applies to each attempt
of the task action. See :ref:`TASK_TIMEOUT <TASK_TIMEOUT>` for more details.
+You can use the implicit ``_task`` variable to access the current result in
``until`` without registering a variable:
+
+.. code-block:: yaml
+
+ - name: Wait for each service to be ready
+ ansible.builtin.command: systemctl is-active {{ item }}
+ loop:
+ - nginx
+ - postgresql
+ - redis
+ retries: 5
+ delay: 2
+ until: _task.result.rc == 0
+
+.. seealso::
+
+ :ref:`registered_variables`
+ For more information on the ``_task`` implicit variable and register
projections.
+
.. _loop_over_inventory:
Looping over inventory
@@ -423,6 +507,19 @@
msg: "Maximum attempts to generate a valid password exceeded"
when: password is not match(password_policy)
+When using register projections, you can reference the registered variables in
``break_when``:
+
+.. code-block:: yaml
+
+ - name: Break after processing two items
+ ansible.builtin.debug:
+ msg: "Processing {{ item }}"
+ loop: [1, 2, 3, 4, 5]
+ loop_control:
+ break_when: items_processed == 2
+ register:
+ items_processed: _task.loop_result.results | length
+
Tracking progress through a loop with ``index_var``
---------------------------------------------------
.. versionadded:: 2.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_variables.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_variables.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/playbook_guide/playbooks_variables.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/playbook_guide/playbooks_variables.rst
2026-08-10 09:18:09.000000000 +0200
@@ -229,7 +229,7 @@
Registering variables
=====================
-You can create a variable from the output of an Ansible task with the task
keyword ``register``. You can use the registered variable in any later task in
your play. For example:
+You can create variables from the output of an Ansible task with the task
keyword ``register``. You can use the registered variables in any later task in
your play. For example:
.. code-block:: yaml
@@ -248,6 +248,61 @@
For more examples of using registered variables in conditions on later tasks,
see :ref:`playbooks_conditionals`. Registered variables may be simple
variables, list variables, dictionary variables, or complex nested data
structures. The documentation for each module includes a ``RETURN`` section
that describes the return values for that module. To see the values for a
particular task, run your playbook with ``-v``.
+.. versionadded:: 2.21
+
+You can also use ``register`` to register multiple variables and manipulate
task output with jinja expressions with a dictionary of ``variable:
expression`` pairs. Ansible provides an implicit task variable ``_task`` for
accessing task output via its ``result`` property.
+
+.. note::
+
+ ``_task`` is a reserved name and used for internal purposes. Do not use
this name to register task results or define variables.
+
+.. code-block:: yaml+jinja
+
+ - hosts: web_servers
+
+ tasks:
+ - name: Run a shell command and register multiple variables
+ ansible.builtin.shell: /usr/bin/foo
+ register:
+ command_result: _task.result # this is equivalent to register:
command_result
+ command_duration: (command_end - command_start).total_seconds()
+ command_start: _task.result.start | to_datetime(time_format)
+ command_end: _task.result.end | to_datetime(time_format)
+ vars:
+ time_format: '%Y-%m-%d %H:%M:%S.%f'
+
+Because this form of ``register`` is always a jinja expression, template
delimiters ``{{ }}`` are not required. Do not use ``{{ }}`` in the register
projection expressions:
+
+.. code-block:: yaml
+
+ # Wrong - do not use template delimiters
+ register:
+ foo: "{{ _task.result }}"
+
+ # Correct
+ register:
+ foo: _task.result
+
+This registration method allows chained access to other variables defined in
the same ``register`` map. You can define variables based on other variables
created in the same step, **and the order of definition does not matter**.
+
+.. code-block:: yaml
+
+ - hosts: web_servers
+
+ tasks:
+ - name: Run a shell command and register multiple variables
+ ansible.builtin.shell: /usr/bin/foo
+ register:
+ capitalized_command_output: command_result.stdout | capitalize #
This works even though command_result is defined after
capitalized_command_output
+ command_result: _task.result # this is equivalent to register:
command_result
+
+Register projections are evaluated after the task completes, not during task
execution. For non-looped tasks, variables defined in a ``register`` map are
not available within the task itself, and references to ``_task.result`` or
other projected variables will reflect the final task state. This lazy
evaluation enables order-independent variable definitions. For looped tasks,
register projections from previous loop items are available, but require the
``default`` filter for the first iteration because ``_task.result`` is not yet
defined.
+
+.. seealso::
+
+ :ref:`playbooks_loops`
+ For examples of using register projections with loops, including
accessing ``_task.loop_result`` and using projections in ``until`` and
``break_when`` conditions.
+
Registered variables are stored in memory. You cannot cache registered
variables for use in future playbook runs. A registered variable is valid only
on the host for the rest of the current playbook run, including subsequent
plays within the same playbook run.
Registered variables are host-level variables. When you register a variable in
a task with a loop, the registered variable contains a value for each item in
the loop. The data structure placed in the variable during the loop contains a
``results`` attribute, which is a list of all responses from the module. For a
more in-depth example of how this works, see the :ref:`playbooks_loops` section
on using register with a loop.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/porting_guides/porting_guide_14.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/porting_guides/porting_guide_14.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/porting_guides/porting_guide_14.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/porting_guides/porting_guide_14.rst
2026-08-10 09:18:09.000000000 +0200
@@ -95,6 +95,40 @@
No notable changes
+Porting Guide for v14.2.0
+=========================
+
+Major Changes
+-------------
+
+splunk.es
+^^^^^^^^^
+
+- ci - integration tests now run against both Splunk Server 9.4 and 10.4 with
Enterprise Security (ES), providing full coverage across supported major
versions and catching regressions against real Splunk ES instances.
+
+Deprecated Features
+-------------------
+
+community.clickhouse
+^^^^^^^^^^^^^^^^^^^^
+
+- clickhouse_db - deprecate pre 22.x handling code for comments
(https://github.com/ansible-collections/community.clickhouse/issues/217).
+- clickhouse_role - list based settings and profiles are marked as deprecated
and sheduled for removal in 3.0.0
(https://github.com/ansible-collections/community.clickhouse/issues/218).
+- clickhouse_user - list based settings and profiles are marked as deprecated
and sheduled for removal in 3.0.0
(https://github.com/ansible-collections/community.clickhouse/issues/218).
+- mark ansible-core-2.17 as deprecated. Support will be removed in future.
+
+community.rabbitmq
+^^^^^^^^^^^^^^^^^^
+
+- Support for RabbitMQ versions prior to 3.7.0 will be dropped in version
2.0.0 of this collection
(https://github.com/ansible-collections/community.rabbitmq/issues/224).
+- Support for ansible-core versions prior to 2.16.0 will be dropped in version
2.0.0 of this collection
(https://github.com/ansible-collections/community.rabbitmq/issues/224).
+- collection - Python 2 support will be dropped in version 2.0.0 of this
collection. Make sure you have Python 3 installed on your target machines
(https://github.com/ansible-collections/community.rabbitmq/issues/214).
+
+purestorage.flashblade
+^^^^^^^^^^^^^^^^^^^^^^
+
+- purefb_fs - The ``nfs_rules`` parameter is deprecated in favour of
``export_policy`` and will be removed in 2.0.0. A deprecation notice is emitted
when it is used.
+
Porting Guide for v14.1.0
=========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/porting_guides/porting_guide_core_2.21.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/porting_guides/porting_guide_core_2.21.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/porting_guides/porting_guide_core_2.21.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/porting_guides/porting_guide_core_2.21.rst
2026-08-10 09:18:09.000000000 +0200
@@ -57,7 +57,13 @@
Deprecated
==========
-No notable changes
+Failure inference from non-zero ``rc``
+--------------------------------------
+
+Failure inference for modules and actions that return a non-zero ``rc`` value
and no ``failed`` value is deprecated.
+Modules and actions may use any logic desired to determine failure (including
consulting ``rc``), but failures must be explicitly communicated in the task
result by setting ``failed`` true, or via methods that do so implicitly, such
as ``fail_json`` or raising an unhandled error.
+Runtime deprecation warnings will be issued in release 2.22 when a deprecated
failure inference occurs.
+When failure inference is removed in future releases, the ``rc`` key will
receive no special attention during task result processing.
.. _2.21_modules:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/reference_appendices/glossary.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/reference_appendices/glossary.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/reference_appendices/glossary.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/reference_appendices/glossary.rst
2026-08-10 09:18:09.000000000 +0200
@@ -399,8 +399,8 @@
Register Variable
The result of running any :term:`task <tasks>` in Ansible can be
- stored in a variable for use in a template or a conditional statement.
- The keyword used to define the variable is called ``register``, taking
+ stored in variables for use in a template or a conditional statement.
+ The keyword used to define the variables is called ``register``, taking
its name from the idea of registers in assembly programming (though
Ansible will never feel like assembly programming). There are an
infinite number of variable names you can use for registration.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/shared_snippets/galaxy_server_list.txt
new/ansible-documentation-2.21.3/docs/docsite/rst/shared_snippets/galaxy_server_list.txt
---
old/ansible-documentation-2.21.2/docs/docsite/rst/shared_snippets/galaxy_server_list.txt
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/shared_snippets/galaxy_server_list.txt
2026-08-10 09:18:09.000000000 +0200
@@ -13,7 +13,7 @@
#. Add the ``server_list`` option under the ``[galaxy]`` section to one or
more server names.
#. Create a new section for each server name.
#. Set the ``url`` option for each server name.
-#. Optionally, set the API token for each server name. Go to
https://galaxy.ansible.com/me/preferences and click :guilabel:`Show API key`.
+#. Optionally, set the API token for each server name. Go to
https://galaxy.ansible.com/ui/token and click :guilabel:`Show API key`.
.. note::
The ``url`` option for each server name must end with a forward slash
``/``. If you do not set the API token in your Galaxy server list, use the
``--api-key`` argument to pass in the token to the ``ansible-galaxy collection
publish`` command.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/vault_guide/scripts/vault-keyring-client.py
new/ansible-documentation-2.21.3/docs/docsite/rst/vault_guide/scripts/vault-keyring-client.py
---
old/ansible-documentation-2.21.2/docs/docsite/rst/vault_guide/scripts/vault-keyring-client.py
1970-01-01 01:00:00.000000000 +0100
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/vault_guide/scripts/vault-keyring-client.py
2026-08-10 09:18:09.000000000 +0200
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# (c) 2014, Matt Martz <[email protected]>
+# (c) 2016, Justin Mayer <https://justinmayer.com/>
+#
+# GNU General Public License v3.0+ (see COPYING or
https://www.gnu.org/licenses/gpl-3.0.txt)
+#
+# =============================================================================
+#
+# This script is to be used with ansible-vault's --vault-id arg
+# to retrieve the vault password via your OS's native keyring application.
+#
+# This file *MUST* be saved with executable permissions. Otherwise, Ansible
+# will try to parse as a password file and display: "ERROR! Decryption failed"
+#
+# The `keyring` Python module is required: https://pypi.org/project/keyring/
+#
+# By default, this script will store the specified password in the keyring of
+# the user that invokes the script. To specify a user keyring, add a [vault]
+# section to ~/ansible-vault.cfg file with a 'username' option. Example:
+#
+# [vault]
+# username = 'ansible-vault'
+#
+# In usage like:
+#
+# ansible-vault --vault-id keyring_id@contrib/vault/vault-keyring-client.py
view some_encrypted_file
+#
+# --vault-id will call this script like:
+#
+# contrib/vault/vault-keyring-client.py --vault-id keyring_id
+#
+# That will retrieve the password from users keyring for the
+# keyring service 'keyring_id'. The equivalent of:
+#
+# keyring get keyring_id $USER
+#
+# If no vault-id name is specified to ansible command line, the
vault-keyring-client.py
+# script will be called without a '--vault-id' and will default to the keyring
service 'ansible'
+# This is equivalent to:
+#
+# keyring get ansible $USER
+#
+# You can configure the `vault_password_file` option in ansible.cfg:
+#
+# [defaults]
+# ...
+# vault_password_file = /path/to/vault-keyring-client.py
+# ...
+#
+# To set your password, `cd` to your project directory and run:
+#
+# # will use default keyring service / vault-id of 'ansible'
+# /path/to/vault-keyring-client.py --set
+#
+# or to specify the keyring service / vault-id of 'my_ansible_secret':
+#
+# /path/to/vault-keyring-client.py --vault-id my_ansible_secret --set
+#
+# If you choose not to configure the path to `vault_password_file` in
+# ansible.cfg, your `ansible-playbook` command might look like:
+#
+# ansible-playbook --vault-id=keyring_id@/path/to/vault-keyring-client.py
site.yml
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import argparse
+import configparser
+import os
+import sys
+import getpass
+import keyring
+
+
+KEYNAME_UNKNOWN_RC = 2
+
+
+def build_arg_parser():
+ parser = argparse.ArgumentParser(description='Get a vault password from
user keyring')
+
+ parser.add_argument('--vault-id', action='store', default=None,
+ dest='vault_id',
+ help='name of the vault secret to get from keyring')
+ parser.add_argument('--username', action='store', default=None,
+ help='the username whose keyring is queried')
+ parser.add_argument('--set', action='store_true', default=False,
+ dest='set_password',
+ help='set the password instead of getting it')
+ return parser
+
+
+def main():
+ # Set default values
+ username = getpass.getuser()
+ keyname = 'ansible'
+
+ # Try to load values from config if one exists
+ config = configparser.ConfigParser()
+ config_file = os.path.expanduser("~/ansible-vault.cfg")
+ config.read(config_file)
+ if config.has_option('vault', 'username'):
+ username = config.get('vault', 'username')
+ if config.has_option('vault', 'keyname'):
+ keyname = config.get('vault', 'keyname')
+
+ # Read values from command line (which override the previous if given)
+ arg_parser = build_arg_parser()
+ args = arg_parser.parse_args()
+
+ username = args.username or username
+ keyname = args.vault_id or keyname
+
+ if args.set_password:
+ intro = 'Storing password in "{}" user keyring using key name: {}\n'
+ sys.stdout.write(intro.format(username, keyname))
+ password = getpass.getpass()
+ confirm = getpass.getpass('Confirm password: ')
+ if password == confirm:
+ keyring.set_password(keyname, username, password)
+ else:
+ sys.stderr.write('Passwords do not match\n')
+ sys.exit(1)
+ else:
+ secret = keyring.get_password(keyname, username)
+ if secret is None:
+ sys.stderr.write('vault-keyring-client could not find key="%s" for
user="%s" via backend="%s"\n' %
+ (keyname, username, keyring.get_keyring().name))
+ sys.exit(KEYNAME_UNKNOWN_RC)
+
+ sys.stdout.write('%s\n' % secret)
+
+ sys.exit(0)
+
+
+if __name__ == '__main__':
+ main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/docs/docsite/rst/vault_guide/vault_managing_passwords.rst
new/ansible-documentation-2.21.3/docs/docsite/rst/vault_guide/vault_managing_passwords.rst
---
old/ansible-documentation-2.21.2/docs/docsite/rst/vault_guide/vault_managing_passwords.rst
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/docs/docsite/rst/vault_guide/vault_managing_passwords.rst
2026-08-10 09:18:09.000000000 +0200
@@ -99,12 +99,15 @@
.. code-block:: bash
- ansible-playbook --vault-id
dev@contrib-scripts/vault/vault-keyring-client.py
+ ansible-playbook --vault-id dev@path/to/vault-keyring-client.py
Ansible executes the client script with a ``--vault-id`` option so the script
knows which vault ID label you specified. For example, a script loading
passwords from a secret manager can use the vault ID label to pick either the
'dev' or 'prod' password. The example command above results in the following
execution of the client script:
.. code-block:: bash
- contrib-scripts/vault/vault-keyring-client.py --vault-id dev
+ path/to/vault-keyring-client.py --vault-id dev
-For an example of a client script that loads passwords from the system
keyring, see the `vault-keyring-client script
<https://github.com/ansible-community/contrib-scripts/blob/main/vault/vault-keyring-client.py>`_.
+For an example of a client script that loads passwords from the system
keyring, see the ``vault-keyring-client`` script.
+
+ .. literalinclude:: scripts/vault-keyring-client.py
+ :language: python
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/hacking/pr_labeler/pr_labeler/actions.py
new/ansible-documentation-2.21.3/hacking/pr_labeler/pr_labeler/actions.py
--- old/ansible-documentation-2.21.2/hacking/pr_labeler/pr_labeler/actions.py
2026-07-13 11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/hacking/pr_labeler/pr_labeler/actions.py
2026-08-10 09:18:09.000000000 +0200
@@ -88,7 +88,6 @@
if (
# Contributor has already been welcomed
NEW_CONTRIBUTOR_LABEL in ctx.previously_labeled
- #
or not is_new_contributor(ctx)
):
return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/hacking/pr_labeler/pr_labeler/cli_context.py
new/ansible-documentation-2.21.3/hacking/pr_labeler/pr_labeler/cli_context.py
---
old/ansible-documentation-2.21.2/hacking/pr_labeler/pr_labeler/cli_context.py
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/hacking/pr_labeler/pr_labeler/cli_context.py
2026-08-10 09:18:09.000000000 +0200
@@ -17,11 +17,10 @@
import github.Repository
if TYPE_CHECKING:
- from typing_extensions import TypeAlias
from .github_utils import IssueOrPr
-IssueOrPrCtx: TypeAlias = "IssueLabelerCtx | PRLabelerCtx"
+type IssueOrPrCtx = "IssueLabelerCtx | PRLabelerCtx"
@dataclasses.dataclass()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/hacking/pr_labeler/pr_labeler/github_utils.py
new/ansible-documentation-2.21.3/hacking/pr_labeler/pr_labeler/github_utils.py
---
old/ansible-documentation-2.21.2/hacking/pr_labeler/pr_labeler/github_utils.py
2026-07-13 11:48:53.000000000 +0200
+++
new/ansible-documentation-2.21.3/hacking/pr_labeler/pr_labeler/github_utils.py
2026-08-10 09:18:09.000000000 +0200
@@ -10,7 +10,7 @@
import json
import os
from contextlib import suppress
-from typing import TYPE_CHECKING, Any
+from typing import Any
import github
import github.Auth
@@ -21,11 +21,7 @@
from .cli_context import IssueLabelerCtx, IssueOrPrCtx
from .utils import log
-if TYPE_CHECKING:
- from typing_extensions import TypeAlias
-
-
-IssueOrPr: TypeAlias = "github.Issue.Issue | github.PullRequest.PullRequest"
+type IssueOrPr = "github.Issue.Issue | github.PullRequest.PullRequest"
def get_repo(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-documentation-2.21.2/ruff.toml
new/ansible-documentation-2.21.3/ruff.toml
--- old/ansible-documentation-2.21.2/ruff.toml 1970-01-01 01:00:00.000000000
+0100
+++ new/ansible-documentation-2.21.3/ruff.toml 2026-08-10 09:18:09.000000000
+0200
@@ -0,0 +1,13 @@
+# GNU General Public License v3.0+ (see COPYING or
https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+# SPDX-FileCopyrightText: Ansible project
+
+target-version = "py312"
+
+[lint]
+# https://docs.astral.sh/ruff/rules/
+
+ignore = [
+ "I001", # unsorted-imports: we use isort
+ "RUF028", # invalid-formatter-suppression-comment: we use black
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/ansible-documentation-2.21.2/tests/checkers/rst-yamllint.py
new/ansible-documentation-2.21.3/tests/checkers/rst-yamllint.py
--- old/ansible-documentation-2.21.2/tests/checkers/rst-yamllint.py
2026-07-13 11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/tests/checkers/rst-yamllint.py
2026-08-10 09:18:09.000000000 +0200
@@ -160,7 +160,7 @@
"message": msg,
}
)
- except Exception as exc:
+ except Exception as exc: # noqa: BLE001
error = str(exc).replace("\n", " / ")
results.append(
{
@@ -173,7 +173,7 @@
),
}
)
- except Exception as exc:
+ except Exception as exc: # noqa: BLE001
error = str(exc).replace("\n", " / ")
results.append(
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-documentation-2.21.2/tests/formatters.txt
new/ansible-documentation-2.21.3/tests/formatters.txt
--- old/ansible-documentation-2.21.2/tests/formatters.txt 2026-07-13
11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/tests/formatters.txt 2026-08-10
09:18:09.000000000 +0200
@@ -10,11 +10,11 @@
# via -r tests/formatters.in
mypy-extensions==1.1.0
# via black
-packaging==26.2
+packaging==26.3
# via black
pathspec==1.1.1
# via black
-platformdirs==4.10.0
+platformdirs==4.11.1
# via black
pytokens==0.4.1
# via black
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-documentation-2.21.2/tests/spelling.txt
new/ansible-documentation-2.21.3/tests/spelling.txt
--- old/ansible-documentation-2.21.2/tests/spelling.txt 2026-07-13
11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/tests/spelling.txt 2026-08-10
09:18:09.000000000 +0200
@@ -1,4 +1,4 @@
# This file was autogenerated by uv via the following command:
# uv pip compile --universal --output-file tests/spelling.txt
tests/spelling.in
-codespell==2.4.2
+codespell==2.4.3
# via -r tests/spelling.in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-documentation-2.21.2/tests/static.txt
new/ansible-documentation-2.21.3/tests/static.txt
--- old/ansible-documentation-2.21.2/tests/static.txt 2026-07-13
11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/tests/static.txt 2026-08-10
09:18:09.000000000 +0200
@@ -1,4 +1,4 @@
# This file was autogenerated by uv via the following command:
# uv pip compile --universal --output-file tests/static.txt tests/static.in
-ruff==0.15.21
+ruff==0.16.2
# via -r tests/static.in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/ansible-documentation-2.21.2/tests/typing.txt
new/ansible-documentation-2.21.3/tests/typing.txt
--- old/ansible-documentation-2.21.2/tests/typing.txt 2026-07-13
11:48:53.000000000 +0200
+++ new/ansible-documentation-2.21.3/tests/typing.txt 2026-08-10
09:18:09.000000000 +0200
@@ -1,18 +1,18 @@
# This file was autogenerated by uv via the following command:
# uv pip compile --universal --output-file tests/typing.txt tests/typing.in
-annotated-doc==0.0.4
+annotated-doc==0.0.5
# via typer
antsibull-docutils==1.4.0
# via -r tests/typing.in
-argcomplete==3.7.0
+argcomplete==3.7.2
# via nox
-ast-serialize==0.6.0
+ast-serialize==0.8.0
# via mypy
attrs==26.1.0
# via nox
-certifi==2026.6.17
+certifi==2026.7.22
# via requests
-cffi==2.1.0 ; platform_python_implementation != 'PyPy'
+cffi==2.1.1 ; platform_python_implementation != 'PyPy'
# via
# cryptography
# pynacl
@@ -24,9 +24,9 @@
# via
# colorlog
# typer
-colorlog==6.10.1
+colorlog==6.12.0
# via nox
-cryptography==49.0.0
+cryptography==50.0.0
# via pyjwt
dependency-groups==1.3.1
# via nox
@@ -34,7 +34,7 @@
# via virtualenv
docutils==0.23
# via antsibull-docutils
-filelock==3.29.7
+filelock==3.32.2
# via
# python-discovery
# virtualenv
@@ -44,7 +44,7 @@
# via requests
jinja2==3.1.6
# via -r tests/../hacking/pr_labeler/requirements.txt
-librt==0.13.0 ; platform_python_implementation != 'PyPy'
+librt==0.15.0 ; platform_python_implementation != 'PyPy'
# via mypy
markdown-it-py==4.2.0
# via rich
@@ -52,22 +52,20 @@
# via jinja2
mdurl==0.1.2
# via markdown-it-py
-mypy==2.2.0
+mypy==2.3.0
# via -r tests/typing.in
mypy-extensions==1.1.0
# via mypy
-nox==2026.4.10
+nox==2026.7.11
# via -r tests/typing.in
-packaging==26.2
+packaging==26.3
# via
# dependency-groups
# nox
pathspec==1.1.1
# via mypy
-platformdirs==4.10.0
- # via
- # python-discovery
- # virtualenv
+platformdirs==4.11.1
+ # via virtualenv
pycparser==3.0 ; implementation_name != 'PyPy' and
platform_python_implementation != 'PyPy'
# via cffi
pygithub==2.9.1
@@ -78,7 +76,7 @@
# via pygithub
pynacl==1.6.2
# via pygithub
-python-discovery==1.4.4
+python-discovery==1.5.1
# via virtualenv
requests==2.34.2
# via pygithub
@@ -86,11 +84,11 @@
# via typer
shellingham==1.5.4
# via typer
-typer==0.26.8
+typer==0.27.1
# via typer-slim
typer-slim==0.24.0
# via -r tests/../hacking/pr_labeler/requirements.txt
-types-docutils==0.22.3.20260518
+types-docutils==0.22.3.20260724
# via -r tests/typing.in
typing-extensions==4.16.0
# via
@@ -100,5 +98,5 @@
# via
# pygithub
# requests
-virtualenv==21.6.1
+virtualenv==21.7.3
# via nox
++++++ ansible-documentation.obsinfo ++++++
--- /var/tmp/diff_new_pack.AyOt2p/_old 2026-08-11 17:18:08.864619137 +0200
+++ /var/tmp/diff_new_pack.AyOt2p/_new 2026-08-11 17:18:08.872619476 +0200
@@ -1,5 +1,5 @@
name: ansible-documentation
-version: 2.21.2
-mtime: 1783936133
-commit: 9c065609c8e15db88b41cff07462f8ef25c6795a
+version: 2.21.3
+mtime: 1786346289
+commit: 57de24c1d19ab232b49d12a2f0a0bace15c40318