#!/usr/bin/env python3 """Create a Gitea issue when a CI workflow fails. Used by the release and publish workflows to alert on failures that would otherwise go unnoticed in the Actions tab. Uses the ``tea`` Gitea CLI for issue creation — tea must be installed and configured. Usage: REPO_TOKEN= python3 scripts/notify_failure.py \ --repo \ --run-id \ --workflow \ --commit """ from __future__ import annotations import contextlib import os import click from dotenv import load_dotenv # pyright: ignore[reportMissingImports,reportUnknownVariableType] from gitea_runner_manager.config import GITEA_API_URL from scripts.gitea_cli import TeaCLI, TeaCLIError from scripts.i18n import _ load_dotenv(override=True) def _create_issue_via_tea(repo: str, title: str, body: str) -> int: """Create issue via tea CLI. Returns issue index. Raises TeaCLIError if tea is not installed or the command fails. """ tea = TeaCLI(repo=repo) # Check if "bug" label exists labels: list[str] = [] with contextlib.suppress(TeaCLIError): existing_labels = tea.list_labels(repo) if any(label.get("name") == "bug" for label in existing_labels): labels = ["bug"] issue = tea.create_issue(repo, title=title, body=body, labels=labels if labels else None) if labels: with contextlib.suppress(TeaCLIError): tea.add_label(repo, issue["index"], labels) return int(issue.get("index", 0)) @click.command() @click.option("--repo", required=True, help="Repository in owner/name format.") @click.option("--run-id", required=True, help="CI run ID.") @click.option("--workflow", required=True, help="Workflow name.") @click.option("--commit", required=True, help="Commit SHA.") def main(repo: str, run_id: str, workflow: str, commit: str) -> None: token = os.environ.get("REPO_TOKEN", "") if not token: raise click.ClickException(_("ERROR: REPO_TOKEN is not set.")) title = f"[CI] {workflow} workflow failed (run #{run_id})" body = ( f"The **{workflow}** workflow failed.\n\n" f"- **Run ID**: #{run_id}\n" f"- **Commit**: `{commit[:8]}`\n" f"- **Check the logs**: {GITEA_API_URL.replace('/api/v1', '')}/" f"{repo}/actions/runs/{run_id}\n\n" f"Please investigate and fix the issue." ) try: issue_id = _create_issue_via_tea(repo, title, body) except TeaCLIError as e: raise click.ClickException(_("Failed to create issue via tea: {error}", error=str(e))) from None click.echo( _( "Created issue #{issue_id}: {title}", issue_id=issue_id or "?", title=title, ) ) if __name__ == "__main__": # pragma: no cover main()