persist coverage badge SVG + deduplicate UV setup (fix #42, fix #43)
Some checks failed
ci/woodpecker/push/infra-ci Pipeline was successful
ci/woodpecker/push/deploy Pipeline failed
coverage 99% coverage
ci/woodpecker/push/ci Pipeline was successful

- Upload badge SVG to Gitea generic package registry for stable URL
- Set UV_PROJECT_ENVIRONMENT=.venv so test reuses lint's installed env
- Remove redundant uv sync/pip install from test and coverage-badge steps
This commit is contained in:
kert
2026-03-13 10:48:14 -04:00
parent d97689abc0
commit 38477e0675
2 changed files with 39 additions and 8 deletions

View File

@@ -11,6 +11,7 @@ steps:
environment: environment:
UV_PYTHON_PREFERENCE: only-system UV_PYTHON_PREFERENCE: only-system
UV_LINK_MODE: copy UV_LINK_MODE: copy
UV_PROJECT_ENVIRONMENT: .venv
commands: commands:
- uv python pin 3.13.11 - uv python pin 3.13.11
- uv sync --dev - uv sync --dev
@@ -23,10 +24,8 @@ steps:
environment: environment:
UV_PYTHON_PREFERENCE: only-system UV_PYTHON_PREFERENCE: only-system
UV_LINK_MODE: copy UV_LINK_MODE: copy
UV_PROJECT_ENVIRONMENT: .venv
commands: commands:
- uv python pin 3.13.11
- uv sync --dev
- uv pip install -e .
- uv run pytest tests/ --cov=src --cov-report=term-missing --cov-fail-under=99 -q 2>&1 | tee pytest.out - uv run pytest tests/ --cov=src --cov-report=term-missing --cov-fail-under=99 -q 2>&1 | tee pytest.out
- uv run python dev/scripts/coverage_badge.py < pytest.out > coverage.svg - uv run python dev/scripts/coverage_badge.py < pytest.out > coverage.svg
depends_on: depends_on:
@@ -38,15 +37,14 @@ steps:
environment: environment:
UV_PYTHON_PREFERENCE: only-system UV_PYTHON_PREFERENCE: only-system
UV_LINK_MODE: copy UV_LINK_MODE: copy
UV_PROJECT_ENVIRONMENT: .venv
GITEA_TOKEN: GITEA_TOKEN:
from_secret: gitea_token from_secret: gitea_token
GITEA_URL: GITEA_URL:
from_secret: gitea_url from_secret: gitea_url
commands: commands:
- uv python pin 3.13.11
- uv sync --dev
- uv pip install -e .
- uv run python dev/scripts/coverage_badge.py --post pytest.out - uv run python dev/scripts/coverage_badge.py --post pytest.out
- uv run python dev/scripts/coverage_badge.py --upload coverage.svg
depends_on: depends_on:
- test - test

View File

@@ -58,9 +58,12 @@ def extract_pct(text: str) -> int:
return int(m.group(1)) return int(m.group(1))
def _gitea_env() -> tuple[str, str]:
return os.environ["GITEA_TOKEN"], os.environ["GITEA_URL"]
def post_status(pct: int) -> None: def post_status(pct: int) -> None:
token = os.environ["GITEA_TOKEN"] token, url = _gitea_env()
url = os.environ["GITEA_URL"]
sha = os.environ["CI_COMMIT_SHA"] sha = os.environ["CI_COMMIT_SHA"]
endpoint = f"{url}/api/v1/repos/homelab/stack/statuses/{sha}" endpoint = f"{url}/api/v1/repos/homelab/stack/statuses/{sha}"
body = json.dumps({ body = json.dumps({
@@ -81,12 +84,42 @@ def post_status(pct: int) -> None:
print(f"Posted coverage status: {pct}% (HTTP {resp.status})") print(f"Posted coverage status: {pct}% (HTTP {resp.status})")
def upload_badge(svg_path: str) -> None:
token, url = _gitea_env()
endpoint = f"{url}/api/packages/homelab/generic/coverage/latest/badge.svg"
data = open(svg_path, "rb").read()
# Delete existing package version first (ignore 404)
try:
req = urllib.request.Request(
f"{url}/api/packages/homelab/generic/coverage/latest",
headers={"Authorization": f"token {token}"},
method="DELETE",
)
urllib.request.urlopen(req)
except urllib.error.HTTPError:
pass
req = urllib.request.Request(
endpoint,
data=data,
headers={
"Authorization": f"token {token}",
"Content-Type": "image/svg+xml",
},
method="PUT",
)
with urllib.request.urlopen(req) as resp:
print(f"Uploaded badge SVG (HTTP {resp.status})")
def main() -> None: def main() -> None:
if "--post" in sys.argv: if "--post" in sys.argv:
path = sys.argv[sys.argv.index("--post") + 1] path = sys.argv[sys.argv.index("--post") + 1]
text = open(path).read() text = open(path).read()
pct = extract_pct(text) pct = extract_pct(text)
post_status(pct) post_status(pct)
elif "--upload" in sys.argv:
svg_path = sys.argv[sys.argv.index("--upload") + 1]
upload_badge(svg_path)
else: else:
text = sys.stdin.read() text = sys.stdin.read()
pct = extract_pct(text) pct = extract_pct(text)