DEVX-153: feat: sync missing features from v0.49.x line to master
Post-merge / detect-and-configure (push) Successful in 16s
Post-merge / release-and-maintain (push) Successful in 1m2s

Co-authored-by: emil User <emil.simeonov@tutanota.com>
This commit was merged in pull request #267.
This commit is contained in:
2026-08-09 01:09:20 +00:00
committed by emo
parent d2aa4c6298
commit 3d4b4940ff
79 changed files with 4697 additions and 361 deletions
-204
View File
@@ -14,7 +14,6 @@ from devx.tools.setup import (
_install_pre_commit_hooks,
_install_python_deps,
_run,
_try_gitea_mirror_install,
_verify,
main,
)
@@ -107,7 +106,6 @@ class TestInstallAnsibleCollections:
with patch("devx.tools.setup.Path") as mock_path:
mock_path.return_value.exists.return_value = True
mock_path.return_value.__str__ = lambda _: str(req)
mock_path.return_value.read_text = lambda: req.read_text()
_install_ansible_collections(".venv/bin")
mock_run.assert_called_once()
@@ -136,7 +134,6 @@ class TestInstallAnsibleCollections:
with patch("devx.tools.setup.Path") as mock_path:
mock_path.return_value.exists.return_value = True
mock_path.return_value.__str__ = lambda _: str(req)
mock_path.return_value.read_text = lambda: req.read_text()
_install_ansible_collections(".venv/bin")
assert mock_run.call_count == 2
@@ -156,211 +153,10 @@ class TestInstallAnsibleCollections:
with patch("devx.tools.setup.Path") as mock_path:
mock_path.return_value.exists.return_value = True
mock_path.return_value.__str__ = lambda _: str(req)
mock_path.return_value.read_text = lambda: req.read_text()
with pytest.raises(_subprocess.CalledProcessError):
_install_ansible_collections(".venv/bin")
assert mock_run.call_count == 3
@patch("devx.tools.setup._try_gitea_mirror_install", return_value=True)
@patch("devx.tools.setup.shutil.which", return_value="/usr/local/bin/ansible-galaxy")
@patch("devx.tools.setup._run")
def test_mirror_install_skips_galaxy_fallback(
self, mock_run: MagicMock, mock_which: MagicMock, mock_mirror: MagicMock, tmp_path: Path
) -> None:
"""When mirror install succeeds, galaxy fallback is not called."""
req = tmp_path / "ansible" / "requirements.yml"
req.parent.mkdir(parents=True)
req.write_text("collections: []")
with patch("devx.tools.setup.Path") as mock_path:
mock_path.return_value.exists.return_value = True
mock_path.return_value.__str__ = lambda _: str(req)
mock_path.return_value.read_text = lambda: req.read_text()
_install_ansible_collections(".venv/bin")
# _run should not be called because mirror install returns True
mock_run.assert_not_called()
class TestTryGiteaMirrorInstall:
"""Tests for _try_gitea_mirror_install — Gitea mirror with auth + fallback."""
_GITEA_URL = "https://git.example.com/api/packages/org/generic/ansible-collections/1.0.0/ansible-posix-1.0.0.tar.gz"
@patch.dict(os.environ, {}, clear=True)
def test_no_url_entries_returns_false(self, tmp_path: Path) -> None:
"""Requirements without type: url entries should return False."""
req = tmp_path / "requirements.yml"
req.write_text("collections:\n - name: ansible.posix\n version: '1.0.0'\n")
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is False
@patch.dict(os.environ, {}, clear=True)
def test_no_token_returns_false(self, tmp_path: Path) -> None:
"""No Gitea token set → return False to fall back to galaxy."""
req = tmp_path / "requirements.yml"
req.write_text(
"collections:\n"
" - name: ansible.posix\n"
" version: '1.0.0'\n"
" type: url\n"
f" source: '{self._GITEA_URL}'\n"
)
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is False
@patch.dict(os.environ, {"CI_GITEA_TOKEN": "tok123"}, clear=True)
def test_yaml_parse_error_returns_false(self, tmp_path: Path) -> None:
"""Malformed YAML → return False."""
req = tmp_path / "requirements.yml"
req.write_text("not: valid: yaml: [[")
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is False
@patch("devx.tools.setup._run")
@patch("urllib.request.urlopen")
@patch.dict(os.environ, {"CI_GITEA_TOKEN": "tok123"}, clear=True)
def test_successful_mirror_install(self, mock_urlopen: MagicMock, mock_run: MagicMock, tmp_path: Path) -> None:
"""Valid URL entries + token → downloads with auth and installs offline."""
req = tmp_path / "requirements.yml"
req.write_text(
f"collections:\n"
f" - name: ansible.posix\n"
f" version: '1.0.0'\n"
f" type: url\n"
f" source: '{self._GITEA_URL}'\n"
)
mock_resp = MagicMock()
mock_resp.read.return_value = b"fake-tarball"
mock_resp.__enter__ = lambda _: mock_resp
mock_resp.__exit__ = lambda *a: None
mock_urlopen.return_value = mock_resp
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is True
# Verify auth header was added
call_args = mock_urlopen.call_args[0][0]
assert call_args.get_header("Authorization") == "token tok123"
# Verify offline install was called
install_cmd = mock_run.call_args[0][0]
assert "collection" in install_cmd
assert "install" in install_cmd
assert "--offline" in install_cmd
@patch("urllib.request.urlopen")
@patch.dict(os.environ, {"CI_GITEA_TOKEN": "tok123"}, clear=True)
def test_download_failure_returns_false(self, mock_urlopen: MagicMock, tmp_path: Path) -> None:
"""Download failure → return False to fall back to galaxy."""
req = tmp_path / "requirements.yml"
req.write_text(
f"collections:\n"
f" - name: ansible.posix\n"
f" version: '1.0.0'\n"
f" type: url\n"
f" source: '{self._GITEA_URL}'\n"
)
mock_urlopen.side_effect = Exception("401 Unauthorized")
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is False
@patch("devx.tools.setup._run")
@patch("urllib.request.urlopen")
@patch.dict(os.environ, {"CI_GITEA_API_TOKEN": "tok456"}, clear=True)
def test_prefers_api_token_over_legacy(self, mock_urlopen: MagicMock, mock_run: MagicMock, tmp_path: Path) -> None:
"""CI_GITEA_API_TOKEN takes priority over CI_GITEA_TOKEN."""
req = tmp_path / "requirements.yml"
req.write_text(
f"collections:\n"
f" - name: ansible.posix\n"
f" version: '1.0.0'\n"
f" type: url\n"
f" source: '{self._GITEA_URL}'\n"
)
mock_resp = MagicMock()
mock_resp.read.return_value = b"fake-tarball"
mock_resp.__enter__ = lambda _: mock_resp
mock_resp.__exit__ = lambda *a: None
mock_urlopen.return_value = mock_resp
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is True
call_args = mock_urlopen.call_args[0][0]
assert call_args.get_header("Authorization") == "token tok456"
@patch("devx.tools.setup._run")
@patch("urllib.request.urlopen")
@patch.dict(os.environ, {"DEVELOPER_GITEA_API_TOKEN": "tok789"}, clear=True)
def test_developer_token_fallback(self, mock_urlopen: MagicMock, mock_run: MagicMock, tmp_path: Path) -> None:
"""DEVELOPER_GITEA_API_TOKEN is used when CI tokens are absent."""
req = tmp_path / "requirements.yml"
req.write_text(
f"collections:\n"
f" - name: ansible.posix\n"
f" version: '1.0.0'\n"
f" type: url\n"
f" source: '{self._GITEA_URL}'\n"
)
mock_resp = MagicMock()
mock_resp.read.return_value = b"fake-tarball"
mock_resp.__enter__ = lambda _: mock_resp
mock_resp.__exit__ = lambda *a: None
mock_urlopen.return_value = mock_resp
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is True
call_args = mock_urlopen.call_args[0][0]
assert call_args.get_header("Authorization") == "token tok789"
@patch("devx.tools.setup._run")
@patch("urllib.request.urlopen")
@patch.dict(os.environ, {"CI_GITEA_TOKEN": "tok123"}, clear=True)
def test_non_gitea_url_passed_through(self, mock_urlopen: MagicMock, mock_run: MagicMock, tmp_path: Path) -> None:
"""URL entries not pointing to /api/packages/ are kept as-is (no download)."""
external_url = "https://galaxy.ansible.com/download/ansible-posix-1.0.0.tar.gz"
req = tmp_path / "requirements.yml"
req.write_text(
f"collections:\n"
f" - name: ansible.posix\n"
f" version: '1.0.0'\n"
f" type: url\n"
f" source: '{external_url}'\n"
)
# Should not call urlopen since the URL is not a Gitea package URL
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is True
mock_urlopen.assert_not_called()
@patch("devx.tools.setup._run")
@patch("urllib.request.urlopen")
@patch.dict(os.environ, {"CI_GITEA_TOKEN": "tok123"}, clear=True)
def test_mixed_entries_gitea_and_non_gitea(
self, mock_urlopen: MagicMock, mock_run: MagicMock, tmp_path: Path
) -> None:
"""Mix of Gitea URL entries and regular galaxy entries."""
req = tmp_path / "requirements.yml"
req.write_text(
f"collections:\n"
f" - name: ansible.posix\n"
f" version: '1.0.0'\n"
f" type: url\n"
f" source: '{self._GITEA_URL}'\n"
f" - name: community.general\n"
f" version: '13.0.0'\n"
)
mock_resp = MagicMock()
mock_resp.read.return_value = b"fake-tarball"
mock_resp.__enter__ = lambda _: mock_resp
mock_resp.__exit__ = lambda *a: None
mock_urlopen.return_value = mock_resp
result = _try_gitea_mirror_install("ansible-galaxy", req)
assert result is True
# Only the Gitea URL entry should trigger a download
mock_urlopen.assert_called_once()
class TestConfigureTeaLogin:
@patch("devx.tools.setup.shutil.which", return_value=None)