Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AqpXh3hQMMaC74pTjFq4it Gitea 1.25 cannot run reusable workflows (workflow_call), so the logic of deploy-app.yml, smoke.yml and ci.yml moves into composite actions under .gitea/actions/, and each repo gets a thin pipeline rendered by tools/gitea-pipeline/render.py from repos.json. .github/workflows is left untouched (Gitea ignores it once .gitea/workflows exists).
58 lines
3.2 KiB
YAML
58 lines
3.2 KiB
YAML
name: Audit - direct push to main
|
|
description: >-
|
|
Tripwire (Gitea port of main-push-audit.yml): if the pushed commit is not tied
|
|
to a merged pull request, open an issue labelled policy-violation + audit.
|
|
Never blocks the push. Uses Gitea's /commits/{sha}/pull API.
|
|
inputs:
|
|
token:
|
|
required: true
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- name: Check commit came from a merged PR
|
|
shell: bash
|
|
env:
|
|
TOKEN: ${{ inputs.token }}
|
|
PUSHER: ${{ github.event.pusher.username || github.event.pusher.login || github.actor }}
|
|
HEAD_MSG: ${{ github.event.head_commit.message }}
|
|
run: |
|
|
set -euo pipefail
|
|
API="$GITHUB_SERVER_URL/api/v1/repos/$GITHUB_REPOSITORY"
|
|
H="Authorization: token $TOKEN"
|
|
SHA="$GITHUB_SHA"; S7="${SHA:0:7}"
|
|
for attempt in 1 2 3 4 5; do
|
|
code=$(curl -s -o pr.json -w '%{http_code}' -H "$H" "$API/commits/$SHA/pull" || echo 000)
|
|
if [ "$code" = 200 ] && python3 -c 'import json,sys; sys.exit(0 if json.load(open("pr.json")).get("merged") else 1)'; then
|
|
echo "OK: commit $S7 came from PR #$(python3 -c 'import json;print(json.load(open("pr.json"))["number"])')"
|
|
exit 0
|
|
fi
|
|
[ "$attempt" -lt 5 ] && sleep 10
|
|
done
|
|
# Ensure both labels exist, collect their ids.
|
|
ids=()
|
|
for L in policy-violation audit; do
|
|
id=$(curl -s -H "$H" "$API/labels?limit=100" | python3 -c "import json,sys; print(next((str(l['id']) for l in json.load(sys.stdin) if l['name']=='$L'),''))")
|
|
if [ -z "$id" ]; then
|
|
color=$([ "$L" = audit ] && echo '#1d76db' || echo '#d93f0b')
|
|
id=$(curl -s -H "$H" -H 'Content-Type: application/json' -X POST "$API/labels" \
|
|
-d "{\"name\":\"$L\",\"color\":\"$color\"}" | python3 -c 'import json,sys;print(json.load(sys.stdin).get("id",""))')
|
|
fi
|
|
[ -n "$id" ] && ids+=("$id")
|
|
done
|
|
MSG=$(printf '%s' "$HEAD_MSG" | head -1)
|
|
python3 - "$S7" "${MSG:-(no message)}" "$PUSHER" "${ids[@]}" > issue.json <<'PY'
|
|
import json, os, sys
|
|
s7, msg, pusher, *ids = sys.argv[1:]
|
|
run = f"{os.environ['GITHUB_SERVER_URL']}/{os.environ['GITHUB_REPOSITORY']}/actions/runs/{os.environ.get('GITHUB_RUN_NUMBER','')}"
|
|
body = "\n".join([
|
|
"**Direct push to `main` detected** - commit was not associated with a merged PR.", "",
|
|
f"- Commit: `{s7}` - {msg}", f"- Pusher: @{pusher}", f"- Workflow run: {run}", "",
|
|
"The project policy is that all changes to `main` go through a pull request so they can be "
|
|
"reviewed before deploying to production. If this push was intentional (hotfix, infra change) "
|
|
"close this issue with a comment explaining why.", "",
|
|
"_Opened automatically by the audit-direct-push action (peptide-e2e)._"])
|
|
print(json.dumps({"title": f"Direct push to main: {s7}", "body": body, "labels": [int(i) for i in ids]}))
|
|
PY
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' -H "$H" -H 'Content-Type: application/json' -X POST "$API/issues" --data-binary @issue.json)
|
|
echo "::warning::Opened audit issue for direct push $S7 (HTTP $code)"
|