DEVX-123: feat: introduce role-based Gitea API token environment variables
Post-merge / detect-type (push) Successful in 10s
Post-merge / validate-commit-msg (push) Successful in 10s
Post-merge / configure-repo (push) Successful in 11s
Post-merge / sync-wiki (push) Successful in 17s
Post-merge / vikunja (push) Successful in 18s
Post-merge / release (push) Successful in 36s
Post-merge / publish (push) Successful in 20s
Post-merge / badges (push) Successful in 35s

This commit was merged in pull request #186.
This commit is contained in:
2026-07-08 19:30:10 +00:00
parent 981d3e41cc
commit 0228fce5b9
41 changed files with 413 additions and 152 deletions
+12
View File
@@ -4,6 +4,7 @@ import json
from pathlib import Path
from unittest.mock import MagicMock, patch
import click
import pytest
from click.testing import CliRunner
@@ -249,3 +250,14 @@ class TestMain:
args, kwargs = mock_count.call_args
assert "myorg" in args
assert "myrepo" in args
@patch("devx.ci.discover_runners.get_ci_token", side_effect=click.ClickException("no token"))
@patch("devx.ci.discover_runners.get_runner_count", return_value=3)
def test_missing_token_runs_without_api(self, mock_count: MagicMock, mock_token: MagicMock) -> None:
"""When no token is available, runner discovery falls back to env/default."""
runner = CliRunner()
result = runner.invoke(main, ["--count"])
assert result.exit_code == 0
assert result.output.strip() == "3"
args, _ = mock_count.call_args
assert args[1] is None # token passed as None when missing
+22
View File
@@ -186,6 +186,28 @@ class TestCli:
timeout=60,
)
@patch("devx.molecule.molecule_ci_guard.get_ci_token", side_effect=click.ClickException("no token"))
def test_missing_token_runs_without_polling(self, mock_token: MagicMock) -> None:
"""When no token is available, cross-runner polling is skipped."""
from click.testing import CliRunner
with (
patch("devx.molecule.molecule_ci_guard.subprocess.Popen") as mock_popen,
patch("devx.molecule.molecule_ci_guard.subprocess.run") as mock_run,
patch("devx.molecule.molecule_ci_guard.poll_for_other_failures") as mock_poll,
patch("time.sleep"),
):
proc = MagicMock()
proc.poll.return_value = 0
proc.returncode = 0
mock_popen.return_value = proc
mock_run.return_value = MagicMock(returncode=0)
runner = CliRunner()
result = runner.invoke(cli, ["default|ubuntu-2204|img:latest|"])
assert result.exit_code == 0
mock_poll.assert_not_called()
def test_invalid_pair_format_raises(self) -> None:
"""Pair with fewer than 2 parts should raise."""
from click.testing import CliRunner
@@ -4,6 +4,7 @@ import json
from pathlib import Path
from unittest.mock import MagicMock, patch
import click
import pytest
from click.testing import CliRunner
@@ -219,3 +220,14 @@ class TestMain:
args, kwargs = mock_count.call_args
assert "myorg" in args
assert "myrepo" in args
@patch("devx.molecule.discover_runners.get_ci_token", side_effect=click.ClickException("no token"))
@patch("devx.molecule.discover_runners.get_runner_count", return_value=3)
def test_missing_token_runs_without_api(self, mock_count: MagicMock, mock_token: MagicMock) -> None:
"""When no token is available, runner discovery falls back to env/default."""
runner = CliRunner()
result = runner.invoke(main, ["--count"])
assert result.exit_code == 0
assert result.output.strip() == "3"
args, _ = mock_count.call_args
assert args[1] is None # token passed as None when missing
+7 -2
View File
@@ -12,9 +12,14 @@ from devx.tools.pr_label import cli
class TestCli:
def test_no_token_raises(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("CI_GITEA_TOKEN", raising=False)
for name in ("DEVELOPER_GITEA_API_TOKEN", "CI_GITEA_API_TOKEN", "CI_GITEA_TOKEN"):
monkeypatch.delenv(name, raising=False)
runner = CliRunner()
result = runner.invoke(cli, ["--pr", "42", "--label", "ready-to-merge"])
result = runner.invoke(
cli,
["--pr", "42", "--label", "ready-to-merge"],
env={"DEVELOPER_GITEA_API_TOKEN": "", "CI_GITEA_API_TOKEN": "", "CI_GITEA_TOKEN": ""},
)
assert result.exit_code != 0
assert "CI_GITEA_TOKEN" in result.output
+7 -2
View File
@@ -153,9 +153,14 @@ class TestPrintLogs:
class TestCli:
def test_no_token_raises(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("CI_GITEA_TOKEN", raising=False)
for name in ("DEVELOPER_GITEA_API_TOKEN", "CI_GITEA_API_TOKEN", "CI_GITEA_TOKEN"):
monkeypatch.delenv(name, raising=False)
runner = CliRunner()
result = runner.invoke(cli, ["--pr", "42"])
result = runner.invoke(
cli,
["--pr", "42"],
env={"DEVELOPER_GITEA_API_TOKEN": "", "CI_GITEA_API_TOKEN": "", "CI_GITEA_TOKEN": ""},
)
assert result.exit_code != 0
assert "CI_GITEA_TOKEN" in result.output
+2 -1
View File
@@ -756,9 +756,10 @@ class TestMain:
result = runner.invoke(main, ["42", "my-org/my-repo"], env={"CI_GITEA_TOKEN": "fake"})
assert result.exit_code != 0
@patch.dict("os.environ", {"CI_GITEA_API_TOKEN": "", "CI_GITEA_TOKEN": ""})
def test_no_token_raises(self) -> None:
runner = CliRunner()
result = runner.invoke(main, ["42", "my-org/my-repo"], env={"CI_GITEA_TOKEN": ""})
result = runner.invoke(main, ["42", "my-org/my-repo"], env={"CI_GITEA_API_TOKEN": "", "CI_GITEA_TOKEN": ""})
assert result.exit_code != 0
assert "CI_GITEA_TOKEN" in result.output
+7 -2
View File
@@ -122,9 +122,14 @@ class TestWaitForCompletion:
class TestCli:
def test_no_token_raises(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("CI_GITEA_TOKEN", raising=False)
for name in ("DEVELOPER_GITEA_API_TOKEN", "CI_GITEA_API_TOKEN", "CI_GITEA_TOKEN"):
monkeypatch.delenv(name, raising=False)
runner = CliRunner()
result = runner.invoke(cli, ["--pr", "42"])
result = runner.invoke(
cli,
["--pr", "42"],
env={"DEVELOPER_GITEA_API_TOKEN": "", "CI_GITEA_API_TOKEN": "", "CI_GITEA_TOKEN": ""},
)
assert result.exit_code != 0
assert "CI_GITEA_TOKEN" in result.output
+3 -2
View File
@@ -256,9 +256,10 @@ class TestCommitAndPush:
class TestMain:
def test_no_token_raises(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("CI_GITEA_TOKEN", raising=False)
for name in ("CI_GITEA_API_TOKEN", "CI_GITEA_TOKEN"):
monkeypatch.delenv(name, raising=False)
runner = CliRunner()
result = runner.invoke(main, [])
result = runner.invoke(main, [], env={"CI_GITEA_API_TOKEN": "", "CI_GITEA_TOKEN": ""})
assert result.exit_code != 0
assert "CI_GITEA_TOKEN" in result.output