Files
Donavan Fritz 591fb5b5d6 auto-log: fetch failing-job log from Gitea API into the details block
New optional inputs (all default to off / safe):
  - auto-log: when true and details is empty, fetch and render the run's
    failing-job log via /api/v1/repos/<repo>/actions/jobs/<id>/logs.
  - token: defaults to github.token (per-run, repo-scoped). Overridable.
  - log-lines: tail-length fallback when no ::error:: annotation present.

Selection heuristic: if any line has ::error::, return those + 12 lines of
context above each (merged windows). Otherwise the last `log-lines` lines.
Timestamp prefixes (act_runner's leading ISO-8601 + Z) are stripped.

The details block already existed; this just makes it cheap for failure
emails to surface the actual build error inline instead of forcing the
reader to click "view run →".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 14:19:32 -05:00

4.1 KiB

action/notify-email

Composite Gitea Action that sends a fritzlab-themed email from a CI workflow. Renders an HTML body (with plain-text fallback) styled to match the websites/fritzlab.net/theme.css palette, and relays via mail.fritzlab.net:25 under the trusted-CIDR rule (no SMTP auth — see k8s-manager skill mail.md).

Gating is the caller's responsibility (typically if: failure()). The action always sends when invoked.

Usage

Minimal failure notification:

- name: notify on failure
  if: failure()
  uses: https://code.fritzlab.net/action/notify-email@v1
  with:
    status: failure
    summary: "agent deploy failed"

With richer context:

- name: notify on failure
  if: failure()
  uses: https://code.fritzlab.net/action/notify-email@v1
  with:
    status: failure
    subject: "agent deploy failed: ${{ github.sha }}"
    summary: "Deploy of ${{ github.sha }} to bob@${{ vars.DEPLOY_HOST }} failed"
    details: |
      Target host: ${{ vars.DEPLOY_HOST }}
      Branch: ${{ github.ref_name }}
    from: agent-ci@fritzlab.net

Auto-include the actual build error from the failing step in the email body:

- name: notify on failure
  if: failure()
  uses: https://code.fritzlab.net/action/notify-email@v1
  with:
    status: failure
    summary: "latchkey build failed"
    auto-log: 'true'
    # token defaults to ${{ github.token }} which has read access to the
    # current repo's actions; no caller-side config needed

auto-log fetches the run's failing-job log via the Gitea API, surfaces the ::error:: annotation context (or the last 40 lines if there isn't one), strips the runner's timestamp prefixes, and renders it in the details block. Skipped if details: is already set (manual takes precedence).

Success notification (e.g. confirm a base-image rebuild cascaded):

- if: success()
  uses: https://code.fritzlab.net/action/notify-email@v1
  with:
    status: success
    summary: "base #${{ github.run_number }} cascaded to runner"

Inputs

Name Required Default Description
summary yes One-line headline rendered at the top of the email body.
status no info failure / success / info — drives accent colour + subject prefix.
subject no summary Mail subject after the status prefix.
details no Multiline preformatted block, rendered in a monospace card.
auto-log no false When true and details is empty, fetch the failing-job log via the Gitea API and render its error context.
token no ${{ github.token }} Gitea API token used for auto-log. The per-run GITHUB_TOKEN normally suffices.
log-lines no 40 Tail length used by auto-log when no ::error:: annotation is found.
to no noc@fritzlab.net Recipient address.
from no ci@fritzlab.net Sender address. Must be permitted by the relay.
smtp-host no mail.fritzlab.net SMTP relay host.
smtp-port no 25 SMTP port.

Auto-injected fields

The action reads the following from ${{ github.* }} and includes them in both HTML and text bodies — callers do not need to pass these:

  • Repository (linked to Gitea repo page)
  • Branch (ref_name)
  • Commit (short SHA linked to commit page)
  • Workflow / job
  • Run number (+ attempt if > 1)
  • Trigger (event_name by actor)
  • "view run" button linking to the Actions run

Status styling

Status Subject prefix Accent
failure [FAILED] red (#fca5a5)
success [OK] green (#86efac)
info [INFO] violet (#7c5cff) — fritzlab default accent

Headers added

  • X-Fritzlab-Status: failure | success | info
  • X-Fritzlab-Source: action/notify-email
  • X-Fritzlab-Repo: <owner>/<repo>

These can be used as Sieve filters in Stalwart to route or tag CI mail.

Why HTML in a CI email

Email clients strip <style> blocks and @import and cannot fetch web fonts, so the fritzlab palette is inlined per-element. Dark-only — fritzlab brand has no light variant. The plain-text alternative covers terminal mail readers and spam-filter previews.