diff --git a/.github/workflows/nox-heavy-rundeck.yml b/.github/workflows/nox-heavy-rundeck.yml new file mode 100644 index 00000000000..fac14ce2dbf --- /dev/null +++ b/.github/workflows/nox-heavy-rundeck.yml @@ -0,0 +1,18 @@ +--- +# Copyright (c) 2026, Alexei Znamensky +# 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 + +# Integration tests for the targets with the `heavy/rundeck` alias +name: nox-heavy-rundeck +'on': + workflow_dispatch: + +permissions: + contents: read + +jobs: + ansible-test: + uses: ansible-community/antsibull-nox/.github/workflows/reusable-nox-matrix.yml@main + with: + include-tags: heavy-rundeck diff --git a/.github/workflows/nox.yml b/.github/workflows/nox.yml index 009da6ebee5..85e0b12d3d9 100644 --- a/.github/workflows/nox.yml +++ b/.github/workflows/nox.yml @@ -34,5 +34,6 @@ jobs: upload-codecov-schedule: true allow-coverage-cd-override: true max-ansible-core: "2.18" + exclude-tags: remote, no-gha, heavy secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b70d8edc682..2b3cbab85ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -106,13 +106,16 @@ If you replace `-Re` with `-e`, then the virtual environments will be re-created ### Heavy integration tests Some integration test targets are not part of the regular `azp/posix/N` or `azp/generic/1` CI targets because they are too slow or need too many resources to run in CI. -Those that can run without credentials or special hardware are also tagged with the `heavy` alias, and should be run every once in a while: +Those that can run without credentials or special hardware are tagged with a `heavy/` alias instead, and should be run every once in a while. +Targets that need the same backend service share the same alias, for example `heavy/rundeck`. +Each alias has its own session in `antsibull-nox.toml`, and all of them can be run with: ```.bash nox -Re ansible-test-integration-heavy ``` Additional options for `ansible-test` can be passed after `--`. +Each backend also has its own GitHub workflow, `nox-heavy-`, that must be triggered manually. ## Run basic sanity, unit or integration tests locally (with ansible-test) diff --git a/antsibull-nox.toml b/antsibull-nox.toml index 5a769b16276..f2440051b8f 100644 --- a/antsibull-nox.toml +++ b/antsibull-nox.toml @@ -358,3 +358,22 @@ remote = [ ] ################################################################################################## + +# Heavy integration tests: +# Targets that are too slow or resource-hungry for regular CI, but that can run without credentials or special hardware. +# Each one has a `heavy/` alias; targets sharing a backend run in the same session. +# The session of each backend is tagged `heavy-`, and only runs in the nox-heavy- workflow, +# which must be triggered manually. + +[[sessions.ansible_test_integration.groups]] +session_name = "ansible-test-integration-heavy" +description = "Meta session for running all heavy integration test sessions." +tags = ["heavy"] + +[[sessions.ansible_test_integration.groups.sessions]] +ansible_core = "devel" +target = [ "heavy/rundeck/" ] +docker = "ubuntu" +tags = ["heavy-rundeck"] + +################################################################################################## diff --git a/noxfile.py b/noxfile.py index 0a6b274bb32..764b24152c0 100644 --- a/noxfile.py +++ b/noxfile.py @@ -57,27 +57,6 @@ def ansible_output(session: nox.Session) -> None: session.run("antsibull-docs", "ansible-output", *args, *session.posargs) -# Integration tests for targets that do not have the regular `azp/...` targets because they are too slow or -# resource-hungry for regular CI, but that can still run without credentials or special hardware. -# These targets are tagged with the `heavy` alias. This session is not registered for CI. -antsibull_nox.add_ansible_test_session( - name="ansible-test-integration-heavy", - description="Run integration tests for the non-CI targets tagged as heavy", - ansible_test_params=[ - "integration", - "-v", - "--docker", - "ubuntu", - "--display-traceback", - "error", - "heavy/", - ], - extra_deps_files=["tests/integration/requirements.yml"], - ansible_core_version="devel", - default=False, -) - - @nox.session(name="update-azp-config", python=False) def update_azp_config(session: nox.Session) -> None: command = [ @@ -85,6 +64,8 @@ def update_azp_config(session: nox.Session) -> None: "update-azp-config", "--min-ansible-core", "2.19", + "--exclude-tags", + "heavy", "--extra-session", '{"group": "Sanity", "title": "Extra sanity tests", "session": "extra-sanity-tests"}', ] diff --git a/tests/integration/targets/rundeck/aliases b/tests/integration/targets/rundeck/aliases index 098c111d818..c4265d2bf80 100644 --- a/tests/integration/targets/rundeck/aliases +++ b/tests/integration/targets/rundeck/aliases @@ -3,6 +3,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later destructive -heavy +heavy/rundeck skip/macos skip/freebsd diff --git a/tests/sanity/extra/aliases.py b/tests/sanity/extra/aliases.py index 96bcb2be53e..82565d737c3 100644 --- a/tests/sanity/extra/aliases.py +++ b/tests/sanity/extra/aliases.py @@ -7,17 +7,46 @@ from __future__ import annotations import glob +import os import sys +import tomllib import yaml -def main(): +def get_heavy_targets() -> tuple[set[str], bool]: + """Return the heavy/ targets that have sessions in antsibull-nox.toml, and whether errors were found.""" + with open("antsibull-nox.toml", "rb") as f: + config = tomllib.load(f) + + targets: set[str] = set() + has_errors = False + for group in config["sessions"]["ansible_test_integration"]["groups"]: + for session in [group] + group.get("sessions", []): + tags = set(group.get("tags", [])) | set(session.get("tags", [])) + target = session.get("target", []) + for value in [target] if isinstance(target, str) else target: + if not value.startswith("heavy/"): + continue + target_name = value.rstrip("/") + backend = target_name.split("/", 1)[1] + if f"heavy-{backend}" not in tags: + print(f'antsibull-nox.toml: session for "{target_name}" has no tag "heavy-{backend}"') + has_errors = True + workflow = f".github/workflows/nox-heavy-{backend}.yml" + if not os.path.exists(workflow): + print(f'{workflow}: workflow for "{target_name}" not found') + has_errors = True + targets.add(target_name) + return targets, has_errors + + +def main() -> int: """Main entry point.""" with open(".azure-pipelines/azure-pipelines.yml", "rb") as f: azp = yaml.safe_load(f) - allowed_targets = {"azp/generic/1", "heavy"} + allowed_targets = {"azp/generic/1"} for stage in azp["stages"]: if stage["stage"].startswith(("sanity", "unit", "Summary")): continue @@ -25,10 +54,11 @@ def main(): for param in job["parameters"]["targets"]: group = param["test"].rsplit("-", 1)[-1] allowed_targets.add(f"azp/posix/{group}") + heavy_targets, has_errors = get_heavy_targets() + allowed_targets.update(heavy_targets) paths = glob.glob("tests/integration/targets/*/aliases") - has_errors = False for path in paths: targets = [] skip = False