name: Codex Reply description: "Risponde a un commento @codex analizzando issue, cronologia e codice repository." inputs: issue-number: description: Numero dell'issue. required: true repository: description: Repository in formato owner/repo. required: true comment-body: description: Testo del commento che contiene @codex. required: true comment-author: description: Login dell'autore del commento. required: true issue-title: description: Titolo dell'issue. required: true issue-body: description: Corpo dell'issue. required: true api-token: description: Token API Gitea. required: true gitea-host: description: URL del server Gitea. required: false default: "https://git.incloud.ovh" api-key: description: API key per opencode. required: true model: description: Modello AI in formato provider/model. required: false default: "deepseek/deepseek-v4-flash" runs: using: composite steps: - name: Configura autenticazione opencode shell: bash run: | set -euo pipefail if ! command -v jq &> /dev/null; then echo "jq non trovato, tentativo di installazione..." if command -v apt-get &> /dev/null; then apt-get update -qq && apt-get install -y -qq jq 2>&1 || true elif command -v apk &> /dev/null; then apk add --no-cache jq 2>&1 || true fi command -v jq &> /dev/null || { echo "ERRORE: impossibile installare jq."; exit 1; } fi mkdir -p ~/.local/share/opencode jq -n \ --arg provider "opencode-go" \ --arg key "${{ inputs.api-key }}" \ '{($provider): {type: "api", key: $key}}' > ~/.local/share/opencode/auth.json chmod 600 ~/.local/share/opencode/auth.json - name: Rispondi a @codex id: codex shell: bash run: | set -euo pipefail if ! command -v curl &> /dev/null; then echo "curl non trovato, tentativo di installazione..." if command -v apt-get &> /dev/null; then apt-get update -qq && apt-get install -y -qq curl 2>&1 || true elif command -v apk &> /dev/null; then apk add --no-cache curl 2>&1 || true fi command -v curl &> /dev/null || { echo "ERRORE: impossibile installare curl."; exit 1; } fi HOST="${{ inputs.gitea-host }}" TOKEN="${{ inputs.api-token }}" REPO="${{ inputs.repository }}" ISSUE_NUM="${{ inputs.issue-number }}" AUTHOR="${{ inputs.comment-author }}" MODEL_ARG=() [ -n "${{ inputs.model }}" ] && MODEL_ARG=(--model "${{ inputs.model }}") # Estrai la domanda dopo @codex QUERY=$(echo "${{ inputs.comment-body }}" | sed -n 's/.*@codex[[:space:],:]*//p') if [ -z "$QUERY" ]; then QUERY="(nessuna domanda specifica dopo @codex)" fi # Recupera cronologia commenti, escludendo quelli del bot COMMENTS_JSON=$(curl -sS -f "$HOST/api/v1/repos/$REPO/issues/$ISSUE_NUM/comments" \ -H "Authorization: token $TOKEN" \ -H "Accept: application/json" 2>/dev/null || echo "[]") COMMENTS_TEXT=$(echo "$COMMENTS_JSON" | jq -r ' [.[] | select(.user.login != "anuti")] | sort_by(.created_at) | .[-20:] | .[] | "**\(.user.login)**: \(.body)\n" ' 2>/dev/null || echo "") # Costruisci il prompt BODY=$(echo "${{ inputs.issue-body }}" | head -c 10000) [ "${#BODY}" -ge 10000 ] && BODY+=$'\n... (troncato)' printf -v PROMPT '%s\n\n%s\n%s\n\n## %s\n%s\n%s\n\n## %s\n%s\n\n## %s - @%s\n%s' \ "Sei un assistente esperto per repository software." \ "Rispondi alla domanda in modo diretto e tecnico, in italiano." \ "Analizza il codice sorgente nel repository quando e' rilevante." \ "Issue" \ "**Titolo**: ${{ inputs.issue-title }}" \ "**Corpo**: $BODY" \ "Cronologia commenti" "$COMMENTS_TEXT" \ "Domanda" "$AUTHOR" "$QUERY" # Esegui opencode OUTFILE="$GITHUB_WORKSPACE/opencode-codex.txt" opencode run "$PROMPT" "${MODEL_ARG[@]}" --dangerously-skip-permissions 2>&1 | tee "$OUTFILE" # Pulisci la risposta: togli ANSI codes, banner build, righe vuote iniziali ESC=$(printf '\x1b') sed "s/${ESC}\[[0-9;]*m//g" "$OUTFILE" > /tmp/codex-clean.txt RESPONSE=$(sed '/^> build /d; /^[[:space:]]*$/d' /tmp/codex-clean.txt) if [ -z "$RESPONSE" ]; then RESPONSE="Mi dispiace, non ho generato una risposta. Riprova." fi # Pubblica il commento COMMENT_JSON=$(jq -n --arg body "$RESPONSE" '{body: $body}') curl -sS -X POST "$HOST/api/v1/repos/$REPO/issues/$ISSUE_NUM/comments" \ -H "Authorization: token $TOKEN" \ -H "Content-Type: application/json" \ -d "$COMMENT_JSON" 2>/dev/null && \ echo "Risposta @codex pubblicata sull'issue #$ISSUE_NUM" || \ echo "WARN: Impossibile pubblicare la risposta"