diff --git a/.gitea/workflows/opencode.yml b/.gitea/workflows/opencode.yml index 39d2c66..0fc3f89 100644 --- a/.gitea/workflows/opencode.yml +++ b/.gitea/workflows/opencode.yml @@ -1,6 +1,8 @@ name: OpenCode Gitea Integration on: + issues: + types: [opened] issue_comment: types: [created] pull_request_review_comment: @@ -15,8 +17,10 @@ jobs: opencode-gitea: if: | github.event_name == 'workflow_dispatch' || - contains(github.event.comment.body, '/oc') || - contains(github.event.comment.body, '/opencode') + (github.event_name == 'issues' && + (contains(github.event.issue.body, '/oc') || contains(github.event.issue.body, '/opencode'))) || + (github.event_name != 'issues' && + (contains(github.event.comment.body, '/oc') || contains(github.event.comment.body, '/opencode'))) runs-on: ubuntu-latest timeout-minutes: 20 @@ -24,8 +28,9 @@ jobs: GITEA_API_URL: "https://gitea.maribit.it" GITEA_TOKEN: ${{ secrets.BOT_GITEA_TOKEN }} REPO_FULL_NAME: ${{ github.repository }} - COMMENT_BODY: ${{ github.event.comment.body || github.event.inputs.prompt }} - COMMENT_AUTHOR: ${{ github.event.comment.user.login || github.actor }} + COMMENT_BODY: ${{ github.event.comment.body || github.event.issue.body || github.event.inputs.prompt }} + COMMENT_AUTHOR: ${{ github.event.comment.user.login || github.event.issue.user.login || github.actor }} + COMMENT_ID: ${{ github.event.comment.id }} IS_PR_EVENT: ${{ github.event_name == 'pull_request_review_comment' }} IS_MANUAL: ${{ github.event_name == 'workflow_dispatch' }} PR_NUMBER_FROM_EVENT: ${{ github.event.pull_request.number }} @@ -38,10 +43,7 @@ jobs: steps: - name: Verifica autorizzazione utente run: | - # Whitelist esplicita: nessuna esecuzione automatica per utenti non fidati. ALLOWED_USERS="maria nicola" - # L'esecuzione manuale (workflow_dispatch) è già ristretta a chi ha - # permessi di scrittura sul repo, quindi la lasciamo passare. if [ "$IS_MANUAL" = "true" ]; then exit 0 fi @@ -50,6 +52,27 @@ jobs: exit 1 fi + # Feedback immediato: 👀 sul commento (o sulla issue) che ha invocato l'agente. + # Le reazioni NON generano eventi issue_comment -> nessun doppio run. + - name: Reagisci al comando (👀) + id: react + run: | + API="$GITEA_API_URL/api/v1/repos/$REPO_FULL_NAME" + if [ -n "$COMMENT_ID" ]; then + RPATH="issues/comments/$COMMENT_ID/reactions" + elif [ -n "$ISSUE_NUMBER" ]; then + RPATH="issues/$ISSUE_NUMBER/reactions" + else + RPATH="" + fi + echo "path=$RPATH" >> "$GITHUB_OUTPUT" + if [ -n "$RPATH" ]; then + curl -s -X POST "$API/$RPATH" \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"content":"eyes"}' >/dev/null || true + fi + - name: Checkout repository uses: actions/checkout@v4 with: @@ -70,20 +93,16 @@ jobs: API="$GITEA_API_URL/api/v1/repos/$REPO_FULL_NAME" if [ "$IS_MANUAL" = "true" ]; then - # Esecuzione manuale: nessuna issue/PR di contesto, branch dedicato. IS_PR=false PR_NUMBER="" BRANCH_NAME="opencode-manual-$RUN_NUMBER" elif [ "$IS_PR_EVENT" = "true" ]; then - # Commento inline su una review: PR e branch noti dal payload. IS_PR=true PR_NUMBER="$PR_NUMBER_FROM_EVENT" BRANCH_NAME="$PR_HEAD_REF_FROM_EVENT" else - # issue_comment: può essere una issue "pura" o un commento su una PR. + # issue / issue_comment: la chiave "pull_request" c'è sempre ma vale null per le issue. ISSUE_JSON=$(curl -s -H "Authorization: token $GITEA_TOKEN" "$API/issues/$ISSUE_NUMBER") - # NB: l'API Gitea restituisce SEMPRE la chiave "pull_request", - # ma vale null per le issue normali: va controllato il VALORE, non la chiave. if [ "$(echo "$ISSUE_JSON" | jq -r '.pull_request // empty')" != "" ]; then IS_PR=true PR_NUMBER="$ISSUE_NUMBER" @@ -96,9 +115,8 @@ jobs: fi fi - # Rete di sicurezza contro branch vuoti / "null". if [ -z "$BRANCH_NAME" ] || [ "$BRANCH_NAME" = "null" ]; then - echo "BRANCH_NAME non valido ('$BRANCH_NAME'): impossibile determinare il contesto. Interrompo." + echo "BRANCH_NAME non valido ('$BRANCH_NAME'). Interrompo." exit 1 fi @@ -107,18 +125,16 @@ jobs: echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT" if [ "$IS_PR" = "true" ]; then - # Continua sullo STESSO branch della PR esistente (loop di review). git fetch origin "$BRANCH_NAME" git checkout -B "$BRANCH_NAME" "origin/$BRANCH_NAME" elif git ls-remote --exit-code --heads origin "$BRANCH_NAME" >/dev/null 2>&1; then - # Un run precedente ha già creato questo branch: riprendilo. git fetch origin "$BRANCH_NAME" git checkout -B "$BRANCH_NAME" "origin/$BRANCH_NAME" else git checkout -b "$BRANCH_NAME" fi - - name: Raccogli contesto aggiuntivo (diff + commenti di review, se PR) + - name: Raccogli contesto aggiuntivo (diff + commenti, se PR) run: | API="$GITEA_API_URL/api/v1/repos/$REPO_FULL_NAME" : > /tmp/context.txt @@ -168,28 +184,30 @@ jobs: git commit -m "OpenCode (big-pickle): $BRANCH_NAME" git push origin "$BRANCH_NAME" - # Apri una PR solo se stiamo partendo da zero (issue o run manuale), - # non se stiamo già iterando su una PR esistente. if [ "${{ steps.ctx.outputs.is_pr }}" != "true" ]; then - TITLE="PR Automatica OpenCode: $BRANCH_NAME" curl -s -X POST "$API/pulls" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ - -d "{\"base\":\"main\",\"head\":\"$BRANCH_NAME\",\"title\":\"$TITLE\",\"body\":\"Generata da big-pickle su richiesta di @$COMMENT_AUTHOR.\"}" + -d "{\"base\":\"main\",\"head\":\"$BRANCH_NAME\",\"title\":\"PR Automatica OpenCode: $BRANCH_NAME\",\"body\":\"Generata da big-pickle su richiesta di @$COMMENT_AUTHOR.\"}" fi - - name: Commenta l'esito - if: always() + # Stato finale via reazione (niente commenti -> niente self-trigger). + - name: Reazione finale 🚀 + if: success() && steps.react.outputs.path != '' continue-on-error: true run: | API="$GITEA_API_URL/api/v1/repos/$REPO_FULL_NAME" - TARGET="${{ steps.ctx.outputs.pr_number || env.ISSUE_NUMBER }}" - # Su esecuzione manuale non c'è una issue/PR di partenza su cui commentare. - if [ -z "$TARGET" ]; then - echo "Nessun target su cui commentare (probabile run manuale). Salto." - exit 0 - fi - curl -sS -X POST "$API/issues/$TARGET/comments" \ + curl -s -X POST "$API/${{ steps.react.outputs.path }}" \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ - -d "{\"body\":\"🤖 OpenCode ha completato l'elaborazione della richiesta di @$COMMENT_AUTHOR.\"}" \ No newline at end of file + -d '{"content":"rocket"}' >/dev/null || true + + - name: Reazione finale 😕 (fallimento) + if: failure() && steps.react.outputs.path != '' + continue-on-error: true + run: | + API="$GITEA_API_URL/api/v1/repos/$REPO_FULL_NAME" + curl -s -X POST "$API/${{ steps.react.outputs.path }}" \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"content":"confused"}' >/dev/null || true \ No newline at end of file