diff options
Diffstat (limited to 'docs')
19 files changed, 680 insertions, 86 deletions
diff --git a/docs/docsite/rst/community/collection_contributors/collection_integration_about.rst b/docs/docsite/rst/community/collection_contributors/collection_integration_about.rst index cac6ba076d..2e2bccb192 100644 --- a/docs/docsite/rst/community/collection_contributors/collection_integration_about.rst +++ b/docs/docsite/rst/community/collection_contributors/collection_integration_about.rst @@ -107,18 +107,18 @@ Covering modules / new features When covering a module, cover all its options separately and their meaningful combinations. Every possible use of the module should be tested against: -- Idempotency (Does rerunning a task report no changes?) -- Check-mode (Does dry-running a task behave the same as a real run? Does it not make any changes?) -- Return values (Does the module return values consistently under different conditions?) +- Idempotency - Does rerunning a task report no changes? +- Check-mode - Does dry-running a task behave the same as a real run? Does it not make any changes? +- Return values - Does the module return values consistently under different conditions? Each test action has to be tested at least the following times: -- Perform an action in check-mode if supported (this should indicate a change). +- Perform an action in check-mode if supported. This should indicate a change. - Check with another module that the changes have ``not`` been actually made. -- Perform the action for real (this should indicate a change). +- Perform the action for real. This should indicate a change. - Check with another module that the changes have been actually made. -- Perform the action again in check-mode (this should indicate ``no`` change). -- Perform the action again for real (this should indicate ``no`` change). +- Perform the action again in check-mode. This should indicate ``no`` change. +- Perform the action again for real. This should indicate ``no`` change. To check a task: @@ -128,7 +128,7 @@ To check a task: #. Expected return values. 2. If the module changes the system state, check the actual system state using at least one other module. For example, if the module changes a file, we can check that the file has been changed by checking its checksum with the :ref:`stat <ansible_collections.ansible.builtin.stat_module>` module before and after the test tasks. -3. Run the same task with ``check_mode: yes`` (if check-mode is supported by the module). Check with other modules that the actual system state has not been changed. +3. Run the same task with ``check_mode: yes`` if check-mode is supported by the module. Check with other modules that the actual system state has not been changed. 4. Cover cases when the module must fail. Use the ``ignore_errors: yes`` option and check the returned message with the ``assert`` module. Example: diff --git a/docs/docsite/rst/community/collection_contributors/collection_integration_add.rst b/docs/docsite/rst/community/collection_contributors/collection_integration_add.rst index cbb3bd920c..d91243314a 100644 --- a/docs/docsite/rst/community/collection_contributors/collection_integration_add.rst +++ b/docs/docsite/rst/community/collection_contributors/collection_integration_add.rst @@ -229,7 +229,7 @@ That is enough for our very basic example. In the first task, we run the ``postgresql_info`` module to fetch information from the database we installed and launched with the ``setup_postgresql_db`` target. We are saving the values returned by the module into the ``result`` variable. -In the second task, we check the ``result`` variable (what the first task returned) with the ``assert`` module. We expect that, among other things, the result has the version and reports that the system state has not been changed. +In the second task, we check the ``result`` variable, which is what the first task returned, with the ``assert`` module. We expect that, among other things, the result has the version and reports that the system state has not been changed. 13. Run the tests in the Ubuntu 20.04 docker container: diff --git a/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst b/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst new file mode 100644 index 0000000000..b4fe739189 --- /dev/null +++ b/docs/docsite/rst/community/collection_contributors/collection_release_with_branches.rst @@ -0,0 +1,319 @@ +.. _collection_release_with_branches: + +Releasing collections with release branches +============================================ + +Collections MUST follow the `semantic versioning <https://semver.org/>`_ rules. See :ref:`releasing_collections` for high-level details. + +.. contents:: + :local: + + +Release planning and announcement +---------------------------------- + +#. Announce your intention to release the collection in a corresponding pinned release issue/community pinboard of the collection and in the ``#ansible-community`` `Matrix/IRC channel <https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat>`_. Repeat the announcement in any other dedicated channels if they exist. + +#. Ensure all the other repository maintainers are informed about the time of the following release. + + +Releasing major collection versions +------------------------------------- + +The new version is assumed to be ``X.0.0``. + +1. If you are going to release the ``community.general`` and ``community.network`` collections, create new ``backport-X`` and ``needs_backport_to_stable_X`` labels in the corresponding repositories. Copy the styles and descriptions from the corresponding existing labels. + +2. Ensure you are in a default branch in your local fork. These examples use ``main``. + + .. code-block:: bash + + git status + git checkout main # if needed + + +3. Update your local fork: + + .. code-block:: bash + + git pull --rebase upstream main + + +Creating the release branch +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Create a branch ``stable-X``. Replace ``X`` with a correct number and push it to the **upstream** repository, NOT to the ``origin``.: + + .. code-block:: bash + + git branch stable-X main + git push upstream stable-X + + +2. Create and checkout to another branch from the ``main`` branch: + + .. code-block:: bash + + git checkout -b update_repo + + +3. Update the version in ``galaxy.yml`` in the branch to the next **expected** version, for example, ``X.1.0``. + + +Creating the changelogs +^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Replace ``changelogs/changelog.yml`` with: + + .. code-block:: yaml + + ancestor: X.0.0 + releases: {} + + +2. Remove all changelog fragments from ``changelogs/fragments/``. Removing the changelog fragments ensures that every major release has a changelog describing changes since the last major release. + +3. Add and commit all the changes made. Push the branch to the ``origin`` repository. + +4. Create a pull request in the collection repository. If CI tests pass, merge the pull request since the ``main`` branch is expecting changes for the next minor/major versions + +5. Switch to the ``stable-X`` branch. + +6. In the ``stable-X`` branch, ensure that ``galaxy.yml`` contains the correct version number ``X.0.0``. If not, update it. + +7. In the ``stable-X`` branch, add a changelog fragment ``changelogs/fragments/X.0.0.yml`` with the content: + + .. code-block:: yaml + + release_summary: |- + Write some text here that should appear as the release summary for this version. + The format is reStructuredText, but not a list as for regular changelog fragments. + This text will be inserted into the changelog. + + For example: + + .. code-block:: yaml + + release_summary: This is release 2.0.0 of ``community.foo``, released on YYYY-MM-DD. + + +8. In the ``stable-X`` branch, generate the changelogs: + + .. code-block:: bash + + antsibull-changelog release --cummulative-release + + +9. In the ``stable-X`` branch, verify that the ``CHANGELOG.rst`` looks as expected. + +10. In the ``stable-X`` branch, update ``README.md`` so that the changelog link points to ``/tree/stable-X/`` and no longer to ``/tree/main/``, and change badges respectively, for example, in case of AZP, add ``?branchName=stable-X`` to the AZP CI badge (https://dev.azure.com/ansible/community.xxx/_apis/build/status/CI?branchName=stable-X). + +11. In the ``stable-X`` branch, add, commit, and push changes to ``README.md``, ``CHANGELOG.rst`` and ``changelogs/changelog.yaml``, and potentially deleted/archived fragments to the **upstream** repository, NOT to the ``origin``. + + +Publishing the collection +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. In the ``stable-X`` branch, add an annotated tag to the last commit with the collection version ``X.0.0``. Pushing this tag to the ``upstream`` repository will make Zuul publish the collection on `Ansible Galaxy <https://galaxy.ansible.com/>`_. + + .. code-block:: bash + + git tag -n # see current tags and their comments + git tag -a NEW_VERSION -m "comment here" # the comment can be, for example, "community.foo: 2.0.0" + git push upstream NEW_VERSION + + +2. Wait until the new version is published on the collection's `Ansible Galaxy <https://galaxy.ansible.com/>`_ page. It will appear in a list of tarballs available to download. + +3. Add a GitHub release for the new tag. The title should be the version and content, such as - ``See https://github.com/ansible-collections/community.xxx/blob/stable-X/CHANGELOG.rst for all changes``. + + +4. Announce the release through the `Bullhorn Newsletter <https://github.com/ansible/community/wiki/News#the-bullhorn>`_. + +5. Announce the release in the pinned release issue/community pinboard of the collection and in the ``#ansible-community`` `Matrix/Libera.Chat IRC channel <https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat>`_. + +6. In the ``stable-X`` branch, update the version in ``galaxy.yml`` to the next **expected** version, for example, ``X.1.0``. Add, commit and push to the **upstream** repository. + + +Releasing minor collection versions +------------------------------------- + +The new version is assumed to be ``X.Y.0``. All changes that should go into it are expected to be previously backported from the default branch to the ``stable-X`` branch. + +Creating the changelogs +^^^^^^^^^^^^^^^^^^^^^^^^ + +1. In the ``stable-X`` branch, make sure that ``galaxy.yml`` contains the correct version number ``X.Y.0``. If not, update it. + +2. In the ``stable-X`` branch, add a changelog fragment ``changelogs/fragments/X.Y.0.yml`` with content: + + .. code-block:: yaml + + release_summary: |- + Write some text here that should appear as the release summary for this version. + The format is reStructuredText, but not a list as for regular changelog fragments. + This text will be inserted into the changelog. + + +3. In the ``stable-X`` branch, run: + + .. code-block:: bash + + antsibull-changelog release + + +4. In the ``stable-X`` branch, verify that ``CHANGELOG.rst`` looks as expected. + +5. In the ``stable-X`` branch, add, commit, and push changes to ``CHANGELOG.rst`` and ``changelogs/changelog.yaml``, and potentially deleted/archived fragments to the **upstream** repository, NOT to the origin. + + +Publishing the collection +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. In the ``stable-X`` branch, add an annotated tag to the last commit with the collection version ``X.Y.0``. Pushing this tag to the ``upstream`` repository will make Zuul publish the collection on `Ansible Galaxy <https://galaxy.ansible.com/>`_. + + .. code-block:: bash + + git tag -n # see current tags and their comments + git tag -a NEW_VERSION -m "comment here" # the comment can be, for example, "community.foo: 2.1.0" + git push upstream NEW_VERSION + + +2. Wait until the new version is published on the collection's `Ansible Galaxy <https://galaxy.ansible.com/>`_ page. The published version will appear in a list of tarballs available to download. + +3. Add a GitHub release for the new tag. The title should be the version and content, such as - ``See https://github.com/ansible-collections/community.xxx/blob/stable-X/CHANGELOG.rst for all changes``. + +4. Announce the release through the `Bullhorn Newsletter <https://github.com/ansible/community/wiki/News#the-bullhorn>`_. + +5. Announce the release in the pinned release issue/community pinboard of the collection and in the ``#ansible-community`` `Matrix/IRC channel <https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat>`_. Additionally, you can announce it using GitHub's Releases system. + +6. In the ``stable-X`` branch, update the version in ``galaxy.yml`` to the next **expected** version, for example, if you have released ``X.1.0``, the next expected version could be ``X.2.0``. Add, commit and push to the **upstream** repository. + +7. Checkout to the ``main`` branch. + +8. In the ``main`` branch: + + #. If more minor versions are released before the next major version, update the version in ``galaxy.yml`` to ``X.(Y+1).0`` as well. Create a dedicated pull request and merge. + + #. If the next version will be a new major version, create a pull request where you update the version in ``galaxy.yml`` to ``(X+1).0.0``. Note that the sanity tests will most likely fail since there will be deprecations with removal scheduled for ``(X+1).0.0``, which are flagged by the tests. + + For every such deprecation, decide: + + * Whether to remove them now. For example you remove the complete ``modules/plugins`` or you remove redirects. + * Whether to add ignore entries to the corresponding ``tests/sanity/ignore-*.txt`` file and create issues, for example for removed features in ``modules/plugins``. + + Once the CI tests pass, merge the pull request. Make sure that this pull request is merged not too much later after the release + for ``verison_added`` sanity tests not to expect the wrong version for the new feature pull request. + +.. note:: + + It makes sense to already do some removals in the days before the release. These removals must happen in the main branch and must not be backported. + + +Releasing patch versions +------------------------- + +The new version is assumed to be ``X.Y.Z``, and the previous patch version is assumed to be ``X.Y.z`` with ``z < Z``. ``z`` is frequently``0`` snce patch releases are uncommon. + +Releasing when more minor versions are expected +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. Checkout the ``X.Y.z`` tag. + +2. Update ``galaxy.yml`` so that the version is ``X.Y.Z``. Add and commit. + +3. Cherry-pick all changes from ``stable-X`` that were added after ``X.Y.z`` and should go into ``X.Y.Z``. + +4. Add a changelog fragment ``changelogs/fragments/X.Y.Z.yml`` with content: + + .. code-block:: yaml + + release_summary: |- + Write some text here that should appear as the release summary for this version. + The format is reStructuredText but not a list as for regular changelog fragments. + This text will be inserted into the changelog. + + Add to git and commit. + +5. Generate the changelogs. + +.. code-block:: bash + + antsibull-changelog release + +6. Verify that ``CHANGELOG.rst`` looks as expected. + +7. Add and commit changes to ``CHANGELOG.rst`` and ``changelogs/changelog.yaml``, and potentially deleted/archived fragments. + +**Publishing the collection** + + +1. Add an annotated tag to the last commit with the collection version ``X.Y.Z``. Pushing this tag to the ``upstream`` repository will make Zuul publish the collection on `Ansible Galaxy <https://galaxy.ansible.com/>`_. + + .. code-block:: bash + + git tag -n # see current tags and their comments + git tag -a NEW_VERSION -m "comment here" # the comment can be, for example, "community.foo: 2.1.1" + git push upstream NEW_VERSION + + +2. Wait until the new version is published on the collection's `Ansible Galaxy <https://galaxy.ansible.com/>`_ page. It will appear in a list of tarballs available to download. + +3. Add a GitHub release for the new tag. The title should be the version and content, such as - ``See https://github.com/ansible-collections/community.xxx/blob/stable-X/CHANGELOG.rst for all changes``. + + .. note:: + + The data for this release is only contained in a tag, and not in a branch, in particular not in ``stable-X``. + This is deliberate, since the next minor release ``X.(Y+1).0`` already contains the changes for ``X.Y.Z`` as well, since these were cherry-picked from ``stable-X``. + + +4. Announce the release through the `Bullhorn Newsletter <https://github.com/ansible/community/wiki/News#the-bullhorn>`_. + +5. Announce the release in the pinned release issue/community pinboard of the collection and in the ``#ansible-community`` `Matrix/IRC channel <https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat>`. + + +Releasing when no more minor versions are expected +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +1. In the ``stable-X`` branch, make sure that ``galaxy.yml`` contains the correct version number ``X.Y.Z``. If not, update it! + +2. In the ``stable-X`` branch, add a changelog fragment ``changelogs/fragments/X.Y.Z.yml`` with content: + + .. code-block:: yaml + + release_summary: |- + Write some text here that should appear as the release summary for this version. + The format is reStructuredText, but not a list as for regular changelog fragments. + This text will be inserted into the changelog. + + +3. Generate the changelogs in the ``stable-X`` branch. + + .. code-block:: bash + + antsibull-changelog release + + +4. In the ``stable-X`` branch, verify that ``CHANGELOG.rst`` looks as expected. + +5. In the ``stable-X`` branch, add, commit, and push changes to ``CHANGELOG.rst`` and ``changelogs/changelog.yaml``, and potentially deleted/archived fragments to the **upstream** repository, NOT to the origin. + +**Publishing the collection** + + +1. In the ``stable-X`` branch, add an annotated tag to the last commit with the collection version ``X.Y.Z``. Pushing this tag to the ``upstream`` repository will make Zuul publish the collection on `Ansible Galaxy <https://galaxy.ansible.com/>`_. + + .. code-block:: bash + + git tag -n # see current tags and their comments + git tag -a NEW_VERSION -m "comment here" # the comment can be, for example, "community.foo: 2.1.1" + git push upstream NEW_VERSION + + +2. Wait until the new version is published on the collection's `Ansible Galaxy <https://galaxy.ansible.com/>`_ page. It will appear in a list of tarballs available to download. + +3. Add a GitHub release for the new tag. Title should be the version and content, such as: ``See https://github.com/ansible-collections/community.xxx/blob/stable-X/CHANGELOG.rst for all changes``. + +4. Announce the release through the `Bullhorn Newsletter <https://github.com/ansible/community/wiki/News#the-bullhorn>`_. + +5. Announce the release in the pinned issue/community pinboard of the collection and in the ``#ansible-community`` `Matrix/IRC channel <https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat>`_. diff --git a/docs/docsite/rst/community/collection_contributors/collection_release_without_branches.rst b/docs/docsite/rst/community/collection_contributors/collection_release_without_branches.rst new file mode 100644 index 0000000000..4cef33f03c --- /dev/null +++ b/docs/docsite/rst/community/collection_contributors/collection_release_without_branches.rst @@ -0,0 +1,115 @@ + +.. _collection_release_without_branches: + +Releasing collections without release branches +=============================================== + +Since no release branches are used, this section does not distinguish between releasing a major, minor, or patch version. + +.. contents:: + :local: + +Release planning and announcement +---------------------------------- + +#. Examine the collection to determine if there are merged changes to release. + +#. According to the changes made, choose an appropriate release version number. Keep in mind that the collections must follow the `semantic versioning <https://semver.org/>`_ rules. See :ref:`collection_versioning_and_deprecation` for details. + +#. Announce your intention to release the collection in a corresponding pinned release issue or community pinboard of the collection and in the ``community`` :ref:`Matrix/IRC channel <communication_irc>`. + +Creating the release branch +---------------------------- + +1. Ensure you are in a default branch in your local fork. We use ``main`` in the following examples. + + .. code:: bash + + git status + git checkout main # if needed + + +2. Update your local fork: + + .. code:: bash + + git pull --rebase upstream main + + +3. Checkout a new release branch from the default branch: + + .. code:: bash + + git checkout -b release_branch + +4. Ensure the ``galaxy.yml`` contains the correct release version number. + + +Generating the changelog +------------------------- + +1. Add a changelog fragment ``changelogs/fragments/X.Y.Z.yml`` with content: + + .. code:: yaml + + release_summary: |- + Write some text here that should appear as the release summary for this version. + The format is reStructuredText, but not a list as for regular changelog fragments. + This text will be inserted into the changelog. + + For example: + + .. code:: yaml + + release_summary: |- + This is the minor release of the ``community.mysql`` collection. + This changelog contains all changes to the modules and plugins in this collection + that have been made after the previous release. + + +2. If the content was recently moved from another collection (for example, migrating a module from one collection to another), ensure you have all related changelog fragments in the ``changelogs/fragments`` directory. If not, copy them previously. + +3. Run ``antsibull-changelog release --reload-plugins`` . This package should previously be installed with ``pip install antsibull-changelog``. + +4. Verify that the ``CHANGELOG.rst`` looks as expected. + +5. Commit and push changes to the ``CHANGELOG.rst`` and ``changelogs/changelog.yaml``, and potentially deleted/archived fragments to the ``origin`` repository's ``release_branch``. + + .. code:: bash + + git commit -a -m "Release VERSION commit" + git push origin release_branch + + +6. Create a pull request in the collection repository. If CI tests pass, merge it. + +7. Checkout the default branch and pull the changes: + + .. code:: bash + + git checkout main + git pull --rebase upstream main + + +Publish the collection +----------------------------------- + +1. Add an annotated tag to the release commit with the collection version. Pushing this tag to the ``upstream`` repository will make Zuul publish the collection on `Ansible Galaxy <https://galaxy.ansible.com/>`_. + + .. code:: bash + + git tag -n # see current tags and their comments + git tag -a NEW_VERSION -m "comment here" # the comment can be, for example, "community.postgresql: 1.2.0" + git push upstream NEW_VERSION + + + +2. Wait until the new version is published on the collection's `Ansible Galaxy <https://galaxy.ansible.com/>`_ page. It will appear in a list of tarballs available to download. + +3. Update the version in the ``galaxy.yml`` file to the next **expected** version. Add, commit, and push to the ``upstream``'s default branch. + +4. Add a GitHub release for the new tag. Title should be the version and content ``See https://github.com/ansible-collections/community.xxx/blob/main/CHANGELOG.rst for all changes``. + +5. Announce the release through the `Bullhorn Newsletter issue <https://github.com/ansible/community/wiki/News#the-bullhorn>`_. + +6. Announce the release in the pinned release issue/community pinboard of the collection mentioned in step 3 and in the ``community`` :ref:`Matrix/IRC channel <communication_irc>`. diff --git a/docs/docsite/rst/community/collection_contributors/collection_releasing.rst b/docs/docsite/rst/community/collection_contributors/collection_releasing.rst new file mode 100644 index 0000000000..481208b007 --- /dev/null +++ b/docs/docsite/rst/community/collection_contributors/collection_releasing.rst @@ -0,0 +1,106 @@ + +.. _releasing_collections: +.. _Releasing: + +Releasing collections +====================== + +Collection maintainers release all supported stable versions of the collections regularly, +provided that there have been enough changes merged to release. + + +.. contents:: + :local: + +Preparing to release a collection +-------------------------------------------- + + +The collections under the `ansible-collections organization <https://github.com/ansible-collections>`_ follow `semantic versioning <https://semver.org/>`_ when releasing. See :ref:`collection_versioning_and_deprecation` for details. + +To prepare for a release, a collection must have: + +* A publicly available policy of releasing, versioning, and deprecation. This can be, for example, written in its README or in a dedicated pinned issue. +* A pinned issue when its release managers inform the community about planned or completed releases. This can be combined with the release policy issue mentioned above. +* A :ref:`changelog <collection_changelogs>`. +* Releases of the collection tagged in the collection's repository. +* CI pipelines up and running. This can be implemented by using GitHub Actions, Azure Pipelines, Zuul. +* All CI tests running against a commit that releases the collection. If they do not pass, the collection MUST NOT be released. + +See :ref:`including_collection_ansible` if you plan on adding a new collection to the Ansible package. + +.. note:: + + Your collection must pass ``ansible-test sanity`` tests. See :ref:`testing_collections` for details. + + +.. _collection_versioning_and_deprecation: + +Collection versioning and deprecation +-------------------------------------- + +.. note:: + + Collections MUST adhere to `semantic versioning <https://semver.org/>`_. + +To preserve backward compatibility for users, every Ansible minor version series (5.1.x, 5.2.x, and so on) will keep the major version of a collection constant. For example, if Ansible 5.0.0 includes ``community.general`` 4.0.2, then each Ansible 5.X.x release will include the latest ``community.general`` 4.y.z release available at build time. Ansible 5.x.x will **never** include a ``community.general`` 5.y.x release, even if it is available. Major collection version changes will be included in the next Ansible major release (6.0.0 in this case). +Ensure that the current major release of your collection included in 6.0.0 receives at least bugfixes as long as new Ansible 6.X.X releases are produced. + +Since new minor releases are included, you can include new features, modules and plugins. You must make sure that you do not break backwards compatibility. See `semantic versioning <https://semver.org/>`_. for more details. This means in particular: + +* You can fix bugs in **patch** releases but not add new features or deprecate things. +* You can add new features and deprecate things in **minor** releases, but not remove things or change behavior of existing features. +* You can only remove things or make breaking changes in **major** releases. + +Ensure that if a deprecation is added in a collection version that is included in 5.x.y, the removal itself will only happen in a collection version included in 7.0.0 or later. +Ensure that the policy of releasing, versioning, and deprecation is announced to contributors and users in some way. For an example of how to do this, see `the announcement in community.general <https://github.com/ansible-collections/community.general/issues/582>`_. You could also do this in the collection README file. + +.. _collection_changelog: + +Collection changelogs +---------------------- + +Collections MUST include a changelog. To give a consistent feel for changelogs across collections and ensure changelogs exist for collections included in the ``ansible`` package, we suggest you use `antsibull-changelog <https://github.com/ansible-community/antsibull-changelog>`_ to maintain and generate this. + +Before releasing, verify the following for your changelogs: + +* All merged pull requests since the last release, except ones related to documentation and new modules/plugins, have :ref:`changelog fragments <collection_changelog_fragments>`. +* New module and plugin pull requests, except jinja2 test and filter plugins, do **not** need a changelog fragment, they are auto-detected by the changelog generator by their ``version_added`` value. +* All the fragments follow the :ref:`changelog entry format <collection_changelogs_how_to_format>`. + +Options for releasing a collection +----------------------------------- + +There are several approaches on how to release a collection. If you are not aware of which approach to use, ask in the ``#ansible-community`` IRC channel or the ``community`` Matrix channel. + +This section assumes that publishing the collection is done with `Zuul <https://github.com/ansible/project-config>`_ and that `antsibull-changelog <https://github.com/ansible-community/antsibull-changelog>`_ is used for the changelog. + +Releasing without release branches +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Use releasing without release branches when: + +* There are no prior major releases of the collection. +* There are no breaking changes introduced since the ``1.0.0`` release of the collection. + +See :ref:`collection_release_without_branches` for details. + +When there is a need to introduce breaking changes, you can switch to the next approach. + +Hybrid approach +^^^^^^^^^^^^^^^^^^^^^ + +In this approach, releases for the current major version are made from the ``main`` branch, while new releases for older major versions are made from release branches for these versions. + +Releasing with release branches +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Use releasing with release branches when breaking changes have been introduced. This approach is usually only used by the large community collections, ``community.general`` and ``community.network``. + +See :ref:`collection_release_with_branches` for details. + +.. toctree:: + :maxdepth: 1 + + collection_release_without_branches + collection_release_with_branches diff --git a/docs/docsite/rst/community/collection_development_process.rst b/docs/docsite/rst/community/collection_development_process.rst index 87bd736536..31f3a368bc 100644 --- a/docs/docsite/rst/community/collection_development_process.rst +++ b/docs/docsite/rst/community/collection_development_process.rst @@ -66,6 +66,8 @@ More precisely: We build short summary changelogs for minor releases as well as for major releases. If you backport a bugfix, include a changelog fragment with the backport PR. +.. _collection_changelogs_how_to_format: + Creating a changelog fragment ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -151,7 +153,8 @@ A single changelog fragment may contain multiple sections but most will only con Each changelog entry must contain a link to its issue between parentheses at the end. If there is no corresponding issue, the entry must contain a link to the PR itself. -Most changelog entries are ``bugfixes`` or ``minor_changes``. +Most changelog entries are ``bugfixes`` or ``minor_changes``. You can also use ``trivial`` for any collection that requires a changelog fragment for each pull request. ``trivial`` changelog fragments are excluded from the changelog output. + Changelog fragment entry format ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/docsite/rst/community/contributions_collections.rst b/docs/docsite/rst/community/contributions_collections.rst index a577bb7f27..4e0d7ba934 100644 --- a/docs/docsite/rst/community/contributions_collections.rst +++ b/docs/docsite/rst/community/contributions_collections.rst @@ -11,10 +11,10 @@ Ansible Collections Contributor Guide reporting_collections create_pr_quick_start collection_contributors/test_index - documentation_contributions maintainers contributing_maintained_collections steering/steering_index + documentation_contributions other_tools_and_programs diff --git a/docs/docsite/rst/community/development_process.rst b/docs/docsite/rst/community/development_process.rst index 148370f8fd..9ed2e3b751 100644 --- a/docs/docsite/rst/community/development_process.rst +++ b/docs/docsite/rst/community/development_process.rst @@ -249,7 +249,9 @@ A single changelog fragment may contain multiple sections but most will only con Each changelog entry must contain a link to its issue between parentheses at the end. If there is no corresponding issue, the entry must contain a link to the PR itself. -Most changelog entries are ``bugfixes`` or ``minor_changes``. +Most changelog entries are ``bugfixes`` or ``minor_changes``. The changelog tool also supports ``trivial``, which are not listed in the actual changelog output but are used by collections repositories that require a changelog fragment for each PR. + + .. _changelogs_how_to_format: diff --git a/docs/docsite/rst/community/maintainers.rst b/docs/docsite/rst/community/maintainers.rst index b43bea0190..bef1567ce6 100644 --- a/docs/docsite/rst/community/maintainers.rst +++ b/docs/docsite/rst/community/maintainers.rst @@ -11,6 +11,7 @@ Thank you for being a community collection maintainer. This guide offers an over maintainers_guidelines maintainers_workflow + collection_contributors/collection_releasing In addition to the information here, module maintainers should be familiar with: diff --git a/docs/docsite/rst/community/maintainers_guidelines.rst b/docs/docsite/rst/community/maintainers_guidelines.rst index 7d3ca609c2..c6843e79fa 100644 --- a/docs/docsite/rst/community/maintainers_guidelines.rst +++ b/docs/docsite/rst/community/maintainers_guidelines.rst @@ -66,7 +66,7 @@ The quarterly Ansible Contributor Summit is a global event that provides our con Weekly community Matrix/IRC meetings ------------------------------------ -The Community and the Steering Committee come together at weekly meetings in the ``#ansible-community`` :ref:`Matrix/Libera.Chat <https://docs.ansible.com/ansible/devel/community/communication.html#real-time-chat>` channel to discuss important project-scale questions. See the `schedule <https://github.com/ansible/community/blob/main/meetings/README.md#schedule>`_ and join. +The Community and the Steering Committee come together at weekly meetings in the ``#ansible-community`` :ref:`Matrix/Libera.Chat <communication_irc>` channel to discuss important project-scale questions. See the `schedule <https://github.com/ansible/community/blob/main/meetings/README.md#schedule>`_ and join. Expanding the collection community =================================== diff --git a/docs/docsite/rst/community/maintainers_workflow.rst b/docs/docsite/rst/community/maintainers_workflow.rst index 926043ec42..37d1179553 100644 --- a/docs/docsite/rst/community/maintainers_workflow.rst +++ b/docs/docsite/rst/community/maintainers_workflow.rst @@ -1,20 +1,5 @@ .. _maintainers_workflow: -.. _Releasing: - -Releasing collections -====================== - -Collection maintainers release all supported stable versions of the collections regularly, -provided that there have been enough changes merged to release. - -Generally, releasing in the collections consists of: - -1. Planning and announcement. -2. Generating a changelog. -3. Creating a release git tag and pushing it. -4. Automatic publishing the release tarball on `Ansible Galaxy <https://galaxy.ansible.com/>`_ by `Zuul <https://dashboard.zuul.ansible.com/t/ansible/builds?pipeline=release>`_. -5. Final announcement. Backporting and Ansible inclusion ================================== @@ -59,6 +44,20 @@ For more information about the collection bot and its interface, see to the `Collection bot overview <https://github.com/ansible-community/collection_bot/blob/main/ISSUE_HELP.md>`_. +Releasing a collection +---------------------- + +Collection maintainers are responsible for releasing new versions of a collection. Generally, releasing in the collections consists of: + +#. Planning and announcement. +#. Generating a changelog. +#. Creating a release git tag and pushing it. +#. Automaticly publishing the release tarball on `Ansible Galaxy <https://galaxy.ansible.com/>`_ through the `Zuul dashboard <https://dashboard.zuul.ansible.com/t/ansible/builds?pipeline=release>`_. +#. Final announcement. +#. Optionally, `file a request to include a new collection into the Ansible package <https://github.com/ansible-collections/ansible-inclusion>`_. + +See :ref:`releasing_collections` for details. + .. _Backporting: Backporting @@ -72,10 +71,12 @@ The manual backport process is similar to the :ref:`ansible-core backporting gui For convenience, backporting can be implemented automatically using GitHub bots (for example, with the `Patchback app <https://github.com/apps/patchback>`_) and labeling as it is done in `community.general <https://github.com/ansible-collections/community.general>`_ and `community.network <https://github.com/ansible-collections/community.network>`_. -Inclusion in Ansible ----------------------- +.. _including_collection_ansible: + +Including a collection in Ansible +----------------------------------- -If a collection is not included in Ansible (not shipped with Ansible package), maintainers can submit the collection for inclusion by creating a discussion under `ansible-collections/ansible-inclusion repository <https://github.com/ansible-collections/ansible-inclusion>`_. For more information, see the `repository's README <https://github.com/ansible-collections/ansible-inclusion/blob/main/README.md>`_. +If a collection is not included in Ansible (not shipped with Ansible package), maintainers can submit the collection for inclusion by creating a discussion under `ansible-collections/ansible-inclusion repository <https://github.com/ansible-collections/ansible-inclusion>`_. For more information, see the `repository's README <https://github.com/ansible-collections/ansible-inclusion/blob/main/README.md>`_, and the `Ansible community package collections requirements <https://github.com/ansible-collections/overview/blob/main/collection_requirements.rst>`. Stepping down as a collection maintainer =========================================== diff --git a/docs/docsite/rst/community/steering/community_steering_committee.rst b/docs/docsite/rst/community/steering/community_steering_committee.rst index dd713d225b..6fc220ee2e 100644 --- a/docs/docsite/rst/community/steering/community_steering_committee.rst +++ b/docs/docsite/rst/community/steering/community_steering_committee.rst @@ -59,6 +59,7 @@ The following table lists the current Steering Committee members. See :ref:`stee +------------------+---------------+-------------+ +John Barker (`gundalow <https://github.com/gundalow>`_) has been elected by the Committee as its :ref:`chairperson`. Committee members are selected based on their active contribution to the Ansible Project and its community. See :ref:`community_steering_guidelines` to learn details. diff --git a/docs/docsite/rst/community/steering/steering_committee_membership.rst b/docs/docsite/rst/community/steering/steering_committee_membership.rst index 3fcb796e03..2fcc0baa07 100644 --- a/docs/docsite/rst/community/steering/steering_committee_membership.rst +++ b/docs/docsite/rst/community/steering/steering_committee_membership.rst @@ -119,6 +119,8 @@ In case of the `Ansible Community Code of Conduct <https://docs.ansible.com/ansi In case of starting the removal process, the topic's description in the reason's part changes correspondingly. +.. _chairperson: + Chairperson ------------ diff --git a/docs/docsite/rst/porting_guides/porting_guide_5.rst b/docs/docsite/rst/porting_guides/porting_guide_5.rst index f618a2848d..c788d58a76 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_5.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_5.rst @@ -127,21 +127,27 @@ Networking No notable changes -Porting Guide for v5.5.0 +Porting Guide for v5.6.0 ======================== -Known Issues ------------- +Added Collections +----------------- + +- community.sap (version 1.0.0) + +Deprecated Features +------------------- cisco.ios ~~~~~~~~~ -- `ios_bgp_global` - Added capability of configure network options. -- `ios_bgp_global` - Added community and local_preference for route_reflector_client. -- `ios_bgp_global` - Added update_source for neighbors. -- `ios_bgp_global` - Correct misspelled attributes with alternates/alias. -- `ios_bgp_global` - Facts and config code optimized for using rm_templates. -- `ios_bgp_global` - Parsers added for non-implemented attributes. +- Deprecates lldp module. + +Porting Guide for v5.5.0 +======================== + +Known Issues +------------ community.general ~~~~~~~~~~~~~~~~~ diff --git a/docs/docsite/rst/shared_snippets/installing_collections_file.rst b/docs/docsite/rst/shared_snippets/installing_collections_file.rst index 60eccab431..7c4fbcd9cb 100644 --- a/docs/docsite/rst/shared_snippets/installing_collections_file.rst +++ b/docs/docsite/rst/shared_snippets/installing_collections_file.rst @@ -16,9 +16,9 @@ Ansible can also install a collection collected with ``ansible-galaxy collection .. code-block:: yaml collections: - - source: /tmp/my_namespace-my_collection-1.0.0.tar.gz + - name: /tmp/my_namespace-my_collection-1.0.0.tar.gz type: file .. note:: - Relative paths are calculated from the current working directory (where you are invoking ``ansible-galaxy install -r`` from). They are not taken relative to the ``requirements.yml`` file.
\ No newline at end of file + Relative paths are calculated from the current working directory (where you are invoking ``ansible-galaxy install -r`` from). They are not taken relative to the ``requirements.yml`` file. diff --git a/docs/docsite/rst/user_guide/complex_data_manipulation.rst b/docs/docsite/rst/user_guide/complex_data_manipulation.rst index d0a6616ccc..5bfce0c5b2 100644 --- a/docs/docsite/rst/user_guide/complex_data_manipulation.rst +++ b/docs/docsite/rst/user_guide/complex_data_manipulation.rst @@ -273,12 +273,14 @@ You can even combine these simple examples with other filters and lookups to cre :caption: Using 'vars' to define dictionary from a set of lists without needing a task vars: - myvarnames: "{{ q('varnames', '^my') }}" - mydict: "{{ dict(myvarnames | zip(q('vars', *myvarnames))) }}" + xyz_stuff: 1234 + xyz_morestuff: 567 + myvarnames: "{{ q('varnames', '^xyz_') }}" + mydict: "{{ dict(myvarnames|map('regex_replace', '^xyz_', '')|list | zip(q('vars', *myvarnames))) }}" A quick explanation, since there is a lot to unpack from these two lines: - - The ``varnames`` lookup returns a list of variables that match "begin with ``my``". + - The ``varnames`` lookup returns a list of variables that match "begin with ``xyz_``". - Then feeding the list from the previous step into the ``vars`` lookup to get the list of values. The ``*`` is used to 'dereference the list' (a pythonism that works in Jinja), otherwise it would take the list as a single argument. - Both lists get passed to the ``zip`` filter to pair them off into a unified list (key, value, key2, value2, ...). diff --git a/docs/docsite/rst/user_guide/intro_inventory.rst b/docs/docsite/rst/user_guide/intro_inventory.rst index 86136f70ae..fc46d9c2ee 100644 --- a/docs/docsite/rst/user_guide/intro_inventory.rst +++ b/docs/docsite/rst/user_guide/intro_inventory.rst @@ -274,8 +274,8 @@ In the above example, running Ansible against the host alias "jumper" will conne .. note:: Values passed in the INI format using the ``key=value`` syntax are interpreted differently depending on where they are declared: - * When declared inline with the host, INI values are interpreted as Python literal structures (strings, numbers, tuples, lists, dicts, booleans, None). Host lines accept multiple ``key=value`` parameters per line. Therefore they need a way to indicate that a space is part of a value rather than a separator. - + * When declared inline with the host, INI values are interpreted as Python literal structures (strings, numbers, tuples, lists, dicts, booleans, None). Host lines accept multiple ``key=value`` parameters per line. Therefore they need a way to indicate that a space is part of a value rather than a separator. Values that contain whitespace can be quoted (single or double). See the `Python shlex parsing rules`_ for details. + * When declared in a ``:vars`` section, INI values are interpreted as strings. For example ``var=FALSE`` would create a string equal to 'FALSE'. Unlike host lines, ``:vars`` sections accept only a single entry per line, so everything after the ``=`` must be the value for the entry. * If a variable value set in an INI inventory must be a certain type (for example, a string or a boolean value), always specify the type with a filter in your task. Do not rely on types set in INI inventories when consuming variables. @@ -284,6 +284,8 @@ In the above example, running Ansible against the host alias "jumper" will conne Generally speaking, this is not the best way to define variables that describe your system policy. Setting variables in the main inventory file is only a shorthand. See :ref:`splitting_out_vars` for guidelines on storing variable values in individual files in the 'host_vars' directory. +.. _Python shlex parsing rules: https://docs.python.org/3/library/shlex.html#parsing-rules + .. _group_variables: Assigning a variable to many machines: group variables diff --git a/docs/docsite/rst/user_guide/playbooks_handlers.rst b/docs/docsite/rst/user_guide/playbooks_handlers.rst index 082c8dd07a..6090f7725e 100644 --- a/docs/docsite/rst/user_guide/playbooks_handlers.rst +++ b/docs/docsite/rst/user_guide/playbooks_handlers.rst @@ -3,7 +3,7 @@ Handlers: running operations on change ====================================== -Sometimes you want a task to run only when a change is made on a machine. For example, you may want to restart a service if a task updates the configuration of that service, but not if the configuration is unchanged. Ansible uses handlers to address this use case. Handlers are tasks that only run when notified. Each handler should have a globally unique name. +Sometimes you want a task to run only when a change is made on a machine. For example, you may want to restart a service if a task updates the configuration of that service, but not if the configuration is unchanged. Ansible uses handlers to address this use case. Handlers are tasks that only run when notified. .. contents:: :local: @@ -46,7 +46,13 @@ This playbook, ``verify-apache.yml``, contains a single play with a handler. name: httpd state: restarted -In this example playbook, the second task notifies the handler. A single task can notify more than one handler: +In this example playbook, the Apache server is restarted by the handler after all tasks complete in the play. + + +Notifying handlers +------------------ + +Tasks can instruct one or more handlers to execute using the ``notify`` keyword. The ``notify`` keyword can be applied to a task and accepts a list of handler names that are notified on a task change. Alternately, a string containing a single handler name can be supplied as well. The following example demonstrates how multiple handlers can be notified by a single task: .. code-block:: yaml @@ -56,8 +62,8 @@ In this example playbook, the second task notifies the handler. A single task ca src: template.j2 dest: /etc/foo.conf notify: - - Restart memcached - Restart apache + - Restart memcached handlers: - name: Restart memcached @@ -70,12 +76,51 @@ In this example playbook, the second task notifies the handler. A single task ca name: apache state: restarted +In the above example the handlers are executed on task change in the following order: ``Restart memcached``, ``Restart apache``. Handlers are executed in the order they are defined in the ``handlers`` section, not in the order listed in the ``notify`` statement. Notifying the same handler multiple times will result in executing the handler only once regardless of how many tasks notify it. For example, if multiple tasks update a configuration file and notify a handler to restart Apache, Ansible only bounces Apache once to avoid unnecessary restarts. + + +Naming handlers +--------------- + +Handlers must be named in order for tasks to be able to notify them using the ``notify`` keyword. + +Alternately, handlers can utilize the ``listen`` keyword. Using this handler keyword, handlers can listen on topics that can group multiple handlers as follows: + +.. code-block:: yaml + + tasks: + - name: Restart everything + command: echo "this task will restart the web services" + notify: "restart web services" + + handlers: + - name: Restart memcached + service: + name: memcached + state: restarted + listen: "restart web services" + + - name: Restart apache + service: + name: apache + state: restarted + listen: "restart web services" + +Notifying the ``restart web services`` topic results in executing all handlers listening to that topic regardless of how those handlers are named. + +This use makes it much easier to trigger multiple handlers. It also decouples handlers from their names, making it easier to share handlers among playbooks and roles (especially when using third-party roles from a shared source such as Ansible Galaxy). + +Each handler should have a globally unique name. If multiple handlers are defined with the same name, only the last one defined is notified with ``notify``, effectively shadowing all of the previous handlers with the same name. Alternately handlers sharing the same name can all be notified and executed if they listen on the same topic by notifying that topic. + +There is only one global scope for handlers (handler names and listen topics) regardless of where the handlers are defined. This also includes handlers defined in roles. + + Controlling when handlers run ----------------------------- -By default, handlers run after all the tasks in a particular play have been completed. This approach is efficient, because the handler only runs once, regardless of how many tasks notify it. For example, if multiple tasks update a configuration file and notify a handler to restart Apache, Ansible only bounces Apache once to avoid unnecessary restarts. +By default, handlers run after all the tasks in a particular play have been completed. Notified handlers are executed automatically after each of the following sections, in the following order: ``pre_tasks``, ``roles``/``tasks`` and ``post_tasks``. This approach is efficient, because the handler only runs once, regardless of how many tasks notify it. For example, if multiple tasks update a configuration file and notify a handler to restart Apache, Ansible only bounces Apache once to avoid unnecessary restarts. -If you need handlers to run before the end of the play, add a task to flush them using the :ref:`meta module <meta_module>`, which executes Ansible actions. +If you need handlers to run before the end of the play, add a task to flush them using the :ref:`meta module <meta_module>`, which executes Ansible actions: .. code-block:: yaml @@ -91,10 +136,15 @@ If you need handlers to run before the end of the play, add a task to flush them The ``meta: flush_handlers`` task triggers any handlers that have been notified at that point in the play. +Once handlers are executed, either automatically after each mentioned section or manually by the ``flush_handlers`` meta task, they can be notified and run again in later sections of the play. + + Using variables with handlers ----------------------------- -You may want your Ansible handlers to use variables. For example, if the name of a service varies slightly by distribution, you want your output to show the exact name of the restarted service for each target machine. Avoid placing variables in the name of the handler. Since handler names are templated early on, Ansible may not have a value available for a handler name like this:: +You may want your Ansible handlers to use variables. For example, if the name of a service varies slightly by distribution, you want your output to show the exact name of the restarted service for each target machine. Avoid placing variables in the name of the handler. Since handler names are templated early on, Ansible may not have a value available for a handler name like this: + +.. code-block:: yaml+jinja handlers: # This handler name may cause your play to fail! @@ -104,7 +154,7 @@ If the variable used in the handler name is not available, the entire play fails Instead, place variables in the task parameters of your handler. You can load the values using ``include_vars`` like this: - .. code-block:: yaml+jinja +.. code-block:: yaml+jinja tasks: - name: Set host variables based on distribution @@ -116,44 +166,25 @@ Instead, place variables in the task parameters of your handler. You can load th name: "{{ web_service_name | default('httpd') }}" state: restarted -Handlers can also "listen" to generic topics, and tasks can notify those topics as follows: +While handler names can contain a template, ``listen`` topics cannot. -.. code-block:: yaml +Handlers in roles +----------------- - handlers: - - name: Restart memcached - ansible.builtin.service: - name: memcached - state: restarted - listen: "restart web services" +Handlers from roles are not just contained in their roles but rather inserted into global scope with all other handlers from a play. As such they can be used outside of the role they are defined in. It also means that their name can conflict with handlers from outside the role. To ensure that a handler from a role is notified as opposed to one from outside the role with the same name, notify the handler by using its name in the following form: ``role_name : handler_name``. - - name: Restart apache - ansible.builtin.service: - name: apache - state: restarted - listen: "restart web services" +Handlers notified within the ``roles`` section are automatically flushed at the end of the ``tasks`` section, but before any ``tasks`` handlers. - tasks: - - name: Restart everything - ansible.builtin.command: echo "this task will restart the web services" - notify: "restart web services" -This use makes it much easier to trigger multiple handlers. It also decouples handlers from their names, -making it easier to share handlers among playbooks and roles (especially when using 3rd party roles from -a shared source like Galaxy). +Includes and imports in handlers +-------------------------------- +Notifying a dynamic include such as ``include_task`` as a handler results in executing all tasks from within the include. It is not possible to notify a handler defined inside a dynamic include. + +Having a static include such as ``import_task`` as a handler results in that handler being effectively rewritten by handlers from within that import before the play execution. A static include itself cannot be notified, the tasks from withing that include, on the other hand, can be notified individually. -.. note:: - * Handlers always run in the order they are defined, not in the order listed in the notify-statement. This is also the case for handlers using `listen`. - * Handler names and `listen` topics live in a global namespace. - * Handler names are templatable and `listen` topics are not. - * Use unique handler names. If you trigger more than one handler with the same name, the first one(s) get overwritten. Only the last one defined will run. - * You can notify a handler defined inside a static include. - * You cannot notify a handler defined inside a dynamic include. - * A handler can not run import_role or include_role. -When using handlers within roles, note that: +Limitations +----------- -* handlers notified within ``pre_tasks``, ``tasks``, and ``post_tasks`` sections are automatically flushed at the end of section where they were notified. -* handlers notified within ``roles`` section are automatically flushed at the end of ``tasks`` section, but before any ``tasks`` handlers. -* handlers are play scoped and as such can be used outside of the role they are defined in. +A handler cannot run ``import_role`` or ``include_role``. diff --git a/docs/docsite/sphinx_conf/core_conf.py b/docs/docsite/sphinx_conf/core_conf.py index f03a8be04d..bd3fe06151 100644 --- a/docs/docsite/sphinx_conf/core_conf.py +++ b/docs/docsite/sphinx_conf/core_conf.py @@ -111,6 +111,9 @@ exclude_patterns = [ 'community/reporting_collections.rst', 'community/contributing_maintained_collections.rst', 'community/collection_development_process.rst', + 'community/collection_contributors/collection_release_without_branches.rst', + 'community/collection_contributors/collection_release_with_branches.rst', + 'community/collection_contributors/collection_releasing.rst', 'community/maintainers_guidelines.rst', 'community/maintainers_workflow.rst', 'community/steering/community_steering_committee.rst', |