feat(pipeline): уведомления CI/CD — PipelineWatcher, CI загрузок на Gitea Actions #50

Merged
Eleboba merged 2 commits from feat/11-pipeline-watcher into dev 2026-10-19 12:40:52 +03:00
3 changed files with 16 additions and 7 deletions
Showing only changes of commit 0c8f1f790b - Show all commits
+2 -1
View File
@@ -148,7 +148,8 @@ class Settings(BaseSettings):
llm: LLMSettings = Field(default_factory=LLMSettings) llm: LLMSettings = Field(default_factory=LLMSettings)
sourcecraft: SourceCraftSettings = Field(default_factory=SourceCraftSettings) sourcecraft: SourceCraftSettings = Field(default_factory=SourceCraftSettings)
git: GitSettings = Field(default_factory=GitSettings) git: GitSettings = Field(default_factory=GitSettings)
ci: CISettings = Field(default_factory=CISettings) # not `ci`: Settings has no env prefix, and CI runners export CI=true
uploads_ci: CISettings = Field(default_factory=CISettings)
docker: DockerSettings = Field(default_factory=DockerSettings) docker: DockerSettings = Field(default_factory=DockerSettings)
runner: RunnerSettings = Field(default_factory=RunnerSettings) runner: RunnerSettings = Field(default_factory=RunnerSettings)
runtime: RuntimeSettings = Field(default_factory=RuntimeSettings) runtime: RuntimeSettings = Field(default_factory=RuntimeSettings)
+5 -5
View File
@@ -100,7 +100,7 @@ async def run(settings: Settings) -> None:
) )
repo = UploadsRepo(settings.git) repo = UploadsRepo(settings.git)
runner = RunnerClient(settings.runner) if settings.runner.host else None runner = RunnerClient(settings.runner) if settings.runner.host else None
ci = make_ci(settings.ci) ci = make_ci(settings.uploads_ci)
deployer = Deployer(repo, runner, alerts) if runner else None deployer = Deployer(repo, runner, alerts) if runner else None
# Without CI and runner there is nothing to watch: the push message just says what was pushed # Without CI and runner there is nothing to watch: the push message just says what was pushed
pipeline = ( pipeline = (
@@ -111,9 +111,9 @@ async def run(settings: Settings) -> None:
ci, ci,
deployer, deployer,
commit_url_template=settings.git.commit_url_template, commit_url_template=settings.git.commit_url_template,
poll_interval=settings.ci.poll_interval, poll_interval=settings.uploads_ci.poll_interval,
max_poll_interval=settings.ci.max_poll_interval, max_poll_interval=settings.uploads_ci.max_poll_interval,
run_timeout=timedelta(minutes=settings.ci.run_timeout_minutes), run_timeout=timedelta(minutes=settings.uploads_ci.run_timeout_minutes),
) )
if ci or deployer if ci or deployer
else None else None
@@ -150,7 +150,7 @@ async def run(settings: Settings) -> None:
"via proxy" if proxy else "direct", "via proxy" if proxy else "direct",
"on" if docker else "off", "on" if docker else "off",
settings.llm.provider if agent else "off", settings.llm.provider if agent else "off",
settings.ci.provider if ci else "off", settings.uploads_ci.provider if ci else "off",
settings.runner.host or "off", settings.runner.host or "off",
) )
try: try:
+9 -1
View File
@@ -3,7 +3,7 @@ from pathlib import Path
import pytest import pytest
from pydantic import ValidationError from pydantic import ValidationError
from app.config import AccessSettings from app.config import AccessSettings, Settings
from app.texts import load_texts from app.texts import load_texts
@@ -21,3 +21,11 @@ def test_texts_with_missing_key_fail_fast(tmp_path: Path) -> None:
(tmp_path / "texts.yaml").write_text("menu: {commit: x}\n", encoding="utf-8") (tmp_path / "texts.yaml").write_text("menu: {commit: x}\n", encoding="utf-8")
with pytest.raises(ValidationError): with pytest.raises(ValidationError):
load_texts(tmp_path) load_texts(tmp_path)
def test_ci_runner_env_does_not_break_settings(monkeypatch: pytest.MonkeyPatch) -> None:
# Gitea/GitHub runners export CI=true; it must not collide with a settings field
monkeypatch.setenv("CI", "true")
monkeypatch.setenv("TELEGRAM_BOT_TOKEN", "42:x")
assert Settings().uploads_ci.provider == "none"