Add secret scanning, Dockerfile lint, ruff lint/format gate, coverage gate, and automatic CVE remediation PRs
- gitleaks (via docker cp, dockerignore-agnostic) and hadolint scan every push/PR - new ruff lint stage (ruff.toml pins known-first-party for host/container consistency; F841/B007 in webui.py left un-fixed via per-file-ignores — app-logic changes, flagged for review rather than auto-fixed) - pytest --cov-fail-under=90 gate on the test stage (already had pytest-cov, never wired into CI until now) - scheduled Trivy critical failures now attempt an apk upgrade rebuild and open a PR if it clears the finding, instead of just failing red - ruff --fix/--format applied to existing code to start the gate clean
This commit is contained in:
+2
-5
@@ -50,9 +50,7 @@ def app_env(tmp_path, monkeypatch, make_image):
|
||||
theme_dir = root / "config" / "themes" / "modern"
|
||||
theme_dir.mkdir(parents=True)
|
||||
(theme_dir / "theme.yaml").write_text(
|
||||
"colors:\n browser_color: '#ffffff'\n"
|
||||
"favicon:\n path: favicon.png\n"
|
||||
"google_fonts: []\n",
|
||||
"colors:\n browser_color: '#ffffff'\nfavicon:\n path: favicon.png\ngoogle_fonts: []\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
make_image(theme_dir / "favicon.png", size=(32, 32), fmt="PNG")
|
||||
@@ -61,8 +59,7 @@ def app_env(tmp_path, monkeypatch, make_image):
|
||||
"hero:\n images: []\ngallery:\n images: []\n", encoding="utf-8"
|
||||
)
|
||||
(root / "config" / "site.yaml").write_text(
|
||||
"info:\n title: Test\n canonical: https://example.com\n"
|
||||
"social:\n thumbnail: ''\n",
|
||||
"info:\n title: Test\n canonical: https://example.com\nsocial:\n thumbnail: ''\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
from src.py.builder import utils
|
||||
|
||||
|
||||
@@ -30,7 +28,7 @@ def test_load_theme_config_missing_raises(tmp_path):
|
||||
themes_dir = tmp_path / "themes"
|
||||
try:
|
||||
utils.load_theme_config("missing", themes_dir)
|
||||
assert False, "expected FileNotFoundError"
|
||||
raise AssertionError("expected FileNotFoundError")
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import yaml
|
||||
|
||||
from src.py.builder import gallery_builder as gb
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from src.py.builder import image_processor as ip
|
||||
@@ -101,8 +99,13 @@ def test_generate_favicons_from_logo_creates_all_sizes(tmp_path, make_image):
|
||||
ip.generate_favicons_from_logo({"favicon": {"path": "favicon.png"}}, theme_dir, output_dir)
|
||||
|
||||
expected = [
|
||||
"favicon-32.png", "favicon-96.png", "favicon-128.png",
|
||||
"favicon-192.png", "favicon-196.png", "favicon-152.png", "favicon-180.png",
|
||||
"favicon-32.png",
|
||||
"favicon-96.png",
|
||||
"favicon-128.png",
|
||||
"favicon-192.png",
|
||||
"favicon-196.png",
|
||||
"favicon-152.png",
|
||||
"favicon-180.png",
|
||||
]
|
||||
for name in expected:
|
||||
assert (output_dir / name).exists()
|
||||
|
||||
@@ -102,7 +102,13 @@ def test_site_info_get_and_post(client, app_env):
|
||||
data = resp.get_json()
|
||||
assert data["info"]["title"] == "Test"
|
||||
|
||||
client.post("/api/site-info", json={"info": {"subtitle": "New subtitle"}, "social": {"instagram_url": "https://insta.example"}})
|
||||
client.post(
|
||||
"/api/site-info",
|
||||
json={
|
||||
"info": {"subtitle": "New subtitle"},
|
||||
"social": {"instagram_url": "https://insta.example"},
|
||||
},
|
||||
)
|
||||
|
||||
updated = client.get("/api/site-info").get_json()
|
||||
assert updated["info"]["title"] == "Test"
|
||||
@@ -271,9 +277,7 @@ def test_trigger_build_success_invokes_subprocess(client, app_env, monkeypatch):
|
||||
)
|
||||
|
||||
calls = []
|
||||
monkeypatch.setattr(
|
||||
webui.subprocess, "run", lambda *a, **k: calls.append((a, k))
|
||||
)
|
||||
monkeypatch.setattr(webui.subprocess, "run", lambda *a, **k: calls.append((a, k)))
|
||||
|
||||
resp = client.post("/api/build")
|
||||
assert resp.get_json() == {"status": "ok"}
|
||||
|
||||
Reference in New Issue
Block a user