name: Workflow Lint on: push: branches: [main] pull_request: types: [opened, synchronize] jobs: workflow-sanity: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Sanity check ci.yml triggers and gates run: | set -euo pipefail python3 - <<'PY' import sys, yaml, re from pathlib import Path p = Path('.gitea/workflows/ci.yml') w = yaml.safe_load(p.read_text()) # 1) Top-level 'on' must exist and include pull_request + issue_comment on = w.get('on') assert isinstance(on, dict), "ci.yml: top-level 'on' must be a mapping" assert 'pull_request' in on, "ci.yml: missing on.pull_request" assert 'issue_comment' in on, "ci.yml: missing on.issue_comment (self-review trigger)" pr_types = on['pull_request'].get('types', []) if isinstance(on['pull_request'], dict) else [] ic_types = on['issue_comment'].get('types', []) if isinstance(on['issue_comment'], dict) else [] for t in ['opened','synchronize']: assert t in pr_types, f"ci.yml: pull_request.types must include '{t}'" for t in ['created','edited']: assert t in ic_types, f"ci.yml: issue_comment.types must include '{t}'" # 2) review-gate must run on both PR and issue_comment (if condition string) rg_if = w['jobs']['review-gate'].get('if','') assert 'github.event_name == ' in rg_if and 'issue_comment' in rg_if and 'pull_request' in rg_if, \ "ci.yml: review-gate.if must include both pull_request and issue_comment" # 3) review job must require self-review reason rev_if = w['jobs']['review'].get('if','') assert "needs.review-gate.outputs.reason == 'self-review'" in rev_if, \ "ci.yml: review.if must require reason=='self-review'" print('OK: ci.yml triggers and gates look sane') PY