From 18c362eef41f7733366caf8e8120f7d1d9e96be3 Mon Sep 17 00:00:00 2001 From: Alexei Znamensky <103110+russoz@users.noreply.github.com> Date: Mon, 29 Dec 2025 21:55:52 +1300 Subject: [PATCH] add devcontainer+pre-commit (#11328) * add devcontainer support * chore(devcontainer): install test requirements * chore: add pre-commit * fix format of pre-commit config file * add licenses for the new files * Apply suggestions from code review * move requirements-dev.txt to inside .devcontainer * specify files for ruff * update CONTRIBUTING.md * chore(devcontainer): use standard image, no docker build * docs: format CONTRIBUTING.md (automatic by IDE) * Update .devcontainer/devcontainer.json * remove extraneous edits in CONTRIBUTING.md --- .devcontainer/devcontainer.json | 34 +++++++++++++++++++++++++ .devcontainer/devcontainer.json.license | 3 +++ .devcontainer/requirements-dev.txt | 10 ++++++++ .devcontainer/setup.sh | 16 ++++++++++++ .pre-commit-config.yaml | 13 ++++++++++ CONTRIBUTING.md | 31 +++++++++++++++++++++- ruff.toml | 3 +++ 7 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/devcontainer.json.license create mode 100644 .devcontainer/requirements-dev.txt create mode 100755 .devcontainer/setup.sh create mode 100644 .pre-commit-config.yaml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..c3a8cb8bfe --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "community.general devcontainer", + "image": "mcr.microsoft.com/devcontainers/python:3.14-bookworm", + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": {} + }, + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + "python.pythonPath": "/usr/local/bin/python", + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.formatOnSave": true, + "files.autoSave": "afterDelay", + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true + }, + "extensions": [ + "charliermarsh.ruff", + "ms-python.python", + "ms-python.vscode-pylance", + "redhat.ansible", + "redhat.vscode-yaml", + "trond-snekvik.simple-rst", + ] + } + }, + "remoteUser": "vscode", + "postCreateCommand": ".devcontainer/setup.sh", + "workspaceFolder": "/workspace/ansible_collections/community/general", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace/ansible_collections/community/general,type=bind" +} diff --git a/.devcontainer/devcontainer.json.license b/.devcontainer/devcontainer.json.license new file mode 100644 index 0000000000..8d6450c136 --- /dev/null +++ b/.devcontainer/devcontainer.json.license @@ -0,0 +1,3 @@ +GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https: //www.gnu.org/licenses/gpl-3.0.txt) +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-FileCopyrightText: 2025 Alexei Znamensky diff --git a/.devcontainer/requirements-dev.txt b/.devcontainer/requirements-dev.txt new file mode 100644 index 0000000000..bef15c3b8c --- /dev/null +++ b/.devcontainer/requirements-dev.txt @@ -0,0 +1,10 @@ +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: 2025 Alexei Znamensky + +nox +ruff +antsibull-nox +pre-commit +ansible-core +andebox diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 0000000000..cced6bc2ca --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +# Copyright (c) Ansible Project +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +sudo chown -R vscode:vscode /workspace/ + +pip install -U pip +pip install -r .devcontainer/requirements-dev.txt +pip install -r tests/unit/requirements.txt + +export ANSIBLE_COLLECTIONS_PATH=/workspace:${ANSIBLE_COLLECTIONS_PATH} +ansible-galaxy collection install -v -r tests/unit/requirements.yml +ansible-galaxy collection install -v -r tests/integration/requirements.yml + +pre-commit install diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000..e20e8ea6cd --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: 2025 Alexei Znamensky + +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.14.10 + hooks: + # Run the linter. + - id: ruff-check + # Run the formatter. + - id: ruff-format diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2adc0446e2..175c45e29a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -133,6 +133,7 @@ ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration Note that for running unit tests, you need to install required collections in the same folder structure that `community.general` is checked out in. Right now, you need to install [`community.internal_test_tools`](https://github.com/ansible-collections/community.internal_test_tools). If you want to use the latest version from GitHub, you can run: + ``` git clone https://github.com/ansible-collections/community.internal_test_tools.git ~/dev/ansible_collections/community/internal_test_tools ``` @@ -155,6 +156,7 @@ ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools Note that for running integration tests, you need to install required collections in the same folder structure that `community.general` is checked out in. Right now, depending on the test, you need to install [`ansible.posix`](https://github.com/ansible-collections/ansible.posix), [`community.crypto`](https://github.com/ansible-collections/community.crypto), and [`community.docker`](https://github.com/ansible-collections/community.docker): If you want to use the latest versions from GitHub, you can run: + ``` mkdir -p ~/dev/ansible_collections/ansible git clone https://github.com/ansible-collections/ansible.posix.git ~/dev/ansible_collections/ansible/posix @@ -167,11 +169,13 @@ The following commands show how to run integration tests: #### In Docker Integration tests on Docker have the following parameters: + - `image_name` (required): The name of the Docker image. To get the list of supported Docker images, run `ansible-test integration --help` and look for _target docker images_. - `test_name` (optional): The name of the integration test. For modules, this equals the short name of the module; for example, `pacman` in case of `community.general.pacman`. For plugins, the plugin type is added before the plugin's short name, for example `callback_yaml` for the `community.general.yaml` callback. + ```.bash # Test all plugins/modules on fedora40 ansible-test integration -v --docker fedora40 @@ -192,6 +196,31 @@ ansible-test integration -v lookup_flattened If you are unsure about the integration test target name for a module or plugin, you can take a look in `tests/integration/targets/`. Tests for plugins have the plugin type prepended. +## Devcontainer + +Since community.general 12.2.0, the project repository supports [devcontainers](https://containers.dev/). In short, it is a standard mechanism to +create a container that is then used during the development cycle. Many tools are pre-installed in the container and will be already available +to you as a developer. A number of different IDEs support that configuration, the most prominent ones being VSCode and PyCharm. + +See the files under [.devcontainer](.devcontainer) for details on what is deployed inside that container. + +Beware of: + +- By default, the devcontainer installs the latest version of `ansible-core`. + When testing your changes locally, keep in mind that the collection must support older versions of + `ansible-core` and, depending on what is being tested, results may vary. +- Integration tests executed directly inside the devcontainer without isolation (see above) may fail if + they expected to be run in full fledged VMs. On the other hand, the devcontainer setup allows running + containers inside the container (the `docker-in-docker` feature). +- The devcontainer is built with a directory structure such that + `.../ansible_collections/community/general` contains the project repository, so `ansible-test` and + other standard tools should work without any additional setup +- By default, the devcontainer installs `pre-commit` and configures it to perform `ruff check` and + `ruff format` on the Python files, prior to commiting. That configuration is going to be used by + `git` even outside the devcontainer. To prevent errors, you have to either install `pre-commit` in + your computer, outside the devcontainer, or run `pre-commit uninstall` from within the devcontainer + before quitting it. + ## Creating new modules or plugins Creating new modules and plugins requires a bit more work than other Pull Requests. @@ -201,7 +230,7 @@ Creating new modules and plugins requires a bit more work than other Pull Reques 2. Please do not add more than one plugin/module in one PR, especially if it is the first plugin/module you are contributing. That makes it easier for reviewers, and increases the chance that your PR will get merged. If you plan to contribute a group - of plugins/modules (say, more than a module and a corresponding ``_info`` module), please mention that in the first PR. In + of plugins/modules (say, more than a module and a corresponding `_info` module), please mention that in the first PR. In such cases, you also have to think whether it is better to publish the group of plugins/modules in a new collection. 3. When creating a new module or plugin, please make sure that you follow various guidelines: diff --git a/ruff.toml b/ruff.toml index 3c7ee4dc0a..c4c0354847 100644 --- a/ruff.toml +++ b/ruff.toml @@ -4,6 +4,9 @@ line-length = 120 +# Include only the files: +include = ["plugins/**/*.py", "tests/unit/**/*.py", "noxfile.py"] + [lint] # https://docs.astral.sh/ruff/rules/