# Alerte pe iPhone pentru eșecurile din GitHub Actions

> Eșecurile din GitHub Actions ajung pe iPhone prin webhookul GitHub, fără să schimbi workflow-urile, sau cu un singur pas, plus o revenire când e iar verde.

Source: https://honk-honk.app/ro/ghiduri/alerte-esec-github-actions

GitHub te poate anunța deja despre rulările de workflow. Activezi în aplicația GitHub Mobile notificările pentru Actions și primești o notificare pentru rulările pornite de tine. Dacă îți ajunge atât, nu mai ai nimic de făcut.

Honk e pentru când ai nevoie de mai mult: eșecuri din multe repository-uri, inclusiv rulările pornite de alții, adunate câte un grup pe workflow și branch, în același inbox cu serverele și joburile cron, plus o revenire când branch-ul e din nou verde. Cel mai rapid e să conectezi webhookul GitHub la Honk: un singur URL și nicio schimbare în workflow-uri. Dacă preferi să decizi chiar în workflow, a doua jumătate a ghidului adaugă un singur pas la finalul unui job.

## Înainte să începi

- Un cont Honk. Deocamdată, Honk e disponibil doar pe bază de invitație: [cere acces](https://honk-honk.app/ro/cere-acces).
- Un proiect pentru CI, într-un spațiu de lucru în care ești proprietar sau administrator.
- Drepturi de admin pe repository sau pe organizație, în GitHub.

## 1. Conectează GitHub în Honk

În aplicația web Honk, deschide proiectul, mergi la **Conexiuni** și apasă **Conectează un serviciu**. Alege **GitHub** și apasă **Conectează**. Honk îți arată URL-ul conexiunii, la **URL de webhook**. Începe cu `https://honk-honk.app/v1/hooks/github/`.

La **Secret de semnare**, apasă **Generează**, copiază secretul, apoi apasă **Salvează secretul**. GitHub semnează fiecare livrare cu el, iar Honk le respinge pe cele care nu se potrivesc. După salvare, Honk nu mai afișează secretul.

## 2. Adaugă webhookul în GitHub

În repository, deschide **Settings ▸ Webhooks** și apasă **Add webhook**. Ca să acoperi deodată toate repository-urile, folosește în schimb **Settings ▸ Webhooks** din organizație. Apoi completează:

- **Payload URL**: URL-ul de la Honk.
- **Content type**: `application/json`. Honk nu poate citi codificarea de formular, care e implicită în GitHub.
- **Secret**: secretul pe care l-ai generat.
- **Which events would you like to trigger this webhook?**: alege **Let me select individual events** și bifează **Workflow runs**, plus **Deployment statuses**, **Releases** și **Issues**, dacă le vrei și pe acestea.

Apasă **Add webhook**. GitHub trimite imediat un ping, iar conexiunea din Honk îl arată ca ultimă livrare.

## 3. Verifică livrările

Tabul **Recent Deliveries** al webhookului din GitHub arată fiecare livrare, cu răspunsul lui Honk: `202` când Honk a acceptat-o, inclusiv pentru tipurile de evenimente pe care le ignoră, și `401` când semnătura nu se potrivește. În Honk, conexiunea arată ora ultimei livrări sau ultima eroare.

_Serviciile conectate ale unui proiect Honk: Stripe, Shopify, Uptime Kuma și Sentry, fiecare cu ora ultimei livrări și cu starea secretului._

Următoarea rulare care eșuează, pe orice branch, te anunță. Nu-ți mai trebuie nimic: niciun secret în repository, niciun pas de adăugat, iar toate workflow-urile sunt acoperite, inclusiv cele noi.

## Ce devine fiecare eveniment

- **O rulare eșuată** (`workflow_run`), inclusiv una care n-a pornit sau a depășit timpul: o problemă, un Claxon lung cu titlul „CI failed on main · acme/api” (titlurile vin în engleză), cu numărul rulării, cine a pornit-o, mesajul commitului și un link către rulare. Câte un grup pe repository, workflow și branch.
- **Următoarea rulare reușită** pe același branch: o revenire, „CI passed on main · acme/api”, care închide problema. Un succes fără un eșec înainte e ignorat, așa că un branch sănătos nu te deranjează niciodată. Rulările anulate și cele sărite sunt ignorate.
- **Un deploy eșuat** (`deployment_status`): o problemă, un Claxon lung, câte un grup pe repository și mediu. Următorul deploy reușit o închide, iar unul reușit fără un eșec înainte e un Bip-bip, „Deployed to production · acme/api”.
- **Un release publicat** (`release`): un Claxon ușor, cu notele release-ului.
- **Un issue deschis** (`issues`): un Claxon ușor, câte un grup pe issue.

La **Evenimente care devin mesaje**, pe conexiune, debifează ce nu vrei și apasă **Salvează**. Fiecare conexiune intră în limita planului spațiului tău de lucru: Free include 2, Pro 20 și Team 100. Mesajele intră în limitele zilnice ale planului, ca oricare altele; le găsești la [prețuri](https://honk-honk.app/ro/preturi).

## Sau: un pas în workflow

Fără conexiune, un pas de la finalul unui job poate raporta singur eșecul. Alegi pentru fiecare job ce trimiți, și merge și acolo unde nu poți adăuga un webhook. Folosește o variantă sau cealaltă pentru aceleași workflow-uri: cu amândouă, ai afla de fiecare eșec de două ori.

Varianta asta are nevoie de o cheie API: în aplicația web, deschide proiectul, apoi **Chei**, și creează una.

### Salvează URL-ul și cheia ca secrete

Secretele de repository merg pentru un singur repository, iar cele de organizație te scutesc să repeți pasul peste tot. Cu GitHub CLI:

```sh
# with the GitHub CLI, for one repository (or use --org for all of them)
gh secret set HONK_URL --body "https://honk-honk.app"
gh secret set HONK_KEY        # paste the ingestion key when asked
```

### Adaugă un pas care rulează doar la eșec

Pune pasul ăsta ultimul în jobul care te interesează. `if: failure()` îl rulează doar dacă a eșuat un pas anterior. Folosește `jq` și `curl`, care există deja pe orice runner găzduit de GitHub, deci nu ai nimic de instalat:

```yaml
      - name: Tell Honk
        if: failure()
        env:
          HONK_URL: ${{ secrets.HONK_URL }}
          HONK_KEY: ${{ secrets.HONK_KEY }}
          WORKFLOW: ${{ github.workflow }}
          REPO: ${{ github.repository }}
          BRANCH: ${{ github.ref_name }}
          RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
          ATTEMPT: ${{ github.run_id }}-${{ github.run_attempt }}
        run: |
          jq -n --arg title "CI failed: $WORKFLOW on $BRANCH" --arg url "$RUN_URL" --arg key "ci/$REPO/$BRANCH" \
            '{title: $title, message: $url, url: $url, severity: "long", event_type: "problem",
              group_key: $key, source: "github-actions", category: "deployments"}' |
          curl -sS --max-time 10 --retry 3 --retry-all-errors "$HONK_URL/v1/messages" \
            -H "Authorization: Bearer $HONK_KEY" -H "Content-Type: application/json" \
            -H "Idempotency-Key: gh-$ATTEMPT" --data-binary @- || true
```

Câteva alegeri de aici contează:

- **Cheia de grup e formată din repository și branch**, `ci/acme/api/main`. Primul eșec pe `main` te anunță; următoarele eșecuri pe `main` intră în același grup și devin actualizări discrete. Un eșec pe alt branch are grupul lui.
- **Cheia de idempotență e ID-ul rulării plus numărul încercării.** Dacă curl reîncearcă după un răspuns pierdut, Honk întoarce evenimentul original în loc să creeze altul. Când apeși însă **Re-run**, noua încercare e un eveniment nou.
- **`jq` construiește JSON-ul**, așa că ghilimelele din numele unui workflow sau al unui branch nu pot strica cererea.
- **`|| true`**: dacă Honk e indisponibil, un build eșuat nu se transformă niciodată într-un alt fel de eșec.

### Opțional: o revenire când e din nou verde

Ca să închizi incidentul când branch-ul trece din nou, adaugă un al doilea pas, care rulează la succes. El întreabă GitHub dacă rularea anterioară de pe branch a eșuat și abia atunci raportează o revenire:

```yaml
      # needs `permissions: actions: read` when the workflow restricts the token
      - name: Tell Honk it works again
        if: success()
        env:
          GH_TOKEN: ${{ github.token }}
          HONK_URL: ${{ secrets.HONK_URL }}
          HONK_KEY: ${{ secrets.HONK_KEY }}
          WORKFLOW: ${{ github.workflow }}
          REPO: ${{ github.repository }}
          BRANCH: ${{ github.ref_name }}
          ATTEMPT: ${{ github.run_id }}-${{ github.run_attempt }}
        run: |
          previous=$(gh run list --repo "$REPO" --workflow "$WORKFLOW" --branch "$BRANCH" \
            --limit 2 --json conclusion --jq '.[1].conclusion')
          [ "$previous" = "failure" ] || exit 0
          jq -n --arg title "CI green again: $WORKFLOW on $BRANCH" --arg key "ci/$REPO/$BRANCH" \
            '{title: $title, message: "The last run passed.", severity: "beep", event_type: "recovery",
              group_key: $key, source: "github-actions", category: "deployments"}' |
          curl -sS --max-time 10 --retry 3 --retry-all-errors "$HONK_URL/v1/messages" \
            -H "Authorization: Bearer $HONK_KEY" -H "Content-Type: application/json" \
            -H "Idempotency-Key: gh-$ATTEMPT-ok" --data-binary @- || true
```

Fără pasul ăsta nu se strică nimic: un episod fără evenimente noi devine inactiv după 24 de ore, iar următorul eșec deschide unul nou și te anunță din nou.

### Același lucru cu CLI-ul honk

Dacă preferi [CLI-ul honk](https://honk-honk.app/ro/integrari/cli), care se ocupă singur de reîncercări, cu o singură cheie de idempotență și o limită totală de timp, instalează-l în pași care rulează doar la eșec și apelează `uhoh`. Go e deja instalat pe runnerele Linux găzduite de GitHub:

```yaml
      - name: Install the honk CLI
        if: failure()
        run: |
          go install github.com/honk-hq/go/cmd/honk@latest
          echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

      - name: Notify
        if: failure()
        env:
          HONK_URL: ${{ secrets.HONK_URL }}
          HONK_KEY: ${{ secrets.HONK_KEY }}
        run: |
          honk uhoh --group-key "ci/${{ github.repository }}/${{ github.ref_name }}" \
            --title "CI failed: ${{ github.workflow }}" --message "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
            --source github-actions --category deployments \
            --idempotency-key "gh-${{ github.run_id }}-${{ github.run_attempt }}" || true
```

## Ce primești

Primul eșec pe `main` vine ca Claxon lung în [Honk pentru iPhone](https://honk-honk.app/ro/iphone), iar din inbox deschizi rularea cu o atingere. Repetările de pe același branch actualizează un singur grup în loc să-ți mai vibreze telefonul, iar orele de liniște țin eșecurile din CI până dimineață, dacă nu sunt urgente. [Ghidul pentru deploy-uri](https://honk-honk.app/ro/ghiduri/notificari-deploy) îți arată și cum îi spui lui Honk despre deploy-urile reușite, iar [ghidul pentru Sentry](https://honk-honk.app/ro/ghiduri/alerte-sentry-iphone) adaugă erorile pe care le aruncă aplicația ta după lansare.
