Ansible 开发周期

Ansible 开发人员(包括社区贡献者)在许多不同的仓库中添加新功能、修复错误并更新代码。ansible/ansible 仓库包含了基本特性和功能的代码,例如将模块代码复制到受管节点。这部分代码也被称为 ansible-core。其他仓库包含使 Ansible 能够执行特定任务的插件和模块,例如向特定数据库添加用户或配置特定的网络设备。这些仓库包含了集合(collections)的源代码。

ansible-core 的开发发生在两个层面。在宏观层面,ansible-core 的开发人员和维护者规划发布,并通过路线图和项目跟踪进度。在微观层面,每个 PR 都有自己的生命周期。

集合的开发也发生在宏观和微观层面。每个集合都有自己的宏观开发周期。有关集合开发周期的更多信息,请参阅 为 Ansible 维护的集合做贡献。PR 的微观层面生命周期在集合和 ansible-core 中是相似的。

宏观开发:ansible-core 路线图、发布和项目

如果你想关注有关即将发布的版本中将为 ansible-core 添加哪些功能以及正在修复哪些错误的讨论,可以关注这些资源

微观开发:PR 的生命周期

如果你想在 ansible-core 或集合中贡献功能或修复错误,必须开启一个 拉取请求(简称“PR”)。GitHub 提供了关于 拉取请求流程通常如何运作 的精彩概述。任何拉取请求的最终目标都是被合并并成为集合或 ansible-core 的一部分。以下是 PR 生命周期的概述

  • 贡献者开启 PR(始终针对 devel 分支)

  • ansible-core 使用 Ansibot 对 PR 进行分类。一些集合仓库使用 Ansibullbot 对 PR 进行分类。对于大多数集合,这是手动或通过其他方式完成的。

  • Azure Pipelines 运行测试套件

  • 开发人员、维护者、社区评审 PR

  • 贡献者处理评审人员的任何反馈

  • 开发人员、维护者、社区重新评审

  • PR 被合并或关闭

  • PR 被 向后移植 到一个或多个 stable-X.Y 分支(可选,仅限错误修复)

让你的 PR 值得合并

我们不会合并每一个 PR。以下是一些让你的 PR 有用、具有吸引力且值得合并的技巧。

签署提交

所有提交到 https://github.com/ansible/ 下仓库的提交都必须签名。要设置签署提交,请参考 Github 关于 GPG 密钥SSH 密钥S/MIME 的文档。

变更日志片段

变更日志可以帮助用户和开发人员跟上 ansible-core 和 Ansible 集合的变化。Ansible 和许多集合通过片段为每个版本构建变更日志。对于使用此模型的 ansible-core 和集合,你 必须 在任何更改功能或修复错误的 PR 中添加一个变更日志片段。

对于以下 PR,你不需要变更日志片段:

  • 添加新的模块和插件,因为 Ansible 工具会自动完成;

  • 仅包含文档更改。

注意

某些集合要求每个拉取请求都要有变更日志片段。对于上述提到的条目,它们使用 trivial: 部分,这些条目在构建版本变更日志时将被跳过。

更准确地说:

  • 每个错误修复(bugfix)PR 都必须有一个变更日志片段。唯一的例外是修复尚未包含在发布版本中的更改。

  • 每个功能(feature)PR 都必须有一个变更日志片段。

  • 新模块和插件(包括 jinja2 过滤器和测试插件)必须在其文档中正确设置 version_added 条目,且不需要变更日志片段。工具会根据其 version_added 值检测新模块和插件,并自动在下一个版本的变更日志中发布它们。

我们会为次要版本以及主要版本构建简短的变更日志摘要。如果你向后移植了一个错误修复,请在向后移植的 PR 中包含一个变更日志片段。

创建变更日志片段

基础变更日志片段是一个放置在 changelogs/fragments/ 目录中的 .yaml.yml 文件。每个文件包含一个 YAML 字典,键名为 bugfixesmajor_changes,后面跟着错误修复或功能的变更日志条目列表。每个变更日志条目都以 RST 格式编写并嵌入在 YAML 文件中。这意味着某些构造需要转义,以便它们可以由 RST 解释而不是由 YAML 解释(或者如果你愿意,可以同时为 YAML 和 RST 转义)。每个 PR 必须 使用一个新的片段文件,而不是添加到现有文件中,这样我们就可以追溯到引入该更改的 PR。

添加新模块或插件的 PR 不一定需要变更日志片段。请参阅上一节 变更日志片段。另请参阅下一节 变更日志片段条目格式,了解变更日志片段应具有的确切格式。

要创建变更日志条目,请在相应仓库的 changelogs/fragments/ 目录中创建一个具有唯一名称的新文件。文件名应包含 PR 编号和更改说明。它必须以文件扩展名 .yaml.yml 结尾。例如:40696-user-backup-shadow-file.yaml

单个变更日志片段可能包含多个部分,但大多数只包含一个部分。顶级键(bugfixes、major_changes 等)定义在我们 发行注记工具配置文件 中。以下是有效的部分及其说明:

breaking_changes (破坏性变更)

必须(MUST)包含破坏现有 playbook 或 role 的更改。这包括任何迫使用户更新任务的现有行为更改。破坏性变更意味着用户在更新时必须做出更改。破坏性变更只能在集合的主要版本中发生。使用现在时编写,并清晰地描述最终用户现在必须遵循的新行为。显示在变更日志和 移植指南 中。

breaking_changes:
  - ansible-test - automatic installation of requirements for cloud test plugins no longer occurs. The affected test plugins are ``aws``, ``azure``, ``cs``, ``hcloud``, ``nios``, ``opennebula``, ``openshift`` and ``vcenter``. Collections should instead use one of the supported integration test requirements files, such as the ``tests/integration/requirements.txt`` file (https://github.com/ansible/ansible/pull/75605).
major_changes (重大变更)

ansible-core 或集合的主要变更。不应(SHOULD NOT)包含单个模块或插件的更改。必须(MUST)包含影响整个或大部分集合的非破坏性更改(例如,为支持整个集合中的新 SDK 版本而进行的更新)。主要更改意味着用户在更新时可以选择进行更改,但并非必须。可用于宣布未来版本中重要且即将到来的 EOL(生命周期结束)或破坏性变更(如果已知,最好提前 6 个月。请参阅 此示例)。使用现在时编写并描述新内容。可选地包含一个“Previously...”句子,以帮助用户识别旧行为应在何处更改。显示在变更日志和 移植指南 中。

major_changes:
  - ansible-test - all cloud plugins which use containers can now be used with all POSIX and Windows hosts. Previously the plugins did not work with Windows at all, and support for hosts created with the ``--remote`` option was inconsistent (https://github.com/ansible/ansible/pull/74216).
minor_changes (次要变更)

ansible-core、模块或插件的微小更改。这包括添加到模块的新参数,或对现有参数的非破坏性行为更改,例如向 choices[] 添加额外的值。微小更改是增强功能,而不是错误修复。使用现在时编写。

minor_changes:
  - lineinfile - add warning when using an empty regexp (https://github.com/ansible/ansible/issues/29443).
deprecated_features (弃用特性)

已弃用并计划在未来版本中移除的功能。使用过去时编写,并在可用时包含被弃用功能的替代方案。显示在变更日志和 移植指南 中。

deprecated_features:
  - include action - is deprecated in favor of ``include_tasks``, ``import_tasks`` and ``import_playbook`` (https://github.com/ansible/ansible/pull/71262).
removed_features (移除特性)

之前已弃用、现在已移除的功能。使用过去时编写,并在可用时包含被弃用功能的替代方案。显示在变更日志和 移植指南 中。

removed_features:
  - _get_item() alias - removed from callback plugin base class which had been deprecated in favor of ``_get_item_label()`` (https://github.com/ansible/ansible/pull/70233).
security_fixes (安全修复)

解决 CVE 或安全疑虑的修复。任何 CVE 必须(MUST)使用 security_fixes。使用现在时编写。包含指向 CVE 信息的链接。

security_fixes:
  - set_options -do not include params in exception when a call to ``set_options`` fails. Additionally, block the exception that is returned from being displayed to stdout. (CVE-2021-3620).
bugfixes (缺陷修复)

解决问题的修复。不应(SHOULD not)用于微小增强(应使用 minor_change 代替)。使用过去时描述问题,使用现在时描述修复方法。

bugfixes:
  - ansible_play_batch - variable included unreachable hosts. Fix now saves unreachable hosts between plays by adding them to the PlayIterator's ``_play._removed_hosts`` (https://github.com/ansible/ansible/issues/66945).
known_issues (已知问题)

当前未修复或将不予修复的已知问题。使用现在时编写,并在可用时使用祈使句描述变通方法。

known_issues:
  - ansible-test - tab completion anywhere other than the end of the command with the new composite options provides incorrect results (https://github.com/kislyuk/argcomplete/issues/351).

每个变更日志条目必须在末尾的括号中包含指向其 issue 的链接。如果没有对应的 issue,条目必须包含指向 PR 本身的链接。

大多数变更日志条目是 bugfixesminor_changes。变更日志工具还支持 trivial,这些条目不会列在实际的变更日志输出中,但由要求每个 PR 都有变更日志片段的集合仓库使用。

变更日志片段条目格式

编写变更日志条目时,请使用以下格式:

- scope - description starting with a lowercase letter and ending with a period at the very end. Multiple sentences are allowed (https://github.com/reference/to/an/issue or, if there is no issue, reference to a pull request itself).

范围(scope)通常是模块或插件名称或模块/插件组,例如 lookup plugins。虽然可以(且应该)直接提到模块名称(foo_module),但在插件名称后面应始终跟着类型(foo inventory plugin)。

对于没有明确范围的更改(例如,影响整个集合的更改),请使用以下格式:

- Description starting with an uppercase letter and ending with a dot at the very end. Multiple sentences are allowed (https://github.com/reference/to/an/issue or, if there is no issue, reference to a pull request itself).

这里有一些例子:

bugfixes:
  - apt_repository - fix crash caused by ``cache.update()`` raising an ``IOError``
    due to a timeout in ``apt update`` (https://github.com/ansible/ansible/issues/51995).
minor_changes:
  - lineinfile - add warning when using an empty regexp (https://github.com/ansible/ansible/issues/29443).
bugfixes:
  - copy - the module was attempting to change the mode of files for
    remote_src=True even if mode was not set as a parameter.  This failed on
    filesystems which do not have permission bits (https://github.com/ansible/ansible/issues/29444).

你可以在 2.19 版本的 变更日志目录 中找到更多变更日志片段示例。

写完 PR 的变更日志片段后,提交该文件并将其随拉取请求一起提交。

新 playbook 的变更日志片段条目格式

虽然新模块、插件和角色会自动在生成的变更日志中提及,但 playbook 不会。为了确保它们被提及,需要一个特定格式的变更日志片段:

# A new playbook:
add object.playbook:
  - # This should be the short (non-FQCN) name of the playbook.
    name: wipe_server
    # The description should be in the same format as short_description for
    # plugins and modules: it should start with an upper-case letter and
    # not have a period at the end.
    description: Wipes a server

测试 PR

为你的 PR 添加测试会使其成为更有力的合并候选者。

有关编写集成测试的信息,请参阅 集成测试 文档页面以及 test/integration 处现有的集成测试。

有关编写单元测试的信息,请参阅 单元测试 文档页面以及 test/units 处现有的单元测试。

如果你不确定如何进行测试编写,请在我们的任何 社区频道 中寻求澄清。

ansible-core 中向后移植已合并的 PR

所有 ansible-core 的 PR 必须先合并到 devel 分支。拉取请求被接受并合并到 devel 分支后,以下说明将帮助你创建一个拉取请求,将更改向后移植到之前的稳定分支。

我们 向后移植功能。

注意

这些说明假设:

  • stable-2.20 是向后移植的目标发布分支

  • https://github.com/ansible/ansible.git 已配置为名为 upstreamgit remote。如果你不使用名为 upstreamgit remote,请相应调整说明。

  • https://github.com/<yourgithubaccount>/ansible.git 已配置为名为 origingit remote。如果你不使用名为 origingit remote,请相应调整说明。

  1. 准备你的 devel、stable 和功能(feature)分支:

git fetch upstream
git checkout -b backport/2.20/[PR_NUMBER_FROM_DEVEL] upstream/stable-2.20
  1. 从 devel 分支拣选(Cherry pick)相关的提交 SHA 到你的功能分支,根据需要处理合并冲突:

git cherry-pick -x [SHA_FROM_DEVEL]
  1. 为更改添加一个 变更日志片段,并提交它。

  2. 将你的功能分支推送到你在 GitHub 上的 fork:

git push origin backport/2.20/[PR_NUMBER_FROM_DEVEL]
  1. 针对 stable-2.20 分支提交针对 backport/2.20/[PR_NUMBER_FROM_DEVEL] 的拉取请求:

  2. 发布经理将决定是否在下一个次要版本之前合并该向后移植 PR。无需后续跟进。只需确保自动化测试 (CI) 为绿色即可。

注意

分支名称 backport/2.20/[PR_NUMBER_FROM_DEVEL] 有点随意,但传达了分支目的的信息。不强制要求使用此分支名称格式,但它很有帮助,特别是在为多个稳定分支制作多个向后移植 PR 时。

注意

如果你愿意,可以使用 CPython 的 cherry-picker 工具(pip install --user 'cherry-picker >= 1.3.2')将提交从 Ansible 的 devel 分支向后移植到 stable 分支。有关安装、配置和使用的详细信息,请查看 cherry-picker 文档