Aggiunge action codex-reply e workflow @codex
This commit is contained in:
136
codex-reply/action.yml
Normal file
136
codex-reply/action.yml
Normal file
@@ -0,0 +1,136 @@
|
||||
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"
|
||||
Reference in New Issue
Block a user